Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/internal-links/admin/js/ilj-keywords-editor.min.asset.php
+++ b/internal-links/admin/js/ilj-keywords-editor.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '5d19d3d9a4690453c7c4');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => '93a99787bca25fbd6a9e');
--- a/internal-links/admin/js/ilj-link-index-status-func.min.asset.php
+++ b/internal-links/admin/js/ilj-link-index-status-func.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => 'ea6d5513fc020ac4118e');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'ea6d5513fc020ac4118e');
--- a/internal-links/admin/js/ilj_admin_menu_bar.min.asset.php
+++ b/internal-links/admin/js/ilj_admin_menu_bar.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '95e0728424530c461c89');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => '95e0728424530c461c89');
--- a/internal-links/admin/js/ilj_admin_script.min.asset.php
+++ b/internal-links/admin/js/ilj_admin_script.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => 'f72b1d63a7d5c4d39018');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'f72b1d63a7d5c4d39018');
--- a/internal-links/admin/js/ilj_ajax_index_rebuild.min.asset.php
+++ b/internal-links/admin/js/ilj_ajax_index_rebuild.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => 'b57689138972d2c5f87e');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'b57689138972d2c5f87e');
--- a/internal-links/admin/js/ilj_custom_links.min.asset.php
+++ b/internal-links/admin/js/ilj_custom_links.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '26d4f17e1cb1d7caa91b');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => '26d4f17e1cb1d7caa91b');
--- a/internal-links/admin/js/ilj_editor.min.asset.php
+++ b/internal-links/admin/js/ilj_editor.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '4cedb45623fa20f17577');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'b30bd66bc7c9d79364e4');
--- a/internal-links/admin/js/ilj_keywords.min.asset.php
+++ b/internal-links/admin/js/ilj_keywords.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '3dbaeff392f22aa1209b');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'da64fabcb2612dc405e2');
--- a/internal-links/admin/js/ilj_menu_settings.min.asset.php
+++ b/internal-links/admin/js/ilj_menu_settings.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '767f1bfec8ae39a5f104');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => '767f1bfec8ae39a5f104');
--- a/internal-links/admin/js/ilj_promo.min.asset.php
+++ b/internal-links/admin/js/ilj_promo.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => 'c0ad3da2998ed0245e08');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'c0ad3da2998ed0245e08');
--- a/internal-links/admin/js/ilj_rating_notification.min.asset.php
+++ b/internal-links/admin/js/ilj_rating_notification.min.asset.php
@@ -1,3 +0,0 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => '0f28bf2ab747c7b799a7');
No newline at end of file
--- a/internal-links/admin/js/ilj_statistic.min.asset.php
+++ b/internal-links/admin/js/ilj_statistic.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => 'a59bce424f1445514818');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'f3ba579982093271486c');
--- a/internal-links/admin/js/ilj_tools.min.asset.php
+++ b/internal-links/admin/js/ilj_tools.min.asset.php
@@ -1,3 +1 @@
-<?php
-
-return array('dependencies' => array('wp-polyfill'), 'version' => 'f87c0eb37b787f57920a');
No newline at end of file
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => '0353c06bf8a4a934c09a');
--- a/internal-links/backend/adminbar.php
+++ b/internal-links/backend/adminbar.php
@@ -5,6 +5,7 @@
use ILJCoreOptions;
use ILJCoreOptionsCacheToggleBtnSwitch;
use ILJHelperBatchInfo as HelperBatchInfo;
+
/**
* Admin bar
*
@@ -13,22 +14,27 @@
* @package ILJBackend
* @since 2.0.0
*/
-class AdminBar
-{
- /**
- * Add a link to the admin toolbar
- *
- * @param WP_Admin_Bar $admin_bar
- *
- * @return void
- * @since 2.0.0
- */
- public static function addLink($admin_bar)
- {
- $batch_build_info = new HelperBatchInfo();
- $batch_percentage = $batch_build_info->getBatchPercentage();
- $status = $batch_build_info->getBatchStatus();
- $args = array('id' => 'ilj', 'title' => '<span class="ilj_icon" aria-hidden="true"></span>', 'href' => add_query_arg(array('page' => AdminMenu::ILJ_MENUPAGE_SLUG), admin_url('admin.php')), 'meta' => array('html' => '
+class AdminBar {
+
+ /**
+ * Add a link to the admin toolbar
+ *
+ * @param WP_Admin_Bar $admin_bar
+ *
+ * @return void
+ * @since 2.0.0
+ */
+ public static function addLink($admin_bar) {
+ $batch_build_info = new HelperBatchInfo();
+ $batch_percentage = $batch_build_info->getBatchPercentage();
+ $status = $batch_build_info->getBatchStatus();
+
+ $args = array(
+ 'id' => 'ilj',
+ 'title' => '<span class="ilj_icon" aria-hidden="true"></span>',
+ 'href' => add_query_arg(array('page' => AdminMenu::ILJ_MENUPAGE_SLUG), admin_url('admin.php')),
+ 'meta' => array(
+ 'html' => '
<a class="ilj_admin_bar_link" style="height: 0px;" href = "' . add_query_arg(array('page' => AdminMenu::ILJ_MENUPAGE_SLUG), admin_url('admin.php')) . '">
<div class="ilj_admin_bar_container">
<div class="ilj_bar_title_container"> Linkindex: <span id="ilj_batch_progress">' . $batch_percentage . '%</span></div>
@@ -36,14 +42,23 @@
<div style="width:' . $batch_percentage . '%"></div>
</div>
</div>
- </a>'));
- $admin_bar->add_node($args);
- $cache_option = Options::getOption(CacheToggleBtnSwitch::getKey());
- if ($cache_option) {
- // Disable in version 2.23.5 due to conflicts with other plugins
- self::add_cache_menu_items($admin_bar);
- }
- $args = array('parent' => 'ilj', 'id' => 'ilj-status', 'title' => '<div class="ilj-build-title"><strong>Status:</strong> <span id="ilj_batch_status">' . HelperBatchInfo::translateBatchStatus($status) . '</span></div>', 'meta' => array('html' => '
+ </a>',
+ ),
+ );
+ $admin_bar->add_node($args);
+
+ $cache_option = Options::getOption(CacheToggleBtnSwitch::getKey());
+ if ($cache_option) {
+ // Disable in version 2.23.5 due to conflicts with other plugins
+ self::add_cache_menu_items($admin_bar);
+ }
+
+ $args = array(
+ 'parent' => 'ilj',
+ 'id' => 'ilj-status',
+ 'title' => '<div class="ilj-build-title"><strong>Status:</strong> <span id="ilj_batch_status">' . HelperBatchInfo::translateBatchStatus($status) . '</span></div>',
+ 'meta' => array(
+ 'html' => '
<hr class="ilj-build-separate" />
<div class="ilj-build-info">
<p>
@@ -51,29 +66,52 @@
' . __('We build your internal links in the background.', 'internal-links') . ' ' . __('As soon as 100% is reached, your new links will be visible in the frontend.', 'internal-links') . '
</p>
</div>
- '));
- $admin_bar->add_node($args);
- }
- /**
- * Add admin bar menu items for deleting transient
- *
- * @param WP_Admin_Bar $admin_bar
- *
- * @return void
- */
- private static function add_cache_menu_items($admin_bar)
- {
- if (!current_user_can('manage_options')) {
- return;
- }
- $args = array('parent' => 'ilj', 'id' => 'ilj-clear-all-transients', 'title' => __('Delete all caches', 'internal-links'), 'href' => wp_nonce_url(admin_url('admin-ajax.php?action=ilj_clear_all_transient'), 'ilj_clear_all_transient'));
- $admin_bar->add_node($args);
- // On single post/ category pages this option should be displayed.
- if (is_category() || is_tag() || is_tax() || is_singular()) {
- $id = get_queried_object_id();
- $type = is_singular() ? 'post' : 'term';
- $args = array('parent' => 'ilj', 'id' => 'ilj-clear-single-transient', 'title' => ('post' === $type) ? sprintf(__('Delete this %s cache', 'internal-links'), get_post_type($id)) : __('Delete this term cache', 'internal-links'), 'href' => admin_url(sprintf('admin-ajax.php?action=%s&_wpnonce=%s&ilj_transient_id=%d&ilj_transient_type=%s', 'ilj_clear_single_transient', wp_create_nonce('ilj_clear_single_transient'), $id, $type)));
- $admin_bar->add_node($args);
- }
- }
-}
No newline at end of file
+ ',
+ ),
+ );
+
+
+ $admin_bar->add_node($args);
+
+ }
+
+ /**
+ * Add admin bar menu items for deleting transient
+ *
+ * @param WP_Admin_Bar $admin_bar
+ *
+ * @return void
+ */
+ private static function add_cache_menu_items($admin_bar) {
+
+ if (!current_user_can('manage_options')) {
+ return;
+ }
+
+ $args = array(
+ 'parent' => 'ilj',
+ 'id' => 'ilj-clear-all-transients',
+ 'title' => __('Delete all caches', 'internal-links'),
+ 'href' => wp_nonce_url(admin_url('admin-ajax.php?action=ilj_clear_all_transient'), 'ilj_clear_all_transient')
+ );
+
+ $admin_bar->add_node($args);
+
+ // On single post/ category pages this option should be displayed.
+ if (is_category() || is_tag() || is_tax() || is_singular()) {
+ $id = get_queried_object_id();
+ $type = is_singular() ? 'post' : 'term';
+ $args = array(
+ 'parent' => 'ilj',
+ 'id' => 'ilj-clear-single-transient',
+ /* translators: %s: Post Type */
+ 'title' => 'post' === $type ? sprintf(__('Delete this %s cache', 'internal-links'), get_post_type($id)) : __('Delete this term cache', 'internal-links'),
+ 'href' => admin_url(sprintf('admin-ajax.php?action=%s&_wpnonce=%s&ilj_transient_id=%d&ilj_transient_type=%s', 'ilj_clear_single_transient', wp_create_nonce('ilj_clear_single_transient'), $id, $type)),
+ );
+
+ $admin_bar->add_node($args);
+ }
+ }
+
+
+}
--- a/internal-links/backend/adminmenu.php
+++ b/internal-links/backend/adminmenu.php
@@ -1,5 +1,4 @@
<?php
-
namespace ILJBackend;
/**
@@ -10,34 +9,51 @@
* @package ILJBackend
* @since 1.0.0
*/
-class AdminMenu
-{
- const ILJ_MENUPAGE_SLUG = 'internal_link_juicer';
- /**
- * Initializes the building process
- *
- * @since 1.0.0
- * @return void
- */
- public static function init()
- {
- self::addMenuPage();
- $submenus = array('ILJBackendMenuPageDashboard', 'ILJBackendMenuPageTools', 'ILJBackendMenuPageSettings', 'ILJBackendMenuPageTour');
- foreach ($submenus as $submenu) {
- $menu_page = new $submenu();
- $menu_page->register();
- }
- }
- /**
- * Registers the menu page for the plugin
- *
- * @since 1.0.0
- * @return void
- */
- private static function addMenuPage()
- {
- add_menu_page(__('Internal Links', 'internal-links'), __('Internal Links', 'internal-links'), 'manage_options', self::ILJ_MENUPAGE_SLUG, function () {
- return;
- }, 'data:image/svg+xml;base64,' . base64_encode('<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150"><path fill="#ffffff" d="M115.1334 73.9667c-4.5667-6.8334-9.5667-13.4-14.4334-20.0334-8.2-11.0333-13.5-23.1-12.8666-37.1.2333-5.4 1.2333-10.7333 1.9-16.3333L80.4 8.9333c-15.7666 14.9-29.9 31.1334-40.3666 50.3-6.7667 12.4334-11.5667 25.5-12.6667 39.8-2.0333 24.6667 16.9667 48.2 41.5667 51.0667 27.1333 3.2333 50.3667-14.4 54.3-41.3333 1.8666-12.5667-1.1334-24.3-8.1-34.8zm-15.9 40.9c-4.9667 0-9.2-3.3333-10.4334-7.9l-15.6666 2.6v.5c0 8.8334-7.2334 16.0667-16.1 16.0667-8.8334 0-16.0667-7.2333-16.0667-16.0667 0-8.8666 7.2333-16.1 16.0667-16.1 1.2 0 2.3333.1 3.5.4l7.6303-21.9204C64.5334 70.7666 62.0334 67.1 62.0334 62.8c0-6.0334 4.9-10.8667 10.9-10.8667 5.9666 0 10.9 4.8333 10.9 10.8667s-4.9334 10.8333-10.9 10.8333c-.8667 0-1.7334-.1-2.5667-.3333l-7.5333 21.7333C67.8 97 71.6334 101.3333 72.8 106.6l15.5667-2.5667c0-6.0667 4.8667-10.9 10.9-10.9 6 0 10.8333 4.8333 10.8333 10.9-.0333 6-4.8333 10.8333-10.8666 10.8333z"/></svg>'), 16);
- }
-}
No newline at end of file
+class AdminMenu {
+
+ const ILJ_MENUPAGE_SLUG = 'internal_link_juicer';
+
+ /**
+ * Initializes the building process
+ *
+ * @since 1.0.0
+ * @return void
+ */
+ public static function init() {
+ self::addMenuPage();
+
+ $submenus = array(
+ 'ILJBackendMenuPageDashboard',
+ 'ILJBackendMenuPageTools',
+ 'ILJBackendMenuPageSettings',
+ 'ILJBackendMenuPageTour',
+ );
+
+
+
+ foreach ($submenus as $submenu) {
+ $menu_page = new $submenu();
+ $menu_page->register();
+ }
+ }
+
+ /**
+ * Registers the menu page for the plugin
+ *
+ * @since 1.0.0
+ * @return void
+ */
+ private static function addMenuPage() {
+ add_menu_page(
+ __('Internal Links', 'internal-links'),
+ __('Internal Links', 'internal-links'),
+ 'manage_options',
+ self::ILJ_MENUPAGE_SLUG,
+ function () {
+ return;
+ },
+ 'data:image/svg+xml;base64,' . base64_encode('<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150"><path fill="#ffffff" d="M115.1334 73.9667c-4.5667-6.8334-9.5667-13.4-14.4334-20.0334-8.2-11.0333-13.5-23.1-12.8666-37.1.2333-5.4 1.2333-10.7333 1.9-16.3333L80.4 8.9333c-15.7666 14.9-29.9 31.1334-40.3666 50.3-6.7667 12.4334-11.5667 25.5-12.6667 39.8-2.0333 24.6667 16.9667 48.2 41.5667 51.0667 27.1333 3.2333 50.3667-14.4 54.3-41.3333 1.8666-12.5667-1.1334-24.3-8.1-34.8zm-15.9 40.9c-4.9667 0-9.2-3.3333-10.4334-7.9l-15.6666 2.6v.5c0 8.8334-7.2334 16.0667-16.1 16.0667-8.8334 0-16.0667-7.2333-16.0667-16.0667 0-8.8666 7.2333-16.1 16.0667-16.1 1.2 0 2.3333.1 3.5.4l7.6303-21.9204C64.5334 70.7666 62.0334 67.1 62.0334 62.8c0-6.0334 4.9-10.8667 10.9-10.8667 5.9666 0 10.9 4.8333 10.9 10.8667s-4.9334 10.8333-10.9 10.8333c-.8667 0-1.7334-.1-2.5667-.3333l-7.5333 21.7333C67.8 97 71.6334 101.3333 72.8 106.6l15.5667-2.5667c0-6.0667 4.8667-10.9 10.9-10.9 6 0 10.8333 4.8333 10.8333 10.9-.0333 6-4.8333 10.8333-10.8666 10.8333z"/></svg>'),
+ 16
+ );
+ }
+}
--- a/internal-links/backend/batchinfo.php
+++ b/internal-links/backend/batchinfo.php
@@ -1,78 +1,90 @@
<?php
-
namespace ILJBackend;
use ILJCoreOptions;
+
/**
* Handles Plugin Batch Information
*
* @package ILJBackend
* @since 2.0.0
*/
-class BatchInfo
-{
- /**
- * Batch info instance
- *
- * @var BatchInfo
- * @since 2.0.0
- */
- private static $instance;
- /**
- * Batch data
- *
- * @var array
- * @since 2.0.0
- */
- private $batch_data;
- protected function __construct()
- {
- $batch_data_default = array('batch_build' => array('last_update' => array('batch_count' => '', 'batch_finished' => '', 'last_update' => '', 'status' => '')));
- $batch_data = Options::getOption(Options::ILJ_OPTION_KEY_BATCH);
- $this->batch_data = wp_parse_args($batch_data, $batch_data_default);
- }
- /**
- * Get data from batch data
- *
- * @since 2.0.0
- * @param string $key The key
- * @return string|bool
- */
- public static function get($key)
- {
- self::init();
- $batch_data = self::$instance->batch_data;
- if (array_key_exists($key, $batch_data)) {
- return $batch_data[$key];
- }
- return false;
- }
- /**
- * Update batch data
- *
- * @since 2.0.0
- * @param string $key The key
- * @param mixed $value The value
- * @return bool
- */
- public static function update($key, $value)
- {
- self::init();
- $batch_data = self::$instance->batch_data;
- $batch_data[$key] = $value;
- Options::setOption(Options::ILJ_OPTION_KEY_BATCH, $batch_data);
- return true;
- }
- /**
- * Init Environment- class
- *
- * @since 2.0.0
- * @return void
- */
- private static function init()
- {
- if (null === self::$instance) {
- self::$instance = new self();
- }
- }
-}
No newline at end of file
+class BatchInfo {
+
+ /**
+ * Batch info instance
+ *
+ * @var BatchInfo
+ * @since 2.0.0
+ */
+ private static $instance;
+
+ /**
+ * Batch data
+ *
+ * @var array
+ * @since 2.0.0
+ */
+ private $batch_data;
+
+ protected function __construct() {
+ $batch_data_default = array(
+ 'batch_build' => array(
+ 'last_update' => array(
+ 'batch_count' => '',
+ 'batch_finished' => '',
+ 'last_update' => '',
+ 'status' => '',
+ ),
+ ),
+ );
+
+ $batch_data = Options::getOption(Options::ILJ_OPTION_KEY_BATCH);
+ $this->batch_data = wp_parse_args($batch_data, $batch_data_default);
+ }
+
+ /**
+ * Get data from batch data
+ *
+ * @since 2.0.0
+ * @param string $key The key
+ * @return string|bool
+ */
+ public static function get($key) {
+ self::init();
+ $batch_data = self::$instance->batch_data;
+ if (array_key_exists($key, $batch_data)) {
+ return $batch_data[$key];
+ }
+ return false;
+ }
+
+ /**
+ * Update batch data
+ *
+ * @since 2.0.0
+ * @param string $key The key
+ * @param mixed $value The value
+ * @return bool
+ */
+ public static function update($key, $value) {
+ self::init();
+ $batch_data = self::$instance->batch_data;
+ $batch_data[$key] = $value;
+ Options::setOption(Options::ILJ_OPTION_KEY_BATCH, $batch_data);
+
+ return true;
+ }
+
+ /**
+ * Init Environment- class
+ *
+ * @since 2.0.0
+ * @return void
+ */
+ private static function init() {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+ }
+}
--- a/internal-links/backend/column.php
+++ b/internal-links/backend/column.php
@@ -3,6 +3,7 @@
namespace ILJBackend;
use ILJDatabasePostmeta;
+
/**
* Listview columns
*
@@ -12,118 +13,161 @@
*
* @since 1.1.3
*/
-class Column
-{
- const ILJ_COLUMN_CONFIGURED_LINKS = 'ilj_column_configured_links';
- /**
- * Returns the title for the configured links column in the frontend
- *
- * @return string
- * @since 1.1.3
- */
- protected static function getConfiguredLinksColumnTitle()
- {
- return __('Configured keywords for internal linking', 'internal-links');
- }
- /**
- * Generates and adds all possible configured links columns
- *
- * @return void
- * @since 1.1.3
- */
- public static function addConfiguredLinksColumn()
- {
- $types = get_post_types(array('public' => true));
- foreach ($types as $type) {
- add_action('manage_' . $type . '_posts_custom_column', array('ILJBackendColumn', 'addConfiguredLinksColumnContent'), 5, 2);
- add_filter('manage_' . $type . '_posts_columns', array('ILJBackendColumn', 'addConfiguredLinksColumnHeader'));
- add_filter('manage_edit-' . $type . '_sortable_columns', array('ILJBackendColumn', 'addConfiguredLinksColumnSorter'));
- add_filter('wp', array('ILJBackendColumn', 'sortConfiguredLinksColumn'));
- }
- }
- /**
- * Adds the configured links column header
- *
- * @param array $columns All columns header
- *
- * @return array
- * @since 1.1.3
- */
- public static function addConfiguredLinksColumnHeader($columns)
- {
- ILJHelperLoader::enqueue_style('ilj_ui', ILJ_URL . 'admin/css/ilj_ui.css', array(), ILJ_VERSION);
- $columns[self::ILJ_COLUMN_CONFIGURED_LINKS] = '<span class="icon icon-ilj" title="' . self::getConfiguredLinksColumnTitle() . '"></span><span class="screen-reader-text">' . self::getConfiguredLinksColumnTitle() . '</span>';
- return $columns;
- }
- /**
- * Outputs the content of the configured links column
- *
- * @param string $column The current column
- * @param int $post_id Post ID
- *
- * @return void
- * @since 1.1.3
- */
- public static function addConfiguredLinksColumnContent($column, $post_id)
- {
- if (self::ILJ_COLUMN_CONFIGURED_LINKS === $column) {
- $data = get_post_meta($post_id, Postmeta::ILJ_META_KEY_LINKDEFINITION);
- if (!is_array($data) && !is_object($data)) {
- echo '0';
- return;
- }
- if (empty($data) || is_array($data) && !is_array($data[0])) {
- echo '0';
- return;
- }
- echo count($data[0]);
- }
- }
- /**
- * Adds the sorter to the configured links column
- *
- * @param array $columns All sortable columns
- *
- * @return array
- * @since 1.1.3
- */
- public static function addConfiguredLinksColumnSorter($columns)
- {
- $columns[self::ILJ_COLUMN_CONFIGURED_LINKS] = self::ILJ_COLUMN_CONFIGURED_LINKS;
- return $columns;
- }
- /**
- * Adds the post sorting logic for configured links column
- *
- * @return void
- * @since 1.1.3
- */
- public static function sortConfiguredLinksColumn()
- {
- global $wp_query;
- if (!is_admin()) {
- return;
- }
- $orderby = $wp_query->get('orderby');
- if (self::ILJ_COLUMN_CONFIGURED_LINKS != $orderby) {
- return;
- }
- $page_offset = $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1;
- $posts_per_page = $wp_query->query_vars['posts_per_page'];
- $order = (isset($wp_query->query_vars) && isset($wp_query->query_vars['order']) && strcasecmp($wp_query->query_vars['order'], 'desc') == 0) ? 'DESC' : 'ASC';
- $args = $wp_query->query;
- $args['posts_per_page'] = -1;
- $new_query = new WP_Query($args);
- $posts = $new_query->posts;
- usort($posts, function ($a, $b) use ($order) {
- $keywords_a = get_post_meta($a->ID, Postmeta::ILJ_META_KEY_LINKDEFINITION);
- $keywords_b = get_post_meta($b->ID, Postmeta::ILJ_META_KEY_LINKDEFINITION);
- $count_a = count($keywords_a) ? count($keywords_a[0]) : 0;
- $count_b = count($keywords_b) ? count($keywords_b[0]) : 0;
- $sorting_value = (('DESC' == $order) ? $count_a > $count_b : ($count_a < $count_b)) ? -1 : (($count_a == $count_b) ? 0 : 1);
- return $sorting_value;
- });
- $sliced = array_slice($posts, ($page_offset - 1) * $posts_per_page, $posts_per_page);
- $wp_query->posts = $sliced;
- }
-}
No newline at end of file
+class Column {
+
+
+ const ILJ_COLUMN_CONFIGURED_LINKS = 'ilj_column_configured_links';
+
+ /**
+ * Returns the title for the configured links column in the frontend
+ *
+ * @return string
+ * @since 1.1.3
+ */
+ protected static function getConfiguredLinksColumnTitle() {
+ return __('Configured keywords for internal linking', 'internal-links');
+ }
+
+ /**
+ * Generates and adds all possible configured links columns
+ *
+ * @return void
+ * @since 1.1.3
+ */
+ public static function addConfiguredLinksColumn() {
+ $types = get_post_types(array('public' => true));
+
+
+
+ foreach ($types as $type) {
+ add_action(
+ 'manage_' . $type . '_posts_custom_column',
+ array(
+ 'ILJBackendColumn',
+ 'addConfiguredLinksColumnContent',
+ ),
+ 5,
+ 2
+ );
+ add_filter(
+ 'manage_' . $type . '_posts_columns',
+ array(
+ 'ILJBackendColumn',
+ 'addConfiguredLinksColumnHeader',
+ )
+ );
+ add_filter(
+ 'manage_edit-' . $type . '_sortable_columns',
+ array(
+ 'ILJBackendColumn',
+ 'addConfiguredLinksColumnSorter',
+ )
+ );
+ add_filter('wp', array('ILJBackendColumn', 'sortConfiguredLinksColumn'));
+ }
+ }
+
+ /**
+ * Adds the configured links column header
+ *
+ * @param array $columns All columns header
+ *
+ * @return array
+ * @since 1.1.3
+ */
+ public static function addConfiguredLinksColumnHeader($columns) {
+ ILJHelperLoader::enqueue_style('ilj_ui', ILJ_URL . 'admin/css/ilj_ui.css', array(), ILJ_VERSION);
+
+ $columns[self::ILJ_COLUMN_CONFIGURED_LINKS] = '<span class="icon icon-ilj" title="' . self::getConfiguredLinksColumnTitle() . '"></span><span class="screen-reader-text">' . self::getConfiguredLinksColumnTitle() . '</span>';
+
+ return $columns;
+ }
+
+ /**
+ * Outputs the content of the configured links column
+ *
+ * @param string $column The current column
+ * @param int $post_id Post ID
+ *
+ * @return void
+ * @since 1.1.3
+ */
+ public static function addConfiguredLinksColumnContent($column, $post_id) {
+ if (self::ILJ_COLUMN_CONFIGURED_LINKS === $column) {
+ $data = get_post_meta($post_id, Postmeta::ILJ_META_KEY_LINKDEFINITION);
+
+ if (!is_array($data) && !is_object($data)) {
+ echo '0';
+ return;
+ }
+
+ if (empty($data) || (is_array($data) && !is_array($data[0]))) {
+ echo '0';
+ return;
+ }
+ echo count($data[0]);
+ }
+ }
+
+ /**
+ * Adds the sorter to the configured links column
+ *
+ * @param array $columns All sortable columns
+ *
+ * @return array
+ * @since 1.1.3
+ */
+ public static function addConfiguredLinksColumnSorter($columns) {
+ $columns[self::ILJ_COLUMN_CONFIGURED_LINKS] = self::ILJ_COLUMN_CONFIGURED_LINKS;
+
+ return $columns;
+ }
+
+ /**
+ * Adds the post sorting logic for configured links column
+ *
+ * @return void
+ * @since 1.1.3
+ */
+ public static function sortConfiguredLinksColumn() {
+ global $wp_query;
+
+ if (!is_admin()) {
+ return;
+ }
+
+ $orderby = $wp_query->get('orderby');
+
+ if (self::ILJ_COLUMN_CONFIGURED_LINKS != $orderby) {
+ return;
+ }
+
+ $page_offset = ($wp_query->query_vars['paged']) ? $wp_query->query_vars['paged'] : 1;
+ $posts_per_page = $wp_query->query_vars['posts_per_page'];
+ $order = isset($wp_query->query_vars) && isset($wp_query->query_vars['order']) && strcasecmp($wp_query->query_vars['order'], 'desc') == 0 ? 'DESC' : 'ASC';
+
+ $args = $wp_query->query;
+ $args['posts_per_page'] = -1;
+
+ $new_query = new WP_Query($args);
+ $posts = $new_query->posts;
+
+ usort(
+ $posts,
+ function ($a, $b) use ($order) {
+ $keywords_a = get_post_meta($a->ID, Postmeta::ILJ_META_KEY_LINKDEFINITION);
+ $keywords_b = get_post_meta($b->ID, Postmeta::ILJ_META_KEY_LINKDEFINITION);
+ $count_a = count($keywords_a) ? count($keywords_a[0]) : 0;
+ $count_b = count($keywords_b) ? count($keywords_b[0]) : 0;
+ $sorting_value = ('DESC' == $order ? ($count_a > $count_b) : ($count_a < $count_b)) ? - 1 : ($count_a == $count_b ? 0 : 1);
+
+ return $sorting_value;
+ }
+ );
+
+ $sliced = array_slice($posts, ($page_offset - 1) * $posts_per_page, $posts_per_page);
+ $wp_query->posts = $sliced;
+ }
+
+
+}
--- a/internal-links/backend/editor.php
+++ b/internal-links/backend/editor.php
@@ -1,15 +1,18 @@
<?php
-
namespace ILJBackend;
use ILJCoreOptions;
use ILJCoreOptionsCacheToggleBtnSwitch;
use ILJDataContent;
+use ILJDatabaseLinkindex;
use ILJHelperHelp;
use ILJTypeKeywordList;
use ILJDatabasePostmeta;
+use ILJDatabaseTermmeta;
use ILJHelperCapabilities;
use ILJHelperIndexAsset as IndexAsset;
+use ILJHelperStatistic;
+
/**
* Admin views
*
@@ -19,358 +22,525 @@
*
* @since 1.0.0
*/
-class Editor
-{
- const ILJ_ADMINVIEW_NONCE = '_ilj_adminview_nonce';
- const ILJ_ACTION_AFTER_KEYWORDS_UPDATE = 'ilj_after_keywords_update';
- const ILJ_EDITOR_HANDLE = 'ilj_editor';
- const ILJ_KEYWORDS_HANDLE = 'ilj_keywords';
- const ILJ_IS_BLACKLISTED = 'ilj_is_blacklisted';
- const ILJ_META_KEY_LIMITINCOMINGLINKS = 'ilj_limitincominglinks';
- const ILJ_META_KEY_MAXINCOMINGLINKS = 'ilj_maxincominglinks';
- const ILJ_META_KEY_BLACKLISTDEFINITION = 'ilj_blacklistdefinition';
- const ILJ_META_KEY_LIMITLINKSPERPARAGRAPH = 'ilj_limitlinksperparagraph';
- const ILJ_META_KEY_LINKSPERPARAGRAPH = 'ilj_linksperparagraph';
- const ILJ_META_KEY_LIMITOUTGOINGLINKS = 'ilj_limitoutgoinglinks';
- const ILJ_META_KEY_MAXOUTGOINGLINKS = 'ilj_maxoutgoinglinks';
- const ILJ_KEYWORD_METABOX_FOOTER_HOOK = 'ilj_keyword_metabox_footer';
- /**
- * Registers the keyword metabox on all public post types
- *
- * @since 1.0.0
- *
- * @return void
- */
- public static function addKeywordMetaBox()
- {
- foreach (get_post_types(array('public' => true)) as $type) {
- add_meta_box(Postmeta::ILJ_META_KEY_LINKDEFINITION, __('Internal Links', 'internal-links'), array(__CLASS__, 'renderKeywordMetaBox'), $type, 'side', 'default');
- }
- }
- /**
- * Renders the keyword metabox
- *
- * @since 1.0.0
- *
- * @param WP_Post $post The post object of the current page
- * @return void
- */
- public static function renderKeywordMetaBox(WP_Post $post)
- {
- $keyword_list = KeywordList::fromMeta($post->ID, 'post', Postmeta::ILJ_META_KEY_LINKDEFINITION);
- $blacklist_keywords = KeywordList::fromMeta($post->ID, 'post', self::ILJ_META_KEY_BLACKLISTDEFINITION);
- wp_nonce_field(basename(__FILE__), self::ILJ_ADMINVIEW_NONCE);
- ?>
+class Editor {
+
+ const ILJ_ADMINVIEW_NONCE = '_ilj_adminview_nonce';
+ const ILJ_ACTION_AFTER_KEYWORDS_UPDATE = 'ilj_after_keywords_update';
+ const ILJ_EDITOR_HANDLE = 'ilj_editor';
+ const ILJ_KEYWORDS_HANDLE = 'ilj_keywords';
+ const ILJ_IS_BLACKLISTED = 'ilj_is_blacklisted';
+ const ILJ_META_KEY_LIMITINCOMINGLINKS = 'ilj_limitincominglinks';
+ const ILJ_META_KEY_MAXINCOMINGLINKS = 'ilj_maxincominglinks';
+ const ILJ_META_KEY_BLACKLISTDEFINITION = 'ilj_blacklistdefinition';
+ const ILJ_META_KEY_LIMITLINKSPERPARAGRAPH = 'ilj_limitlinksperparagraph';
+ const ILJ_META_KEY_LINKSPERPARAGRAPH = 'ilj_linksperparagraph';
+ const ILJ_META_KEY_LIMITOUTGOINGLINKS = 'ilj_limitoutgoinglinks';
+ const ILJ_META_KEY_MAXOUTGOINGLINKS = 'ilj_maxoutgoinglinks';
+ const ILJ_KEYWORD_METABOX_FOOTER_HOOK = 'ilj_keyword_metabox_footer';
+ const ILJ_MODAL = 'ilj_modal';
+
+ /**
+ * Registers the keyword metabox on all public post types
+ *
+ * @since 1.0.0
+ *
+ * @return void
+ */
+ public static function addKeywordMetaBox() {
+ foreach (get_post_types(array('public' => true)) as $type) {
+ add_meta_box(
+ Postmeta::ILJ_META_KEY_LINKDEFINITION,
+ __('Internal Links', 'internal-links'),
+ array(__CLASS__, 'renderKeywordMetaBox'),
+ $type,
+ 'side',
+ 'default'
+ );
+ }
+
+
+ }
+
+ /**
+ * Renders the keyword metabox
+ *
+ * @since 1.0.0
+ *
+ * @param WP_Post $post The post object of the current page
+ * @return void
+ */
+ public static function renderKeywordMetaBox(WP_Post $post) {
+ $keyword_list = KeywordList::fromMeta($post->ID, 'post', Postmeta::ILJ_META_KEY_LINKDEFINITION);
+ $blacklist_keywords = KeywordList::fromMeta($post->ID, 'post', self::ILJ_META_KEY_BLACKLISTDEFINITION);
+
+ wp_nonce_field(basename(__FILE__), self::ILJ_ADMINVIEW_NONCE);
+ ?>
<p>
- <label for="<?php
- echo esc_attr(Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys');
- ?>"><?php
- esc_html_e('The keywords', 'internal-links');
- ?>:</label>
+ <label for="<?php echo esc_attr(Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys'); ?>"><?php esc_html_e('The keywords', 'internal-links'); ?>:</label>
<br />
<input
type="text"
- name="<?php
- echo esc_attr(Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys');
- ?>"
- value="<?php
- echo esc_attr($keyword_list->encoded());
- ?>" size="30"/>
- <?php
- ?>
+ name="<?php echo esc_attr(Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys'); ?>"
+ value="<?php echo esc_attr($keyword_list->encoded()); ?>" size="30"/>
+ <?php
+
+ ?>
<input type="text"
- name="<?php
- echo esc_attr(self::ILJ_IS_BLACKLISTED);
- ?>"
- value="<?php
- echo esc_attr(self::isBlacklisted($post->ID, 'post'));
- ?>"
+ name="<?php echo esc_attr(self::ILJ_IS_BLACKLISTED); ?>"
+ value="<?php echo esc_attr(self::isBlacklisted($post->ID, 'post')); ?>"
style="display:none"/>
<input type="text"
- name="<?php
- echo esc_attr(self::ILJ_META_KEY_BLACKLISTDEFINITION);
- ?>"
- value="<?php
- echo esc_attr($blacklist_keywords->encoded());
- ?>"
+ name="<?php echo esc_attr(self::ILJ_META_KEY_BLACKLISTDEFINITION); ?>"
+ value="<?php echo esc_attr($blacklist_keywords->encoded()); ?>"
size="30"
style="display:none"/>
</p>
<template id="ilj_keyword_metabox_footer">
- <?php
- $content = Content::from_post($post);
- /**
- * This action is used to render content dynamically in to metabox footer.
- * The HTML content inside <template> tag will rendered at the footer of editor.
- *
- * @param $content Content|null The content, null if its rendered on add post or add term page.
- * @since 2.23.5
- */
- do_action(self::ILJ_KEYWORD_METABOX_FOOTER_HOOK, $content);
- ?>
+ <?php
+ $content = Content::from_post($post);
+ /**
+ * This action is used to render content dynamically in to metabox footer.
+ * The HTML content inside <template> tag will rendered at the footer of editor.
+ *
+ * @param $content Content|null The content, null if its rendered on add post or add term page.
+ * @since 2.23.5
+ */
+ do_action(self::ILJ_KEYWORD_METABOX_FOOTER_HOOK, $content);
+ ?>
</template>
- <?php
- }
- /**
- * Hooks in to {@link self::ILJ_KEYWORD_METABOX_FOOTER_HOOK} to add custom html to <template> tag
- *
- * @param Content|null $content The content, null if its rendered on add post or add term page.
- * @return void
- */
- public static function render_keyword_metabox_footer($content)
- {
- ?>
+ <?php
+ }
+
+ /**
+ * Hooks in to {@link self::ILJ_KEYWORD_METABOX_FOOTER_HOOK} to add custom html to <template> tag
+ *
+ * @param Content|null $content The content, null if its rendered on add post or add term page.
+ * @return void
+ */
+ public static function render_keyword_metabox_footer($content) {
+ ?>
<div class="ilj-row">
<div class="col-12 ilj-footer">
<a href="https://internallinkjuicer.com/docs/editor/?utm_source=editor&utm_medium=help&utm_campaign=plugin"
rel="noopener" target="_blank" class="help">
<span class="dashicons dashicons-editor-help"></span>
- <?php
- esc_html_e('Get help', 'internal-links');
- ?>
+ <?php esc_html_e('Get help', 'internal-links'); ?>
</a>
- <?php
- self::render_delete_cache_button($content);
- ?>
+ <?php self::render_delete_cache_button($content); ?>
</div>
</div>
- <?php
- }
- /**
- * Renders delete cache button inside metabox.
- *
- * @param Content|null $content The content, null if its rendered on add post or add term page.
- * @return void
- */
- private static function render_delete_cache_button($content)
- {
- if (!$content) {
- return;
- }
- $link = admin_url(sprintf('admin-ajax.php?action=%s&_wpnonce=%s&ilj_transient_id=%d&ilj_transient_type=%s&ilj_skip_notice=true', 'ilj_clear_single_transient', wp_create_nonce('ilj_clear_single_transient'), $content->get_id(), $content->get_type()));
- $cache_option = Options::getOption(CacheToggleBtnSwitch::getKey());
- if ($cache_option) {
- ?>
+ <?php
+ }
+
+ /**
+ * Renders delete cache button inside metabox.
+ *
+ * @param Content|null $content The content, null if its rendered on add post or add term page.
+ * @return void
+ */
+ private static function render_delete_cache_button($content) {
+ if (!$content) {
+ return;
+ }
+ $link = admin_url(
+ sprintf( 'admin-ajax.php?action=%s&_wpnonce=%s&ilj_transient_id=%d&ilj_transient_type=%s&ilj_skip_notice=true',
+ 'ilj_clear_single_transient',
+ wp_create_nonce('ilj_clear_single_transient'),
+ $content->get_id(),
+ $content->get_type()
+ )
+ );
+ $cache_option = Options::getOption(CacheToggleBtnSwitch::getKey());
+ if ($cache_option) {
+ ?>
<div class="ilj-delete-cache-container">
- <button class="ilj-button-danger button" id="ilj-delete-cache" type="button" data-ilj-delete-cache-url="<?php
- echo esc_attr($link);
- ?>">
- <?php
- esc_html_e('Delete Cache', 'internal-links');
- ?>
+ <button class="ilj-button-danger button" id="ilj-delete-cache" type="button" data-ilj-delete-cache-url="<?php echo esc_attr($link); ?>">
+ <?php esc_html_e('Delete Cache', 'internal-links'); ?>
</button>
<span class="spinner is-active ilj-spinner ilj-hidden"></span>
</div>
- <?php
- }
- }
- /**
- * Responsible for saving keyword meta values and
- * stores limit linking settings for posts and
- * stores limit linking settings for posts
- *
- * @since 1.0.0
- *
- * @param int $post_id The ID of the post
- * @param WP_Post $post The post object
- * @return void
- */
- public static function saveKeywordMeta($post_id, WP_Post $post)
- {
- if (is_null($post_id) || is_null($post)) {
- return;
- }
- if (!isset($_POST[self::ILJ_ADMINVIEW_NONCE]) || !wp_verify_nonce($_POST[self::ILJ_ADMINVIEW_NONCE], basename(__FILE__))) {
- return $post_id;
- }
- $post_type = get_post_type_object($post->post_type);
- if (!current_user_can($post_type->cap->edit_post, $post_id)) {
- return $post_id;
- }
- if (array_key_exists(self::ILJ_META_KEY_BLACKLISTDEFINITION, $_POST)) {
- $input_blacklist = stripslashes($_POST[self::ILJ_META_KEY_BLACKLISTDEFINITION]);
- $sanitized_blacklist_meta_value = sanitize_text_field($input_blacklist);
- $keywordsblacklist = KeywordList::fromInput($sanitized_blacklist_meta_value);
- update_post_meta($post_id, self::ILJ_META_KEY_BLACKLISTDEFINITION, array_slice($keywordsblacklist->getKeywords(), 0, 2));
- }
- if (array_key_exists(self::ILJ_IS_BLACKLISTED, $_POST) && true == $_POST[self::ILJ_IS_BLACKLISTED]) {
- self::addToBlacklist($post_id, 'post');
- } else {
- self::removeFromBlacklist($post_id, 'post');
- }
- if (array_key_exists(Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys', $_POST)) {
- $input = stripslashes($_POST[Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys']);
- $sanitized_meta_value = sanitize_text_field($input);
- $keywords = KeywordList::fromInput($sanitized_meta_value);
- $update_status = self::set_keywords($post_id, $keywords);
- /**
- * Fires after keyword meta got saved
- *
- * @since 1.0.0
- */
- if (true == $update_status) {
- do_action(self::ILJ_ACTION_AFTER_KEYWORDS_UPDATE, $_POST['post_ID'], 'post', $_POST['post_status']);
- }
- }
- }
- /**
- * Set keywords for a post id, returns boolean or int based on the value.
- *
- * @param int $post_id The post id.
- * @param KeywordList $keywords The keyword list for post.
- *
- * @return bool|int
- */
- public static function set_keywords($post_id, $keywords)
- {
- $prev_value = get_post_meta($post_id, Postmeta::ILJ_META_KEY_LINKDEFINITION, true);
- return update_post_meta($post_id, Postmeta::ILJ_META_KEY_LINKDEFINITION, $keywords->getKeywords(), $prev_value);
- }
- /**
- * Logic for adding the assets based on subscription
- *
- * @since 1.1.0
- *
- * @return void
- */
- public static function addAssets()
- {
- $required_role = 'administrator';
- if (!current_user_can($required_role)) {
- return;
- }
- global $pagenow;
- if (in_array($pagenow, array('post-new.php', 'post.php'))) {
- if (!isset($_GET['post_type'])) {
- self::registerAssets();
- return;
- }
- $post_type = get_post_type_object($_GET['post_type']);
- if (!$post_type || !$post_type->public) {
- return;
- }
- self::registerAssets();
- }
- }
- /**
- * Registering the assets for editor frontend
- *
- * @since 1.1.0
- *
- * @return void
- */
- private static function registerAssets()
- {
- add_action('admin_enqueue_scripts', function () {
- ILJHelperLoader::enqueue_script('jquery-ui-sortable');
- ILJHelperLoader::register_script(Editor::ILJ_KEYWORDS_HANDLE, ILJ_URL . 'admin/js/ilj_keywords.js', array(), ILJ_VERSION);
- ILJHelperLoader::register_script(Editor::ILJ_EDITOR_HANDLE, ILJ_URL . 'admin/js/ilj_editor.js', array(), ILJ_VERSION);
- wp_localize_script(Editor::ILJ_EDITOR_HANDLE, 'ilj_editor_translation', Editor::getTranslation());
- wp_add_inline_script(Editor::ILJ_EDITOR_HANDLE, 'const ilj_editor_basic_restriction = ' . json_encode(Editor::getBasicRestrictions()), 'before');
- ILJHelperLoader::enqueue_script('ilj_tipso', ILJ_URL . 'admin/js/tipso.js', array(), ILJ_VERSION);
- ILJHelperLoader::enqueue_script(Editor::ILJ_KEYWORDS_HANDLE);
- ILJHelperLoader::enqueue_script(Editor::ILJ_EDITOR_HANDLE);
- ILJHelperLoader::enqueue_style('ilj_tipso', ILJ_URL . 'admin/css/tipso.css', array(), ILJ_VERSION);
- ILJHelperLoader::enqueue_style(Editor::ILJ_EDITOR_HANDLE, ILJ_URL . 'admin/css/ilj_editor.css', array(), ILJ_VERSION);
- ILJHelperLoader::enqueue_style('ilj_ui', ILJ_URL . 'admin/css/ilj_ui.css', array(), ILJ_VERSION);
- }, 10, 1);
- }
- /**
- * Returns the frontend translation
- *
- * @since 1.0.1
- *
- * @return array
- */
- public static function getTranslation()
- {
- $translation = array('add_keyword' => __('Add Keyword', 'internal-links'), 'placeholder_keyword' => __('Keyword', 'internal-links'), 'howto_case' => __('Keywords get used <strong>case insensitive</strong>', 'internal-links'), 'howto_keyword' => __('Separate multiple keywords by commas', 'internal-links'), 'howto_gap' => __('Configure the gap dimension.', 'internal-links') . ' ' . __('It represents the number of keywords that appear between your other keywords dynamically.', 'internal-links') . ' ' . __('Learn more in our documentation:', 'internal-links') . '<br><strong><a target="_blank" rel="noopener" href="' . Help::getLinkUrl('editor/', 'gaps', 'gap help', 'editor') . '">' . __('Click here to open', 'internal-links') . '</a></strong>', 'headline_gaps' => __('Keyword gaps', 'internal-links'), 'add_gap' => __('Add gap', 'internal-links'), 'gap_type' => __('Gap type', 'internal-links'), 'type_min' => __('Minimum', 'internal-links'), 'type_exact' => __('Exact', 'internal-links'), 'type_max' => __('Maximum', 'internal-links'), 'howto_gap_min' => __('Minimum amount of keywords within the gap.', 'internal-links') . ' ' . __('No upper limits.', 'internal-links'), 'howto_gap_exact' => __('Exact amount of keywords within the gap.', 'internal-links'), 'howto_gap_max' => __('Maximum amount of keywords within the gap.', 'internal-links'), 'howto_links_per_paragraph' => __('Overrides the general setting for the current asset.', 'internal-links'), 'howto_add_to_blacklist' => __('Toggle to add/remove from global blacklist.', 'internal-links'), 'howto_limit_incoming_links' => __('Toggle to add/remove incoming links limit.', 'internal-links'), 'howto_limit_outgoing_links' => __('Toggle to add/remove outgoing links limit.', 'internal-links'), 'insert_gaps' => __('Insert gaps between keywords', 'internal-links'), 'headline_configured_keywords' => __('Configured keywords', 'internal-links'), 'message_keyword_exists' => __('This keyword already exists.', 'internal-links'), 'message_no_keyword' => __('No keyword defined.', 'internal-links'), 'message_length_not_valid' => __('Length of given keyword not valid.', 'internal-links'), 'message_multiple_placeholder' => __('Multiple consecutive placeholders are not allowed.', 'internal-links'), 'no_keywords' => __('No keywords configured.', 'internal-links'), 'gap_hover_exact' => __('Exact keyword gap:', 'internal-links'), 'gap_hover_max' => __('Maximum keyword gap:', 'internal-links'), 'gap_hover_min' => __('Minimum keyword gap:', 'internal-links'), 'limit_incoming_links' => __('Limit incoming Links:', 'internal-links'), 'max_incoming_links' => __('Maximum incoming links:', 'internal-links'), 'blacklist_incoming_links' => __('Keywords, that don`t get linked in the current content:', 'internal-links'), 'message_limited_blacklist_keyword' => __('With the free Basic version of the Iternal Link Juicer, you can block 2 keywords from being linked.', 'internal-links'), 'message_limited_blacklist_keyword_upgrade' => sprintf('» <a href="%s">', get_admin_url(null, 'admin.php?page=' . AdminMenu::ILJ_MENUPAGE_SLUG . '-pricing')) . __('Upgrade to Pro and add unlimited keywords', 'internal-links') . '</a>', 'headline_configured_keywords_blacklist' => __('Configured keyword blacklist:', 'internal-links'), 'is_blacklisted' => __('Is on global blacklist:', 'internal-links'), 'limit_links_per_paragraph' => __('Limit links per paragraph:', 'internal-links'), 'max_links_per_paragraph' => __('Maximum links per paragraph:', 'internal-links'), 'limit_outgoing_links' => __('Limit outgoing Links:', 'internal-links'), 'max_outgoing_links' => __('Maximum outgoing links:', 'internal-links'), 'cache_cleared' => __('Cache cleared.', 'internal-links'), 'upgrade_to_pro_button_text' => __('Upgrade to Pro', 'internal-links'), 'upgrade_to_pro_link' => get_admin_url(null, 'admin.php?billing_cycle=annual&trial=true&page=' . AdminMenu::ILJ_MENUPAGE_SLUG . '-pricing'), 'pro_feature_title' => __('This is a PRO Feature.', 'internal-links'));
- return $translation;
- }
- /**
- * Sets Basic version restrictions
- *
- * @version 1.2.15
- *
- * @return array
- */
- protected static function getBasicRestrictions()
- {
- $current_screen = get_current_screen();
- $basic_restrictions = array('blacklist_limit' => 2, 'is_active' => true, 'disable_title' => 'class="pro-title"', 'disable_setting' => 'pro-setting', 'disabled' => 'disabled', 'lock_icon' => '<span class="dashicons dashicons-lock tip" title="' . __('This feature is part of the Pro version', 'internal-links') . '"></span>', 'current_screen' => $current_screen->post_type);
- return $basic_restrictions;
- }
- /**
- * Checks if an asset is on the blacklist
- *
- * @since 1.2.15
- *
- * @param int $id The asset ID
- * @param string $type The asset type
- * @return bool True if blacklisted , false if not
- */
- public static function isBlacklisted($id, $type)
- {
- if ('post' == $type) {
- $postBlacklist = Options::getOption(ILJCoreOptionsBlacklist::getKey());
- $blacklisted = false;
- if (is_array($postBlacklist)) {
- if (in_array($id, $postBlacklist)) {
- $blacklisted = true;
- }
- }
- return $blacklisted;
- }
- return false;
- }
- /**
- * Removes an asset from blacklist
- *
- * @since 1.2.15
- *
- * @param int $id The asset id
- * @param string $type The asset type
- * @return void
- */
- protected static function removeFromBlacklist($id, $type)
- {
- $blacklist = array();
- if ('post' == $type) {
- $blacklist = Options::getOption(ILJCoreOptionsBlacklist::getKey());
- }
- $blacklist = is_array($blacklist) ? $blacklist : array();
- if (($key = array_search($id, $blacklist)) !== false) {
- unset($blacklist[$key]);
- } else {
- return;
- }
- if ('post' == $type) {
- Options::setOption(ILJCoreOptionsBlacklist::getKey(), $blacklist);
- }
- }
- /**
- * Adds ID to Blacklist Option of post/terms
- *
- * @since 1.2.15
- *
- * @param int $id The asset id
- * @param string $type The asset type
- * @return void
- */
- protected static function addToBlacklist($id, $type)
- {
- $blacklist = array();
- if ('post' == $type) {
- $blacklist = Options::getOption(ILJCoreOptionsBlacklist::getKey());
- }
- $blacklist = is_array($blacklist) ? $blacklist : array();
- if (in_array($id, $blacklist)) {
- return;
- }
- $blacklist[] = $id;
- if ('post' == $type) {
- Options::setOption(ILJCoreOptionsBlacklist::getKey(), $blacklist);
- }
- }
-}
No newline at end of file
+ <?php
+ }
+ }
+
+ /**
+ * Responsible for saving keyword meta values and
+ * stores limit linking settings for posts and
+ * stores limit linking settings for posts
+ *
+ * @since 1.0.0
+ *
+ * @param int $post_id The ID of the post
+ * @param WP_Post $post The post object
+ * @return void
+ */
+ public static function saveKeywordMeta($post_id, WP_Post $post) {
+ if (is_null($post_id) || is_null($post)) {
+ return;
+ }
+
+ if (!isset($_POST[self::ILJ_ADMINVIEW_NONCE]) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST[self::ILJ_ADMINVIEW_NONCE])), basename(__FILE__))
+ ) {
+ return $post_id;
+ }
+
+ $post_type = get_post_type_object($post->post_type);
+
+ if (!current_user_can($post_type->cap->edit_post, $post_id)) {
+ return $post_id;
+ }
+
+
+
+ if (array_key_exists(self::ILJ_META_KEY_BLACKLISTDEFINITION, $_POST)) {
+ $sanitized_blacklist_meta_value = sanitize_text_field(wp_unslash($_POST[self::ILJ_META_KEY_BLACKLISTDEFINITION]));
+ $keywordsblacklist = KeywordList::fromInput($sanitized_blacklist_meta_value);
+
+ {
+ update_post_meta(
+ $post_id,
+ self::ILJ_META_KEY_BLACKLISTDEFINITION,
+ array_slice($keywordsblacklist->getKeywords(), 0, 2)
+ );
+ }
+ }
+
+ if (array_key_exists(self::ILJ_IS_BLACKLISTED, $_POST) && true == $_POST[self::ILJ_IS_BLACKLISTED]) {
+ self::addToBlacklist($post_id, 'post');
+ } else {
+ self::removeFromBlacklist($post_id, 'post');
+ }
+
+ if (array_key_exists(Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys', $_POST)) {
+
+ $sanitized_meta_value = sanitize_text_field(wp_unslash($_POST[Postmeta::ILJ_META_KEY_LINKDEFINITION . '_keys']));
+ $keywords = KeywordList::fromInput($sanitized_meta_value);
+
+ // Retrieve the old keywords before updating
+ $old_keyword_list = KeywordList::fromMeta($post_id, 'post', Postmeta::ILJ_META_KEY_LINKDEFINITION);
+ $old_keyword_count = $old_keyword_list->getCount();
+ $update_status = self::set_keywords($post_id, $keywords);
+
+ /**
+ * Fires after keyword meta got saved
+ *
+ * @since 1.0.0
+ */
+ if (true == $update_status) {
+ $post_id = isset($_POST['post_ID']) ? intval($_POST['post_ID']) : 0;
+ $post_status = isset($_POST['post_status']) ? sanitize_text_field(wp_unslash($_POST['post_status'])) : '';
+ $keyword_list = KeywordList::fromMeta($post_id, 'post', Postmeta::ILJ_META_KEY_LINKDEFINITION);
+ $keyword_count = $keyword_list->getCount();
+ if ($old_keyword_count > 0 && 0 == $keyword_count) {
+ Linkindex::delete_link_to($post_id, 'post');
+ Statistic::updateStatisticsInfo();
+ } elseif ($keyword_count > 0) {
+ do_action(self::ILJ_ACTION_AFTER_KEYWORDS_UPDATE, $post_id, 'post', $post_status);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Set keywords for a post id, returns boolean or int based on the value.
+ *
+ * @param int $post_id The post id.
+ * @param KeywordList $keywords The keyword list for post.
+ *
+ * @return bool|int
+ */
+ public static function set_keywords($post_id, $keywords) {
+ $prev_value = get_post_meta($post_id, Postmeta::ILJ_META_KEY_LINKDEFINITION, true);
+ return update_post_meta(
+ $post_id,
+ Postmeta::ILJ_META_KEY_LINKDEFINITION,
+ $keywords->getKeywords(),
+ $prev_value
+ );
+ }
+
+ /**
+ * Logic for adding the assets based on subscription
+ *
+ * @since 1.1.0
+ *
+ * @return void
+ */
+ public static function addAssets() {
+ $required_role = 'administrator';
+
+
+
+ if (!current_user_can($required_role)) {
+ return;
+ }
+
+ global $pagenow;
+
+ if (in_array($pagenow, array('post-new.php', 'post.php'))) {
+
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It gets the post type on the add/edit post admin dashboard page. No nonce verification needed.
+ if (!isset($_GET['post_type'])) {
+ self::registerAssets();
+ return;
+ }
+
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It gets the post type on the add/edit post admin dashboard page. No nonce verification needed.
+ $post_type = get_post_type_object(sanitize_text_field(wp_unslash($_GET['post_type'])));
+
+
+
+ if (!$post_type || !$post_type->public) {
+ return;
+ }
+
+ self::registerAssets();
+ }
+
+
+ }
+
+ /**
+ * Registering the assets for editor frontend
+ *
+ * @since 1.1.0
+ *
+ * @return void
+ */
+ private static function registerAssets() {
+ add_action(
+ 'admin_enqueue_scripts',
+ function () {
+ ILJHelperLoader::enqueue_script('jquery-ui-sortable');
+ ILJHelperLoader::register_script(Editor::ILJ_KEYWORDS_HANDLE, ILJ_URL . 'admin/js/ilj_keywords.js', array(), ILJ_VERSION);
+ ILJHelperLoader::register_script(Editor::ILJ_EDITOR_HANDLE, ILJ_URL . 'admin/js/ilj_editor.js', array(), ILJ_VERSION);
+ ILJHelperLoader::register_script(Editor::ILJ_MODAL, ILJ_URL . 'admin/js/ilj_modal.js', array(), ILJ_VERSION);
+ wp_localize_script(Editor::ILJ_EDITOR_HANDLE, 'ilj_editor_duplicate', array(
+ 'nonce' => wp_create_nonce('ilj-editor-action'),
+ ));
+ wp_localize_script(Editor::ILJ_EDITOR_HANDLE, 'ilj_editor_translation', array_merge(
+ Editor::getTranslation(),
+ array('nonce' => wp_create_nonce('render-keyword-meta-box-nonce'))
+ ));
+ wp_add_inline_script(Editor::ILJ_EDITOR_HANDLE, 'const ilj_editor_basic_restriction = ' . wp_json_encode(Editor::getBasicRestrictions()), 'before');
+ ILJHelperLoader::enqueue_script('ilj_tipso', ILJ_URL . 'admin/js/tipso.js', array(), ILJ_VERSION);
+ ILJHelperLoader::enqueue_script(Editor::ILJ_KEYWORDS_HANDLE);
+ ILJHelperLoader::enqueue_script(Editor::ILJ_EDITOR_HANDLE);
+ ILJHelperLoader::enqueue_script(Editor::ILJ_MODAL);
+ ILJHelperLoader::enqueue_style('ilj_tipso', ILJ_URL . 'admin/css/tipso.css', array(), ILJ_VERSION);
+ ILJHelperLoader::enqueue_style(Editor::ILJ_EDITOR_HANDLE, ILJ_URL . 'admin/css/ilj_editor.css', array(), ILJ_VERSION);
+ ILJHelperLoader::enqueue_style(Editor::ILJ_EDITOR_HANDLE, ILJ_URL . 'admin/css/ilj_modal.css', array(), ILJ_VERSION);
+ ILJHelperLoader::enqueue_style('ilj_ui', ILJ_URL . 'admin/css/ilj_ui.css', array(), ILJ_VERSION);
+ },
+ 10,
+ 1
+ );
+
+ }
+
+ /**
+ * Returns the frontend translation
+ *
+ * @since 1.0.1
+ *
+ * @return array
+ */
+ public static function getTranslation() {
+ $translation = array(
+ 'add_keyword' => __('Add Keyword', 'internal-links'),
+ 'placeholder_keyword' => __('Keyword', 'internal-links'),
+ 'howto_case' => __('Keywords get used <strong>case insensitive</strong>', 'internal-links'),
+ 'howto_keyword' => __('Separate multiple keywords by commas', 'internal-links'),
+ 'howto_gap' => __('Configure the gap dimension.', 'internal-links') . ' ' . __('It represents the number of keywords that appear between your other keywords dynamically.', 'internal-links') . ' ' . __('Learn more in our documentation:', 'internal-links') . '<br><strong><a target="_blank" rel="noopener" href="' . Help::getLinkUrl('editor/', 'gaps', 'gap help', 'editor') . '">' . __('Click here to open', 'internal-links') . '</a></strong>',
+ 'headline_gaps' => __('Keyword gaps', 'internal-links'),
+ 'add_gap' => __('Add gap', 'internal-links'),
+ 'gap_type' => __('Gap type', 'internal-links'),
+ 'type_min' => __('Minimum', 'internal-links'),
+ 'type_exact' => __('Exact', 'internal-links'),
+ 'type_max' => __('Maximum', 'internal-links'),
+ 'howto_gap_min' => __('Minimum amount of keywords within the gap.', 'internal-links') . ' ' . __('No upper limits.', 'internal-links'),
+ 'howto_gap_exact' => __('Exact amount of keywords within the gap.', 'internal-links'),
+ 'howto_gap_max' => __('Maximum amount of keywords within the gap.', 'internal-links'),
+ 'howto_links_per_paragraph' => __('Overrides the general setting for the current asset.', 'internal-links'),
+ 'howto_add_to_blacklist' => __('Toggle to add/remove from global blacklist.', 'internal-links'),
+ 'howto_limit_incoming_links' => __('Toggle to add/remove incoming links limit.', 'internal-links'),
+ 'howto_limit_outgoing_links' => __('Toggle to add/remove outgoing links limit.', 'internal-links'),
+ 'insert_gaps' => __('Insert gaps between keywords', 'internal-links'),
+ 'headline_configured_keywords' => __('Configured keywords', 'internal-links'),
+ 'message_keyword_exists' => __('This keyword already exists.', 'internal-links'),
+ 'message_no_keyword' => __('No keyword defined.', 'internal-links'),
+ 'message_length_not_valid' => __('Length of given keyword not valid.', 'internal-links'),
+ 'message_multiple_placeholder' => __('Multiple consecutive placeholders are not allowed.', 'internal-links'),
+ 'no_keywords' => __('No keywords configured.', 'internal-links'),
+ 'gap_hover_exact' => __('Exact keyword gap:', 'internal-links'),
+ 'gap_hover_max' => __('Max