Commit 79494a4c authored by Simonas's avatar Simonas

Plugins added

parent 3b70bd3b
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
- check if dev.biuro.lt, dev.biuro.lv, dev.biuro.ee works - check if dev.biuro.lt, dev.biuro.lv, dev.biuro.ee works
### DB backup ### DB backup
- `C:\web\dev.biuro> docker exec -i mysql mysqldump -uroot -pIiIjnsLi2wR9i1kWVbVpUAzP --default-character-set=utf8 wordpress > docker/mariadb/db_003.sql` - `C:\web\dev.biuro> docker exec -i mysql mysqldump -uroot -pIiIjnsLi2wR9i1kWVbVpUAzP --default-character-set=utf8 wordpress > docker/mariadb/db_004.sql`
### DB restore ### DB restore
- `C:\web\dev.biuro> docker exec -i mysql mysql -uroot -pIiIjnsLi2wR9i1kWVbVpUAzP --default-character-set=utf8 wordpress < docker/mariadb/db_002.sql` - `C:\web\dev.biuro> docker exec -i mysql mysql -uroot -pIiIjnsLi2wR9i1kWVbVpUAzP --default-character-set=utf8 wordpress < docker/mariadb/db_003.sql`
## Development ## Development
- `C:\web\dev.biuro\wordpress>yarn (or npm install)` - `C:\web\dev.biuro\wordpress>yarn (or npm install)`
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
- info@biuro.eu - info@biuro.eu
### Plugins ### Plugins
#### Akismet Anti-Spam
#### Gutenberg
#### Polylang
#### Yoast SEO
### SEO ### SEO
- https://docs.google.com/document/d/1FiwVoiLvGGmi9V-HPBgJ3gsh3wGswt27csgvfdTU24w/edit?usp=sharing - https://docs.google.com/document/d/1FiwVoiLvGGmi9V-HPBgJ3gsh3wGswt27csgvfdTU24w/edit?usp=sharing
...@@ -49,7 +53,7 @@ p.s. might not be shared with everyone ...@@ -49,7 +53,7 @@ p.s. might not be shared with everyone
ERROR: for mysql Cannot start service mysql: error while creating mount source path '/host_mnt/c/web/dev.biuro/var/mariadb': mkdir /host_mnt/c: file exists ERROR: for mysql Cannot start service mysql: error while creating mount source path '/host_mnt/c/web/dev.biuro/var/mariadb': mkdir /host_mnt/c: file exists
### Solution ### Solution
Restart docker Restart docker (sometimes PC restart may be required)
......
This diff is collapsed.
{ {
"name": "Our demo", "name": "Biuro",
"short_name": "Our demo", "short_name": "Biuro",
"icons": [ "icons": [
{ {
"src": "/wp-content/themes/biuro/icons/android-chrome-192x192.png", "src": "/wp-content/themes/biuro/icons/android-chrome-192x192.png",
......
{ {
"name": "Our demo", "name": "Biuro",
"short_name": "Our demo", "short_name": "Biuro",
"icons": [ "icons": [
{ {
"src": "/wp-content/themes/biuro/icons/android-chrome-192x192.png", "src": "/wp-content/themes/biuro/icons/android-chrome-192x192.png",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Ajax
*/
/**
* Class WPSEO_Recalculate_Scores
*
* This class handles the SEO score recalculation for all posts with a filled focus keyword
*/
class WPSEO_Recalculate_Scores_Ajax {
/**
* Initialize the AJAX hooks
*/
public function __construct() {
add_action( 'wp_ajax_wpseo_recalculate_scores', array( $this, 'recalculate_scores' ) );
add_action( 'wp_ajax_wpseo_update_score', array( $this, 'save_score' ) );
add_action( 'wp_ajax_wpseo_recalculate_total', array( $this, 'get_total' ) );
}
/**
* Get the totals for the posts and the terms.
*/
public function get_total() {
check_ajax_referer( 'wpseo_recalculate', 'nonce' );
wp_die(
wp_json_encode(
array(
'posts' => $this->calculate_posts(),
'terms' => $this->calculate_terms(),
)
)
);
}
/**
* Start recalculation
*/
public function recalculate_scores() {
check_ajax_referer( 'wpseo_recalculate', 'nonce' );
$fetch_object = $this->get_fetch_object();
if ( ! empty( $fetch_object ) ) {
$paged = filter_input( INPUT_POST, 'paged', FILTER_VALIDATE_INT );
$response = $fetch_object->get_items_to_recalculate( $paged );
if ( ! empty( $response ) ) {
wp_die( wp_json_encode( $response ) );
}
}
wp_die( '' );
}
/**
* Saves the new linkdex score for given post
*/
public function save_score() {
check_ajax_referer( 'wpseo_recalculate', 'nonce' );
$fetch_object = $this->get_fetch_object();
if ( ! empty( $fetch_object ) ) {
$scores = filter_input( INPUT_POST, 'scores', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
$fetch_object->save_scores( $scores );
}
wp_die();
}
/**
* Returns the needed object for recalculating scores.
*
* @return WPSEO_Recalculate_Posts|WPSEO_Recalculate_Terms
*/
private function get_fetch_object() {
switch ( filter_input( INPUT_POST, 'type' ) ) {
case 'post':
return new WPSEO_Recalculate_Posts();
case 'term':
return new WPSEO_Recalculate_Terms();
}
return null;
}
/**
* Gets the total number of posts
*
* @return int
*/
private function calculate_posts() {
$count_posts_query = new WP_Query(
array(
'post_type' => 'any',
'meta_key' => '_yoast_wpseo_focuskw',
'posts_per_page' => 1,
'fields' => 'ids',
)
);
return $count_posts_query->found_posts;
}
/**
* Get the total number of terms
*
* @return int
*/
private function calculate_terms() {
$total = 0;
foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) {
$total += wp_count_terms( $taxonomy->name, array( 'hide_empty' => false ) );
}
return $total;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Ajax
*/
/**
* Class WPSEO_Shortcode_Filter
*
* Used for parsing WP shortcodes with AJAX
*/
class WPSEO_Shortcode_Filter {
/**
* Initialize the AJAX hooks
*/
public function __construct() {
add_action( 'wp_ajax_wpseo_filter_shortcodes', array( $this, 'do_filter' ) );
}
/**
* Parse the shortcodes
*/
public function do_filter() {
check_ajax_referer( 'wpseo-filter-shortcodes', 'nonce' );
$shortcodes = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
$parsed_shortcodes = array();
foreach ( $shortcodes as $shortcode ) {
$parsed_shortcodes[] = array(
'shortcode' => $shortcode,
'output' => do_shortcode( $shortcode ),
);
}
wp_die( wp_json_encode( $parsed_shortcodes ) );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Ajax
*/
/**
* This class will catch the request to dismiss the target notice (set by notice_name) and will store the dismiss status as an user meta
* in the database
*/
class Yoast_Dismissable_Notice_Ajax {
/**
* @var string Notice type toggle value for user notices.
*/
const FOR_USER = 'user_meta';
/**
* @var string Notice type toggle value for network notices.
*/
const FOR_NETWORK = 'site_option';
/**
* @var string Notice type toggle value for site notices.
*/
const FOR_SITE = 'option';
/**
* @var string Name of the notice that will be dismissed.
*/
private $notice_name;
/**
* @var string
*/
private $notice_type;
/**
* Initialize the hooks for the AJAX request
*
* @param string $notice_name The name for the hook to catch the notice.
* @param string $notice_type The notice type.
*/
public function __construct( $notice_name, $notice_type = self::FOR_USER ) {
$this->notice_name = $notice_name;
$this->notice_type = $notice_type;
add_action( 'wp_ajax_wpseo_dismiss_' . $notice_name, array( $this, 'dismiss_notice' ) );
}
/**
* Handles the dismiss notice request
*/
public function dismiss_notice() {
check_ajax_referer( 'wpseo-dismiss-' . $this->notice_name );
$this->save_dismissed();
wp_die( 'true' );
}
/**
* Storing the dismissed value in the database. The target location is based on the set notification type.
*/
private function save_dismissed() {
if ( $this->notice_type === self::FOR_SITE ) {
update_option( 'wpseo_dismiss_' . $this->notice_name, 1 );
return;
}
if ( $this->notice_type === self::FOR_NETWORK ) {
update_site_option( 'wpseo_dismiss_' . $this->notice_name, 1 );
return;
}
update_user_meta( get_current_user_id(), 'wpseo_dismiss_' . $this->notice_name, 1 );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Ajax
*/
/**
* Class Yoast_OnPage_Ajax
*
* This class will catch the request to dismiss the Ryte notice and will store
* the dismiss status as an user meta in the database.
*/
class Yoast_OnPage_Ajax {
/**
* Initialize the hooks for the AJAX request
*/
public function __construct() {
add_action( 'wp_ajax_wpseo_dismiss_onpageorg', array( $this, 'dismiss_notice' ) );
}
/**
* Handles the dismiss notice request
*/
public function dismiss_notice() {
check_ajax_referer( 'wpseo-dismiss-onpageorg' );
$this->save_dismissed();
wp_die( 'true' );
}
/**
* Storing the dismissed value as an user option in the database
*/
private function save_dismissed() {
update_user_meta( get_current_user_id(), WPSEO_OnPage::USER_META_KEY, 1 );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Ajax
*/
/**
* Class Yoast_Plugin_Conflict_Ajax
*/
class Yoast_Plugin_Conflict_Ajax {
/**
* @var string
*/
private $option_name = 'wpseo_dismissed_conflicts';
/**
* @var array
*/
private $dismissed_conflicts = array();
/**
* Initialize the hooks for the AJAX request
*/
public function __construct() {
add_action( 'wp_ajax_wpseo_dismiss_plugin_conflict', array( $this, 'dismiss_notice' ) );
}
/**
* Handles the dismiss notice request
*/
public function dismiss_notice() {
check_ajax_referer( 'dismiss-plugin-conflict' );
$conflict_data = filter_input( INPUT_POST, 'data', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
$this->dismissed_conflicts = $this->get_dismissed_conflicts( $conflict_data['section'] );
$this->compare_plugins( $conflict_data['plugins'] );
$this->save_dismissed_conflicts( $conflict_data['section'] );
wp_die( 'true' );
}
/**
* Getting the user option from the database
*
* @return bool|array
*/
private function get_dismissed_option() {
return get_user_meta( get_current_user_id(), $this->option_name, true );
}
/**
* Getting the dismissed conflicts from the database
*
* @param string $plugin_section Type of conflict group (such as Open Graph or sitemap).
*
* @return array
*/
private function get_dismissed_conflicts( $plugin_section ) {
$dismissed_conflicts = $this->get_dismissed_option();
if ( is_array( $dismissed_conflicts ) && array_key_exists( $plugin_section, $dismissed_conflicts ) ) {
return $dismissed_conflicts[ $plugin_section ];
}
return array();
}
/**
* Storing the conflicting plugins as an user option in the database
*
* @param string $plugin_section Plugin conflict type (such as Open Graph or sitemap).
*/
private function save_dismissed_conflicts( $plugin_section ) {
$dismissed_conflicts = $this->get_dismissed_option();
$dismissed_conflicts[ $plugin_section ] = $this->dismissed_conflicts;
update_user_meta( get_current_user_id(), $this->option_name, $dismissed_conflicts );
}
/**
* Loop through the plugins to compare them with the already stored dismissed plugin conflicts
*
* @param array $posted_plugins Plugin set to check.
*/
public function compare_plugins( array $posted_plugins ) {
foreach ( $posted_plugins as $posted_plugin ) {
$this->compare_plugin( $posted_plugin );
}
}
/**
* Check if plugin is already dismissed, if not store it in the array that will be saved later
*
* @param string $posted_plugin Plugin to check against dismissed conflicts.
*/
private function compare_plugin( $posted_plugin ) {
if ( ! in_array( $posted_plugin, $this->dismissed_conflicts, true ) ) {
$this->dismissed_conflicts[] = $posted_plugin;
}
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Abstract Capability Manager shared code.
*/
abstract class WPSEO_Abstract_Capability_Manager implements WPSEO_Capability_Manager {
/** @var array Registered capabilities */
protected $capabilities = array();
/**
* Registers a capability.
*
* @param string $capability Capability to register.
* @param array $roles Roles to add the capability to.
* @param bool $overwrite Optional. Use add or overwrite as registration method.
*/
public function register( $capability, array $roles, $overwrite = false ) {
if ( $overwrite || ! isset( $this->capabilities[ $capability ] ) ) {
$this->capabilities[ $capability ] = $roles;
return;
}
// Combine configurations.
$this->capabilities[ $capability ] = array_merge( $roles, $this->capabilities[ $capability ] );
// Remove doubles.
$this->capabilities[ $capability ] = array_unique( $this->capabilities[ $capability ] );
}
/**
* Returns the list of registered capabilitities.
*
* @return string[] Registered capabilities.
*/
public function get_capabilities() {
return array_keys( $this->capabilities );
}
/**
* Returns a list of WP_Role roles.
*
* The string array of role names are converted to actual WP_Role objects.
* These are needed to be able to use the API on them.
*
* @param array $roles Roles to retrieve the objects for.
*
* @return WP_Role[] List of WP_Role objects.
*/
protected function get_wp_roles( array $roles ) {
$wp_roles = array_map( 'get_role', $roles );
return array_filter( $wp_roles );
}
/**
* Filter capability roles.
*
* @param string $capability Capability to filter roles for.
* @param array $roles List of roles which can be filtered.
*
* @return array Filtered list of roles for the capability.
*/
protected function filter_roles( $capability, array $roles ) {
/**
* Filter: Allow changing roles that a capability is added to.
*
* @api array $roles The default roles to be filtered.
*/
$filtered = apply_filters( $capability . '_roles', $roles );
// Make sure we have the expected type.
if ( ! is_array( $filtered ) ) {
return array();
}
return $filtered;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Capability Manager Factory.
*/
class WPSEO_Capability_Manager_Factory {
/**
* Returns the Manager to use.
*
* @return WPSEO_Capability_Manager Manager to use.
*/
public static function get() {
static $manager = null;
if ( $manager === null ) {
if ( function_exists( 'wpcom_vip_add_role_caps' ) ) {
$manager = new WPSEO_Capability_Manager_VIP();
}
if ( ! function_exists( 'wpcom_vip_add_role_caps' ) ) {
$manager = new WPSEO_Capability_Manager_WP();
}
}
return $manager;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Integrates Yoast SEO capabilities with third party role manager plugins.
*
* Integrates with: Members
* Integrates with: User Role Editor
*/
class WPSEO_Capability_Manager_Integration implements WPSEO_WordPress_Integration {
/** @var WPSEO_Capability_Manager Capability manager to use. */
public $manager;
/**
* WPSEO_Capability_Manager_Integration constructor.
*
* @param WPSEO_Capability_Manager $manager The capability manager to use.
*/
public function __construct( WPSEO_Capability_Manager $manager ) {
$this->manager = $manager;
}
/**
* Registers the hooks.
*
* @return void
*/
public function register_hooks() {
add_filter( 'members_get_capabilities', array( $this, 'get_capabilities' ) );
add_action( 'members_register_cap_groups', array( $this, 'action_members_register_cap_group' ) );
add_filter( 'ure_capabilities_groups_tree', array( $this, 'filter_ure_capabilities_groups_tree' ) );
add_filter( 'ure_custom_capability_groups', array( $this, 'filter_ure_custom_capability_groups' ), 10, 2 );
}
/**
* Get the Yoast SEO capabilities.
* Optionally append them to an existing array.
*
* @param array $caps Optional existing capability list.
* @return array
*/
public function get_capabilities( array $caps = array() ) {
if ( ! did_action( 'wpseo_register_capabilities' ) ) {
do_action( 'wpseo_register_capabilities' );
}
return array_merge( $caps, $this->manager->get_capabilities() );
}
/**
* Add capabilities to its own group in the Members plugin.
*
* @see members_register_cap_group()
*/
public function action_members_register_cap_group() {
if ( ! function_exists( 'members_register_cap_group' ) ) {
return;
}
// Register the yoast group.
members_register_cap_group( 'wordpress-seo',
array(
'label' => esc_html__( 'Yoast SEO', 'wordpress-seo' ),
'caps' => $this->get_capabilities(),
'icon' => 'dashicons-admin-plugins',
'diff_added' => true,
)
);
}
/**
* Adds Yoast SEO capability group in the User Role Editor plugin.
*
* @see URE_Capabilities_Groups_Manager::get_groups_tree()
*
* @param array $groups Current groups.
*
* @return array Filtered list of capabilty groups.
*/
public function filter_ure_capabilities_groups_tree( $groups = array() ) {
$groups = (array) $groups;
$groups['wordpress-seo'] = array(
'caption' => 'Yoast SEO',
'parent' => 'custom',
'level' => 3,
);
return $groups;
}
/**
* Adds capabilities to the Yoast SEO group in the User Role Editor plugin.
*
* @see URE_Capabilities_Groups_Manager::get_cap_groups()
*
* @param array $groups Current capability groups.
* @param string $cap_id Capability identifier.
*
* @return array List of filtered groups.
*/
public function filter_ure_custom_capability_groups( $groups = array(), $cap_id = '' ) {
if ( in_array( $cap_id, $this->get_capabilities(), true ) ) {
$groups = (array) $groups;
$groups[] = 'wordpress-seo';
}
return $groups;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* VIP implementation of the Capability Manager.
*/
final class WPSEO_Capability_Manager_VIP extends WPSEO_Abstract_Capability_Manager {
/**
* Adds the registered capabilities to the system.
*
* @return void
*/
public function add() {
$role_capabilities = array();
foreach ( $this->capabilities as $capability => $roles ) {
$role_capabilities = $this->get_role_capabilities( $role_capabilities, $capability, $roles );
}
foreach ( $role_capabilities as $role => $capabilities ) {
wpcom_vip_add_role_caps( $role, $capabilities );
}
}
/**
* Removes the registered capabilities from the system
*
* @return void
*/
public function remove() {
// Remove from any role it has been added to.
$roles = wp_roles()->get_names();
$roles = array_keys( $roles );
$role_capabilities = array();
foreach ( array_keys( $this->capabilities ) as $capability ) {
// Allow filtering of roles.
$role_capabilities = $this->get_role_capabilities( $role_capabilities, $capability, $roles );
}
foreach ( $role_capabilities as $role => $capabilities ) {
wpcom_vip_remove_role_caps( $role, $capabilities );
}
}
/**
* Returns the roles which the capability is registered on.
*
* @param array $role_capabilities List of all roles with their capabilities.
* @param string $capability Capability to filter roles for.
* @param array $roles List of default roles.
*
* @return array List of capabilities.
*/
protected function get_role_capabilities( $role_capabilities, $capability, $roles ) {
// Allow filtering of roles.
$filtered_roles = $this->filter_roles( $capability, $roles );
foreach ( $filtered_roles as $role ) {
if ( ! isset( $add_role_caps[ $role ] ) ) {
$role_capabilities[ $role ] = array();
}
$role_capabilities[ $role ][] = $capability;
}
return $role_capabilities;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Default WordPress capability manager implementation.
*/
final class WPSEO_Capability_Manager_WP extends WPSEO_Abstract_Capability_Manager {
/**
* Adds the capabilities to the roles.
*
* @return void
*/
public function add() {
foreach ( $this->capabilities as $capability => $roles ) {
$filtered_roles = $this->filter_roles( $capability, $roles );
$wp_roles = $this->get_wp_roles( $filtered_roles );
foreach ( $wp_roles as $wp_role ) {
$wp_role->add_cap( $capability );
}
}
}
/**
* Unregisters the capabilities from the system.
*
* @return void
*/
public function remove() {
// Remove from any roles it has been added to.
$roles = wp_roles()->get_names();
$roles = array_keys( $roles );
foreach ( $this->capabilities as $capability => $_roles ) {
$registered_roles = array_unique( array_merge( $roles, $this->capabilities[ $capability ] ) );
// Allow filtering of roles.
$filtered_roles = $this->filter_roles( $capability, $registered_roles );
$wp_roles = $this->get_wp_roles( $filtered_roles );
foreach ( $wp_roles as $wp_role ) {
$wp_role->remove_cap( $capability );
}
}
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Capability Manager interface.
*/
interface WPSEO_Capability_Manager {
/**
* Registers a capability.
*
* @param string $capability Capability to register.
* @param array $roles Roles to add the capability to.
* @param bool $overwrite Optional. Use add or overwrite as registration method.
*/
public function register( $capability, array $roles, $overwrite = false );
/**
* Adds the registerd capabilities to the system.
*/
public function add();
/**
* Removes the registered capabilities from the system.
*/
public function remove();
/**
* Returns the list of registered capabilities.
*
* @return string[] List of registered capabilities.
*/
public function get_capabilities();
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Capability Utils collection.
*/
class WPSEO_Capability_Utils {
/**
* Checks if the user has the proper capabilities.
*
* @param string $capability Capability to check.
*
* @return bool True if the user has the proper rights.
*/
public static function current_user_can( $capability ) {
if ( $capability === 'wpseo_manage_options' ) {
return self::has( $capability );
}
return self::has_any( array( 'wpseo_manage_options', $capability ) );
}
/**
* Checks if the current user has at least one of the supplied capabilities.
*
* @param array $capabilities Capabilities to check against.
*
* @return bool True if the user has at least one capability.
*/
protected static function has_any( array $capabilities ) {
foreach ( $capabilities as $capability ) {
if ( self::has( $capability ) ) {
return true;
}
}
return false;
}
/**
* Checks if the user has a certain capability.
*
* @param string $capability Capability to check against.
*
* @return bool True if the user has the capability.
*/
protected static function has( $capability ) {
return current_user_can( $capability );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Capabilities
*/
/**
* Capabilities registration class.
*/
class WPSEO_Register_Capabilities implements WPSEO_WordPress_Integration {
/**
* Registers the hooks.
*
* @return void
*/
public function register_hooks() {
add_action( 'wpseo_register_capabilities', array( $this, 'register' ) );
if ( is_multisite() ) {
add_action( 'user_has_cap', array( $this, 'filter_user_has_wpseo_manage_options_cap' ), 10, 4 );
}
}
/**
* Registers the capabilities.
*
* @return void
*/
public function register() {
$manager = WPSEO_Capability_Manager_Factory::get();
$manager->register( 'wpseo_bulk_edit', array( 'editor', 'wpseo_editor', 'wpseo_manager' ) );
$manager->register( 'wpseo_edit_advanced_metadata', array( 'wpseo_editor', 'wpseo_manager' ) );
$manager->register( 'wpseo_manage_options', array( 'administrator', 'wpseo_manager' ) );
}
/**
* Revokes the 'wpseo_manage_options' capability from administrator users if it should only
* only be granted to network administrators.
*
* @param array $allcaps An array of all the user's capabilities.
* @param array $caps Actual capabilities being checked.
* @param array $args Optional parameters passed to has_cap(), typically object ID.
* @param WP_User $user The user object.
*
* @return array Possibly modified array of the user's capabilities.
*/
public function filter_user_has_wpseo_manage_options_cap( $allcaps, $caps, $args, $user ) {
// We only need to do something if 'wpseo_manage_options' is being checked.
if ( ! in_array( 'wpseo_manage_options', $caps, true ) ) {
return $allcaps;
}
// If the user does not have 'wpseo_manage_options' anyway, we don't need to revoke access.
if ( empty( $allcaps['wpseo_manage_options'] ) ) {
return $allcaps;
}
// If the user does not have 'delete_users', they are not an administrator.
if ( empty( $allcaps['delete_users'] ) ) {
return $allcaps;
}
$options = WPSEO_Options::get_instance();
if ( $options->get( 'access' ) === 'superadmin' && ! is_super_admin( $user->ID ) ) {
unset( $allcaps['wpseo_manage_options'] );
}
return $allcaps;
}
}
<?php
/**
* @package WPSEO\Admin
*/
/**
* Class to print out the translatable strings for the Add Keyword modal.
*/
class WPSEO_Add_Keyword_Modal {
/**
* Returns the translations for the Add Keyword modal.
*
* These strings are not escaped because they're meant to be used with React
* which already takes care of that. If used in PHP, they should be escaped.
*
* @return array Translated text strings for the Add Keyword modal.
*/
public function get_translations() {
return array(
'title' => __( 'Would you like to add more than one keyphrase?', 'wordpress-seo' ),
'intro' => sprintf(
/* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
__( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
'{{link}}Yoast SEO Premium{{/link}}'
),
'link' => WPSEO_Shortlinker::get( 'https://yoa.st/pe-premium-page' ),
'other' => sprintf(
/* translators: %s expands to 'Yoast SEO Premium'. */
__( 'Other benefits of %s for you:', 'wordpress-seo' ),
'Yoast SEO Premium'
),
'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
'buy' => sprintf(
/* translators: %s expands to 'Yoast SEO Premium'. */
__( 'Get %s', 'wordpress-seo' ),
'Yoast SEO Premium'
),
'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
'a11yNotice.opensInNewTab' => __( '(Opens in a new browser tab)', 'wordpress-seo' ),
);
}
/**
* Passes translations to JS for the Add Keyword modal component.
*
* @return array Translated text strings for the Add Keyword modal component.
*/
public function get_translations_for_js() {
$translations = $this->get_translations();
return array(
'locale' => WPSEO_Utils::get_user_locale(),
'intl' => $translations,
);
}
/**
* Prints the localized Add Keyword modal translations for JS.
*/
public function enqueue_translations() {
wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-global-script', 'yoastAddKeywordModalL10n', $this->get_translations_for_js() );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Represents a way to determine the analysis worker asset location.
*/
final class WPSEO_Admin_Asset_Analysis_Worker_Location implements WPSEO_Admin_Asset_Location {
/**
* @var WPSEO_Admin_Asset_Location $asset_location.
*/
private $asset_location;
/**
* @var WPSEO_Admin_Asset $asset.
*/
private $asset;
/**
* Constructs the location of the analysis worker asset.
*
* @param string $flat_version The flat version of the asset.
* @param string $name The name of the analysis worker asset.
*/
public function __construct( $flat_version = '', $name = 'analysis-worker' ) {
if ( $flat_version === '' ) {
$asset_manager = new WPSEO_Admin_Asset_Manager();
$flat_version = $asset_manager->flatten_version( WPSEO_VERSION );
}
$this->asset_location = WPSEO_Admin_Asset_Manager::create_default_location();
$asset_arguments = array(
'name' => $name,
'src' => 'wp-seo-' . $name . '-' . $flat_version,
);
$this->asset = new WPSEO_Admin_Asset( $asset_arguments );
}
/**
* Retrieves the analysis worker asset.
*
* @return WPSEO_Admin_Asset The analysis worker asset.
*/
public function get_asset() {
return $this->asset;
}
/**
* Determines the URL of the asset on the dev server.
*
* @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
* @param string $type The type of asset. Usually JS or CSS.
*
* @return string The URL of the asset.
*/
public function get_url( WPSEO_Admin_Asset $asset, $type ) {
return $this->asset_location->get_url( $asset, $type );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Changes the asset paths to dev server paths.
*/
final class WPSEO_Admin_Asset_Dev_Server_Location implements WPSEO_Admin_Asset_Location {
const DEFAULT_URL = 'http://localhost:8080';
/**
* @var string
*/
private $url;
/**
* @param string $url Where the dev server is located.
*/
public function __construct( $url = null ) {
if ( $url === null ) {
$url = self::DEFAULT_URL;
}
$this->url = $url;
}
/**
* Determines the URL of the asset on the dev server.
*
* @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
* @param string $type The type of asset. Usually JS or CSS.
*
* @return string The URL of the asset.
*/
public function get_url( WPSEO_Admin_Asset $asset, $type ) {
if ( WPSEO_Admin_Asset::TYPE_CSS === $type ) {
return $this->get_default_url( $asset, $type );
}
$asset_manager = new WPSEO_Admin_Asset_Manager();
$flat_version = $asset_manager->flatten_version( WPSEO_VERSION );
$version_less_source = str_replace( '-' . $flat_version, '', $asset->get_src() );
if ( false !== strpos( $version_less_source, 'select2' ) ) {
return $this->get_default_url( $asset, $type );
}
$path = sprintf( '%s%s.js', $asset->get_src(), $asset->get_suffix() );
return trailingslashit( $this->url ) . $path;
}
/**
* Determines the URL of the asset not using the dev server.
*
* @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
* @param string $type The type of asset.
*
* @return string The URL of the asset file.
*/
public function get_default_url( WPSEO_Admin_Asset $asset, $type ) {
$default_location = new WPSEO_Admin_Asset_SEO_Location( WPSEO_FILE );
return $default_location->get_url( $asset, $type );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Represents a way to determine an assets location.
*/
interface WPSEO_Admin_Asset_Location {
/**
* Determines the URL of the asset on the dev server.
*
* @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
* @param string $type The type of asset. Usually JS or CSS.
*
* @return string The URL of the asset.
*/
public function get_url( WPSEO_Admin_Asset $asset, $type );
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Determines the location of an asset within the SEO plugin.
*/
final class WPSEO_Admin_Asset_SEO_Location implements WPSEO_Admin_Asset_Location {
/**
* @var string
*/
protected $plugin_file;
/**
* The plugin file to base the asset location upon.
*
* @param string $plugin_file The plugin file string.
*/
public function __construct( $plugin_file ) {
$this->plugin_file = $plugin_file;
}
/**
* Determines the URL of the asset on the dev server.
*
* @param WPSEO_Admin_Asset $asset The asset to determine the URL for.
* @param string $type The type of asset. Usually JS or CSS.
*
* @return string The URL of the asset.
*/
public function get_url( WPSEO_Admin_Asset $asset, $type ) {
$path = $this->get_path( $asset, $type );
if ( empty( $path ) ) {
return '';
}
if ( YOAST_ENVIRONMENT !== 'development' && ! $asset->get_suffix() ) {
$plugin_path = plugin_dir_path( $this->plugin_file );
if ( ! file_exists( $plugin_path . $path ) ) {
// Give a notice to the user in the console (only once).
WPSEO_Utils::javascript_console_notification(
'Development Files',
sprintf(
/* translators: %1$s resolves to https://github.com/Yoast/wordpress-seo */
__( 'You are trying to load non-minified files. These are only available in our development package. Check out %1$s to see all the source files.', 'wordpress-seo' ),
'https://github.com/Yoast/wordpress-seo'
),
true
);
// Just load the .min file.
$path = $this->get_path( $asset, $type, '.min' );
}
}
return plugins_url( $path, $this->plugin_file );
}
/**
* Determines the path relative to the plugin folder of an asset.
*
* @param WPSEO_Admin_Asset $asset The asset to determine the path
* for.
* @param string $type The type of asset.
* @param string|null $force_suffix The suffix to force, or null when
* to use the default suffix.
*
* @return string The path to the asset file.
*/
protected function get_path( WPSEO_Admin_Asset $asset, $type, $force_suffix = null ) {
$relative_path = '';
$rtl_suffix = '';
$suffix = ( $force_suffix === null ) ? $asset->get_suffix() : $force_suffix;
switch ( $type ) {
case WPSEO_Admin_Asset::TYPE_JS:
$relative_path = 'js/dist/' . $asset->get_src() . $suffix . '.js';
break;
case WPSEO_Admin_Asset::TYPE_CSS:
// Path and suffix for RTL stylesheets.
if ( function_exists( 'is_rtl' ) && is_rtl() && $asset->has_rtl() ) {
$rtl_suffix = '-rtl';
}
$relative_path = 'css/dist/' . $asset->get_src() . $rtl_suffix . $suffix . '.css';
break;
}
return $relative_path;
}
}
<?php
/**
* @package WPSEO\Admin
*/
/**
* Localizes JavaScript files.
*/
final class WPSEO_Admin_Asset_Yoast_Components_L10n {
/**
* Localizes the given script with the JavaScript translations.
*
* @param string $script_handle The script handle to localize for.
*
* @return void
*/
public function localize_script( $script_handle ) {
$translations = array(
'yoast-components' => $this->get_translations( 'yoast-components' ),
'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
);
wp_localize_script( $script_handle, 'wpseoYoastJSL10n', $translations );
}
/**
* Returns translations necessary for JS files.
*
* @param string $component The component to retrieve the translations for.
* @return object The translations in a Jed format for JS files.
*/
protected function get_translations( $component ) {
$locale = WPSEO_Utils::get_user_locale();
$file = plugin_dir_path( WPSEO_FILE ) . 'languages/' . $component . '-' . $locale . '.json';
if ( file_exists( $file ) ) {
$file = file_get_contents( $file );
if ( is_string( $file ) && $file !== '' ) {
return json_decode( $file, true );
}
}
return null;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Determines the editor specific replacement variables.
*/
class WPSEO_Admin_Editor_Specific_Replace_Vars {
/**
* @var array The editor specific replacement variables.
*/
protected $replacement_variables = array(
// Posts types.
'page' => array( 'id', 'pt_single', 'pt_plural', 'parent_title' ),
'post' => array( 'id', 'term404', 'pt_single', 'pt_plural' ),
// Custom post type.
'custom_post_type' => array( 'id', 'term404', 'pt_single', 'pt_plural', 'parent_title' ),
// Settings - archive pages.
'custom-post-type_archive' => array( 'pt_single', 'pt_plural' ),
// Taxonomies.
'category' => array( 'term_title', 'term_description', 'category_description', 'parent_title' ),
'post_tag' => array( 'term_title', 'term_description', 'tag_description' ),
'post_format' => array(),
// Custom taxonomy.
'term-in-custom-taxonomy' => array( 'term_title', 'term_description', 'category_description', 'parent_title' ),
// Settings - special pages.
'search' => array( 'searchphrase' ),
);
/**
* WPSEO_Admin_Editor_Specific_Replace_Vars constructor.
*/
public function __construct() {
$this->add_for_page_types(
array( 'page', 'post', 'custom_post_type' ),
WPSEO_Custom_Fields::get_custom_fields()
);
$this->add_for_page_types(
array( 'post', 'term-in-custom-taxonomies' ),
WPSEO_Custom_Taxonomies::get_custom_taxonomies()
);
}
/**
* Retrieves the editor specific replacement variables.
*
* @return array The editor specific replacement variables.
*/
public function get() {
/**
* Filter: Adds the possibility to add extra editor specific replacement variables.
*
* @api array $replacement_variables Empty array to add the editor specific replace vars to.
*/
$replacement_variables = apply_filters(
'wpseo_editor_specific_replace_vars',
$this->replacement_variables
);
if ( ! is_array( $replacement_variables ) ) {
$replacement_variables = $this->replacement_variables;
}
return array_filter( $replacement_variables, 'is_array' );
}
/**
* Retrieves the generic replacement variable names.
*
* Which are the replacement variables without the editor specific ones.
*
* @param array $replacement_variables Possibly generic replacement variables.
*
* @return array The generic replacement variable names.
*/
public function get_generic( $replacement_variables ) {
$shared_variables = array_diff(
$this->extract_names( $replacement_variables ),
$this->get_unique_replacement_variables()
);
return array_values( $shared_variables );
}
/**
* Determines the page type of the current term.
*
* @param string $taxonomy The taxonomy name.
*
* @return string The page type.
*/
public function determine_for_term( $taxonomy ) {
$replacement_variables = $this->get();
if ( array_key_exists( $taxonomy, $replacement_variables ) ) {
return $taxonomy;
}
return 'term-in-custom-taxonomy';
}
/**
* Determines the page type of the current post.
*
* @param WP_Post $post A WordPress post instance.
*
* @return string The page type.
*/
public function determine_for_post( $post ) {
if ( $post instanceof WP_Post === false ) {
return 'post';
}
$replacement_variables = $this->get();
if ( array_key_exists( $post->post_type, $replacement_variables ) ) {
return $post->post_type;
}
return 'custom_post_type';
}
/**
* Determines the page type for a post type.
*
* @param string $post_type The name of the post_type.
* @param string $fallback The page type to fall back to.
*
* @return string The page type.
*/
public function determine_for_post_type( $post_type, $fallback = 'custom_post_type' ) {
if ( ! $this->has_for_page_type( $post_type ) ) {
return $fallback;
}
return $post_type;
}
/**
* Determines the page type for an archive page.
*
* @param string $name The name of the archive.
* @param string $fallback The page type to fall back to.
*
* @return string The page type.
*/
public function determine_for_archive( $name, $fallback = 'custom-post-type_archive' ) {
$page_type = $name . '_archive';
if ( ! $this->has_for_page_type( $page_type ) ) {
return $fallback;
}
return $page_type;
}
/**
* Adds the replavement variables for the given page types.
*
* @param array $page_types Page types to add variables for.
* @param array $replacement_variables_to_add The variables to add.
*
* @return void
*/
protected function add_for_page_types( array $page_types, array $replacement_variables_to_add ) {
if ( empty( $replacement_variables_to_add ) ) {
return;
}
$replacement_variables_to_add = array_fill_keys( $page_types, $replacement_variables_to_add );
$replacement_variables = $this->replacement_variables;
$this->replacement_variables = array_merge_recursive( $replacement_variables, $replacement_variables_to_add );
}
/**
* Extracts the names from the given replacements variables.
*
* @param array $replacement_variables Replacement variables to extract the name from.
*
* @return array Extracted names.
*/
protected function extract_names( $replacement_variables ) {
$extracted_names = array();
foreach ( $replacement_variables as $replacement_variable ) {
if ( empty( $replacement_variable['name'] ) ) {
continue;
}
$extracted_names[] = $replacement_variable['name'];
}
return $extracted_names;
}
/**
* Returns whether the given page type has editor specific replace vars.
*
* @param string $page_type The page type to check.
*
* @return bool True if there are associated editor specific replace vars.
*/
protected function has_for_page_type( $page_type ) {
$replacement_variables = $this->get();
return ( ! empty( $replacement_variables[ $page_type ] ) && is_array( $replacement_variables[ $page_type ] ) );
}
/**
* Merges all editor specific replacement variables into one array and removes duplicates.
*
* @return array The list of unique editor specific replacement variables.
*/
protected function get_unique_replacement_variables() {
$merged_replacement_variables = call_user_func_array( 'array_merge', $this->get() );
return array_unique( $merged_replacement_variables );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Handles the Gutenberg Compatibility notification showing and hiding.
*/
class WPSEO_Admin_Gutenberg_Compatibility_Notification implements WPSEO_WordPress_Integration {
/**
* Notification ID to use.
*
* @var string
*/
private $notification_id = 'wpseo-outdated-gutenberg-plugin';
/**
* @var WPSEO_Gutenberg_Compatibility
*/
private $compatibility_checker;
/**
* @var Yoast_Notification_Center
*/
private $notification_center;
/**
* WPSEO_Admin_Gutenberg_Compatibility_Notification constructor.
*/
public function __construct() {
$this->compatibility_checker = new WPSEO_Gutenberg_Compatibility();
$this->notification_center = Yoast_Notification_Center::get();
}
/**
* Registers all hooks to WordPress.
*
* @return void
*/
public function register_hooks() {
add_action( 'admin_init', array( $this, 'manage_notification' ) );
}
/**
* Manages if the notification should be shown or removed.
*
* @return void
*/
public function manage_notification() {
if ( ! $this->compatibility_checker->is_installed() || $this->compatibility_checker->is_fully_compatible() ) {
$this->notification_center->remove_notification_by_id( $this->notification_id );
return;
}
$this->add_notification();
}
/**
* Adds the notification to the notificaton center.
*
* @return void
*/
private function add_notification() {
$level = $this->compatibility_checker->is_below_minimum() ? Yoast_Notification::ERROR : Yoast_Notification::WARNING;
$message = sprintf(
/* translators: %1$s expands to Yoast SEO, %2$s expands to the installed version, %3$s expands to Gutenberg */
__( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ),
'Yoast SEO',
$this->compatibility_checker->get_installed_version(),
'Gutenberg'
);
$notification = new Yoast_Notification(
$message,
array(
'id' => $this->notification_id,
'type' => $level,
'priority' => 1,
)
);
$this->notification_center->add_notification( $notification );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Generates the HTML for an inline Help Button and Panel.
*/
class WPSEO_Admin_Help_Panel {
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $help_button_text;
/**
* @var string
*/
private $help_content;
/**
* @var string
*/
private $wrapper;
/**
* Constructor.
*
* @param string $id Unique identifier of the element the inline help refers to, used as an identifier in the html.
* @param string $help_button_text The Help Button text. Needs a properly escaped string.
* @param string $help_content The Help Panel content. Needs a properly escaped string (might contain HTML).
* @param string $wrapper Optional Whether to print out a container div element for the Help Panel, used for styling.
* Pass a `has-wrapper` value to print out the container. Default: no container.
*/
public function __construct( $id, $help_button_text, $help_content, $wrapper = '' ) {
$this->id = $id;
$this->help_button_text = $help_button_text;
$this->help_content = $help_content;
$this->wrapper = $wrapper;
}
/**
* Returns the html for the Help Button.
*
* @return string
*/
public function get_button_html() {
if ( ! $this->id || ! $this->help_button_text || ! $this->help_content ) {
return '';
}
return sprintf(
' <button type="button" class="yoast_help yoast-help-button dashicons" id="%1$s-help-toggle" aria-expanded="false" aria-controls="%1$s-help"><span class="yoast-help-icon" aria-hidden="true"></span><span class="screen-reader-text">%2$s</span></button>',
esc_attr( $this->id ),
$this->help_button_text
);
}
/**
* Returns the html for the Help Panel.
*
* @return string
*/
public function get_panel_html() {
if ( ! $this->id || ! $this->help_button_text || ! $this->help_content ) {
return '';
}
$wrapper_start = '';
$wrapper_end = '';
if ( 'has-wrapper' === $this->wrapper ) {
$wrapper_start = '<div class="yoast-seo-help-container">';
$wrapper_end = '</div>';
}
return sprintf(
'%1$s<p id="%2$s-help" class="yoast-help-panel">%3$s</p>%4$s',
$wrapper_start,
esc_attr( $this->id ),
$this->help_content,
$wrapper_end
);
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Handles the media purge notification showing and hiding.
*/
class WPSEO_Admin_Media_Purge_Notification implements WPSEO_WordPress_Integration {
/**
* Notification ID to use.
*
* @var string
*/
private $notification_id = 'wpseo_media_purge';
/**
* Registers all hooks to WordPress.
*
* @return void
*/
public function register_hooks() {
add_action( 'admin_init', array( $this, 'manage_notification' ) );
add_filter( 'wpseo_option_tab-metas_media', array( $this, 'output_hidden_setting' ) );
// Dismissing is just setting the relevancy to false, which cancels out any functionality.
if ( WPSEO_Utils::is_yoast_seo_page() && filter_input( INPUT_GET, 'dismiss' ) === $this->notification_id ) {
WPSEO_Options::set( 'is-media-purge-relevant', false );
}
}
/**
* Adds a hidden setting to the media tab.
*
* To make sure the setting is not reverted to the default when -anything-
* is saved on the entire page (not just the media tab).
*
* @param string|null $input Current filter value.
*
* @return string|null
*/
public function output_hidden_setting( $input ) {
$form = Yoast_Form::get_instance();
$form->hidden( 'is-media-purge-relevant' );
return $input;
}
/**
* Manages if the notification should be shown or removed.
*
* @return void
*/
public function manage_notification() {
$this->remove_notification();
}
/**
* Retrieves the notification that should be shown or removed.
*
* @return Yoast_Notification The notification to use.
*/
private function get_notification() {
$content = sprintf(
/* translators: %1$s expands to the link to the article, %2$s closes the link tag. */
__( 'Your site\'s settings currently allow attachment URLs on your site to exist. Please read %1$sthis post about a potential issue%2$s with attachment URLs and check whether you have the correct setting for your site.', 'wordpress-seo' ),
'<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/2r8' ) ) . '" rel="noopener noreferrer" target="_blank">',
'</a>'
);
$content .= '<br><br>';
$content .= sprintf(
/* translators: %1$s dismiss link open tag, %2$s closes the link tag. */
__( 'If you know what this means and you do not want to see this message anymore, you can %1$sdismiss this message%2$s.', 'wordpress-seo' ),
'<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_dashboard&dismiss=' . $this->notification_id ) ) . '">',
'</a>'
);
return new Yoast_Notification(
$content,
array(
'type' => Yoast_Notification::ERROR,
'id' => $this->notification_id,
'capabilities' => 'wpseo_manage_options',
'priority' => 1,
)
);
}
/**
* Adds the notification to the notificaton center.
*
* @return void
*/
private function add_notification() {
$notification_center = Yoast_Notification_Center::get();
$notification_center->add_notification( $this->get_notification() );
}
/**
* Removes the notification from the notification center.
*
* @return void
*/
private function remove_notification() {
$notification_center = Yoast_Notification_Center::get();
$notification_center->remove_notification( $this->get_notification() );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Determines the recommended replacement variables based on the context.
*/
class WPSEO_Admin_Recommended_Replace_Vars {
/**
* @var array The recommended replacement variables.
*/
protected $recommended_replace_vars = array(
// Posts types.
'page' => array( 'sitename', 'title', 'sep', 'primary_category' ),
'post' => array( 'sitename', 'title', 'sep', 'primary_category' ),
// Homepage.
'homepage' => array( 'sitename', 'sitedesc', 'sep' ),
// Custom post type.
'custom_post_type' => array( 'sitename', 'title', 'sep' ),
// Taxonomies.
'category' => array( 'sitename', 'term_title', 'sep' ),
'post_tag' => array( 'sitename', 'term_title', 'sep' ),
'post_format' => array( 'sitename', 'term_title', 'sep', 'page' ),
// Custom taxonomy.
'term-in-custom-taxomomy' => array( 'sitename', 'term_title', 'sep' ),
// Settings - archive pages.
'author_archive' => array( 'sitename', 'title', 'sep', 'page' ),
'date_archive' => array( 'sitename', 'sep', 'date', 'page' ),
'custom-post-type_archive' => array( 'sitename', 'title', 'sep', 'page' ),
// Settings - special pages.
'search' => array( 'sitename', 'searchphrase', 'sep', 'page' ),
'404' => array( 'sitename', 'sep' ),
);
/**
* Determines the page type of the current term.
*
* @param string $taxonomy The taxonomy name.
*
* @return string The page type.
*/
public function determine_for_term( $taxonomy ) {
$recommended_replace_vars = $this->get_recommended_replacevars();
if ( array_key_exists( $taxonomy, $recommended_replace_vars ) ) {
return $taxonomy;
}
return 'term-in-custom-taxomomy';
}
/**
* Determines the page type of the current post.
*
* @param WP_Post $post A WordPress post instance.
*
* @return string The page type.
*/
public function determine_for_post( $post ) {
if ( $post instanceof WP_Post === false ) {
return 'post';
}
if ( $post->post_type === 'page' && $this->is_homepage( $post ) ) {
return 'homepage';
}
$recommended_replace_vars = $this->get_recommended_replacevars();
if ( array_key_exists( $post->post_type, $recommended_replace_vars ) ) {
return $post->post_type;
}
return 'custom_post_type';
}
/**
* Determines the page type for a post type.
*
* @param string $post_type The name of the post_type.
* @param string $fallback The page type to fall back to.
*
* @return string The page type.
*/
public function determine_for_post_type( $post_type, $fallback = 'custom_post_type' ) {
$page_type = $post_type;
$recommended_replace_vars = $this->get_recommended_replacevars();
$has_recommended_replacevars = $this->has_recommended_replace_vars( $recommended_replace_vars, $page_type );
if ( ! $has_recommended_replacevars ) {
return $fallback;
}
return $page_type;
}
/**
* Determines the page type for an archive page.
*
* @param string $name The name of the archive.
* @param string $fallback The page type to fall back to.
*
* @return string The page type.
*/
public function determine_for_archive( $name, $fallback = 'custom-post-type_archive' ) {
$page_type = $name . '_archive';
$recommended_replace_vars = $this->get_recommended_replacevars();
$has_recommended_replacevars = $this->has_recommended_replace_vars( $recommended_replace_vars, $page_type );
if ( ! $has_recommended_replacevars ) {
return $fallback;
}
return $page_type;
}
/**
* Retrieves the recommended replacement variables for the given page type.
*
* @param string $page_type The page type.
*
* @return array The recommended replacement variables.
*/
public function get_recommended_replacevars_for( $page_type ) {
$recommended_replace_vars = $this->get_recommended_replacevars();
$has_recommended_replace_vars = $this->has_recommended_replace_vars( $recommended_replace_vars, $page_type );
if ( ! $has_recommended_replace_vars ) {
return array();
}
return $recommended_replace_vars[ $page_type ];
}
/**
* Retrieves the recommended replacement variables.
*
* @return array The recommended replacement variables.
*/
public function get_recommended_replacevars() {
/**
* Filter: Adds the possibility to add extra recommended replacement variables.
*
* @api array $additional_replace_vars Empty array to add the replacevars to.
*/
$recommended_replace_vars = apply_filters( 'wpseo_recommended_replace_vars', $this->recommended_replace_vars );
if ( ! is_array( $recommended_replace_vars ) ) {
return $this->recommended_replace_vars;
}
return $recommended_replace_vars;
}
/**
* Returns whether the given page type has recommended replace vars.
*
* @param array $recommended_replace_vars The recommended replace vars
* to check in.
* @param string $page_type The page type to check.
*
* @return bool True if there are associated recommended replace vars.
*/
private function has_recommended_replace_vars( $recommended_replace_vars, $page_type ) {
if ( ! isset( $recommended_replace_vars[ $page_type ] ) ) {
return false;
}
if ( ! is_array( $recommended_replace_vars[ $page_type ] ) ) {
return false;
}
return true;
}
/**
* Determines whether or not a post is the homepage.
*
* @param WP_Post $post The WordPress global post object.
*
* @return bool True if the given post is the homepage.
*/
private function is_homepage( $post ) {
if ( $post instanceof WP_Post === false ) {
return false;
}
/*
* The page on front returns a string with normal WordPress interaction, while the post ID is an int.
* This way we make sure we always compare strings.
*/
$post_id = (int) $post->ID;
$page_on_front = (int) get_option( 'page_on_front' );
return get_option( 'show_on_front' ) === 'page' && $page_on_front === $post_id;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
* @since 1.8.0
*/
/**
* Customizes user profile.
*/
class WPSEO_Admin_User_Profile {
/**
* Class constructor.
*/
public function __construct() {
add_action( 'show_user_profile', array( $this, 'user_profile' ) );
add_action( 'edit_user_profile', array( $this, 'user_profile' ) );
add_action( 'personal_options_update', array( $this, 'process_user_option_update' ) );
add_action( 'edit_user_profile_update', array( $this, 'process_user_option_update' ) );
add_action( 'update_user_meta', array( $this, 'clear_author_sitemap_cache' ), 10, 3 );
}
/**
* Clear author sitemap cache when settings are changed.
*
* @since 3.1
*
* @param int $meta_id The ID of the meta option changed.
* @param int $object_id The ID of the user.
* @param string $meta_key The key of the meta field changed.
*/
public function clear_author_sitemap_cache( $meta_id, $object_id, $meta_key ) {
if ( '_yoast_wpseo_profile_updated' === $meta_key ) {
WPSEO_Sitemaps_Cache::clear( array( 'author' ) );
}
}
/**
* Filter POST variables.
*
* @param string $var_name Name of the variable to filter.
*
* @return mixed
*/
private function filter_input_post( $var_name ) {
$val = filter_input( INPUT_POST, $var_name );
if ( $val ) {
return WPSEO_Utils::sanitize_text_field( $val );
}
return '';
}
/**
* Updates the user metas that (might) have been set on the user profile page.
*
* @param int $user_id User ID of the updated user.
*/
public function process_user_option_update( $user_id ) {
update_user_meta( $user_id, '_yoast_wpseo_profile_updated', time() );
$nonce_value = $this->filter_input_post( 'wpseo_nonce' );
if ( empty( $nonce_value ) ) { // Submit from alternate forms.
return;
}
check_admin_referer( 'wpseo_user_profile_update', 'wpseo_nonce' );
update_user_meta( $user_id, 'wpseo_title', $this->filter_input_post( 'wpseo_author_title' ) );
update_user_meta( $user_id, 'wpseo_metadesc', $this->filter_input_post( 'wpseo_author_metadesc' ) );
update_user_meta( $user_id, 'wpseo_noindex_author', $this->filter_input_post( 'wpseo_noindex_author' ) );
update_user_meta( $user_id, 'wpseo_content_analysis_disable', $this->filter_input_post( 'wpseo_content_analysis_disable' ) );
update_user_meta( $user_id, 'wpseo_keyword_analysis_disable', $this->filter_input_post( 'wpseo_keyword_analysis_disable' ) );
}
/**
* Add the inputs needed for SEO values to the User Profile page.
*
* @param WP_User $user User instance to output for.
*/
public function user_profile( $user ) {
wp_nonce_field( 'wpseo_user_profile_update', 'wpseo_nonce' );
require_once WPSEO_PATH . 'admin/views/user-profile.php';
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Represents the utils for the admin.
*/
class WPSEO_Admin_Utils {
/**
* Gets the install URL for the passed plugin slug.
*
* @param string $slug The slug to create an install link for.
*
* @return string The install URL. Empty string if the current user doesn't have the proper capabilities.
*/
public static function get_install_url( $slug ) {
if ( ! current_user_can( 'install_plugins' ) ) {
return '';
}
return wp_nonce_url(
self_admin_url( 'update.php?action=install-plugin&plugin=' . dirname( $slug ) ),
'install-plugin_' . dirname( $slug )
);
}
/**
* Gets the activation URL for the passed plugin slug.
*
* @param string $slug The slug to create an activation link for.
*
* @return string The activation URL. Empty string if the current user doesn't have the proper capabilities.
*/
public static function get_activation_url( $slug ) {
if ( ! current_user_can( 'install_plugins' ) ) {
return '';
}
return wp_nonce_url(
self_admin_url( 'plugins.php?action=activate&plugin_status=all&paged=1&s&plugin=' . $slug ),
'activate-plugin_' . $slug
);
}
/**
* Creates a link if the passed plugin is deemend a directly-installable plugin.
*
* @param array $plugin The plugin to create the link for.
*
* @return string The link to the plugin install. Returns the title if the plugin is deemed a Premium product.
*/
public static function get_install_link( $plugin ) {
$install_url = self::get_install_url( $plugin['slug'] );
if ( $install_url === '' || ( isset( $plugin['premium'] ) && $plugin['premium'] === true ) ) {
return $plugin['title'];
}
return sprintf(
'<a href="%s">%s</a>',
$install_url,
$plugin['title']
);
}
/* ********************* DEPRECATED METHODS ********************* */
/**
* Determines whether or not the user has an invalid version of PHP installed.
*
* @deprecated 8.1
* @codeCoverageIgnore
*
* @return bool Whether or not PHP 5.2 or lower is installed.
*/
public static function is_supported_php_version_installed() {
// Intentionally left blank.
return true;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Represents a WPSEO asset
*/
class WPSEO_Admin_Asset {
const TYPE_JS = 'js';
const TYPE_CSS = 'css';
const NAME = 'name';
const SRC = 'src';
const DEPS = 'deps';
const VERSION = 'version';
// Style specific.
const MEDIA = 'media';
const RTL = 'rtl';
// Script specific.
const IN_FOOTER = 'in_footer';
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $src;
/**
* @var string|array
*/
protected $deps;
/**
* @var string
*/
protected $version;
/**
* @var string
*/
protected $media;
/**
* @var boolean
*/
protected $in_footer;
/**
* @var boolean
*/
protected $rtl;
/**
* @var string
*/
protected $suffix;
/**
* Default asset arguments.
*
* @var array
*/
private $defaults = array(
'deps' => array(),
'version' => WPSEO_VERSION,
'in_footer' => true,
'rtl' => true,
'media' => 'all',
'suffix' => WPSEO_CSSJS_SUFFIX,
);
/**
* @param array $args The arguments for this asset.
*
* @throws InvalidArgumentException Throws when no name or src has been provided.
*/
public function __construct( array $args ) {
if ( ! isset( $args['name'] ) ) {
throw new InvalidArgumentException( 'name is a required argument' );
}
if ( ! isset( $args['src'] ) ) {
throw new InvalidArgumentException( 'src is a required argument' );
}
$args = array_merge( $this->defaults, $args );
$this->name = $args['name'];
$this->src = $args['src'];
$this->deps = $args['deps'];
$this->version = $args['version'];
$this->media = $args['media'];
$this->in_footer = $args['in_footer'];
$this->rtl = $args['rtl'];
$this->suffix = $args['suffix'];
}
/**
* @return string
*/
public function get_name() {
return $this->name;
}
/**
* @return string
*/
public function get_src() {
return $this->src;
}
/**
* @return array|string
*/
public function get_deps() {
return $this->deps;
}
/**
* @return string
*/
public function get_version() {
return $this->version;
}
/**
* @return string
*/
public function get_media() {
return $this->media;
}
/**
* @return boolean
*/
public function is_in_footer() {
return $this->in_footer;
}
/**
* @return boolean
*/
public function has_rtl() {
return $this->rtl;
}
/**
* @return string
*/
public function get_suffix() {
return $this->suffix;
}
/**
* Returns the full URL for this asset based on the path to the plugin file.
*
* @param string $type Type of asset.
* @param string $plugin_file Absolute path to the plugin file.
*
* @return string The full URL to the asset.
*/
public function get_url( $type, $plugin_file ) {
_deprecated_function( __CLASS__ . '::get_url', '6.2', 'WPSEO_Admin_Asset_SEO_Location::get_url' );
$asset_location = new WPSEO_Admin_Asset_SEO_Location( $plugin_file );
return $asset_location->get_url( $this, $type );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Bulk Editor
* @since 1.5.0
*/
/**
* Implements table for bulk description editing.
*/
class WPSEO_Bulk_Description_List_Table extends WPSEO_Bulk_List_Table {
/**
* Current type for this class will be (meta) description.
*
* @var string
*/
protected $page_type = 'description';
/**
* Settings with are used in __construct
*
* @var array
*/
protected $settings = array(
'singular' => 'wpseo_bulk_description',
'plural' => 'wpseo_bulk_descriptions',
'ajax' => true,
);
/**
* The field in the database where meta field is saved.
*
* @var string
*/
protected $target_db_field = 'metadesc';
/**
* The columns shown on the table
*
* @return array
*/
public function get_columns() {
$columns = array(
'col_existing_yoast_seo_metadesc' => __( 'Existing Yoast Meta Description', 'wordpress-seo' ),
'col_new_yoast_seo_metadesc' => __( 'New Yoast Meta Description', 'wordpress-seo' ),
);
return $this->merge_columns( $columns );
}
/**
* Parse the metadescription
*
* @param string $column_name Column name.
* @param object $record Data object.
* @param string $attributes HTML attributes.
*
* @return string
*/
protected function parse_page_specific_column( $column_name, $record, $attributes ) {
switch ( $column_name ) {
case 'col_new_yoast_seo_metadesc':
return sprintf(
'<textarea id="%1$s" name="%1$s" class="wpseo-new-metadesc" data-id="%2$s" aria-labelledby="col_new_yoast_seo_metadesc"></textarea>',
esc_attr( 'wpseo-new-metadesc-' . $record->ID ),
esc_attr( $record->ID )
);
case 'col_existing_yoast_seo_metadesc':
// @todo Inconsistent return/echo behavior R.
echo $this->parse_meta_data_field( $record->ID, $attributes );
break;
}
}
} /* End of class */
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin\Bulk Editor
* @since 1.5.0
*/
/**
* Implements table for bulk title editing.
*/
class WPSEO_Bulk_Title_Editor_List_Table extends WPSEO_Bulk_List_Table {
/**
* Current type for this class will be title
*
* @var string
*/
protected $page_type = 'title';
/**
* Settings with are used in __construct
*
* @var array
*/
protected $settings = array(
'singular' => 'wpseo_bulk_title',
'plural' => 'wpseo_bulk_titles',
'ajax' => true,
);
/**
* The field in the database where meta field is saved.
*
* @var string
*/
protected $target_db_field = 'title';
/**
* The columns shown on the table
*
* @return array
*/
public function get_columns() {
$columns = array(
/* translators: %1$s expands to Yoast SEO */
'col_existing_yoast_seo_title' => sprintf( __( 'Existing %1$s Title', 'wordpress-seo' ), 'Yoast SEO' ),
/* translators: %1$s expands to Yoast SEO */
'col_new_yoast_seo_title' => sprintf( __( 'New %1$s Title', 'wordpress-seo' ), 'Yoast SEO' ),
);
return $this->merge_columns( $columns );
}
/**
* Parse the title columns
*
* @param string $column_name Column name.
* @param object $record Data object.
* @param string $attributes HTML attributes.
*
* @return string
*/
protected function parse_page_specific_column( $column_name, $record, $attributes ) {
// Fill meta data if exists in $this->meta_data.
$meta_data = ( ! empty( $this->meta_data[ $record->ID ] ) ) ? $this->meta_data[ $record->ID ] : array();
switch ( $column_name ) {
case 'col_existing_yoast_seo_title':
// @todo Inconsistent echo/return behavior R.
echo $this->parse_meta_data_field( $record->ID, $attributes );
break;
case 'col_new_yoast_seo_title':
return sprintf(
'<input type="text" id="%1$s" name="%1$s" class="wpseo-new-title" data-id="%2$s" aria-labelledby="col_new_yoast_seo_title" />',
'wpseo-new-title-' . $record->ID,
$record->ID
);
}
unset( $meta_data );
}
} /* End of class */
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Collects the data from the added collection objects.
*/
class WPSEO_Collector {
/** @var WPSEO_Collection[] */
protected $collections = array();
/**
* Adds a collection object to the collections.
*
* @param WPSEO_Collection $collection The collection object to add.
*/
public function add_collection( WPSEO_Collection $collection ) {
$this->collections[] = $collection;
}
/**
* Collects the data from the collection objects.
*
* @return array The collected data.
*/
public function collect() {
$data = array();
foreach ( $this->collections as $collection ) {
$data = array_merge( $data, $collection->get() );
}
return $data;
}
/**
* Returns the collected data as a JSON encoded string.
*
* @return false|string The encode string.
*/
public function get_as_json() {
return wp_json_encode( $this->collect() );
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Exposes shortlinks in a global, so that we can pass them to our Javascript components.
*/
class WPSEO_Expose_Shortlinks implements WPSEO_WordPress_Integration {
/**
* @var array Array containing the keys and shortlinks.
*/
private $shortlinks = array(
'shortlinks.focus_keyword_info' => 'https://yoa.st/focus-keyword',
'shortlinks.snippet_preview_info' => 'https://yoa.st/snippet-preview',
'shortlinks.cornerstone_content_info' => 'https://yoa.st/1i9',
'shortlinks.upsell.sidebar.focus_keyword_synonyms_link' => 'https://yoa.st/textlink-synonyms-popup-sidebar',
'shortlinks.upsell.sidebar.focus_keyword_synonyms_button' => 'https://yoa.st/keyword-synonyms-popup-sidebar',
'shortlinks.upsell.sidebar.focus_keyword_additional_link' => 'https://yoa.st/textlink-keywords-popup-sidebar',
'shortlinks.upsell.sidebar.focus_keyword_additional_button' => 'https://yoa.st/add-keywords-popup-sidebar',
'shortlinks.upsell.sidebar.additional_link' => 'https://yoa.st/textlink-keywords-sidebar',
'shortlinks.upsell.sidebar.additional_button' => 'https://yoa.st/add-keywords-sidebar',
'shortlinks.upsell.metabox.go_premium' => 'https://yoa.st/pe-premium-page',
'shortlinks.upsell.metabox.focus_keyword_synonyms_link' => 'https://yoa.st/textlink-synonyms-popup-metabox',
'shortlinks.upsell.metabox.focus_keyword_synonyms_button' => 'https://yoa.st/keyword-synonyms-popup',
'shortlinks.upsell.metabox.focus_keyword_additional_link' => 'https://yoa.st/textlink-keywords-popup-metabox',
'shortlinks.upsell.metabox.focus_keyword_additional_button' => 'https://yoa.st/add-keywords-popup',
'shortlinks.upsell.metabox.additional_link' => 'https://yoa.st/textlink-keywords-metabox',
'shortlinks.upsell.metabox.additional_button' => 'https://yoa.st/add-keywords-metabox',
'shortlinks.readability_analysis_info' => 'https://yoa.st/readability-analysis',
'shortlinks.activate_premium_info' => 'https://yoa.st/activate-subscription',
);
/**
* Registers all hooks to WordPress.
*
* @return void
*/
public function register_hooks() {
add_filter( 'wpseo_admin_l10n', array( $this, 'expose_shortlinks' ) );
}
/**
* Adds shortlinks to the passed array.
*
* @param array $input The array to add shortlinks to.
*
* @return array The passed array with the additional shortlinks.
*/
public function expose_shortlinks( $input ) {
foreach ( $this->shortlinks as $key => $shortlink ) {
$input[ $key ] = WPSEO_Shortlinker::get( $shortlink );
}
$input['default_query_params'] = WPSEO_Shortlinker::get_query_params();
return $input;
}
}
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Admin
*/
/**
* Class WPSEO_Recalculate_Scores
*
* This class handles the SEO score recalculation for all posts with a filled focus keyword
*/
class WPSEO_Recalculate_Scores {
/**
* Constructing the object by modalbox, the localization and the totals.
*/
public function __construct() {
add_action( 'admin_enqueue_scripts', array( $this, 'recalculate_assets' ) );
add_action( 'admin_footer', array( $this, 'modal_box' ), 20 );
}
/**
* Run the localize script.
*/
public function recalculate_assets() {
$asset_manager = new WPSEO_Admin_Asset_Manager();
$asset_manager->enqueue_script( 'recalculate' );
}
/**
* Initialize the modal box to be displayed when needed.
*/
public function modal_box() {
// Adding the thickbox.
add_thickbox();
$progress = sprintf(
/* translators: 1: expands to a <span> containing the number of posts recalculated. 2: expands to a <strong> containing the total number of posts. */
esc_html__( '%1$s of %2$s done.', 'wordpress-seo' ),
'<span id="wpseo_count">0</span>',
'<strong id="wpseo_count_total">0</strong>'
);
?>
<div id="wpseo_recalculate" class="hidden">
<p><?php esc_html_e( 'Recalculating SEO scores for all pieces of content with a focus keyphrase.', 'wordpress-seo' ); ?></p>
<div id="wpseo_progressbar"></div>
<p><?php echo $progress; ?></p>
</div>
<?php
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment