: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Singleton variable to save menu locations.
public static $navMenuLocations;
* Singleton variable to save menu items on which popup is set.
public static $navMenuItems;
public function __construct()
* Initialize actions and filters.
add_action('wp_nav_menu_item_custom_fields', array($this, 'fields'), 10, 4);
add_action('wp_update_nav_menu_item', array($this, 'save'), 10, 2);
add_filter('nav_menu_css_class', array($this, 'addPopupTriggeringClass'), 10, 2);
add_filter('wp_setup_nav_menu_item', array($this, 'addCustomNavFields'));
add_filter('sgpbLoadablePopups', array($this, 'addPopupToLoad'));
public function addPopupTriggeringClass($classes, $menuItem)
if (!isset($menuItem->sgpbPopupId)) {
$popupId = $menuItem->sgpbPopupId;
if ($popupId && !in_array('sg-popup-id-'.$popupId, $classes)) {
array_push($classes, 'sg-popup-id-'.$popupId);
public function addPopupToLoad($popups) {
$registeredMenus = $this->getNavMenuLocations();
/* Will only return menu items on which popup is set */
$menuItems = $this->getNavMenuItemsWithPopup($registeredMenus);
foreach ($menuItems as $menuItem) {
$menuPopupId = (int)$menuItem->sgpbPopupId;
/* As $menuItems contains only menu items on which popup is set
we can check if the popup should load on current page or not */
$popup = $this->shouldLoadPopupForMenuItem($menuPopupId, $popups);
$popup = SGPopup::find($menuPopupId);
if (!$popup instanceof SGPopup) continue;
/* We could set param everywhere as popup was not suppose to load on current page.
We could also load popup to current requested page but to avoid any confusion
it will be better to use everywhere */
// $popup->setTarget(array(
// array('param' => 'everywhere')
$popupOpeningEvents = $popup->getEvents();
/* If the popup is setup inside the menu but there is no onclick event we will add manually */
if (!$this->inMultiDimArray('click', $popupOpeningEvents)) {
$popup->setEvents(array('param' => 'click', 'value' => ''));
/* if the popup is set on menu item we don't need any limitation */
//$this->disablePopupLimitation($popup);
private function disablePopupLimitation(&$popup)
$popupOptions = $popup->getOptions();
unset($popupOptions['sgpb-show-popup-same-user']);
$popup->setOptions($popupOptions);
private function inMultiDimArray($item , $array){
return preg_match('/"'.preg_quote($item, '/').'"/i' , wp_json_encode($array));
private function shouldLoadPopupForMenuItem($menuPopupId, &$popups) {
foreach ($popups as $popup) {
$popupId = $popup->getId();
/* Menu item contains popup with current id and the popup is loaded */
if ($menuPopupId == $popupId) {
* @param false $forceUpdate
public function getNavMenuLocations($forceUpdate = false)
if (!isset(self::$navMenuLocations) && !$forceUpdate) {
self::$navMenuLocations = get_nav_menu_locations();
return isset(self::$navMenuLocations) ? self::$navMenuLocations : array();
* @param array $navMenuLocations
* @param false $forceUpdate
* @return array of menu items where popup is set
public function getNavMenuItemsWithPopup($navMenuLocations = array(), $forceUpdate = false)
if (!isset(self::$navMenuItems) && !$forceUpdate) {
foreach ($navMenuLocations as $menuName => $menuId) {
$menuItems = wp_get_nav_menu_items($menuId);
if (!empty($menuItems)) {
foreach ($menuItems as $menuItem) {
$popupId = $menuItem->sgpbPopupId;
self::$navMenuItems[] = $menuItem;
return isset(self::$navMenuItems) ? self::$navMenuItems : array();
public function addCustomNavFields($menuItem)
$menuItem->sgpbPopupId = get_post_meta($menuItem->ID, '_menu_sgpb_popup_id', true);
* @return array of popup objects
public static function getPopups()
return SGPopup::getAllPopups();
* Adds custom fields to the menu item editor.
public function fields($itemId, $item, $depth, $args)
<div class="description description-wide">
<label for="edit-menu-item-pb-<?php echo esc_attr($item->ID); ?>">
<?php esc_html_e('Select a Popup', 'popup-builder'); ?><br/>
<select class="widefat" name="menu-item-pb[<?php echo esc_attr($item->ID); ?>][popup]"
id="edit-menu-item-pb-<?php echo esc_attr($item->ID); ?>">
<option value=""></option>
<?php foreach (self::getPopups() as $popup) : ?>
<option value="<?php echo esc_attr($popup->getId()); ?>" <?php selected($popup->getId(), (int)get_post_meta($itemId, '_menu_sgpb_popup_id', true)); ?>>
<?php echo esc_html($popup->getTitle()); ?>
<span class="description"><?php esc_html_e('Open a popup once this item is clicked.', 'popup-builder'); ?></span>
* Processes the saving of menu items.
public function save($menu_id, $item_id)
if (!isset($_POST['menu-item-pb'])) { // phpcs:ignore WordPress.Security.NonceVerification
if ( current_user_can( 'edit_theme_options' ) ) {
check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
delete_post_meta($item_id, '_menu_sgpb_popup_id');
if (isset($_POST['menu-item-pb'][$item_id]['popup'])) {
$popupId = (int)sanitize_text_field($_POST['menu-item-pb'][$item_id]['popup']);
update_post_meta($item_id, '_menu_sgpb_popup_id', $popupId);