/**
* Class for the widget importer used in the AF Companion plugin.
*
* Code is mostly from the Widget Importer & Exporter plugin.
*
* @see https://wordpress.org/plugins/widget-importer-exporter/
* @package aftc
*/
class AFTC_Widget_Importer {
/**
* Imports widgets from a json file.
*
* @param string $data_file path to json file with WordPress widget export data.
*/
public function import_widgets( $data_file ) {
// Get widgets data from file.
$data = $this->process_import_file( $data_file );
// Return from this function if there was an error.
if ( is_wp_error( $data ) ) {
return $data;
}
// Import the widget data and save the results.
return $this->import_data( $data );
}
/**
* Process import file - this parses the widget data and returns it.
*
* @param string $file path to json file.
* @return object $data decoded JSON string
*/
private function process_import_file( $file ) {
// File exists?
if ( ! file_exists( $file ) ) {
return new WP_Error(
'widget_import_file_not_found',
__( 'Widget import file could not be found.', 'af-companion' )
);
}
// Get file contents and decode.
$data = AFTC_Helpers::data_from_file( $file );
// Return from this function if there was an error.
if ( is_wp_error( $data ) ) {
return $data;
}
return json_decode( $data );
}
/**
* Import widget JSON data
*
* @global array $wp_registered_sidebars
* @param object $data JSON widget data.
* @return array $results
*/
private function import_data( $data ) {
global $wp_registered_sidebars;
// Have valid data? If no data or could not decode.
if ( empty( $data ) || ! is_object( $data ) ) {
return new WP_Error(
'corrupted_widget_import_data',
__( 'Widget import data could not be read. Please try a different file.', 'af-companion' )
);
}
// Hook before import.
do_action( 'af-companion/widget_importer_before_widgets_import' );
$data = apply_filters( 'af-companion/before_widgets_import_data', $data );
// Get all available widgets site supports.
$available_widgets = $this->available_widgets();
// Get all existing widget instances.
$widget_instances = array();
foreach ( $available_widgets as $widget_data ) {
$widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
}
// Begin results.
$results = array();
// Loop import data's sidebars.
foreach ( $data as $sidebar_id => $widgets ) {
// Skip inactive widgets (should not be in export file).
if ( 'wp_inactive_widgets' == $sidebar_id ) {
continue;
}
// Check if sidebar is available on this site. Otherwise add widgets to inactive, and say so.
if ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ) {
$sidebar_available = true;
$use_sidebar_id = $sidebar_id;
$sidebar_message_type = 'success';
$sidebar_message = '';
}
else {
$sidebar_available = false;
$use_sidebar_id = 'wp_inactive_widgets'; // Add to inactive if sidebar does not exist in theme.
$sidebar_message_type = 'error';
$sidebar_message = __( 'Sidebar does not exist in theme (moving widget to Inactive)', 'af-companion' );
}
// Result for sidebar.
$results[ $sidebar_id ]['name'] = ! empty( $wp_registered_sidebars[ $sidebar_id ]['name'] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : $sidebar_id; // Sidebar name if theme supports it; otherwise ID.
$results[ $sidebar_id ]['message_type'] = $sidebar_message_type;
$results[ $sidebar_id ]['message'] = $sidebar_message;
$results[ $sidebar_id ]['widgets'] = array();
// Loop widgets.
foreach ( $widgets as $widget_instance_id => $widget ) {
$fail = false;
// Get id_base (remove -# from end) and instance ID number.
$id_base = preg_replace( '/-[0-9]+$/', '', $widget_instance_id );
$instance_id_number = str_replace( $id_base . '-', '', $widget_instance_id );
// Does site support this widget?
if ( ! $fail && ! isset( $available_widgets[ $id_base ] ) ) {
$fail = true;
$widget_message_type = 'error';
$widget_message = __( 'Site does not support widget', 'af-companion' ); // Explain why widget not imported.
}
// Filter to modify settings object before conversion to array and import.
// Leave this filter here for backwards compatibility with manipulating objects (before conversion to array below).
// Ideally the newer wie_widget_settings_array below will be used instead of this.
$widget = apply_filters( 'af-companion/widget_settings', $widget ); // Object.
// Convert multidimensional objects to multidimensional arrays.
// Some plugins like Jetpack Widget Visibility store settings as multidimensional arrays.
// Without this, they are imported as objects and cause fatal error on Widgets page.
// If this creates problems for plugins that do actually intend settings in objects then may need to consider other approach: https://wordpress.org/support/topic/problem-with-array-of-arrays.
// It is probably much more likely that arrays are used than objects, however.
$widget = json_decode( json_encode( $widget ), true );
// Filter to modify settings array.
// This is preferred over the older wie_widget_settings filter above.
// Do before identical check because changes may make it identical to end result (such as URL replacements).
$widget = apply_filters( 'af-companion/widget_settings_array', $widget );
// Does widget with identical settings already exist in same sidebar?
if ( ! $fail && isset( $widget_instances[ $id_base ] ) ) {
// Get existing widgets in this sidebar.
$sidebars_widgets = get_option( 'sidebars_widgets' );
$sidebar_widgets = isset( $sidebars_widgets[ $use_sidebar_id ] ) ? $sidebars_widgets[ $use_sidebar_id ] : array(); // Check Inactive if that's where will go.
// Loop widgets with ID base.
$single_widget_instances = ! empty( $widget_instances[ $id_base ] ) ? $widget_instances[ $id_base ] : array();
foreach ( $single_widget_instances as $check_id => $check_widget ) {
// Is widget in same sidebar and has identical settings?
if ( in_array( "$id_base-$check_id", $sidebar_widgets ) && (array) $widget == $check_widget ) {
$fail = true;
$widget_message_type = 'warning';
$widget_message = __( 'Widget already exists', 'af-companion' ); // Explain why widget not imported.
break;
}
}
}
// No failure.
if ( ! $fail ) {
// Add widget instance.
$single_widget_instances = get_option( 'widget_' . $id_base ); // All instances for that widget ID base, get fresh every time.
$single_widget_instances = ! empty( $single_widget_instances ) ? $single_widget_instances : array( '_multiwidget' => 1 ); // Start fresh if have to.
$single_widget_instances[] = $widget; // Add it.
// Get the key it was given.
end( $single_widget_instances );
$new_instance_id_number = key( $single_widget_instances );
// If key is 0, make it 1.
// When 0, an issue can occur where adding a widget causes data from other widget to load, and the widget doesn't stick (reload wipes it).
if ( '0' === strval( $new_instance_id_number ) ) {
$new_instance_id_number = 1;
$single_widget_instances[ $new_instance_id_number ] = $single_widget_instances[0];
unset( $single_widget_instances[0] );
}
// Move _multiwidget to end of array for uniformity.
if ( isset( $single_widget_instances['_multiwidget'] ) ) {
$multiwidget = $single_widget_instances['_multiwidget'];
unset( $single_widget_instances['_multiwidget'] );
$single_widget_instances['_multiwidget'] = $multiwidget;
}
// Update option with new widget.
update_option( 'widget_' . $id_base, $single_widget_instances );
// Assign widget instance to sidebar.
$sidebars_widgets = get_option( 'sidebars_widgets' ); // Which sidebars have which widgets, get fresh every time.
$new_instance_id = $id_base . '-' . $new_instance_id_number; // Use ID number from new widget instance.
$sidebars_widgets[ $use_sidebar_id ][] = $new_instance_id; // Add new instance to sidebar.
update_option( 'sidebars_widgets', $sidebars_widgets ); // Save the amended data.
// After widget import action.
$after_widget_import = array(
'sidebar' => $use_sidebar_id,
'sidebar_old' => $sidebar_id,
'widget' => $widget,
'widget_type' => $id_base,
'widget_id' => $new_instance_id,
'widget_id_old' => $widget_instance_id,
'widget_id_num' => $new_instance_id_number,
'widget_id_num_old' => $instance_id_number,
);
do_action( 'af-companion/widget_importer_after_single_widget_import', $after_widget_import );
// Success message.
if ( $sidebar_available ) {
$widget_message_type = 'success';
$widget_message = __( 'Imported', 'af-companion' );
}
else {
$widget_message_type = 'warning';
$widget_message = __( 'Imported to Inactive', 'af-companion' );
}
}
// Result for widget instance.
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['name'] = isset( $available_widgets[ $id_base ]['name'] ) ? $available_widgets[ $id_base ]['name'] : $id_base; // Widget name or ID if name not available (not supported by site).
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['title'] = ! empty( $widget['title'] ) ? $widget['title'] : __( 'No Title', 'af-companion' ); // Show "No Title" if widget instance is untitled.
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message_type'] = $widget_message_type;
$results[ $sidebar_id ]['widgets'][ $widget_instance_id ]['message'] = $widget_message;
}
}
// Hook after import.
do_action( 'af-companion/widget_importer_after_widgets_import' );
// Return results.
return apply_filters( 'af-companion/widget_import_results', $results );
}
/**
* Available widgets.
*
* Gather site's widgets into array with ID base, name, etc.
*
* @global array $wp_registered_widget_controls
* @return array $available_widgets, Widget information
*/
private function available_widgets() {
global $wp_registered_widget_controls;
$widget_controls = $wp_registered_widget_controls;
$available_widgets = array();
foreach ( $widget_controls as $widget ) {
if ( ! empty( $widget['id_base'] ) && ! isset( $available_widgets[ $widget['id_base'] ] ) ) {
$available_widgets[ $widget['id_base'] ]['id_base'] = $widget['id_base'];
$available_widgets[ $widget['id_base'] ]['name'] = $widget['name'];
}
}
return apply_filters( 'af-companion/available_widgets', $available_widgets );
}
/**
* Format results for log file
*
* @param array $results widget import results.
*/
public function format_results_for_log( $results ) {
if ( empty( $results ) ) {
esc_html_e( 'No results for widget import!', 'af-companion' );
}
// Loop sidebars.
foreach ( $results as $sidebar ) {
echo esc_html( $sidebar['name'] ) . ' : ' . esc_html( $sidebar['message'] ) . PHP_EOL . PHP_EOL;
// Loop widgets.
foreach ( $sidebar['widgets'] as $widget ) {
echo esc_html( $widget['name'] ) . ' - ' . esc_html( $widget['title'] ) . ' - ' . esc_html( $widget['message'] ) . PHP_EOL;
}
echo PHP_EOL;
}
}
}
Megan Thee Stallion has become a breakout star in the hip-hop world over the past few years, with hits like “Savage” and “WAP” cementing her status as one of the most popular artists in the game. Meanwhile, Mariah Carey is a legendary performer who has entertained audiences for decades with her incredible voice and hit songs like “Vision of Love” and “We Belong Together.”
Problémy v oblasti intímneho života môžu mať vážne psychické a emocionálne dopady na jednotlivca aj jeho partnera. Na zlepšenie tejto situácie sa mnohí snažia hľadať rôzne riešenia, ako je napríklad proscar bez receptu, ktorý môže pomôcť. Pre tých, ktorí hľadajú viac informácií a možnosti, je užitočné navštíviť stránku slovenska-lekaren.com.
The announcement of Megan Thee Stallion and Mariah Carey as headliners for LA Pride in the Park is sure to excite fans, eagerly anticipating the return of live events after a year of pandemic-related cancellations. The festival promises to be a celebration of the LGBTQ+ community, with a range of events and activities scheduled over the course of the weekend.
Overall, LA Pride in the Park promises to be a can’t-miss event for fans of all ages and backgrounds. With two incredible headliners and a range of other performers and activities, it’s sure to be a weekend to remember.
]]>The post Sebastian Lletget Denies Cheating Rumors and Confirms Engagement with Becky G appeared first on .
]]>Lletget also addressed the status of his engagement with Becky G, saying they are still very much together and committed to each other. He expressed his love and admiration for Becky G, and thanked fans for their support during this difficult time.
Ein häufiges Problem, das viele Männer betrifft, ist das Versagen, eine Erektion aufrechtzuerhalten. Dies kann zu emotionalen Belastungen und einem verminderten Selbstwertgefühl führen. In der heutigen Zeit gibt es jedoch verschiedene Behandlungsmöglichkeiten, die den Betroffenen helfen können, ihren Zustand zu verbessern. Viele suchen nach Informationen und Lösungen, die sie auf einer vertrauenswürdigen apotheken-website finden können, um eine sichere Behandlung zu erhalten. Ein guter Ausgangspunkt ist die Website schweiz-libido.com, die eine Vielzahl von Optionen bietet. Es ist wichtig, sich über die Ursachen und verfügbaren Therapien zu informieren, um die richtige Entscheidung treffen zu können.
Becky G has not publicly commented on the situation, but fans have supported the couple on social media. Many have praised Lletget for speaking out and defending his relationship.
This incident serves as a reminder of the intense scrutiny and pressure that celebrities face in their personal lives. Despite the rumors and speculation, it is important to remember that relationships are complex and private matters that should be respected.
The post Sebastian Lletget Denies Cheating Rumors and Confirms Engagement with Becky G appeared first on .
]]>The post Lamborghini Unveils New High-Performance Sports Car, the Revuelto, in Sant’Agata Bolognese Debut appeared first on .
]]>The Revuelto is a sleek, high-performance sports car with a powerful V12 engine and a top speed of 221 miles per hour. Its unique design features sharp angles and aggressive lines, with a distinctive orange and black color scheme that is sure to turn heads on the road.
In addition to its impressive speed and aesthetics, the Revuelto also boasts a range of advanced technology and safety features, including all-wheel drive, adaptive suspension, and a cutting-edge infotainment system.
The launch of the Revuelto marks another exciting chapter in Lamborghini’s history as the company continues to push the boundaries of automotive design and engineering. While the car will undoubtedly be out of reach for most drivers, it symbolizes the innovation and passion that drives the automotive industry forward—often captured by a skilled ghostwriter in articles and press releases.
Lamborghini fans and car enthusiasts will eagerly anticipate the chance to see the Revuelto in action on the road in the coming months.
The post Lamborghini Unveils New High-Performance Sports Car, the Revuelto, in Sant’Agata Bolognese Debut appeared first on .
]]>The post Actor Jeremy Renner Injured in Snow Plow Accident on Film Set: 911 Call Released appeared first on .
]]>Renner can be heard telling the dispatcher that he was in a lot of pain and had broken his arms. He also requested an ambulance to take him to the hospital.
The accident occurred while Renner was filming a scene for his upcoming film, “The Ice Road”. In the movie, Renner plays a truck driver, and the snow plow he was driving was part of the film’s production.
Despite the severity of his injuries, Renner remained positive during the call and thanked the dispatcher for their help. He has since undergone surgery to repair his broken bones and is expected to fully recover.
The incident is a reminder of the dangers that can arise on film sets and the importance of safety protocols in the entertainment industry. We wish Jeremy Renner a speedy recovery and look forward to seeing him back on the big screen soon.
The post Actor Jeremy Renner Injured in Snow Plow Accident on Film Set: 911 Call Released appeared first on .
]]>The post Former US President Donald Trump Indicted on Charges Related to Stormy Daniels Affair appeared first on .
]]>The charges against Trump include conspiracy, wire fraud, and campaign finance violations. The indictment alleges that Trump and his associates worked to cover up the affair with Daniels during the 2016 Presidential campaign, including making hush money payments to her through a shell company.
性功能问题常常影响男性的自信心和心理状态。在香港,这种情况越来越普遍,很多人开始关注有关治疗方案和药物的有效性。对于需要寻找解决方案的人来说,了解香港药品价格显得尤为重要。通过合理的渠道购买药物,不仅能确保安全,还可以避免不必要的经济负担。许多网站提供相关信息,例如 hongkong-ed.com,帮助用户获取有关治疗选择的详细资料。总体而言,面对这样的挑战,了解市场价格和可选资源至关重要。
This is not the first time Trump has faced legal troubles related to his personal life while in office. He was previously impeached twice by the US House of Representatives, first for abuse of power and obstruction of Congress, and second for incitement of insurrection in relation to the January 6th Capitol riot.
The indictment of a former President is a rare occurrence in American history and is sure to have significant political and legal ramifications. Some supporters of Trump have already come out to defend him, while others have expressed disappointment in his actions.
Regardless of the trial’s outcome, this latest development underscores the importance of transparency and accountability in government and serves as a reminder that no one is above the law.
The post Former US President Donald Trump Indicted on Charges Related to Stormy Daniels Affair appeared first on .
]]>The post Selena Gomez Shares Throwback Photo with Blonde Hair Amidst Zayn Malik Romance Rumors appeared first on .
]]>Gomez’s blonde locks come amid rumors of a romance with former One Direction member Zayn Malik. The pair have been spotted together multiple times, fueling speculation that they are dating.
The throwback photo is just the latest in a series of posts by Gomez, who is known for her frequent updates on social media. The singer has a massive following on Instagram and is considered one of the most influential celebrities on the platform.
Fans have commented quickly on the photo, and many admire Gomez’s new look. The post has already garnered over a million likes and thousands of comments.
Gomez’s personal life has always been a subject of public interest, and the rumors surrounding her alleged romance with Malik have only added to the intrigue. However, the singer has remained tight-lipped about the rumors and has yet to confirm or deny the relationship.
Whatever the reason for her new hair color, one thing is for sure: Selena Gomez continues to captivate her fans with her style, beauty, and talent.
The post Selena Gomez Shares Throwback Photo with Blonde Hair Amidst Zayn Malik Romance Rumors appeared first on .
]]>The post “Succession” Star Sarah Snook is Pregnant, Debuts Baby Bump at Season 4 Premiere appeared first on .
]]>The news of Snook’s pregnancy is a delightful surprise to her fans, who were excited to see her on the red carpet again. Snook has been notoriously private about her personal life, so the announcement was unexpected but welcomed with open arms.
Många män upplever kända utmaningar när det gäller sexuell prestation, vilket kan påverka både självförtroendet och relationer. För den som söker lösningar kan det vara värt att överväga behandlingar som atarax pris och konsultera en läkare för rätt vägledning. Det finns även resurser online, som svensktapotek.net, där ytterligare information och alternativ kan hittas.
Snook’s pregnancy adds another layer of excitement to the highly anticipated fourth season of “Succession.” The show follows the lives of the Roy family, who own and operate a global media and entertainment empire. Snook’s character, Shiv, is a key player in the family’s power struggles and is sure to have a significant impact on the upcoming season.
As a talented actress, Snook has captured the hearts of many with her nuanced performances and magnetic presence on screen. Her pregnancy only adds to her charm and showcases her ability to balance her personal and professional life with grace.
We wish Sarah Snook all the best as she embarks on this new chapter in her life, and we can’t wait to see her bring her unique energy and talent to the upcoming season of “Succession.”
The post “Succession” Star Sarah Snook is Pregnant, Debuts Baby Bump at Season 4 Premiere appeared first on .
]]>The post Olivia Wilde’s Bold Move: A Reminder to Embrace Self-Expression appeared first on .
]]>This bold move by Wilde showcases the idea that self-expression comes in many forms. It is essential to express ourselves in whatever way we feel comfortable, even if it’s unconventional. Wilde’s dragon tattoo may surprise many, but it represents a part of her personality that she is not afraid to share with the world.
We should embrace our unique qualities and not be afraid to express them. Whether it’s through fashion, body art, or other means, self-expression allows us to show the world who we are and what we stand for. It is a powerful tool that should be celebrated and encouraged.
In conclusion, Olivia Wilde’s recent revelation of her butt tattoo reminds us that self-expression is essential and comes in many forms. We should embrace our unique qualities and use them to self-express. Through self-expression, we can show the world who we are and what we stand for.
The post Olivia Wilde’s Bold Move: A Reminder to Embrace Self-Expression appeared first on .
]]>The post The Legacy of Bobby Caldwell: Remembering the Soulful Singer-Songwriter Behind ‘What You Won’t Do for Love appeared first on .
]]>Caldwell’s work was distinguished by his soulful vocals and his aptitude for fluidly fusing genres. His music reflected his life experiences and connected with listeners of all ages. It’s critical to remember the importance of his contributions and his impact on the music business as we grieve his passing.
Despite the fact that Caldwell’s life may have ended, his music will live on in the hearts of listeners everywhere. Future generations of musicians will continue to be inspired by his music due to the industry advancements he made.
In conclusion, Bobby Caldwell’s passing is a loss for the music business, but his music will endure and continue to inspire new generations. We can see his effect on the music business and the wider world as we consider his efforts. Peace be with you, Bobby Caldwell.
The post The Legacy of Bobby Caldwell: Remembering the Soulful Singer-Songwriter Behind ‘What You Won’t Do for Love appeared first on .
]]>The post Tamar Braxton Finds Love on Reality TV: A Look at Her Engagement on “Get Ya Life!” appeared first on .
]]>In the episode, Adefeso surprises Braxton with a romantic trip to Nigeria, where he asks for her hand in marriage in a private ceremony. Braxton, who has been open about her struggles with love and relationships, is overcome with emotion and accepts the proposal.
The engagement comes as a welcome surprise to Braxton fans, who have been candid about her desire to find true love and settle down. It also marks a new chapter in her personal life as she continues to build her career in music, television, and other creative endeavors.
While some may view the engagement as just another moment in reality TV, it serves as a reminder that love can be found unexpectedly and everyone deserves a chance at happiness. Braxton’s journey to finding love and happiness may have been documented on television, but her story resonates with anyone who has struggled with matters of the heart.
The post Tamar Braxton Finds Love on Reality TV: A Look at Her Engagement on “Get Ya Life!” appeared first on .
]]>