Archived
Updates
This commit is contained in:
1 parent
70d2335bba
commit
7428b67da5
1086 files changed
+94145
-59082
No files matched your search
@@ -1,416 +1,429 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Modified (Reduced) TextStatistics Class
|
||||
*
|
||||
* Mostly removed functionality that isn't needed within the WordPress SEO plugin.
|
||||
*
|
||||
* @link http://code.google.com/p/php-text-statistics/
|
||||
* @link https://github.com/DaveChild/Text-Statistics (new repo location)
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD license
|
||||
*
|
||||
* @todo [JRF => whomever] Research if a class/library can be found which will offer
|
||||
* this functionality to a broader scope of languages/charsets.
|
||||
* Now basically limited to English.
|
||||
*/
|
||||
class Yoast_TextStatistics {
|
||||
|
||||
if ( ! class_exists( 'Yoast_TextStatistics' ) ) {
|
||||
/**
|
||||
* Modified (Reduced) TextStatistics Class
|
||||
*
|
||||
* Mostly removed functionality that isn't needed within the WordPress SEO plugin.
|
||||
*
|
||||
* @link http://code.google.com/p/php-text-statistics/
|
||||
* @link https://github.com/DaveChild/Text-Statistics (new repo location)
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD license
|
||||
*
|
||||
* @todo [JRF => whomever] Research if a class/library can be found which will offer
|
||||
* this functionality to a broader scope of languages/charsets.
|
||||
* Now basically limited to English.
|
||||
* @var string $strEncoding Used to hold character encoding to be used by object, if set
|
||||
*/
|
||||
class Yoast_TextStatistics {
|
||||
protected $strEncoding = '';
|
||||
|
||||
/**
|
||||
* @var string $strEncoding Used to hold character encoding to be used by object, if set
|
||||
*/
|
||||
protected $strEncoding = '';
|
||||
/**
|
||||
* @var string $blnMbstring Efficiency: Is the MB String extension loaded ?
|
||||
*/
|
||||
protected $blnMbstring = true;
|
||||
|
||||
/**
|
||||
* @var string $blnMbstring Efficiency: Is the MB String extension loaded ?
|
||||
*/
|
||||
protected $blnMbstring = true;
|
||||
|
||||
/**
|
||||
* @var bool $normalize Should the result be normalized ?
|
||||
*/
|
||||
public $normalize = true;
|
||||
/**
|
||||
* @var bool $normalize Should the result be normalized ?
|
||||
*/
|
||||
public $normalize = true;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $strEncoding Optional character encoding.
|
||||
*/
|
||||
public function __construct( $strEncoding = '' ) {
|
||||
if ( $strEncoding <> '' ) {
|
||||
// Encoding is given. Use it!
|
||||
$this->strEncoding = $strEncoding;
|
||||
}
|
||||
$this->blnMbstring = extension_loaded( 'mbstring' );
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $strEncoding Optional character encoding.
|
||||
*/
|
||||
public function __construct( $strEncoding = '' ) {
|
||||
if ( $strEncoding <> '' ) {
|
||||
// Encoding is given. Use it!
|
||||
$this->strEncoding = $strEncoding;
|
||||
}
|
||||
$this->blnMbstring = extension_loaded( 'mbstring' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the Flesch-Kincaid Reading Ease of text entered rounded to one digit
|
||||
*
|
||||
* @param string $strText Text to be checked
|
||||
*
|
||||
* @return int|float
|
||||
*/
|
||||
public function flesch_kincaid_reading_ease( $strText ) {
|
||||
$strText = $this->clean_text( $strText );
|
||||
$score = WPSEO_Utils::calc( WPSEO_Utils::calc( 206.835, '-', WPSEO_Utils::calc( 1.015, '*', $this->average_words_per_sentence( $strText ) ) ), '-', WPSEO_Utils::calc( 84.6, '*', $this->average_syllables_per_word( $strText ) ) );
|
||||
|
||||
return $this->normalize_score( $score, 0, 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives string length.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function text_length( $strText ) {
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strlen( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the Flesch-Kincaid Reading Ease of text entered rounded to one digit
|
||||
*
|
||||
* @param string $strText Text to be checked
|
||||
* @return int|float
|
||||
*/
|
||||
public function flesch_kincaid_reading_ease( $strText ) {
|
||||
$strText = $this->clean_text( $strText );
|
||||
$score = wpseo_calc( wpseo_calc( 206.835, '-', wpseo_calc( 1.015, '*', $this->average_words_per_sentence( $strText ) ) ), '-', wpseo_calc( 84.6, '*', $this->average_syllables_per_word( $strText ) ) );
|
||||
|
||||
return $this->normalize_score( $score, 0, 100 );
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$intTextLength = mb_strlen( $strText );
|
||||
}
|
||||
else {
|
||||
$intTextLength = mb_strlen( $strText, $this->strEncoding );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$intTextLength = strlen( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives string length.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function text_length( $strText ) {
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strlen( $strText );
|
||||
}
|
||||
return $intTextLength;
|
||||
}
|
||||
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$intTextLength = mb_strlen( $strText );
|
||||
} else {
|
||||
$intTextLength = mb_strlen( $strText, $this->strEncoding );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$intTextLength = strlen( $strText );
|
||||
}
|
||||
/**
|
||||
* Gives letter count (ignores all non-letters). Tries mb_strlen and if that fails uses regular strlen.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function letter_count( $strText ) {
|
||||
$strText = $this->clean_text( $strText ); // To clear out newlines etc
|
||||
$strText = preg_replace( '`[^A-Za-z]+`', '', $strText );
|
||||
|
||||
return $intTextLength;
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strlen( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives letter count (ignores all non-letters). Tries mb_strlen and if that fails uses regular strlen.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function letter_count( $strText ) {
|
||||
$strText = $this->clean_text( $strText ); // To clear out newlines etc
|
||||
$strText = preg_replace( '`[^A-Za-z]+`', '', $strText );
|
||||
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strlen( $strText );
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$intTextLength = mb_strlen( $strText );
|
||||
}
|
||||
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$intTextLength = mb_strlen( $strText );
|
||||
} else {
|
||||
$intTextLength = mb_strlen( $strText, $this->strEncoding );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$intTextLength = strlen( $strText );
|
||||
else {
|
||||
$intTextLength = mb_strlen( $strText, $this->strEncoding );
|
||||
}
|
||||
|
||||
return $intTextLength;
|
||||
} catch ( Exception $e ) {
|
||||
$intTextLength = strlen( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims, removes line breaks, multiple spaces and generally cleans text before processing.
|
||||
*
|
||||
* @param string $strText Text to be transformed
|
||||
* @return string
|
||||
*/
|
||||
protected function clean_text( $strText ) {
|
||||
static $clean = array();
|
||||
return $intTextLength;
|
||||
}
|
||||
|
||||
$key = sha1( $strText );
|
||||
/**
|
||||
* Trims, removes line breaks, multiple spaces and generally cleans text before processing.
|
||||
*
|
||||
* @param string $strText Text to be transformed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function clean_text( $strText ) {
|
||||
static $clean = array();
|
||||
|
||||
if ( isset( $clean[ $key ] ) ) {
|
||||
return $clean[ $key ];
|
||||
}
|
||||
$key = sha1( $strText );
|
||||
|
||||
// all these tags should be preceeded by a full stop.
|
||||
$fullStopTags = array( 'li', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dd' );
|
||||
foreach ( $fullStopTags as $tag ) {
|
||||
$strText = str_ireplace( '</' . $tag . '>', '.', $strText );
|
||||
}
|
||||
$strText = strip_tags( $strText );
|
||||
$strText = preg_replace( '`[",:;\(\)-]`', ' ', $strText ); // Replace commas, hyphens etc (count them as spaces)
|
||||
$strText = preg_replace( '`[\.!?]`', '.', $strText ); // Unify terminators
|
||||
$strText = trim( $strText ) . '.'; // Add final terminator, just in case it's missing.
|
||||
$strText = preg_replace( '`[ ]*(\n|\r\n|\r)[ ]*`', ' ', $strText ); // Replace new lines with spaces
|
||||
$strText = preg_replace( '`([\.])[\. ]+`', '$1', $strText ); // Check for duplicated terminators
|
||||
$strText = trim( preg_replace( '`[ ]*([\.])`', '$1 ', $strText ) ); // Pad sentence terminators
|
||||
$strText = preg_replace( '` [0-9]+ `', ' ', ' ' . $strText . ' ' ); // Remove "words" comprised only of numbers
|
||||
$strText = preg_replace( '`[ ]+`', ' ', $strText ); // Remove multiple spaces
|
||||
$strText = preg_replace_callback( '`\. [^ ]+?`', create_function( '$matches', 'return strtolower( $matches[0] );' ), $strText ); // Lower case all words following terminators (for gunning fog score)
|
||||
|
||||
$strText = trim( $strText );
|
||||
|
||||
// Cache it and return
|
||||
$clean[ $key ] = $strText;
|
||||
return $strText;
|
||||
if ( isset( $clean[ $key ] ) ) {
|
||||
return $clean[ $key ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string to lower case. Tries mb_strtolower and if that fails uses regular strtolower.
|
||||
*
|
||||
* @param string $strText Text to be transformed
|
||||
* @return string
|
||||
*/
|
||||
protected function lower_case( $strText ) {
|
||||
// all these tags should be preceeded by a full stop.
|
||||
$fullStopTags = array( 'li', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dd' );
|
||||
foreach ( $fullStopTags as $tag ) {
|
||||
$strText = str_ireplace( '</' . $tag . '>', '.', $strText );
|
||||
}
|
||||
$strText = strip_tags( $strText );
|
||||
$strText = preg_replace( '`[",:;\(\)-]`', ' ', $strText ); // Replace commas, hyphens etc (count them as spaces)
|
||||
$strText = preg_replace( '`[\.!?]`', '.', $strText ); // Unify terminators
|
||||
$strText = trim( $strText ) . '.'; // Add final terminator, just in case it's missing.
|
||||
$strText = preg_replace( '`[ ]*(\n|\r\n|\r)[ ]*`', ' ', $strText ); // Replace new lines with spaces
|
||||
$strText = preg_replace( '`([\.])[\. ]+`', '$1', $strText ); // Check for duplicated terminators
|
||||
$strText = trim( preg_replace( '`[ ]*([\.])`', '$1 ', $strText ) ); // Pad sentence terminators
|
||||
$strText = preg_replace( '` [0-9]+ `', ' ', ' ' . $strText . ' ' ); // Remove "words" comprised only of numbers
|
||||
$strText = preg_replace( '`[ ]+`', ' ', $strText ); // Remove multiple spaces
|
||||
$strText = preg_replace_callback( '`\. [^ ]+?`', create_function( '$matches', 'return strtolower( $matches[0] );' ), $strText ); // Lower case all words following terminators (for gunning fog score)
|
||||
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strtolower( $strText );
|
||||
}
|
||||
$strText = trim( $strText );
|
||||
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$strLowerCaseText = mb_strtolower( $strText );
|
||||
} else {
|
||||
$strLowerCaseText = mb_strtolower( $strText, $this->strEncoding );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$strLowerCaseText = strtolower( $strText );
|
||||
}
|
||||
// Cache it and return
|
||||
$clean[ $key ] = $strText;
|
||||
|
||||
return $strLowerCaseText;
|
||||
return $strText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string to lower case. Tries mb_strtolower and if that fails uses regular strtolower.
|
||||
*
|
||||
* @param string $strText Text to be transformed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function lower_case( $strText ) {
|
||||
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strtolower( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string to upper case. Tries mb_strtoupper and if that fails uses regular strtoupper.
|
||||
*
|
||||
* @param string $strText Text to be transformed
|
||||
* @return string
|
||||
*/
|
||||
protected function upper_case( $strText ) {
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strtoupper( $strText );
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$strLowerCaseText = mb_strtolower( $strText );
|
||||
}
|
||||
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$strUpperCaseText = mb_strtoupper( $strText );
|
||||
} else {
|
||||
$strUpperCaseText = mb_strtoupper( $strText, $this->strEncoding );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$strUpperCaseText = strtoupper( $strText );
|
||||
else {
|
||||
$strLowerCaseText = mb_strtolower( $strText, $this->strEncoding );
|
||||
}
|
||||
|
||||
return $strUpperCaseText;
|
||||
} catch ( Exception $e ) {
|
||||
$strLowerCaseText = strtolower( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sentence count for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
* @return int
|
||||
*/
|
||||
public function sentence_count( $strText ) {
|
||||
if ( strlen( trim( $strText ) ) == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
return $strLowerCaseText;
|
||||
}
|
||||
|
||||
$strText = $this->clean_text( $strText );
|
||||
// Will be tripped up by "Mr." or "U.K.". Not a major concern at this point.
|
||||
// [JRF] Will also be tripped up by ... or ?!
|
||||
// @todo [JRF => whomever] May be replace with something along the lines of this - will at least provide better count in ... and ?! situations:
|
||||
// $intSentences = max( 1, preg_match_all( '`[^\.!?]+[\.!?]+([\s]+|$)`u', $strText, $matches ) ); [/JRF]
|
||||
$intSentences = max( 1, $this->text_length( preg_replace( '`[^\.!?]`', '', $strText ) ) );
|
||||
return $intSentences;
|
||||
/**
|
||||
* Converts string to upper case. Tries mb_strtoupper and if that fails uses regular strtoupper.
|
||||
*
|
||||
* @param string $strText Text to be transformed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function upper_case( $strText ) {
|
||||
if ( ! $this->blnMbstring ) {
|
||||
return strtoupper( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns word count for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
* @return int
|
||||
*/
|
||||
public function word_count( $strText ) {
|
||||
if ( strlen( trim( $strText ) ) == 0 ) {
|
||||
return 0;
|
||||
try {
|
||||
if ( $this->strEncoding == '' ) {
|
||||
$strUpperCaseText = mb_strtoupper( $strText );
|
||||
}
|
||||
|
||||
$strText = $this->clean_text( $strText );
|
||||
// Will be tripped by em dashes with spaces either side, among other similar characters
|
||||
$intWords = 1 + $this->text_length( preg_replace( '`[^ ]`', '', $strText ) ); // Space count + 1 is word count
|
||||
return $intWords;
|
||||
else {
|
||||
$strUpperCaseText = mb_strtoupper( $strText, $this->strEncoding );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$strUpperCaseText = strtoupper( $strText );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns average words per sentence for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
* @return int|float
|
||||
*/
|
||||
public function average_words_per_sentence( $strText ) {
|
||||
$strText = $this->clean_text( $strText );
|
||||
$intSentenceCount = $this->sentence_count( $strText );
|
||||
$intWordCount = $this->word_count( $strText );
|
||||
return ( wpseo_calc( $intWordCount, '/', $intSentenceCount ) );
|
||||
return $strUpperCaseText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sentence count for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sentence_count( $strText ) {
|
||||
if ( strlen( trim( $strText ) ) == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns average syllables per word for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
* @return int|float
|
||||
*/
|
||||
public function average_syllables_per_word( $strText ) {
|
||||
$strText = $this->clean_text( $strText );
|
||||
$intSyllableCount = 0;
|
||||
$intWordCount = $this->word_count( $strText );
|
||||
$arrWords = explode( ' ', $strText );
|
||||
for ( $i = 0; $i < $intWordCount; $i++ ) {
|
||||
$intSyllableCount += $this->syllable_count( $arrWords[ $i ] );
|
||||
}
|
||||
return ( wpseo_calc( $intSyllableCount, '/', $intWordCount ) );
|
||||
$strText = $this->clean_text( $strText );
|
||||
// Will be tripped up by "Mr." or "U.K.". Not a major concern at this point.
|
||||
// [JRF] Will also be tripped up by ... or ?!
|
||||
// @todo [JRF => whomever] May be replace with something along the lines of this - will at least provide better count in ... and ?! situations:
|
||||
// $intSentences = max( 1, preg_match_all( '`[^\.!?]+[\.!?]+([\s]+|$)`u', $strText, $matches ) ); [/JRF]
|
||||
$intSentences = max( 1, $this->text_length( preg_replace( '`[^\.!?]`', '', $strText ) ) );
|
||||
|
||||
return $intSentences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns word count for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function word_count( $strText ) {
|
||||
if ( strlen( trim( $strText ) ) == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of syllables in the word.
|
||||
* Based in part on Greg Fast's Perl module Lingua::EN::Syllables
|
||||
*
|
||||
* @param string $strWord Word to be measured
|
||||
* @return int
|
||||
*/
|
||||
public function syllable_count( $strWord ) {
|
||||
if ( strlen( trim( $strWord ) ) == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
$strText = $this->clean_text( $strText );
|
||||
// Will be tripped by em dashes with spaces either side, among other similar characters
|
||||
$intWords = ( 1 + $this->text_length( preg_replace( '`[^ ]`', '', $strText ) ) ); // Space count + 1 is word count
|
||||
return $intWords;
|
||||
}
|
||||
|
||||
// Should be no non-alpha characters
|
||||
$strWord = preg_replace( '`[^A-Za-z]`', '', $strWord );
|
||||
/**
|
||||
* Returns average words per sentence for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int|float
|
||||
*/
|
||||
public function average_words_per_sentence( $strText ) {
|
||||
$strText = $this->clean_text( $strText );
|
||||
$intSentenceCount = $this->sentence_count( $strText );
|
||||
$intWordCount = $this->word_count( $strText );
|
||||
|
||||
$intSyllableCount = 0;
|
||||
$strWord = $this->lower_case( $strWord );
|
||||
return ( WPSEO_Utils::calc( $intWordCount, '/', $intSentenceCount ) );
|
||||
}
|
||||
|
||||
// Specific common exceptions that don't follow the rule set below are handled individually
|
||||
// Array of problem words (with word as key, syllable count as value)
|
||||
$arrProblemWords = array(
|
||||
'simile' => 3,
|
||||
'forever' => 3,
|
||||
'shoreline' => 2,
|
||||
);
|
||||
if ( isset( $arrProblemWords[ $strWord ] ) ) {
|
||||
$intSyllableCount = $arrProblemWords[ $strWord ];
|
||||
}
|
||||
if ( $intSyllableCount > 0 ) {
|
||||
return $intSyllableCount;
|
||||
}
|
||||
/**
|
||||
* Returns average syllables per word for text.
|
||||
*
|
||||
* @param string $strText Text to be measured
|
||||
*
|
||||
* @return int|float
|
||||
*/
|
||||
public function average_syllables_per_word( $strText ) {
|
||||
$strText = $this->clean_text( $strText );
|
||||
$intSyllableCount = 0;
|
||||
$intWordCount = $this->word_count( $strText );
|
||||
$arrWords = explode( ' ', $strText );
|
||||
for ( $i = 0; $i < $intWordCount; $i ++ ) {
|
||||
$intSyllableCount += $this->syllable_count( $arrWords[ $i ] );
|
||||
}
|
||||
|
||||
// These syllables would be counted as two but should be one
|
||||
$arrSubSyllables = array(
|
||||
'cial',
|
||||
'tia',
|
||||
'cius',
|
||||
'cious',
|
||||
'giu',
|
||||
'ion',
|
||||
'iou',
|
||||
'sia$',
|
||||
'[^aeiuoyt]{2,}ed$',
|
||||
'.ely$',
|
||||
'[cg]h?e[rsd]?$',
|
||||
'rved?$',
|
||||
'[aeiouy][dt]es?$',
|
||||
'[aeiouy][^aeiouydt]e[rsd]?$',
|
||||
// Sorts out deal, deign etc
|
||||
'^[dr]e[aeiou][^aeiou]+$',
|
||||
// Purse, hearse
|
||||
'[aeiouy]rse$',
|
||||
);
|
||||
return ( WPSEO_Utils::calc( $intSyllableCount, '/', $intWordCount ) );
|
||||
}
|
||||
|
||||
// These syllables would be counted as one but should be two
|
||||
$arrAddSyllables = array(
|
||||
'ia',
|
||||
'riet',
|
||||
'dien',
|
||||
'iu',
|
||||
'io',
|
||||
'ii',
|
||||
'[aeiouym]bl$',
|
||||
'[aeiou]{3}',
|
||||
'^mc',
|
||||
'ism$',
|
||||
'([^aeiouy])\1l$',
|
||||
'[^l]lien',
|
||||
'^coa[dglx].',
|
||||
'[^gq]ua[^auieo]',
|
||||
'dnt$',
|
||||
'uity$',
|
||||
'ie(r|st)$',
|
||||
);
|
||||
/**
|
||||
* Returns the number of syllables in the word.
|
||||
* Based in part on Greg Fast's Perl module Lingua::EN::Syllables
|
||||
*
|
||||
* @param string $strWord Word to be measured
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function syllable_count( $strWord ) {
|
||||
if ( strlen( trim( $strWord ) ) == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Single syllable prefixes and suffixes
|
||||
$arrPrefixSuffix = array(
|
||||
'`^un`',
|
||||
'`^fore`',
|
||||
'`ly$`',
|
||||
'`less$`',
|
||||
'`ful$`',
|
||||
'`ers?$`',
|
||||
'`ings?$`',
|
||||
);
|
||||
// Should be no non-alpha characters
|
||||
$strWord = preg_replace( '`[^A-Za-z]`', '', $strWord );
|
||||
|
||||
// Remove prefixes and suffixes and count how many were taken
|
||||
$strWord = preg_replace( $arrPrefixSuffix, '', $strWord, -1, $intPrefixSuffixCount );
|
||||
$intSyllableCount = 0;
|
||||
$strWord = $this->lower_case( $strWord );
|
||||
|
||||
// Removed non-word characters from word
|
||||
$strWord = preg_replace( '`[^a-z]`is', '', $strWord );
|
||||
$arrWordParts = preg_split( '`[^aeiouy]+`', $strWord );
|
||||
$intWordPartCount = 0;
|
||||
foreach ( $arrWordParts as $strWordPart ) {
|
||||
if ( $strWordPart <> '' ) {
|
||||
$intWordPartCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Some syllables do not follow normal rules - check for them
|
||||
// Thanks to Joe Kovar for correcting a bug in the following lines
|
||||
$intSyllableCount = $intWordPartCount + $intPrefixSuffixCount;
|
||||
foreach ( $arrSubSyllables as $strSyllable ) {
|
||||
$intSyllableCount -= preg_match( '`' . $strSyllable . '`', $strWord );
|
||||
}
|
||||
foreach ( $arrAddSyllables as $strSyllable ) {
|
||||
$intSyllableCount += preg_match( '`' . $strSyllable . '`', $strWord );
|
||||
}
|
||||
$intSyllableCount = ( $intSyllableCount == 0 ) ? 1 : $intSyllableCount;
|
||||
// Specific common exceptions that don't follow the rule set below are handled individually
|
||||
// Array of problem words (with word as key, syllable count as value)
|
||||
$arrProblemWords = array(
|
||||
'simile' => 3,
|
||||
'forever' => 3,
|
||||
'shoreline' => 2,
|
||||
);
|
||||
if ( isset( $arrProblemWords[ $strWord ] ) ) {
|
||||
$intSyllableCount = $arrProblemWords[ $strWord ];
|
||||
}
|
||||
if ( $intSyllableCount > 0 ) {
|
||||
return $intSyllableCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes score according to min & max allowed. If score larger
|
||||
* than max, max is returned. If score less than min, min is returned.
|
||||
* Also rounds result to specified precision.
|
||||
* Thanks to github.com/lvil.
|
||||
*
|
||||
* @param int|float $score Initial score
|
||||
* @param int $min Minimum score allowed
|
||||
* @param int $max Maximum score allowed
|
||||
* @return int|float
|
||||
*/
|
||||
public function normalize_score( $score, $min, $max, $dps = 1 ) {
|
||||
$score = wpseo_calc( $score, '+', 0, true, $dps ); // Round
|
||||
if ( ! $this->normalize ) {
|
||||
return $score;
|
||||
}
|
||||
// These syllables would be counted as two but should be one
|
||||
$arrSubSyllables = array(
|
||||
'cial',
|
||||
'tia',
|
||||
'cius',
|
||||
'cious',
|
||||
'giu',
|
||||
'ion',
|
||||
'iou',
|
||||
'sia$',
|
||||
'[^aeiuoyt]{2,}ed$',
|
||||
'.ely$',
|
||||
'[cg]h?e[rsd]?$',
|
||||
'rved?$',
|
||||
'[aeiouy][dt]es?$',
|
||||
'[aeiouy][^aeiouydt]e[rsd]?$',
|
||||
// Sorts out deal, deign etc
|
||||
'^[dr]e[aeiou][^aeiou]+$',
|
||||
// Purse, hearse
|
||||
'[aeiouy]rse$',
|
||||
);
|
||||
|
||||
if ( $score > $max ) {
|
||||
$score = $max;
|
||||
} elseif ( $score < $min ) {
|
||||
$score = $min;
|
||||
}
|
||||
// These syllables would be counted as one but should be two
|
||||
$arrAddSyllables = array(
|
||||
'ia',
|
||||
'riet',
|
||||
'dien',
|
||||
'iu',
|
||||
'io',
|
||||
'ii',
|
||||
'[aeiouym]bl$',
|
||||
'[aeiou]{3}',
|
||||
'^mc',
|
||||
'ism$',
|
||||
'([^aeiouy])\1l$',
|
||||
'[^l]lien',
|
||||
'^coa[dglx].',
|
||||
'[^gq]ua[^auieo]',
|
||||
'dnt$',
|
||||
'uity$',
|
||||
'ie(r|st)$',
|
||||
);
|
||||
|
||||
// Single syllable prefixes and suffixes
|
||||
$arrPrefixSuffix = array(
|
||||
'`^un`',
|
||||
'`^fore`',
|
||||
'`ly$`',
|
||||
'`less$`',
|
||||
'`ful$`',
|
||||
'`ers?$`',
|
||||
'`ings?$`',
|
||||
);
|
||||
|
||||
// Remove prefixes and suffixes and count how many were taken
|
||||
$strWord = preg_replace( $arrPrefixSuffix, '', $strWord, - 1, $intPrefixSuffixCount );
|
||||
|
||||
// Removed non-word characters from word
|
||||
$strWord = preg_replace( '`[^a-z]`is', '', $strWord );
|
||||
$arrWordParts = preg_split( '`[^aeiouy]+`', $strWord );
|
||||
$intWordPartCount = 0;
|
||||
foreach ( $arrWordParts as $strWordPart ) {
|
||||
if ( $strWordPart <> '' ) {
|
||||
$intWordPartCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Some syllables do not follow normal rules - check for them
|
||||
// Thanks to Joe Kovar for correcting a bug in the following lines
|
||||
$intSyllableCount = ( $intWordPartCount + $intPrefixSuffixCount );
|
||||
foreach ( $arrSubSyllables as $strSyllable ) {
|
||||
$intSyllableCount -= preg_match( '`' . $strSyllable . '`', $strWord );
|
||||
}
|
||||
foreach ( $arrAddSyllables as $strSyllable ) {
|
||||
$intSyllableCount += preg_match( '`' . $strSyllable . '`', $strWord );
|
||||
}
|
||||
$intSyllableCount = ( $intSyllableCount == 0 ) ? 1 : $intSyllableCount;
|
||||
|
||||
return $intSyllableCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes score according to min & max allowed. If score larger
|
||||
* than max, max is returned. If score less than min, min is returned.
|
||||
* Also rounds result to specified precision.
|
||||
* Thanks to github.com/lvil.
|
||||
*
|
||||
* @param int|float $score Initial score
|
||||
* @param int $min Minimum score allowed
|
||||
* @param int $max Maximum score allowed
|
||||
* @param int $dps Round to # decimals
|
||||
*
|
||||
* @return int|float
|
||||
*/
|
||||
public function normalize_score( $score, $min, $max, $dps = 1 ) {
|
||||
$score = WPSEO_Utils::calc( $score, '+', 0, true, $dps ); // Round
|
||||
if ( ! $this->normalize ) {
|
||||
return $score;
|
||||
}
|
||||
|
||||
} /* End of class */
|
||||
} /* End of class-exists wrapper */
|
||||
if ( $score > $max ) {
|
||||
$score = $max;
|
||||
}
|
||||
elseif ( $score < $min ) {
|
||||
$score = $min;
|
||||
}
|
||||
|
||||
return $score;
|
||||
}
|
||||
|
||||
} /* End of class */
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -9,6 +9,20 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo this whole thing should probably be a proper class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convenience function to JSON encode and echo resuls and then die
|
||||
*
|
||||
* @param array $results
|
||||
*/
|
||||
function wpseo_ajax_json_echo_die( $results ) {
|
||||
echo json_encode( $results );
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used from AJAX calls, takes it variables from $_POST, dies on exit.
|
||||
*/
|
||||
@@ -19,7 +33,7 @@ function wpseo_set_option() {
|
||||
|
||||
check_ajax_referer( 'wpseo-setoption' );
|
||||
|
||||
$option = sanitize_text_field( $_POST['option'] );
|
||||
$option = sanitize_text_field( WPSEO_Utils::filter_input( INPUT_POST, 'option' ) );
|
||||
if ( $option !== 'page_comments' ) {
|
||||
die( '-1' );
|
||||
}
|
||||
@@ -41,7 +55,7 @@ function wpseo_set_ignore() {
|
||||
check_ajax_referer( 'wpseo-ignore' );
|
||||
|
||||
$options = get_option( 'wpseo' );
|
||||
$ignore_key = sanitize_text_field( $_POST['option'] );
|
||||
$ignore_key = sanitize_text_field( WPSEO_Utils::filter_input( INPUT_POST, 'option' ) );
|
||||
$options[ 'ignore_' . $ignore_key ] = true;
|
||||
update_option( 'wpseo', $options );
|
||||
die( '1' );
|
||||
@@ -70,7 +84,7 @@ function wpseo_kill_blocking_files() {
|
||||
}
|
||||
else {
|
||||
unset( $options['blocking_files'][ $k ] );
|
||||
$files_removed++;
|
||||
$files_removed ++;
|
||||
}
|
||||
}
|
||||
if ( $files_removed > 0 ) {
|
||||
@@ -90,7 +104,7 @@ add_action( 'wp_ajax_wpseo_kill_blocking_files', 'wpseo_kill_blocking_files' );
|
||||
function wpseo_get_suggest() {
|
||||
check_ajax_referer( 'wpseo-get-suggest' );
|
||||
|
||||
$term = urlencode( $_GET['term'] );
|
||||
$term = urlencode( WPSEO_Utils::filter_input( INPUT_GET, 'term' ) );
|
||||
$result = wp_remote_get( 'https://www.google.com/complete/search?output=toolbar&q=' . $term );
|
||||
|
||||
$return_arr = array();
|
||||
@@ -104,8 +118,7 @@ function wpseo_get_suggest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode( $return_arr );
|
||||
die();
|
||||
wpseo_ajax_json_echo_die( $return_arr );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpseo_get_suggest', 'wpseo_get_suggest' );
|
||||
@@ -114,11 +127,12 @@ add_action( 'wp_ajax_wpseo_get_suggest', 'wpseo_get_suggest' );
|
||||
* Used in the editor to replace vars for the snippet preview
|
||||
*/
|
||||
function wpseo_ajax_replace_vars() {
|
||||
global $post;
|
||||
check_ajax_referer( 'wpseo-replace-vars' );
|
||||
|
||||
$post = get_post( $_POST['post_id'] );
|
||||
$post = get_post( intval( WPSEO_Utils::filter_input( INPUT_POST, 'post_id' ) ) );
|
||||
$omit = array( 'excerpt', 'excerpt_only', 'title' );
|
||||
echo wpseo_replace_vars( stripslashes( $_POST['string'] ), $post, $omit );
|
||||
echo wpseo_replace_vars( stripslashes( WPSEO_Utils::filter_input( INPUT_POST, 'string' ) ), $post, $omit );
|
||||
die;
|
||||
}
|
||||
|
||||
@@ -128,40 +142,54 @@ add_action( 'wp_ajax_wpseo_replace_vars', 'wpseo_ajax_replace_vars' );
|
||||
* Save an individual SEO title from the Bulk Editor.
|
||||
*/
|
||||
function wpseo_save_title() {
|
||||
check_ajax_referer( 'wpseo-bulk-editor' );
|
||||
|
||||
$new_title = $_POST['new_value'];
|
||||
$id = intval( $_POST['wpseo_post_id'] );
|
||||
$original_title = $_POST['existing_value'];
|
||||
|
||||
$results = wpseo_upsert_new_title( $id, $new_title, $original_title );
|
||||
|
||||
echo json_encode( $results );
|
||||
die();
|
||||
wpseo_save_what( 'title' );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpseo_save_title', 'wpseo_save_title' );
|
||||
|
||||
/**
|
||||
* Helper function for updating an existing seo title or create a new one
|
||||
* if it doesn't already exist.
|
||||
* Save an individual meta description from the Bulk Editor.
|
||||
*/
|
||||
function wpseo_upsert_new_title( $post_id, $new_title, $original_title ) {
|
||||
function wpseo_save_description() {
|
||||
wpseo_save_what( 'metadesc' );
|
||||
}
|
||||
|
||||
$meta_key = WPSEO_Meta::$meta_prefix . 'title';
|
||||
$return_key = 'title';
|
||||
return wpseo_upsert_meta( $post_id, $new_title, $original_title, $meta_key, $return_key );
|
||||
add_action( 'wp_ajax_wpseo_save_metadesc', 'wpseo_save_description' );
|
||||
|
||||
/**
|
||||
* Save titles & descriptions
|
||||
*
|
||||
* @param string $what
|
||||
*/
|
||||
function wpseo_save_what( $what ) {
|
||||
check_ajax_referer( 'wpseo-bulk-editor' );
|
||||
|
||||
$new = WPSEO_Utils::filter_input( INPUT_POST, 'new_value' );
|
||||
$post_id = intval( WPSEO_Utils::filter_input( INPUT_POST, 'wpseo_post_id' ) );
|
||||
$original = WPSEO_Utils::filter_input( INPUT_POST, 'existing_value' );
|
||||
|
||||
$results = wpseo_upsert_new( $what, $post_id, $new, $original );
|
||||
|
||||
wpseo_ajax_json_echo_die( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to update a post's meta data, returning relevant information
|
||||
* about the information updated and the results or the meta update.
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param string $new_meta_value
|
||||
* @param string $orig_meta_value
|
||||
* @param string $meta_key
|
||||
* @param string $return_key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function wpseo_upsert_meta( $post_id, $new_meta_value, $orig_meta_value, $meta_key, $return_key ) {
|
||||
|
||||
$post_id = intval( $post_id );
|
||||
$sanitized_new_meta_value = wp_strip_all_tags( $new_meta_value );
|
||||
$orig_meta_value = wp_strip_all_tags( $orig_meta_value );
|
||||
$post_id = intval( $post_id );
|
||||
$sanitized_new_meta_value = wp_strip_all_tags( $new_meta_value );
|
||||
$orig_meta_value = wp_strip_all_tags( $orig_meta_value );
|
||||
|
||||
$upsert_results = array(
|
||||
'status' => 'success',
|
||||
@@ -224,73 +252,69 @@ function wpseo_upsert_meta( $post_id, $new_meta_value, $orig_meta_value, $meta_k
|
||||
* Save all titles sent from the Bulk Editor.
|
||||
*/
|
||||
function wpseo_save_all_titles() {
|
||||
check_ajax_referer( 'wpseo-bulk-editor' );
|
||||
|
||||
$new_titles = $_POST['items'];
|
||||
$original_titles = $_POST['existing_items'];
|
||||
|
||||
$results = array();
|
||||
|
||||
if ( is_array( $new_titles ) && $new_titles !== array() ) {
|
||||
foreach ( $new_titles as $id => $new_title ) {
|
||||
$original_title = $original_titles[ $id ];
|
||||
$results[] = wpseo_upsert_new_title( $id, $new_title, $original_title );
|
||||
}
|
||||
}
|
||||
echo json_encode( $results );
|
||||
die();
|
||||
wpseo_save_all( 'title' );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpseo_save_all_titles', 'wpseo_save_all_titles' );
|
||||
|
||||
/**
|
||||
* Save an individual meta description from the Bulk Editor.
|
||||
*/
|
||||
function wpseo_save_description() {
|
||||
|
||||
check_ajax_referer( 'wpseo-bulk-editor' );
|
||||
|
||||
$new_metadesc = $_POST['new_value'];
|
||||
$id = intval( $_POST['wpseo_post_id'] );
|
||||
$original_metadesc = $_POST['existing_value'];
|
||||
|
||||
$results = wpseo_upsert_new_description( $id, $new_metadesc, $original_metadesc );
|
||||
|
||||
echo json_encode( $results );
|
||||
die();
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpseo_save_metadesc', 'wpseo_save_description' );
|
||||
|
||||
/**
|
||||
* Helper function to create or update a post's meta description.
|
||||
*/
|
||||
function wpseo_upsert_new_description( $post_id, $new_metadesc, $original_metadesc ) {
|
||||
|
||||
$meta_key = WPSEO_Meta::$meta_prefix . 'metadesc';
|
||||
$return_key = 'metadesc';
|
||||
return wpseo_upsert_meta( $post_id, $new_metadesc, $original_metadesc, $meta_key, $return_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all description sent from the Bulk Editor.
|
||||
*/
|
||||
function wpseo_save_all_descriptions() {
|
||||
check_ajax_referer( 'wpseo-bulk-editor' );
|
||||
|
||||
$new_metadescs = $_POST['items'];
|
||||
$original_metadescs = $_POST['existing_items'];
|
||||
|
||||
$results = array();
|
||||
|
||||
if ( is_array( $new_metadescs ) && $new_metadescs !== array() ) {
|
||||
foreach ( $new_metadescs as $id => $new_metadesc ) {
|
||||
$original_metadesc = $original_metadescs[ $id ];
|
||||
$results[] = wpseo_upsert_new_description( $id, $new_metadesc, $original_metadesc );
|
||||
}
|
||||
}
|
||||
echo json_encode( $results );
|
||||
die();
|
||||
wpseo_save_all( 'metadesc' );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpseo_save_all_descriptions', 'wpseo_save_all_descriptions' );
|
||||
|
||||
/**
|
||||
* Utility function to save values
|
||||
*
|
||||
* @param string $what
|
||||
*/
|
||||
function wpseo_save_all( $what ) {
|
||||
check_ajax_referer( 'wpseo-bulk-editor' );
|
||||
|
||||
// @todo the WPSEO Utils class can't filter arrays in POST yet.
|
||||
$new_values = $_POST['items'];
|
||||
$original_values = $_POST['existing_items'];
|
||||
|
||||
$results = array();
|
||||
|
||||
if ( is_array( $new_values ) && $new_values !== array() ) {
|
||||
foreach ( $new_values as $post_id => $new_value ) {
|
||||
$original_value = $original_values[ $post_id ];
|
||||
$results[] = wpseo_upsert_new( $what, $post_id, $new_value, $original_value );
|
||||
}
|
||||
}
|
||||
wpseo_ajax_json_echo_die( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new value
|
||||
*
|
||||
* @param string $what
|
||||
* @param int $post_id
|
||||
* @param string $new
|
||||
* @param string $original
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function wpseo_upsert_new( $what, $post_id, $new, $original ) {
|
||||
$meta_key = WPSEO_Meta::$meta_prefix . $what;
|
||||
|
||||
return wpseo_upsert_meta( $post_id, $new, $original, $meta_key, $what );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an export and return the URL
|
||||
*/
|
||||
function wpseo_get_export() {
|
||||
check_ajax_referer( 'wpseo-export' );
|
||||
|
||||
$include_taxonomy = ( WPSEO_Utils::filter_input( INPUT_POST, 'include_taxonomy' ) === 'true' ) ? true : false;
|
||||
$export = new WPSEO_Export( $include_taxonomy );
|
||||
|
||||
wpseo_ajax_json_echo_die( $export->get_results() );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpseo_export', 'wpseo_get_export' );
|
||||
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Performs the load on admin side.
|
||||
*/
|
||||
class WPSEO_Admin_Init {
|
||||
|
||||
/**
|
||||
* Holds the WP SEO Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Holds the global `$pagenow` variable's value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $pagenow;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->options = WPSEO_Options::get_all();
|
||||
|
||||
$GLOBALS['wpseo_admin'] = new WPSEO_Admin;
|
||||
|
||||
$this->pagenow = $GLOBALS['pagenow'];
|
||||
|
||||
add_action( 'admin_init', array( $this, 'redirect_to_about_page' ), 15 );
|
||||
$this->load_meta_boxes();
|
||||
$this->load_taxonomy_class();
|
||||
$this->load_admin_page_class();
|
||||
$this->load_admin_user_class();
|
||||
$this->load_yoast_tracking();
|
||||
$this->load_tour();
|
||||
$this->load_xml_sitemaps_admin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect first time or just upgraded users to the about screen.
|
||||
*/
|
||||
public function redirect_to_about_page() {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->options['seen_about'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( in_array( $this->pagenow, array(
|
||||
'update.php',
|
||||
'update-core.php',
|
||||
'plugins.php',
|
||||
'plugin-install.php',
|
||||
) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We're redirecting the user to the about screen, let's make sure we don't do it again until he/she upgrades again
|
||||
$wpseo_option = get_option( 'wpseo' );
|
||||
$wpseo_option['seen_about'] = true;
|
||||
update_option( 'wpseo', $wpseo_option );
|
||||
|
||||
wp_safe_redirect( admin_url( 'admin.php?page=wpseo_dashboard&intro=1' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether we should load the meta box class and if so, load it.
|
||||
*/
|
||||
private function load_meta_boxes() {
|
||||
/**
|
||||
* Filter: 'wpseo_always_register_metaboxes_on_admin' - Allow developers to change whether
|
||||
* the WPSEO metaboxes are only registered on the typical pages (lean loading) or always
|
||||
* registered when in admin.
|
||||
*
|
||||
* @api bool Whether to always register the metaboxes or not. Defaults to false.
|
||||
*/
|
||||
if ( in_array( $this->pagenow, array(
|
||||
'edit.php',
|
||||
'post.php',
|
||||
'post-new.php',
|
||||
) ) || apply_filters( 'wpseo_always_register_metaboxes_on_admin', false )
|
||||
) {
|
||||
$GLOBALS['wpseo_metabox'] = new WPSEO_Metabox;
|
||||
if ( $this->options['opengraph'] === true || $this->options['twitter'] === true || $this->options['googleplus'] === true ) {
|
||||
new WPSEO_Social_Admin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we should load our taxonomy edit class and if so, load it.
|
||||
*/
|
||||
private function load_taxonomy_class() {
|
||||
if ( 'edit-tags.php' === $this->pagenow ) {
|
||||
new WPSEO_Taxonomy;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we should load our admin pages class and if so, load it.
|
||||
*
|
||||
* Loads admin page class for all admin pages starting with `wpseo_`.
|
||||
*/
|
||||
private function load_admin_user_class() {
|
||||
if ( in_array( $this->pagenow, array( 'user-edit.php', 'profile.php' ) ) ) {
|
||||
new WPSEO_Admin_User_Profile;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we should load our admin pages class and if so, load it.
|
||||
*
|
||||
* Loads admin page class for all admin pages starting with `wpseo_`.
|
||||
*/
|
||||
private function load_admin_page_class() {
|
||||
$page = filter_input( INPUT_GET, 'page' );
|
||||
if ( 'admin.php' === $this->pagenow && strpos( $page, 'wpseo' ) === 0 ) {
|
||||
// For backwards compatabilty, this still needs a global, for now...
|
||||
$GLOBALS['wpseo_admin_pages'] = new WPSEO_Admin_Pages;
|
||||
$this->register_i18n_promo_class();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the promotion class for our GlotPress instance
|
||||
*
|
||||
* @link https://github.com/Yoast/i18n-module
|
||||
*/
|
||||
function register_i18n_promo_class() {
|
||||
new yoast_i18n(
|
||||
array(
|
||||
'textdomain' => 'wordpress-seo',
|
||||
'project_slug' => 'wordpress-seo',
|
||||
'plugin_name' => 'WordPress SEO by Yoast',
|
||||
'hook' => 'wpseo_admin_footer',
|
||||
'glotpress_url' => 'http://translate.yoast.com/',
|
||||
'glotpress_name' => 'Yoast Translate',
|
||||
'glotpress_logo' => 'https://cdn.yoast.com/wp-content/uploads/i18n-images/Yoast_Translate.svg',
|
||||
'register_url' => 'http://translate.yoast.com/projects#utm_source=plugin&utm_medium=promo-box&utm_campaign=wpseo-i18n-promo',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we're allowed to load our tracking class and if so, load it.
|
||||
*/
|
||||
private function load_yoast_tracking() {
|
||||
if ( $this->options['yoast_tracking'] === true ) {
|
||||
/**
|
||||
* @internal this is not a proper lean loading implementation (method_exist will autoload the class),
|
||||
* but it can't be helped as there are other plugins out there which also use versions
|
||||
* of the Yoast Tracking class and we need to take that into account unfortunately
|
||||
*/
|
||||
if ( method_exists( 'Yoast_Tracking', 'get_instance' ) ) {
|
||||
add_action( 'yoast_tracking', array( 'Yoast_Tracking', 'get_instance' ) );
|
||||
}
|
||||
else {
|
||||
$GLOBALS['yoast_tracking'] = new Yoast_Tracking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if we should start our tour.
|
||||
*/
|
||||
private function load_tour() {
|
||||
$restart_tour = filter_input( INPUT_GET, 'wpseo_restart_tour' );
|
||||
if ( $restart_tour ) {
|
||||
$this->options['ignore_tour'] = false;
|
||||
update_option( 'wpseo', $this->options );
|
||||
}
|
||||
|
||||
if ( $this->options['tracking_popup_done'] === false || $this->options['ignore_tour'] === false ) {
|
||||
add_action( 'admin_enqueue_scripts', array( 'WPSEO_Pointers', 'get_instance' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if we should start our XML Sitemaps Admin class
|
||||
*/
|
||||
private function load_xml_sitemaps_admin() {
|
||||
if ( $this->options['enablexmlsitemap'] === true ) {
|
||||
new WPSEO_Sitemaps_Admin;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @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' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter POST variables.
|
||||
*
|
||||
* @param string $var_name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function filter_input_post( $var_name ) {
|
||||
$val = filter_input( INPUT_POST, $var_name );
|
||||
if ( $val ) {
|
||||
return WPSEO_Option::sanitize_text_field( $val );
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user metas that (might) have been set on the user profile page.
|
||||
*
|
||||
* @param int $user_id of the updated user
|
||||
*/
|
||||
public function process_user_option_update( $user_id ) {
|
||||
|
||||
if ( current_user_can( 'edit_user', $user_id ) ) {
|
||||
update_user_meta( $user_id, '_yoast_wpseo_profile_updated', time() );
|
||||
}
|
||||
|
||||
if ( $this->filter_input_post( 'wpseo_author_title' ) ) {
|
||||
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_metakey', $this->filter_input_post( 'wpseo_author_metakey' ) );
|
||||
update_user_meta( $user_id, 'wpseo_excludeauthorsitemap', $this->filter_input_post( 'wpseo_author_exclude' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the inputs needed for SEO values to the User Profile page
|
||||
*
|
||||
* @param object $user
|
||||
*/
|
||||
public function user_profile( $user ) {
|
||||
|
||||
if ( ! current_user_can( 'edit_users' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
wp_nonce_field( 'wpseo_user_profile_update', 'wpseo_nonce' );
|
||||
|
||||
require_once( 'views/user-profile.php' );
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
+59
-64
@@ -1,81 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin\Bulk Editor
|
||||
* @since 1.5.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Implements table for bulk description editing.
|
||||
*/
|
||||
class WPSEO_Bulk_Description_List_Table extends WPSEO_Bulk_List_Table {
|
||||
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Bulk_Description_List_Table' ) ) {
|
||||
/**
|
||||
* Current type for this class will be (meta) description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
class WPSEO_Bulk_Description_List_Table extends WPSEO_Bulk_List_Table {
|
||||
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,
|
||||
);
|
||||
|
||||
/**
|
||||
* Current type for this class will be (meta) description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $page_type = 'description';
|
||||
/**
|
||||
* The field in the database where meta field is saved.
|
||||
* @var string
|
||||
*/
|
||||
protected $target_db_field = 'metadesc';
|
||||
|
||||
/**
|
||||
* Settings with are used in __construct
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = array(
|
||||
'singular' => 'wpseo_bulk_description',
|
||||
'plural' => 'wpseo_bulk_descriptions',
|
||||
'ajax' => true,
|
||||
/**
|
||||
* 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' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* The field in the database where meta field is saved.
|
||||
* @var string
|
||||
*/
|
||||
protected $target_db_field = 'metadesc';
|
||||
return $this->merge_columns( $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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' ),
|
||||
);
|
||||
/**
|
||||
* Parse the metadescription
|
||||
*
|
||||
* @param string $column_name
|
||||
* @param object $record
|
||||
* @param string $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"></textarea>',
|
||||
'wpseo-new-metadesc-' . $record->ID,
|
||||
$record->ID
|
||||
);
|
||||
break;
|
||||
|
||||
return $this->merge_columns( $columns );
|
||||
case 'col_existing_yoast_seo_metadesc':
|
||||
// TODO inconsistent return/echo behavior R.
|
||||
echo $this->parse_meta_data_field( $record->ID, $attributes );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the metadescription
|
||||
*
|
||||
* @param string $column_name
|
||||
* @param object $record
|
||||
* @param string $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"></textarea>', 'wpseo-new-metadesc-' . $record->ID, $record->ID );
|
||||
break;
|
||||
|
||||
|
||||
case 'col_existing_yoast_seo_metadesc':
|
||||
echo $this->parse_meta_data_field( $record->ID, $attributes );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} /* End of class */
|
||||
} /* End of class-exists wrapper */
|
||||
} /* End of class */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,88 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin\Bulk Editor
|
||||
* @since 1.5.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Implements table for bulk title editing.
|
||||
*/
|
||||
class WPSEO_Bulk_Title_Editor_List_Table extends WPSEO_Bulk_List_Table {
|
||||
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Bulk_Title_Editor_List_Table' ) ) {
|
||||
/**
|
||||
* Current type for this class will be title
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
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';
|
||||
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,
|
||||
/**
|
||||
* 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(
|
||||
'col_existing_yoast_seo_title' => __( 'Existing Yoast SEO Title', 'wordpress-seo' ),
|
||||
'col_new_yoast_seo_title' => __( 'New Yoast SEO Title', 'wordpress-seo' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* The field in the database where meta field is saved.
|
||||
* @var string
|
||||
*/
|
||||
protected $target_db_field = 'title';
|
||||
return $this->merge_columns( $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* The columns shown on the table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
/**
|
||||
* Parse the title columns
|
||||
*
|
||||
* @param string $column_name
|
||||
* @param object $record
|
||||
* @param string $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parse_page_specific_column( $column_name, $record, $attributes ) {
|
||||
|
||||
$columns = array(
|
||||
'col_existing_yoast_seo_title' => __( 'Existing Yoast SEO Title', 'wordpress-seo' ),
|
||||
'col_new_yoast_seo_title' => __( 'New Yoast SEO Title', 'wordpress-seo' ),
|
||||
);
|
||||
// Fill meta data if exists in $this->meta_data
|
||||
$meta_data = ( ! empty( $this->meta_data[ $record->ID ] ) ) ? $this->meta_data[ $record->ID ] : array();
|
||||
|
||||
return $this->merge_columns($columns);
|
||||
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" />',
|
||||
'wpseo-new-title-' . $record->ID,
|
||||
$record->ID
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the title columns
|
||||
*
|
||||
* @param string $column_name
|
||||
* @param object $record
|
||||
* @param string $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':
|
||||
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" />', 'wpseo-new-title-' . $record->ID, $record->ID );
|
||||
break;
|
||||
}
|
||||
|
||||
unset( $meta_data );
|
||||
}
|
||||
unset( $meta_data );
|
||||
}
|
||||
|
||||
|
||||
} /* End of class */
|
||||
} /* End of class-exists wrapper */
|
||||
} /* End of class */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin\Export
|
||||
*/
|
||||
|
||||
/**
|
||||
* class WPSEO_Export
|
||||
*
|
||||
* Class with functionality to export the WP SEO settings
|
||||
*/
|
||||
class WPSEO_Export {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $export = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $error = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $export_zip_url = '';
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
public $success;
|
||||
|
||||
/**
|
||||
* Whether or not the export will include taxonomy metadata
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $include_taxonomy;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $dir = array();
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param boolean $include_taxonomy Whether to include the taxonomy metadata the plugin creates.
|
||||
*/
|
||||
public function __construct( $include_taxonomy = false ) {
|
||||
$this->include_taxonomy = $include_taxonomy;
|
||||
$this->dir = wp_upload_dir();
|
||||
$this->success = $this->export_settings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with status and output message.
|
||||
*
|
||||
* @return array $results
|
||||
*/
|
||||
public function get_results() {
|
||||
$results = array();
|
||||
if ( $this->success ) {
|
||||
$results['status'] = 'success';
|
||||
$results['msg'] = sprintf( __( 'Export created: %1$sdownload your export file here%2$s.', 'wordpress-seo' ), '<a href="' . $this->export_zip_url . '">', '</a>' );
|
||||
}
|
||||
else {
|
||||
$results['status'] = 'failure';
|
||||
$results['msg'] = __( 'Error creating WordPress SEO export: ', 'wordpress-seo' ) . $this->error;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the current site's WP SEO settings.
|
||||
*
|
||||
* @return boolean|string $return true when success, error when failed.
|
||||
*/
|
||||
private function export_settings() {
|
||||
|
||||
$this->export_header();
|
||||
|
||||
foreach ( WPSEO_Options::get_option_names() as $opt_group ) {
|
||||
$this->write_opt_group( $opt_group, $this->export );
|
||||
}
|
||||
|
||||
$this->taxonomy_metadata();
|
||||
|
||||
if ( $this->write_file() ) {
|
||||
if ( $this->zip_file() ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
$this->error = __( 'Could not zip settings-file.', 'wordpress-seo' );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->error = __( 'Could not write settings to file.', 'wordpress-seo' );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the header of the export file.
|
||||
*/
|
||||
private function export_header() {
|
||||
$this->write_line( '; ' . __( 'This is a settings export file for the WordPress SEO plugin by Yoast.com', 'wordpress-seo' ) . ' - https://yoast.com/wordpress/plugins/seo/' );
|
||||
if ( $this->include_taxonomy ) {
|
||||
$this->write_line( '; ' . __( 'This export includes taxonomy metadata', 'wordpress-seo' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a line to the export
|
||||
*
|
||||
* @param string $line
|
||||
* @param boolean $newline_first
|
||||
*/
|
||||
private function write_line( $line, $newline_first = false ) {
|
||||
if ( $newline_first ) {
|
||||
$this->export .= PHP_EOL;
|
||||
}
|
||||
$this->export .= $line . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an entire option group to the export
|
||||
*
|
||||
* @param string $opt_group
|
||||
*/
|
||||
private function write_opt_group( $opt_group ) {
|
||||
$this->write_line( '[' . $opt_group . ']', true );
|
||||
|
||||
$options = get_option( $opt_group );
|
||||
|
||||
if ( ! is_array( $options ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $options as $key => $elem ) {
|
||||
if ( is_array( $elem ) ) {
|
||||
for ( $i = 0; $i < count( $elem ); $i ++ ) {
|
||||
$this->write_setting( $key . '[]', $elem[ $i ] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->write_setting( $key, $elem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a settings line to the export
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $val
|
||||
*/
|
||||
private function write_setting( $key, $val ) {
|
||||
if ( is_string( $val ) ) {
|
||||
$val = '"' . $val . '"';
|
||||
}
|
||||
$this->write_line( $key . ' = ' . $val );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the taxonomy meta data if there is any
|
||||
*/
|
||||
private function taxonomy_metadata() {
|
||||
if ( $this->include_taxonomy ) {
|
||||
$taxonomy_meta = get_option( 'wpseo_taxonomy_meta' );
|
||||
if ( is_array( $taxonomy_meta ) ) {
|
||||
$this->write_line( '[wpseo_taxonomy_meta]', true );
|
||||
$this->write_setting( 'wpseo_taxonomy_meta', urlencode( json_encode( $taxonomy_meta ) ) );
|
||||
}
|
||||
else {
|
||||
$this->write_line( '; ' . __( 'No taxonomy metadata found', 'wordpress-seo' ), true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the settings to our temporary settings.ini file
|
||||
*
|
||||
* @return boolean unsigned
|
||||
*/
|
||||
private function write_file() {
|
||||
$handle = fopen( $this->dir['path'] . '/settings.ini', 'w' );
|
||||
if ( ! $handle ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$res = fwrite( $handle, $this->export );
|
||||
if ( ! $res ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose( $handle );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips the settings ini file
|
||||
*
|
||||
* @return boolean unsigned
|
||||
*/
|
||||
private function zip_file() {
|
||||
chdir( $this->dir['path'] );
|
||||
$zip = new PclZip( './settings.zip' );
|
||||
if ( 0 === $zip->create( './settings.ini' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->export_zip_url = $this->dir['url'] . '/settings.zip';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin\Import\External
|
||||
*/
|
||||
|
||||
/**
|
||||
* class WPSEO_Import_WooThemes_SEO
|
||||
*
|
||||
* Class with functionality to import WP SEO settings from WooThemes SEO
|
||||
*/
|
||||
class WPSEO_Import_AIOSEO extends WPSEO_Import_External {
|
||||
|
||||
/**
|
||||
* Holds the AOIOSEO options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $aioseo_options;
|
||||
|
||||
/**
|
||||
* Import All In One SEO settings
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->aioseo_options = get_option( 'aioseop_options' );
|
||||
|
||||
$this->import_metas();
|
||||
$this->import_ga();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import All In One SEO meta values
|
||||
*/
|
||||
private function import_metas() {
|
||||
WPSEO_Meta::replace_meta( '_aioseop_description', WPSEO_Meta::$meta_prefix . 'metadesc', $this->replace );
|
||||
WPSEO_Meta::replace_meta( '_aioseop_keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $this->replace );
|
||||
WPSEO_Meta::replace_meta( '_aioseop_title', WPSEO_Meta::$meta_prefix . 'title', $this->replace );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import the Google Analytics settings
|
||||
*/
|
||||
private function import_ga() {
|
||||
if ( isset( $this->aioseo_options['aiosp_google_analytics_id'] ) ) {
|
||||
|
||||
if ( get_option( 'yst_ga' ) === false ) {
|
||||
update_option( 'yst_ga', $this->determine_ga_settings() );
|
||||
}
|
||||
|
||||
$plugin_install_nonce = wp_create_nonce( 'install-plugin_google-analytics-for-wordpress' ); // Use the old name because that's the WordPress.org repo
|
||||
|
||||
$this->set_msg( __( sprintf(
|
||||
'All in One SEO data successfully imported. Would you like to %sdisable the All in One SEO plugin%s. You\'ve had Google Analytics enabled in All in One SEO, would you like to install our %sGoogle Analytics plugin%s?',
|
||||
'<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=import-export&deactivate_aioseo=1#top#import-seo' ) ) . '">',
|
||||
'</a>',
|
||||
'<a href="' . esc_url( admin_url( 'update.php?action=install-plugin&plugin=google-analytics-for-wordpress&_wpnonce=' . $plugin_install_nonce ) ) . '">',
|
||||
'</a>'
|
||||
), 'wordpress-seo' ) );
|
||||
}
|
||||
else {
|
||||
$this->set_msg( __( sprintf( 'All in One SEO data successfully imported. Would you like to %sdisable the All in One SEO plugin%s.', '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=import-export&deactivate_aioseo=1#top#import-seo' ) ) . '">', '</a>' ), 'wordpress-seo' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the appropriate GA settings for this site
|
||||
*
|
||||
* @return array $ga_settings
|
||||
*/
|
||||
private function determine_ga_settings() {
|
||||
$ga_universal = 0;
|
||||
if ( $this->aioseo_options['aiosp_ga_use_universal_analytics'] == 'on' ) {
|
||||
$ga_universal = 1;
|
||||
}
|
||||
|
||||
$ga_track_outbound = 0;
|
||||
if ( $this->aioseo_options['aiosp_ga_track_outbound_links'] == 'on' ) {
|
||||
$ga_track_outbound = 1;
|
||||
}
|
||||
|
||||
$ga_anonymize_ip = 0;
|
||||
if ( $this->aioseo_options['aiosp_ga_anonymize_ip'] == 'on' ) {
|
||||
$ga_anonymize_ip = 1;
|
||||
}
|
||||
|
||||
return array(
|
||||
'ga_general' => array(
|
||||
'manual_ua_code' => (int) 1,
|
||||
'manual_ua_code_field' => $this->aioseo_options['aiosp_google_analytics_id'],
|
||||
'enable_universal' => $ga_universal,
|
||||
'track_outbound' => $ga_track_outbound,
|
||||
'ignore_users' => (array) $this->aioseo_options['aiosp_ga_exclude_users'],
|
||||
'anonymize_ips' => (int) $ga_anonymize_ip,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin\Import\External
|
||||
*/
|
||||
|
||||
/**
|
||||
* class WPSEO_Import_External
|
||||
*
|
||||
* Class with functionality to import WP SEO settings from other plugins
|
||||
*/
|
||||
class WPSEO_Import_External {
|
||||
|
||||
/**
|
||||
* Whether or not to delete old data
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $replace;
|
||||
|
||||
/**
|
||||
* Message about the import
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $msg = '';
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param boolean $replace
|
||||
*/
|
||||
public function __construct( $replace = false ) {
|
||||
$this->replace = $replace;
|
||||
|
||||
WPSEO_Options::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function to set import message
|
||||
*
|
||||
* @param string $msg
|
||||
*/
|
||||
protected function set_msg( $msg ) {
|
||||
if ( ! empty( $this->msg ) ) {
|
||||
$this->msg .= PHP_EOL;
|
||||
}
|
||||
$this->msg .= $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an option depending on the class replace state
|
||||
*
|
||||
* @param string $option
|
||||
*/
|
||||
protected function perhaps_delete( $option ) {
|
||||
if ( $this->replace ) {
|
||||
delete_option( $option );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import HeadSpace SEO settings
|
||||
*/
|
||||
public function import_headspace() {
|
||||
global $wpdb;
|
||||
|
||||
WPSEO_Meta::replace_meta( '_headspace_description', WPSEO_Meta::$meta_prefix . 'metadesc', $this->replace );
|
||||
WPSEO_Meta::replace_meta( '_headspace_keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $this->replace );
|
||||
WPSEO_Meta::replace_meta( '_headspace_page_title', WPSEO_Meta::$meta_prefix . 'title', $this->replace );
|
||||
/* @todo [JRF => whomever] verify how headspace sets these metas ( 'noindex', 'nofollow', 'noarchive', 'noodp', 'noydir' )
|
||||
* and if the values saved are concurrent with the ones we use (i.e. 0/1/2) */
|
||||
WPSEO_Meta::replace_meta( '_headspace_noindex', WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', $this->replace );
|
||||
WPSEO_Meta::replace_meta( '_headspace_nofollow', WPSEO_Meta::$meta_prefix . 'meta-robots-nofollow', $this->replace );
|
||||
|
||||
/* @todo - [JRF => whomever] check if this can be done more efficiently by querying only the meta table
|
||||
* possibly directly changing it using concat on the existing values
|
||||
*/
|
||||
$posts = $wpdb->get_results( "SELECT ID FROM $wpdb->posts" );
|
||||
if ( is_array( $posts ) && $posts !== array() ) {
|
||||
foreach ( $posts as $post ) {
|
||||
$custom = get_post_custom( $post->ID );
|
||||
$robotsmeta_adv = '';
|
||||
if ( isset( $custom['_headspace_noarchive'] ) ) {
|
||||
$robotsmeta_adv .= 'noarchive,';
|
||||
}
|
||||
if ( isset( $custom['_headspace_noodp'] ) ) {
|
||||
$robotsmeta_adv .= 'noodp,';
|
||||
}
|
||||
if ( isset( $custom['_headspace_noydir'] ) ) {
|
||||
$robotsmeta_adv .= 'noydir';
|
||||
}
|
||||
$robotsmeta_adv = preg_replace( '`,$`', '', $robotsmeta_adv );
|
||||
WPSEO_Meta::set_value( 'meta-robots-adv', $robotsmeta_adv, $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->replace ) {
|
||||
$hs_meta = array( 'noarchive', 'noodp', 'noydir' );
|
||||
foreach ( $hs_meta as $meta ) {
|
||||
delete_post_meta_by_key( '_headspace_' . $meta );
|
||||
}
|
||||
unset( $hs_meta, $meta );
|
||||
}
|
||||
$this->set_msg( __( 'HeadSpace2 data successfully imported', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import from Joost's old robots meta plugin
|
||||
*/
|
||||
public function import_robots_meta() {
|
||||
global $wpdb;
|
||||
|
||||
$posts = $wpdb->get_results( "SELECT ID, robotsmeta FROM $wpdb->posts" );
|
||||
|
||||
if ( ! $posts ) {
|
||||
$this->set_msg( __( 'Error: no Robots Meta data found to import.', 'wordpress-seo' ) );
|
||||
|
||||
return;
|
||||
}
|
||||
if ( is_array( $posts ) && $posts !== array() ) {
|
||||
foreach ( $posts as $post ) {
|
||||
// sync all possible settings
|
||||
if ( $post->robotsmeta ) {
|
||||
$pieces = explode( ',', $post->robotsmeta );
|
||||
foreach ( $pieces as $meta ) {
|
||||
switch ( $meta ) {
|
||||
case 'noindex':
|
||||
WPSEO_Meta::set_value( 'meta-robots-noindex', '1', $post->ID );
|
||||
break;
|
||||
|
||||
case 'index':
|
||||
WPSEO_Meta::set_value( 'meta-robots-noindex', '2', $post->ID );
|
||||
break;
|
||||
|
||||
case 'nofollow':
|
||||
WPSEO_Meta::set_value( 'meta-robots-nofollow', '1', $post->ID );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->set_msg( __( sprintf( 'Robots Meta values imported. We recommend %sdisabling the Robots-Meta plugin%s to avoid any conflicts.', '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_tools&tool=import-export&deactivate_robots_meta=1#top#import-other' ) ) . '">', '</a>' ), 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import from old Yoast RSS Footer plugin
|
||||
*/
|
||||
public function import_rss_footer() {
|
||||
$optold = get_option( 'RSSFooterOptions' );
|
||||
$optnew = get_option( 'wpseo_rss' );
|
||||
if ( $optold['position'] == 'after' ) {
|
||||
if ( $optnew['rssafter'] === '' || $optnew['rssafter'] === WPSEO_Options::get_default( 'wpseo_rss', 'rssafter' ) ) {
|
||||
$optnew['rssafter'] = $optold['footerstring'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* @internal Uncomment the second part if a default would be given to the rssbefore value */
|
||||
if ( $optnew['rssbefore'] === '' /*|| $optnew['rssbefore'] === WPSEO_Options::get_default( 'wpseo_rss', 'rssbefore' )*/ ) {
|
||||
$optnew['rssbefore'] = $optold['footerstring'];
|
||||
}
|
||||
}
|
||||
update_option( 'wpseo_rss', $optnew );
|
||||
$this->set_msg( __( 'RSS Footer options imported successfully.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import from Yoast Breadcrumbs plugin
|
||||
*/
|
||||
public function import_yoast_breadcrumbs() {
|
||||
$optold = get_option( 'yoast_breadcrumbs' );
|
||||
$optnew = get_option( 'wpseo_internallinks' );
|
||||
|
||||
if ( is_array( $optold ) && $optold !== array() ) {
|
||||
foreach ( $optold as $opt => $val ) {
|
||||
if ( is_bool( $val ) && $val === true ) {
|
||||
$optnew[ 'breadcrumbs-' . $opt ] = true;
|
||||
}
|
||||
else {
|
||||
$optnew[ 'breadcrumbs-' . $opt ] = $val;
|
||||
}
|
||||
}
|
||||
unset( $opt, $val );
|
||||
update_option( 'wpseo_internallinks', $optnew );
|
||||
$this->set_msg( __( 'Yoast Breadcrumbs options imported successfully.', 'wordpress-seo' ) );
|
||||
}
|
||||
else {
|
||||
$this->set_msg( __( 'Yoast Breadcrumbs options could not be found', 'wordpress-seo' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin\Import\External
|
||||
*/
|
||||
|
||||
/**
|
||||
* class WPSEO_Import_WooThemes_SEO
|
||||
*
|
||||
* Class with functionality to import WP SEO settings from WooThemes SEO
|
||||
*/
|
||||
class WPSEO_Import_WooThemes_SEO extends WPSEO_Import_External {
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->import_home();
|
||||
$this->import_option( 'seo_woo_single_layout', 'post' );
|
||||
$this->import_option( 'seo_woo_page_layout', 'page' );
|
||||
$this->import_archive_option();
|
||||
$this->import_custom_values( 'seo_woo_meta_home_desc', 'metadesc-home-wpseo' );
|
||||
$this->import_custom_values( 'seo_woo_meta_home_key', 'metakey-home-wpseo' );
|
||||
$this->import_metas();
|
||||
|
||||
update_option( 'wpseo_titles', $this->options );
|
||||
|
||||
$this->set_msg( __( 'WooThemes SEO framework settings & data successfully imported.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds the WPSEO Title Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Import options.
|
||||
*
|
||||
* @param string $option
|
||||
* @param string $post_type
|
||||
*/
|
||||
private function import_option( $option, $post_type ) {
|
||||
switch ( get_option( $option ) ) {
|
||||
case 'a':
|
||||
$this->options[ 'title-' . $post_type ] = '%%title%% %%sep%% %%sitename%%';
|
||||
break;
|
||||
case 'b':
|
||||
$this->options[ 'title-' . $post_type ] = '%%title%%';
|
||||
break;
|
||||
case 'c':
|
||||
$this->options[ 'title-' . $post_type ] = '%%sitename%% %%sep%% %%title%%';
|
||||
break;
|
||||
case 'd':
|
||||
$this->options[ 'title-' . $post_type ] = '%%title%% %%sep%% %%sitedesc%%';
|
||||
break;
|
||||
case 'e':
|
||||
$this->options[ 'title-' . $post_type ] = '%%sitename%% %%sep%% %%title%% %%sep%% %%sitedesc%%';
|
||||
break;
|
||||
}
|
||||
$this->perhaps_delete( $option );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import the archive layout for all taxonomies
|
||||
*/
|
||||
private function import_archive_option() {
|
||||
$reinstate_replace = false;
|
||||
if ( $this->replace ) {
|
||||
$this->replace = false;
|
||||
$reinstate_replace = true;
|
||||
}
|
||||
$taxonomies = get_taxonomies( array( 'public' => true ), 'names' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
$this->import_option( 'seo_woo_archive_layout', 'tax-' . $tax );
|
||||
}
|
||||
}
|
||||
if ( $reinstate_replace ) {
|
||||
$this->replace = true;
|
||||
$this->perhaps_delete( 'seo_woo_archive_layout' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import custom descriptions and meta keys
|
||||
*
|
||||
* @param string $option
|
||||
* @param string $key
|
||||
*/
|
||||
private function import_custom_values( $option, $key ) {
|
||||
// Import the custom homepage description
|
||||
if ( 'c' == get_option( $option ) ) {
|
||||
$this->options[ $key ] = get_option( $option . '_custom' );
|
||||
}
|
||||
$this->perhaps_delete( $option );
|
||||
$this->perhaps_delete( $option . '_custom' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports the WooThemes SEO homepage settings
|
||||
*/
|
||||
private function import_home() {
|
||||
switch ( get_option( 'seo_woo_home_layout' ) ) {
|
||||
case 'a':
|
||||
$this->options['title-home-wpseo'] = '%%sitename%% %%sep%% %%sitedesc%%';
|
||||
break;
|
||||
case 'b':
|
||||
$this->options['title-home-wpseo'] = '%%sitename%% ' . get_option( 'seo_woo_paged_var' ) . ' %%pagenum%%';
|
||||
break;
|
||||
case 'c':
|
||||
$this->options['title-home-wpseo'] = '%%sitedesc%%';
|
||||
break;
|
||||
}
|
||||
$this->perhaps_delete( 'seo_woo_home_layout' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import meta values if they're applicable
|
||||
*/
|
||||
private function import_metas() {
|
||||
WPSEO_Meta::replace_meta( 'seo_follow', WPSEO_Meta::$meta_prefix . 'meta-robots-nofollow', $this->replace );
|
||||
WPSEO_Meta::replace_meta( 'seo_noindex', WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', $this->replace );
|
||||
|
||||
// If WooSEO is set to use the Woo titles, import those
|
||||
if ( 'true' == get_option( 'seo_woo_wp_title' ) ) {
|
||||
WPSEO_Meta::replace_meta( 'seo_title', WPSEO_Meta::$meta_prefix . 'title', $this->replace );
|
||||
}
|
||||
|
||||
// If WooSEO is set to use the Woo meta descriptions, import those
|
||||
if ( 'b' == get_option( 'seo_woo_meta_single_desc' ) ) {
|
||||
WPSEO_Meta::replace_meta( 'seo_description', WPSEO_Meta::$meta_prefix . 'metadesc', $this->replace );
|
||||
}
|
||||
|
||||
// If WooSEO is set to use the Woo meta keywords, import those
|
||||
if ( 'b' == get_option( 'seo_woo_meta_single_key' ) ) {
|
||||
WPSEO_Meta::replace_meta( 'seo_keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $this->replace );
|
||||
}
|
||||
|
||||
foreach ( array( 'seo_woo_wp_title', 'seo_woo_meta_single_desc', 'seo_woo_meta_single_key' ) as $option ) {
|
||||
$this->perhaps_delete( $option );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin\Import
|
||||
*/
|
||||
|
||||
/**
|
||||
* class WPSEO_Import
|
||||
*
|
||||
* Class with functionality to import the WP SEO settings
|
||||
*/
|
||||
class WPSEO_Import {
|
||||
|
||||
/**
|
||||
* Message about the import
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $msg = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $filename;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $old_wpseo_version = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $upload_dir;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( ! $this->handle_upload() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->determine_path();
|
||||
|
||||
if ( ! $this->unzip_file() ) {
|
||||
$this->clean_up();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->parse_options();
|
||||
|
||||
$this->clean_up();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the file upload
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function handle_upload() {
|
||||
$this->file = wp_handle_upload( $_FILES['settings_import_file'] );
|
||||
if ( is_wp_error( $this->file ) ) {
|
||||
$this->msg = __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . $this->file->get_error_message();
|
||||
|
||||
return false;
|
||||
}
|
||||
elseif ( ! isset( $this->file['file'] ) ) {
|
||||
$this->msg = __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'Upload failed.', 'wordpress-seo' );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the path to the import file
|
||||
*/
|
||||
private function determine_path() {
|
||||
$this->upload_dir = wp_upload_dir();
|
||||
|
||||
if ( ! defined( 'DIRECTORY_SEPARATOR' ) ) {
|
||||
define( 'DIRECTORY_SEPARATOR', '/' );
|
||||
}
|
||||
$this->path = $this->upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'wpseo-import' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if ( ! isset( $GLOBALS['wp_filesystem'] ) || ! is_object( $GLOBALS['wp_filesystem'] ) ) {
|
||||
WP_Filesystem();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzip the file
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function unzip_file() {
|
||||
$unzipped = unzip_file( $this->file['file'], $this->path );
|
||||
if ( is_wp_error( $unzipped ) ) {
|
||||
$this->msg = __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . sprintf( __( 'Unzipping failed with error "%s".', 'wordpress-seo' ), $unzipped->get_error_message() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->filename = $this->path . 'settings.ini';
|
||||
if ( ! is_file( $this->filename ) || ! is_readable( $this->filename ) ) {
|
||||
$this->msg = __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'Unzipping failed - file settings.ini not found.', 'wordpress-seo' );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the option file
|
||||
*/
|
||||
private function parse_options() {
|
||||
$options = parse_ini_file( $this->filename, true );
|
||||
|
||||
if ( is_array( $options ) && $options !== array() ) {
|
||||
if ( isset( $options['wpseo']['version'] ) && $options['wpseo']['version'] !== '' ) {
|
||||
$this->old_wpseo_version = $options['wpseo']['version'];
|
||||
}
|
||||
foreach ( $options as $name => $opt_group ) {
|
||||
$this->parse_option_group( $name, $opt_group, $options );
|
||||
}
|
||||
$this->msg = __( 'Settings successfully imported.', 'wordpress-seo' );
|
||||
}
|
||||
else {
|
||||
$this->msg = __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'No settings found in file.', 'wordpress-seo' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the option group and import it
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $opt_group
|
||||
* @param array $options
|
||||
*/
|
||||
private function parse_option_group( $name, $opt_group, $options ) {
|
||||
if ( $name === 'wpseo_taxonomy_meta' ) {
|
||||
$opt_group = json_decode( urldecode( $opt_group['wpseo_taxonomy_meta'] ), true );
|
||||
}
|
||||
|
||||
// Make sure that the imported options are cleaned/converted on import
|
||||
$option_instance = WPSEO_Options::get_option_instance( $name );
|
||||
if ( is_object( $option_instance ) && method_exists( $option_instance, 'import' ) ) {
|
||||
$option_instance->import( $opt_group, $this->old_wpseo_version, $options );
|
||||
}
|
||||
elseif ( WP_DEBUG === true || ( defined( 'WPSEO_DEBUG' ) && WPSEO_DEBUG === true ) ) {
|
||||
$this->msg = sprintf( __( 'Setting "%s" is no longer used and has been discarded.', 'wordpress-seo' ), $name );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the files
|
||||
*/
|
||||
private function clean_up() {
|
||||
if ( file_exists( $this->filename ) && is_writable( $this->filename ) ) {
|
||||
unlink( $this->filename );
|
||||
}
|
||||
if ( file_exists( $this->file['file'] ) && is_writable( $this->file['file'] ) ) {
|
||||
unlink( $this->file['file'] );
|
||||
}
|
||||
if ( file_exists( $this->path ) && is_writable( $this->path ) ) {
|
||||
rmdir( $this->path );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,157 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* This class adds the Social tab to the WP SEO metabox and makes sure the settings are saved.
|
||||
*/
|
||||
class WPSEO_Social_Admin extends WPSEO_Metabox {
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Social_Admin' ) ) {
|
||||
/**
|
||||
* This class adds the Social tab to the WP SEO metabox and makes sure the settings are saved.
|
||||
* Class constructor
|
||||
*/
|
||||
class WPSEO_Social_Admin extends WPSEO_Metabox {
|
||||
public function __construct() {
|
||||
add_action( 'wpseo_tab_translate', array( $this, 'translate_meta_boxes' ) );
|
||||
add_action( 'wpseo_tab_header', array( $this, 'tab_header' ), 60 );
|
||||
add_action( 'wpseo_tab_content', array( $this, 'tab_content' ) );
|
||||
add_filter( 'wpseo_save_metaboxes', array( $this, 'save_meta_boxes' ), 10, 1 );
|
||||
add_action( 'wpseo_save_compare_data', array( $this, 'og_data_compare' ), 10, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wpseo_tab_translate', array( $this, 'translate_meta_boxes' ) );
|
||||
add_action( 'wpseo_tab_header', array( $this, 'tab_header' ), 60 );
|
||||
add_action( 'wpseo_tab_content', array( $this, 'tab_content' ) );
|
||||
add_filter( 'wpseo_save_metaboxes', array( $this, 'save_meta_boxes' ), 10, 1 );
|
||||
add_action( 'wpseo_save_compare_data', array( $this, 'og_data_compare' ), 10, 1 );
|
||||
/**
|
||||
* Translate text strings for use in the meta box
|
||||
*
|
||||
* IMPORTANT: if you want to add a new string (option) somewhere, make sure you add that array key to
|
||||
* the main meta box definition array in the class WPSEO_Meta() as well!!!!
|
||||
*/
|
||||
public static function translate_meta_boxes() {
|
||||
$title_text = __( 'If you don\'t want to use the post title for sharing the post on %s but instead want another title there, write it here.', 'wordpress-seo' );
|
||||
$description_text = __( 'If you don\'t want to use the meta description for sharing the post on %s but want another description there, write it here.', 'wordpress-seo' );
|
||||
$image_text = __( 'If you want to override the image used on %s for this post, upload / choose an image or add the URL here.', 'wordpress-seo' );
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
$social_networks = array(
|
||||
'opengraph' => __( 'Facebook', 'wordpress-seo' ),
|
||||
'twitter' => __( 'Twitter', 'wordpress-seo' ),
|
||||
'googleplus' => __( 'Google+', 'wordpress-seo' ),
|
||||
);
|
||||
|
||||
foreach ( $social_networks as $network => $label ) {
|
||||
if ( true === $options[ $network ] ) {
|
||||
if ( 'googleplus' == $network ) {
|
||||
$network = 'google-plus'; // Yuck, I know.
|
||||
}
|
||||
|
||||
self::$meta_fields['social'][ $network . '-title' ]['title'] = sprintf( __( '%s Title', 'wordpress-seo' ), $label );
|
||||
self::$meta_fields['social'][ $network . '-title' ]['description'] = sprintf( $title_text, $label );
|
||||
|
||||
self::$meta_fields['social'][ $network . '-description' ]['title'] = sprintf( __( '%s Description', 'wordpress-seo' ), $label );
|
||||
self::$meta_fields['social'][ $network . '-description' ]['description'] = sprintf( $description_text, $label );
|
||||
|
||||
self::$meta_fields['social'][ $network . '-image' ]['title'] = sprintf( __( '%s Image', 'wordpress-seo' ), $label );
|
||||
self::$meta_fields['social'][ $network . '-image' ]['description'] = sprintf( $image_text, $label );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate text strings for use in the meta box
|
||||
*
|
||||
* IMPORTANT: if you want to add a new string (option) somewhere, make sure you add that array key to
|
||||
* the main meta box definition array in the class WPSEO_Meta() as well!!!!
|
||||
*/
|
||||
public static function translate_meta_boxes() {
|
||||
$title_text = __( 'If you don\'t want to use the post title for sharing the post on %s but instead want another title there, write it here.', 'wordpress-seo' );
|
||||
$description_text = __( 'If you don\'t want to use the meta description for sharing the post on %s but want another description there, write it here.', 'wordpress-seo' );
|
||||
$image_text = __( 'If you want to override the image used on %s for this post, upload / choose an image or add the URL here.', 'wordpress-seo' );
|
||||
/**
|
||||
* Output the tab header for the Social tab
|
||||
*/
|
||||
public function tab_header() {
|
||||
echo '<li class="social"><a class="wpseo_tablink" href="#wpseo_social">', __( 'Social', 'wordpress-seo' ), '</a></li>';
|
||||
}
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
/**
|
||||
* Output the tab content
|
||||
*/
|
||||
public function tab_content() {
|
||||
$content = '';
|
||||
foreach ( $this->get_meta_field_defs( 'social' ) as $meta_key => $meta_field ) {
|
||||
$content .= $this->do_meta_box( $meta_field, $meta_key );
|
||||
}
|
||||
$this->do_tab( 'social', __( 'Social', 'wordpress-seo' ), $content );
|
||||
}
|
||||
|
||||
foreach (
|
||||
array(
|
||||
'opengraph' => __( 'Facebook', 'wordpress-seo' ),
|
||||
'twitter' => __( 'Twitter', 'wordpress-seo' ),
|
||||
'googleplus' => __( 'Google+', 'wordpress-seo' ),
|
||||
) as $network => $label
|
||||
) {
|
||||
if ( true === $options[ $network ] ) {
|
||||
if ( 'googleplus' == $network ) {
|
||||
$network = 'google-plus'; // Yuck, I know.
|
||||
}
|
||||
|
||||
self::$meta_fields['social'][ $network . '-title' ]['title'] = sprintf( __( '%s Title', 'wordpress-seo' ), $label );
|
||||
self::$meta_fields['social'][ $network . '-title' ]['description'] = sprintf( $title_text, $label );
|
||||
/**
|
||||
* Filter over the meta boxes to save, this function adds the Social meta boxes.
|
||||
*
|
||||
* @param array $field_defs Array of metaboxes to save.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function save_meta_boxes( $field_defs ) {
|
||||
return array_merge( $field_defs, $this->get_meta_field_defs( 'social' ) );
|
||||
}
|
||||
|
||||
self::$meta_fields['social'][ $network . '-description' ]['title'] = sprintf( __( '%s Description', 'wordpress-seo' ), $label );
|
||||
self::$meta_fields['social'][ $network . '-description' ]['description'] = sprintf( $description_text, $label );
|
||||
/**
|
||||
* This method will compare opengraph fields with the posted values.
|
||||
*
|
||||
* When fields are changed, the facebook cache will be purge.
|
||||
*
|
||||
* @param object $post
|
||||
*/
|
||||
public function og_data_compare( $post ) {
|
||||
|
||||
self::$meta_fields['social'][ $network . '-image' ]['title'] = sprintf( __( '%s Image', 'wordpress-seo' ), $label );
|
||||
self::$meta_fields['social'][ $network . '-image' ]['description'] = sprintf( $image_text, $label );
|
||||
// Check if post data is available, if post_id is set and if original post_status is publish
|
||||
if (
|
||||
! empty( $_POST ) && ! empty( $post->ID ) && $post->post_status == 'publish' &&
|
||||
isset ( $_POST['original_post_status'] ) && $_POST['original_post_status'] === 'publish'
|
||||
) {
|
||||
|
||||
$fields_to_compare = array(
|
||||
'opengraph-title',
|
||||
'opengraph-description',
|
||||
'opengraph-image',
|
||||
);
|
||||
|
||||
$reset_facebook_cache = false;
|
||||
|
||||
foreach ( $fields_to_compare as $field_to_compare ) {
|
||||
$old_value = self::get_value( $field_to_compare, $post->ID );
|
||||
$new_value = self::get_post_value( self::$form_prefix . $field_to_compare );
|
||||
|
||||
if ( $old_value !== $new_value ) {
|
||||
$reset_facebook_cache = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset( $field_to_compare, $old_value, $new_value );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the tab header for the Social tab
|
||||
*/
|
||||
public function tab_header() {
|
||||
echo '<li class="social"><a class="wpseo_tablink" href="#wpseo_social">' . __( 'Social', 'wordpress-seo' ) . '</a></li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the tab content
|
||||
*/
|
||||
public function tab_content() {
|
||||
$content = '';
|
||||
foreach ( $this->get_meta_field_defs( 'social' ) as $meta_key => $meta_field ) {
|
||||
$content .= $this->do_meta_box( $meta_field, $meta_key );
|
||||
}
|
||||
$this->do_tab( 'social', __( 'Social', 'wordpress-seo' ), $content );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter over the meta boxes to save, this function adds the Social meta boxes.
|
||||
*
|
||||
* @param array $field_defs Array of metaboxes to save.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function save_meta_boxes( $field_defs ) {
|
||||
return array_merge( $field_defs, $this->get_meta_field_defs( 'social' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will compare opengraph fields with the posted values.
|
||||
*
|
||||
* When fields are changed, the facebook cache will be purge.
|
||||
*
|
||||
* @param object $post
|
||||
*/
|
||||
public function og_data_compare( $post ) {
|
||||
|
||||
// Check if post data is available, if post_id is set and if original post_status is publish
|
||||
if ( ! empty( $_POST ) && ! empty( $post->ID ) && $post->post_status == 'publish' && $_POST['original_post_status'] === 'publish' ) {
|
||||
|
||||
$fields_to_compare = array(
|
||||
'opengraph-title',
|
||||
'opengraph-description',
|
||||
'opengraph-image'
|
||||
if ( $reset_facebook_cache ) {
|
||||
wp_remote_get(
|
||||
'https://graph.facebook.com/?id=' . get_permalink( $post->ID ) . '&scrape=true&method=post'
|
||||
);
|
||||
|
||||
$reset_facebook_cache = false;
|
||||
|
||||
foreach ( $fields_to_compare AS $field_to_compare ) {
|
||||
$old_value = self::get_value( $field_to_compare, $post->ID );
|
||||
$new_value = self::get_post_value( self::$form_prefix . $field_to_compare );
|
||||
|
||||
if ( $old_value !== $new_value ) {
|
||||
$reset_facebook_cache = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $reset_facebook_cache ) {
|
||||
wp_remote_get(
|
||||
'https://graph.facebook.com/?id=' . get_permalink( $post->ID ) . '&scrape=true&method=post'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************** DEPRECATED METHODS **********************/
|
||||
/********************** DEPRECATED METHODS **********************/
|
||||
|
||||
/**
|
||||
* Define the meta boxes for the Social tab
|
||||
*
|
||||
* @deprecated 1.5.0
|
||||
* @deprecated use WPSEO_Meta::get_meta_field_defs()
|
||||
* @see WPSEO_Meta::get_meta_field_defs()
|
||||
*
|
||||
* @param string $post_type
|
||||
*
|
||||
* @return array Array containing the meta boxes
|
||||
*/
|
||||
public function get_meta_boxes( $post_type = 'post' ) {
|
||||
_deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Meta::get_meta_field_defs()' );
|
||||
/**
|
||||
* Define the meta boxes for the Social tab
|
||||
*
|
||||
* @deprecated 1.5.0
|
||||
* @deprecated use WPSEO_Meta::get_meta_field_defs()
|
||||
* @see WPSEO_Meta::get_meta_field_defs()
|
||||
*
|
||||
* @param string $post_type
|
||||
*
|
||||
* @return array Array containing the meta boxes
|
||||
*/
|
||||
public function get_meta_boxes( $post_type = 'post' ) {
|
||||
_deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Meta::get_meta_field_defs()' );
|
||||
|
||||
return $this->get_meta_field_defs( 'social' );
|
||||
}
|
||||
return $this->get_meta_field_defs( 'social' );
|
||||
}
|
||||
|
||||
} /* End of class */
|
||||
|
||||
} /* End of class-exists wrapper */
|
||||
} /* End of class */
|
||||
@@ -1,129 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Contains list of conflicting plugins.
|
||||
*/
|
||||
class WPSEO_Plugin_Conflict extends Yoast_Plugin_Conflict {
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Plugin_Conflict' ) ) {
|
||||
|
||||
class WPSEO_Plugin_Conflict extends Yoast_Plugin_Conflict {
|
||||
|
||||
/**
|
||||
* The plugins must be grouped per section.
|
||||
*
|
||||
* It's possible to check for each section if there are conflicting plugin
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $plugins = array(
|
||||
// The plugin which are writing OG metadata
|
||||
'open_graph' => array(
|
||||
'2-click-socialmedia-buttons/2-click-socialmedia-buttons.php',
|
||||
|
||||
// 2 Click Social Media Buttons
|
||||
'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook
|
||||
'add-meta-tags/add-meta-tags.php', // Add Meta Tags
|
||||
'easy-facebook-share-thumbnails/esft.php', // Easy Facebook Share Thumbnail
|
||||
'facebook/facebook.php', // Facebook (official plugin)
|
||||
'facebook-awd/AWD_facebook.php', // Facebook AWD All in one
|
||||
'facebook-featured-image-and-open-graph-meta-tags/fb-featured-image.php',
|
||||
// Facebook Featured Image & OG Meta Tags
|
||||
'facebook-meta-tags/facebook-metatags.php', // Facebook Meta Tags
|
||||
'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
|
||||
// Facebook Open Graph Meta Tags for WordPress
|
||||
'facebook-revised-open-graph-meta-tag/index.php', // Facebook Revised Open Graph Meta Tag
|
||||
'facebook-thumb-fixer/_facebook-thumb-fixer.php', // Facebook Thumb Fixer
|
||||
'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
|
||||
// Fedmich's Facebook Open Graph Meta
|
||||
'header-footer/plugin.php', // Header and Footer
|
||||
'network-publisher/networkpub.php', // Network Publisher
|
||||
'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG
|
||||
'social-networks-auto-poster-facebook-twitter-g/NextScripts_SNAP.php',
|
||||
// NextScripts SNAP
|
||||
'opengraph/opengraph.php', // Open Graph
|
||||
'open-graph-protocol-framework/open-graph-protocol-framework.php',
|
||||
// Open Graph Protocol Framework
|
||||
'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments
|
||||
'seo-ultimate/seo-ultimate.php', // SEO Ultimate
|
||||
'sexybookmarks/sexy-bookmarks.php', // Shareaholic
|
||||
'shareaholic/sexy-bookmarks.php', // Shareaholic
|
||||
'sharepress/sharepress.php', // SharePress
|
||||
'simple-facebook-connect/sfc.php', // Simple Facebook Connect
|
||||
'social-discussions/social-discussions.php', // Social Discussions
|
||||
'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit
|
||||
'socialize/socialize.php', // Socialize
|
||||
'only-tweet-like-share-and-google-1/tweet-like-plusone.php',
|
||||
// Tweet, Like, Google +1 and Share
|
||||
'wordbooker/wordbooker.php', // Wordbooker
|
||||
'wpsso/wpsso.php', // WordPress Social Sharing Optimization
|
||||
'wp-caregiver/wp-caregiver.php', // WP Caregiver
|
||||
'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php',
|
||||
// WP Facebook Like Send & Open Graph Meta
|
||||
'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol
|
||||
'wp-ogp/wp-ogp.php', // WP-OGP
|
||||
'zoltonorg-social-plugin/zosp.php', // Zolton.org Social Plugin
|
||||
),
|
||||
|
||||
'xml_sitemaps' => array(
|
||||
'google-sitemap-plugin/google-sitemap-plugin.php', // Google Sitemap (BestWebSoft)
|
||||
'xml-sitemaps/xml-sitemaps.php', // XML Sitemaps (Denis de Bernardy and Mike Koepke)
|
||||
'bwp-google-xml-sitemaps/bwp-simple-gxs.php', // Better WordPress Google XML Sitemaps (Khang Minh)
|
||||
'google-sitemap-generator/sitemap.php', // Google XML Sitemaps (Arne Brachhold)
|
||||
'xml-sitemap-feed/xml-sitemap.php', // XML Sitemap & Google News feeds (RavanH)
|
||||
'google-monthly-xml-sitemap/monthly-xml-sitemap.php', // Google Monthly XML Sitemap (Andrea Pernici)
|
||||
'simple-google-sitemap-xml/simple-google-sitemap-xml.php', // Simple Google Sitemap XML (iTx Technologies)
|
||||
'another-simple-xml-sitemap/another-simple-xml-sitemap.php', // Another Simple XML Sitemap
|
||||
'xml-maps/google-sitemap.php', // Xml Sitemap (Jason Martens)
|
||||
'google-xml-sitemap-generator-by-anton-dachauer/adachauer-google-xml-sitemap.php', // Google XML Sitemap Generator by Anton Dachauer (Anton Dachauer)
|
||||
'wp-xml-sitemap/wp-xml-sitemap.php', // WP XML Sitemap (Team Vivacity)
|
||||
'sitemap-generator-for-webmasters/sitemap.php', // Sitemap Generator for Webmasters (iwebslogtech)
|
||||
'xml-sitemap-xml-sitemapcouk/xmls.php', // XML Sitemap - XML-Sitemap.co.uk (Simon Hancox)
|
||||
'sewn-in-xml-sitemap/sewn-xml-sitemap.php', // Sewn In XML Sitemap (jcow)
|
||||
'rps-sitemap-generator/rps-sitemap-generator.php', // RPS Sitemap Generator (redpixelstudios)
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Overrides instance to set with this class as class
|
||||
*
|
||||
* @return Yoast_Plugin_Conflict
|
||||
*/
|
||||
public static function get_instance( $classname = __CLASS__ ) {
|
||||
return parent::get_instance( $classname );
|
||||
}
|
||||
|
||||
/**
|
||||
* After activating any plugin, this method will be executed by a hook.
|
||||
*
|
||||
* If the activated plugin is conflicting with ours a notice will be shown.
|
||||
*
|
||||
* @param string|bool $plugin
|
||||
*
|
||||
*/
|
||||
public static function hook_check_for_plugin_conflicts( $plugin = false ) {
|
||||
// The instance of itself
|
||||
$instance = self::get_instance();
|
||||
|
||||
// Only add plugin as active plugin if $plugin isn't false
|
||||
if ( $plugin ) {
|
||||
// Because it's just activated
|
||||
$instance->add_active_plugin( $instance->find_plugin_category( $plugin ), $plugin );
|
||||
}
|
||||
|
||||
$plugin_sections = array(
|
||||
'open_graph' => 'open graph',
|
||||
'xml_sitemaps' => 'xml sitemaps'
|
||||
);
|
||||
|
||||
$instance->check_plugin_conflicts( $plugin_sections );
|
||||
}
|
||||
/**
|
||||
* The plugins must be grouped per section.
|
||||
*
|
||||
* It's possible to check for each section if there are conflicting plugin
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $plugins = array(
|
||||
// The plugin which are writing OG metadata
|
||||
'open_graph' => array(
|
||||
'2-click-socialmedia-buttons/2-click-socialmedia-buttons.php',
|
||||
// 2 Click Social Media Buttons
|
||||
'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook
|
||||
'add-meta-tags/add-meta-tags.php', // Add Meta Tags
|
||||
'easy-facebook-share-thumbnails/esft.php', // Easy Facebook Share Thumbnail
|
||||
'facebook/facebook.php', // Facebook (official plugin)
|
||||
'facebook-awd/AWD_facebook.php', // Facebook AWD All in one
|
||||
'facebook-featured-image-and-open-graph-meta-tags/fb-featured-image.php',
|
||||
// Facebook Featured Image & OG Meta Tags
|
||||
'facebook-meta-tags/facebook-metatags.php', // Facebook Meta Tags
|
||||
'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
|
||||
// Facebook Open Graph Meta Tags for WordPress
|
||||
'facebook-revised-open-graph-meta-tag/index.php', // Facebook Revised Open Graph Meta Tag
|
||||
'facebook-thumb-fixer/_facebook-thumb-fixer.php', // Facebook Thumb Fixer
|
||||
'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
|
||||
// Fedmich's Facebook Open Graph Meta
|
||||
'header-footer/plugin.php', // Header and Footer
|
||||
'network-publisher/networkpub.php', // Network Publisher
|
||||
'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG
|
||||
'opengraph/opengraph.php', // Open Graph
|
||||
'open-graph-protocol-framework/open-graph-protocol-framework.php',
|
||||
// Open Graph Protocol Framework
|
||||
'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments
|
||||
'seo-ultimate/seo-ultimate.php', // SEO Ultimate
|
||||
'sexybookmarks/sexy-bookmarks.php', // Shareaholic
|
||||
'shareaholic/sexy-bookmarks.php', // Shareaholic
|
||||
'sharepress/sharepress.php', // SharePress
|
||||
'simple-facebook-connect/sfc.php', // Simple Facebook Connect
|
||||
'social-discussions/social-discussions.php', // Social Discussions
|
||||
'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit
|
||||
'socialize/socialize.php', // Socialize
|
||||
'only-tweet-like-share-and-google-1/tweet-like-plusone.php',
|
||||
// Tweet, Like, Google +1 and Share
|
||||
'wordbooker/wordbooker.php', // Wordbooker
|
||||
'wpsso/wpsso.php', // WordPress Social Sharing Optimization
|
||||
'wp-caregiver/wp-caregiver.php', // WP Caregiver
|
||||
'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php',
|
||||
// WP Facebook Like Send & Open Graph Meta
|
||||
'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol
|
||||
'wp-ogp/wp-ogp.php', // WP-OGP
|
||||
'zoltonorg-social-plugin/zosp.php', // Zolton.org Social Plugin
|
||||
),
|
||||
'xml_sitemaps' => array(
|
||||
'google-sitemap-plugin/google-sitemap-plugin.php',
|
||||
// Google Sitemap (BestWebSoft)
|
||||
'xml-sitemaps/xml-sitemaps.php',
|
||||
// XML Sitemaps (Denis de Bernardy and Mike Koepke)
|
||||
'bwp-google-xml-sitemaps/bwp-simple-gxs.php',
|
||||
// Better WordPress Google XML Sitemaps (Khang Minh)
|
||||
'google-sitemap-generator/sitemap.php',
|
||||
// Google XML Sitemaps (Arne Brachhold)
|
||||
'xml-sitemap-feed/xml-sitemap.php',
|
||||
// XML Sitemap & Google News feeds (RavanH)
|
||||
'google-monthly-xml-sitemap/monthly-xml-sitemap.php',
|
||||
// Google Monthly XML Sitemap (Andrea Pernici)
|
||||
'simple-google-sitemap-xml/simple-google-sitemap-xml.php',
|
||||
// Simple Google Sitemap XML (iTx Technologies)
|
||||
'another-simple-xml-sitemap/another-simple-xml-sitemap.php',
|
||||
// Another Simple XML Sitemap
|
||||
'xml-maps/google-sitemap.php',
|
||||
// Xml Sitemap (Jason Martens)
|
||||
'google-xml-sitemap-generator-by-anton-dachauer/adachauer-google-xml-sitemap.php',
|
||||
// Google XML Sitemap Generator by Anton Dachauer (Anton Dachauer)
|
||||
'wp-xml-sitemap/wp-xml-sitemap.php',
|
||||
// WP XML Sitemap (Team Vivacity)
|
||||
'sitemap-generator-for-webmasters/sitemap.php',
|
||||
// Sitemap Generator for Webmasters (iwebslogtech)
|
||||
'xml-sitemap-xml-sitemapcouk/xmls.php',
|
||||
// XML Sitemap - XML-Sitemap.co.uk (Simon Hancox)
|
||||
'sewn-in-xml-sitemap/sewn-xml-sitemap.php',
|
||||
// Sewn In XML Sitemap (jcow)
|
||||
'rps-sitemap-generator/rps-sitemap-generator.php',
|
||||
// RPS Sitemap Generator (redpixelstudios)
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Overrides instance to set with this class as class
|
||||
*
|
||||
* @param string $class_name
|
||||
*
|
||||
* @return Yoast_Plugin_Conflict
|
||||
*/
|
||||
public static function get_instance( $class_name = __CLASS__ ) {
|
||||
return parent::get_instance( $class_name );
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* After activating any plugin, this method will be executed by a hook.
|
||||
*
|
||||
* If the activated plugin is conflicting with ours a notice will be shown.
|
||||
*
|
||||
* @param string|bool $plugin
|
||||
*
|
||||
*/
|
||||
public static function hook_check_for_plugin_conflicts( $plugin = false ) {
|
||||
// The instance of itself
|
||||
$instance = self::get_instance();
|
||||
|
||||
// Only add plugin as active plugin if $plugin isn't false
|
||||
if ( $plugin ) {
|
||||
// Because it's just activated
|
||||
$instance->add_active_plugin( $instance->find_plugin_category( $plugin ), $plugin );
|
||||
}
|
||||
|
||||
$plugin_sections = array(
|
||||
/* translators: %s: 'Facebook' plugin name of possibly conflicting plugin with regard to creating OpenGraph output*/
|
||||
'open_graph' => __( 'Both WordPress SEO by Yoast and %s create OpenGraph output, which might make Facebook, Twitter, LinkedIn and other social networks use the wrong texts and images when your pages are being shared.', 'wordpress-seo' ) . '<br/><br/>'
|
||||
. '<a target="_blank" class="button" href="' . admin_url( 'admin.php?page=wpseo_social#top#facebook' ) . '">' . __( 'Configure WordPress SEO\'s OpenGraph settings', 'wordpress-seo' ) . '</a>' ,
|
||||
/* translators: %s: 'Google XML Sitemaps' plugin name of possibly conflicting plugin with regard to the creation of sitemaps*/
|
||||
'xml_sitemaps' => __( 'Both WordPress SEO by Yoast and %s can create XML sitemaps. Having two XML sitemaps is not beneficial for search engines, yet might slow down your site.', 'wordpress-seo' ) . '<br/><br/>'
|
||||
. '<a target="_blank" class="button" href="' . admin_url( 'admin.php?page=wpseo_xml' ) . '">' . __( 'Configure WordPress SEO\'s XML Sitemap settings', 'wordpress-seo' ) . '</a>' ,
|
||||
);
|
||||
|
||||
$instance->check_plugin_conflicts( $plugin_sections );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,362 +1,306 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* This class handles the pointers used in the introduction tour.
|
||||
*
|
||||
* @todo Add an introductory pointer on the edit post page too.
|
||||
*/
|
||||
class WPSEO_Pointers {
|
||||
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Pointers' ) ) {
|
||||
/**
|
||||
* This class handles the pointers used in the introduction tour.
|
||||
*
|
||||
* @todo Add an introductory pointer on the edit post page too.
|
||||
* @var object Instance of this class
|
||||
*/
|
||||
class WPSEO_Pointers {
|
||||
public static $instance;
|
||||
|
||||
/**
|
||||
* @var object Instance of this class
|
||||
*/
|
||||
public static $instance;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$options = get_option( 'wpseo' );
|
||||
if ( $options['tracking_popup_done'] === false || $options['ignore_tour'] === false ) {
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_script( 'jquery-ui' );
|
||||
wp_enqueue_script( 'wp-pointer' );
|
||||
wp_enqueue_script( 'utils' );
|
||||
}
|
||||
if ( $options['tracking_popup_done'] === false && ! isset( $_GET['allow_tracking'] ) ) {
|
||||
add_action( 'admin_print_footer_scripts', array( $this, 'tracking_request' ) );
|
||||
} elseif ( $options['ignore_tour'] === false ) {
|
||||
add_action( 'admin_print_footer_scripts', array( $this, 'intro_tour' ) );
|
||||
}
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
private function __construct() {
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$options = get_option( 'wpseo' );
|
||||
if ( $options['tracking_popup_done'] === false || $options['ignore_tour'] === false ) {
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_script( 'jquery-ui' );
|
||||
wp_enqueue_script( 'wp-pointer' );
|
||||
wp_enqueue_script( 'utils' );
|
||||
}
|
||||
if ( $options['tracking_popup_done'] === false && ! isset( $_GET['allow_tracking'] ) ) {
|
||||
add_action( 'admin_print_footer_scripts', array( $this, 'tracking_request' ) );
|
||||
}
|
||||
elseif ( $options['ignore_tour'] === false ) {
|
||||
add_action( 'admin_print_footer_scripts', array( $this, 'intro_tour' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a popup that asks for permission to allow tracking.
|
||||
*/
|
||||
function tracking_request() {
|
||||
$id = '#wpadminbar';
|
||||
$nonce = wp_create_nonce( 'wpseo_activate_tracking' );
|
||||
|
||||
$content = '<h3>' . __( 'Help improve WordPress SEO', 'wordpress-seo' ) . '</h3>';
|
||||
$content .= '<p>' . __( 'You’ve just installed WordPress SEO by Yoast. Please helps us improve it by allowing us to gather anonymous usage stats so we know which configurations, plugins and themes to test with.', 'wordpress-seo' ) . '</p>';
|
||||
$opt_arr = array(
|
||||
/**
|
||||
* Shows a popup that asks for permission to allow tracking.
|
||||
*/
|
||||
function tracking_request() {
|
||||
$id = '#wpadminbar';
|
||||
$nonce = wp_create_nonce( 'wpseo_activate_tracking' );
|
||||
|
||||
$content = '<h3>' . __( 'Help improve WordPress SEO', 'wordpress-seo' ) . '</h3>';
|
||||
$content .= '<p>' . __( 'You’ve just installed WordPress SEO by Yoast. Please helps us improve it by allowing us to gather anonymous usage stats so we know which configurations, plugins and themes to test with.', 'wordpress-seo' ) . '</p>';
|
||||
$opt_arr = array(
|
||||
'content' => $content,
|
||||
'position' => array( 'edge' => 'top', 'align' => 'center' )
|
||||
);
|
||||
$button_array = array(
|
||||
'button1' => array(
|
||||
'text' => __( 'Do not allow tracking', 'wordpress-seo' ),
|
||||
'function' => 'wpseo_store_answer("no","' . $nonce . '")',
|
||||
),
|
||||
'button2' => array(
|
||||
'text' => __( 'Allow tracking', 'wordpress-seo' ),
|
||||
'function' => 'wpseo_store_answer("yes","' . $nonce . '")',
|
||||
),
|
||||
);
|
||||
|
||||
$this->print_scripts( $id, $opt_arr, $button_array );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the introduction tour
|
||||
*/
|
||||
function intro_tour() {
|
||||
global $pagenow, $current_user;
|
||||
|
||||
$admin_pages = array(
|
||||
'dashboard' => array(
|
||||
'content' => '<h3>' . __( 'General settings', 'wordpress-seo' ) . '</h3><p>' . __( 'These are the General settings for WordPress SEO, here you can restart this tour or revert the WP SEO settings to default.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Tracking', 'wordpress-seo' ) . '</strong><br/>' . __( 'To provide you with the best experience possible, we need your help. Please enable tracking to help us gather anonymous usage data.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Tab: Your Info / Company Info', 'wordpress-seo' ) . '</strong><br/>' . __( 'Add some info here needed for Google\'s Knowledge Graph.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Tab: Webmaster Tools', 'wordpress-seo' ) . '</strong><br/>' . __( 'You can add the verification codes for the different Webmaster Tools programs here, we highly encourage you to check out both Google and Bing’s Webmaster Tools.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Tab: Security', 'wordpress-seo' ) . '</strong><br/>' . __( 'Determine who has access to the plugins advanced settings on the post edit screen.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'More WordPress SEO', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'There’s more to learn about WordPress & SEO than just using this plugin. A great start is our article %1$sthe definitive guide to WordPress SEO%2$s.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/articles/wordpress-seo/#utm_source=wpseo_dashboard&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong style="font-size:150%;">' . __( 'Subscribe to our Newsletter', 'wordpress-seo' ) . '</strong><br/>'
|
||||
. __( 'If you would like us to keep you up-to-date regarding WordPress SEO and other plugins by Yoast, subscribe to our newsletter:', 'wordpress-seo' ) . '</p>' .
|
||||
'<form action="http://yoast.us1.list-manage1.com/subscribe/post?u=ffa93edfe21752c921f860358&id=972f1c9122" method="post" id="newsletter-form" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">' .
|
||||
'<p>' .
|
||||
'<input style="margin: 5px; color:#666" name="EMAIL" value="' . esc_attr( $current_user->user_email ) . '" id="newsletter-email" placeholder="' . __( 'Email', 'wordpress-seo' ) . '"/>' .
|
||||
'<input type="hidden" name="group" value="2"/>' .
|
||||
'<button type="submit" class="button-primary">' . __( 'Subscribe', 'wordpress-seo' ) . '</button>' .
|
||||
'</p></form>',
|
||||
'next_page' => 'titles',
|
||||
),
|
||||
'titles' => array(
|
||||
'content' => '<h3>' . __( 'Title & Metas settings', 'wordpress-seo' ) . '</h3>' . '<p>' . __( 'This is where you set the titles and meta-information for all your post types, taxonomies, archives, special pages and for your homepage. The page is divided into different tabs. Make sure you check ’em all out!', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Sitewide settings', 'wordpress-seo' ) . '</strong><br/>' . __( 'The first tab will show you site-wide settings for titles, normally you\'ll only need to change the Title Separator.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Templates and settings', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'Now click on the ‘%1$sPost Types%2$s’-tab, as this will be our example.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=wpseo_titles#top#post_types' ) ) . '">', '</a>' ) . '<br />' . __( 'The templates are built using variables. You can find all these variables in the help tab (in the top-right corner of the page). The settings allow you to set specific behavior for the post types.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Archives', 'wordpress-seo' ) . '</strong><br/>' . __( 'On the archives tab you can set templates for specific pages like author archives, search results and more.', 'wordpress-seo' )
|
||||
. '<p><strong>' . __( 'Other', 'wordpress-seo' ) . '</strong><br/>' . __( 'On the Other tab you can change sitewide meta settings, like enable meta keywords.', 'wordpress-seo' ),
|
||||
'next_page' => 'social',
|
||||
'prev_page' => 'dashboard',
|
||||
),
|
||||
'social' => array(
|
||||
'content' => '<h3>' . __( 'Social settings', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'Facebook', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'On this tab you can enable the %1$sFacebook Open Graph%2$s functionality from this plugin, as well as assign a Facebook user or Application to be the admin of your site, so you can view the Facebook insights.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/facebook-open-graph-protocol/#utm_source=wpseo_social&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p><p>' . __( 'The frontpage settings allow you to set meta-data for your homepage, whereas the default settings allow you to set a fallback for all posts/pages without images. ', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Twitter', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'With %1$sTwitter Cards%2$s, you can attach rich photos, videos and media experience to tweets that drive traffic to your website. Simply check the box, sign up for the service, and users who Tweet links to your content will have a “Card” added to the tweet that’s visible to all of their followers.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/twitter-cards/#utm_source=wpseo_social&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Pinterest', 'wordpress-seo' ) . '</strong><br/>' . __( 'On this tab you can verify your site with Pinterest and enter your Pinterest account.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Google+', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'This tab allows you to add specific post meta data for Google+. And if you have a Google+ page for your business, add that URL here and link it on your %1$sGoogle+%2$s page’s about page.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://plus.google.com/' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Other', 'wordpress-seo' ) . '</strong><br/>' . __( 'On this tab you can enter some more of your social accounts, mostly used for Google\'s Knowledge Graph.', 'wordpress-seo' ) . '</p>',
|
||||
'next_page' => 'xml',
|
||||
'prev_page' => 'titles',
|
||||
),
|
||||
'xml' => array(
|
||||
'content' => '<h3>' . __( 'XML Sitemaps', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'What are XML sitemaps?', 'wordpress-seo' ) . '</strong><br/>' . __( 'A Sitemap is an XML file that lists the URLs for a site. It allows webmasters to include additional information about each URL: when it was last updated, how often it changes, and how important it is in relation to other URLs in the site. This allows search engines to crawl the site more intelligently.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'What does the plugin do with XML Sitemaps?', 'wordpress-seo' ) . '</strong><br/>' . __( 'This plugin adds XML sitemaps to your site. The sitemaps are automatically updated when you publish a new post, page or custom post and Google and Bing will be automatically notified.', 'wordpress-seo' ) . '</p><p>' . __( 'If you want to exclude certain post types and/or taxonomies, you can also set that on this page.', 'wordpress-seo' ) . '</p><p>' . __( 'Is your webserver low on memory? Decrease the entries per sitemap (default: 1000) to reduce load.', 'wordpress-seo' ) . '</p>',
|
||||
'next_page' => 'advanced',
|
||||
'prev_page' => 'social',
|
||||
),
|
||||
'advanced' => array(
|
||||
'content' => '<h3>' . __( 'Advanced Settings', 'wordpress-seo' ) . '</h3><p>' . __( 'All of the options on these tabs are for advanced users only, if you don’t know whether you should check any, don’t touch them.', 'wordpress-seo' ) . '</p>',
|
||||
'next_page' => 'licenses',
|
||||
'prev_page' => 'xml',
|
||||
),
|
||||
'licenses' => array(
|
||||
'content' => '<h3>' . __( 'Extensions and Licenses', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'Extensions', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'The powerful functions of WordPress SEO can be extended with %1$sYoast premium plugins%2$s. These premium plugins require the installation of WordPress SEO or WordPress SEO Premium and add specific functionality. You can read all about the Yoast Premium Plugins %1$shere%2$s.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/wordpress/plugins/#utm_source=wpseo_licenses&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Licenses', 'wordpress-seo' ) . '</strong><br/>' . __( 'Once you’ve purchased WordPress SEO Premium or any other premium Yoast plugin, you’ll have to enter a license key. You can do so on the Licenses-tab. Once you’ve activated your premium plugin, you can use all its powerful features.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Like this plugin?', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'So, we’ve come to the end of the tour. If you like the plugin, please %srate it 5 stars on WordPress.org%s!', 'wordpress-seo' ), '<a target="_blank" href="https://wordpress.org/plugins/wordpress-seo/">', '</a>' ) . '</p>'
|
||||
. '<p>' . sprintf( __( 'Thank you for using our plugin and good luck with your SEO!<br/><br/>Best,<br/>Team Yoast - %1$sYoast.com%2$s', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/#utm_source=wpseo_licenses&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>',
|
||||
'prev_page' => 'advanced',
|
||||
),
|
||||
);
|
||||
|
||||
$page = filter_input( INPUT_GET, 'page' );
|
||||
$page = str_replace( 'wpseo_', '', $page );
|
||||
|
||||
$button_array = array(
|
||||
'button1' => array(
|
||||
'text' => __( 'Close', 'wordpress-seo' ),
|
||||
'function' => '',
|
||||
),
|
||||
);
|
||||
$opt_arr = array();
|
||||
$id = '#wpseo-title';
|
||||
if ( 'admin.php' != $pagenow || ! array_key_exists( $page, $admin_pages ) ) {
|
||||
$id = 'li.toplevel_page_wpseo_dashboard';
|
||||
$content = '
|
||||
<h3>' . __( 'Congratulations!', 'wordpress-seo' ) . '</h3>
|
||||
<p>' . __( 'You’ve just installed WordPress SEO by Yoast! Click “Start Tour” to view a quick introduction of this plugin’s core functionality.', 'wordpress-seo' ) . '</p>';
|
||||
$opt_arr = array(
|
||||
'content' => $content,
|
||||
'position' => array( 'edge' => 'top', 'align' => 'center' )
|
||||
'position' => array( 'edge' => 'bottom', 'align' => 'center' )
|
||||
);
|
||||
$button_array = array(
|
||||
'button1' => array(
|
||||
'text' => __( 'Do not allow tracking', 'wordpress-seo' ),
|
||||
'function' => 'wpseo_store_answer("no","' . $nonce . '")',
|
||||
),
|
||||
'button2' => array(
|
||||
'text' => __( 'Allow tracking', 'wordpress-seo' ),
|
||||
'function' => 'wpseo_store_answer("yes","' . $nonce . '")',
|
||||
),
|
||||
);
|
||||
|
||||
$this->print_scripts( $id, $opt_arr, $button_array );
|
||||
$button_array['button2']['text'] = __( 'Start Tour', 'wordpress-seo' );
|
||||
$button_array['button2']['function'] = sprintf( 'document.location="%s";', admin_url( 'admin.php?page=wpseo_dashboard' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the introduction tour
|
||||
*/
|
||||
function intro_tour() {
|
||||
global $pagenow, $current_user;
|
||||
|
||||
// @FIXME: Links to tabs only work with target="_blank" and thus open in a new window
|
||||
$adminpages = array(
|
||||
'wpseo_dashboard' => array(
|
||||
'content' => '<h3>' . __( 'Dashboard', 'wordpress-seo' ) . '</h3><p>' . __( 'This is the WordPress SEO Dashboard, here you can restart this tour or revert the WP SEO settings to default.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'More WordPress SEO', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'There’s more to learn about WordPress & SEO than just using this plugin. A great start is our article %1$sthe definitive guide to WordPress SEO%2$s.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/articles/wordpress-seo/#utm_source=wpseo_dashboard&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Tracking', 'wordpress-seo' ) . '</strong><br/>' . __( 'To provide you with the best experience possible, we need your help. Please enable tracking to help us gather anonymous usage data.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Webmaster Tools', 'wordpress-seo' ) . '</strong><br/>' . __( 'You can also add the verification codes for the different Webmaster Tools programs here, we highly encourage you to check out both Google and Bing’s Webmaster Tools.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'WordPress SEO Tour', 'wordpress-seo' ) . '</strong><br/>' . __( 'This tour will show you around in the plugin, to give you a general overview of the plugin.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Newsletter', 'wordpress-seo' ) . '</strong><br/>' .
|
||||
__( 'If you would like to us to keep you up-to-date regarding WordPress SEO and other plugins by Yoast, subscribe to our newsletter:', 'wordpress-seo' ) . '</p>' .
|
||||
'<form action="http://yoast.us1.list-manage1.com/subscribe/post?u=ffa93edfe21752c921f860358&id=972f1c9122" method="post" id="newsletter-form" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">' .
|
||||
'<p>' .
|
||||
'<label for="newsletter-email">' . __( 'Email', 'wordpress-seo' ) . ':</label> <input style="margin: 5px; color:#666" name="EMAIL" value="' . esc_attr( $current_user->user_email ) . '" id="newsletter-email" placeholder="' . __( 'Email', 'wordpress-seo' ) . '"/><br/>' .
|
||||
'<input type="hidden" name="group" value="2"/>' .
|
||||
'<button type="submit" class="button-primary">' . __( 'Subscribe', 'wordpress-seo' ) . '</button>' .
|
||||
'</p></form>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_titles' ) . '";',
|
||||
'position' => array( 'edge' => 'top', 'align' => 'center' ),
|
||||
),
|
||||
'wpseo_titles' => array(
|
||||
'content' => '<h3>' . __( 'Title & Metas settings', 'wordpress-seo' ) . '</h3>' . '<p>' . __( 'This is where you set the titles and meta-information for all your post types, taxonomies, archives, special pages and for your homepage. The page is divided into different tabs. Make sure you check ’em all out!', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Sitewide settings', 'wordpress-seo' ) . '</strong><br/>' . __( 'The first tab will show you site-wide settings. You can also set some settings for the entire site here to add specific meta tags or to remove some unneeded cruft.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Templates and settings', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'Now click on the ‘%1$sPost Types%2$s’-tab, as this will be our example.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=wpseo_titles#top#post_types' ) ) . '">', '</a>' ) . '<br />' . __( 'The templates are built using variables. You can find all these variables in the help tab (in the top-right corner of the page). The settings allow you to set specific behavior for the post types.', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_social' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_dashboard' ) . '";',
|
||||
),
|
||||
'wpseo_social' => array(
|
||||
'content' => '<h3>' . __( 'Social settings', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'Facebook', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'On this tab you can enable the %1$sFacebook Open Graph%2$s functionality from this plugin, as well as assign a Facebook user or Application to be the admin of your site, so you can view the Facebook insights.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/facebook-open-graph-protocol/#utm_source=wpseo_social&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p><p>' . __( 'The frontpage settings allow you to set meta-data for your homepage, whereas the default settings allow you to set a fallback for all posts/pages without images. ', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Twitter', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'With %1$sTwitter Cards%2$s, you can attach rich photos, videos and media experience to tweets that drive traffic to your website. Simply check the box, sign up for the service, and users who Tweet links to your content will have a “Card” added to the tweet that’s visible to all of their followers.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/twitter-cards/#utm_source=wpseo_social&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Google+', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'This tab allows you to add specific post meta data for Google+. And if you have a Google+ page for your business, add that URL here and link it on your %1$sGoogle+%2$s page’s about page.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://plus.google.com/' ) . '">', '</a>' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_xml' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_titles' ) . '";',
|
||||
),
|
||||
'wpseo_xml' => array(
|
||||
'content' => '<h3>' . __( 'XML Sitemaps', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'What are XML sitemaps?', 'wordpress-seo' ) . '</strong><br/>' . __( 'A Sitemap is an XML file that lists the URLs for a site. It allows webmasters to include additional information about each URL: when it was last updated, how often it changes, and how important it is in relation to other URLs in the site. This allows search engines to crawl the site more intelligently.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'What does the plugin do with XML Sitemaps?', 'wordpress-seo' ) . '</strong><br/>' . __( 'This plugin adds XML sitemaps to your site. The sitemaps are automatically updated when you publish a new post, page or custom post and Google and Bing will be automatically notified. You can also have the plugin automatically notify Yahoo! and Ask.com.', 'wordpress-seo' ) . '</p><p>' . __( 'If you want to exclude certain post types and/or taxonomies, you can also set that on this page.', 'wordpress-seo' ) . '</p><p>' . __( 'Is your webserver low on memory? Decrease the entries per sitemap (default: 1000) to reduce load.', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_permalinks' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_social' ) . '";',
|
||||
),
|
||||
'wpseo_permalinks' => array(
|
||||
'content' => '<h3>' . __( 'Permalink Settings', 'wordpress-seo' ) . '</h3><p>' . __( 'All of the options here are for advanced users only, if you don’t know whether you should check any, don’t touch them.', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_internal-links' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_xml' ) . '";',
|
||||
),
|
||||
'wpseo_internal-links' => array(
|
||||
'content' => '<h3>' . __( 'Breadcrumbs Settings', 'wordpress-seo' ) . '</h3><p>' . sprintf( __( 'If your theme supports my breadcrumbs, as all Genesis and WooThemes themes as well as a couple of other ones do, you can change the settings for those here. If you want to modify your theme to support them, %sfollow these instructions%s.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/wordpress/plugins/breadcrumbs/#utm_source=wpseo_permalinks&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_rss' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_permalinks' ) . '";',
|
||||
),
|
||||
'wpseo_rss' => array(
|
||||
'content' => '<h3>' . __( 'RSS Settings', 'wordpress-seo' ) . '</h3><p>' . __( 'This incredibly powerful function allows you to add content to the beginning and end of your posts in your RSS feed. This helps you gain links from people who steal your content!', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_import' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_internal-links' ) . '";',
|
||||
),
|
||||
'wpseo_import' => array(
|
||||
'content' => '<h3>' . esc_html__( 'Import & Export', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'Import from other (SEO) plugins', 'wordpress-seo' ) . '</strong><br/>' . __( 'We can imagine that you switch from another SEO plugin to WordPress SEO. If you just did, you can use these options to transfer your SEO-data. If you were using one of my older plugins like Robots Meta & RSS Footer, you can import the settings here too.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Other imports', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'If you’re using one of our premium plugins, such as %1$sLocal SEO%2$s, you can also find specific import-options for that plugin here.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/wordpress/plugins/local-seo/#utm_source=wpseo_import&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Export', 'wordpress-seo' ) . '</strong><br/>' . __( 'If you have multiple blogs and you’re happy with how you’ve configured this blog, you can export the settings and import them on another blog so you don’t have to go through this process twice!', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . network_admin_url( 'admin.php?page=wpseo_bulk-editor' ) . '";', // will auto-use admin_url if not on multi-site
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_rss' ) . '";',
|
||||
),
|
||||
'wpseo_bulk-editor' => array(
|
||||
'content' => '<h3>' . __( 'Bulk Editor', 'wordpress-seo' ) . '</h3><p>' . __( 'This page lets you view and edit the titles and meta descriptions of all posts and pages on your site. This allows you to edit the title or meta description of all your pages in one place, rather than having to edit each individual page.', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_files' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_import' ) . '";',
|
||||
),
|
||||
'wpseo_files' => array(
|
||||
'content' => '<h3>' . __( 'File Editor', 'wordpress-seo' ) . '</h3><p>' . __( 'Here you can edit the .htaccess and robots.txt files, two of the most powerful files in your WordPress install, if your WordPress installation has write-access to the files. But please, only touch these files if you know what you’re doing!', 'wordpress-seo' ) . '</p>',
|
||||
'next' => __( 'Next', 'wordpress-seo' ),
|
||||
'next_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_licenses' ) . '";',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_bulk-editor' ) . '";',
|
||||
),
|
||||
'wpseo_licenses' => array(
|
||||
'content' => '<h3>' . __( 'Extensions and Licenses', 'wordpress-seo' ) . '</h3>'
|
||||
. '<p><strong>' . __( 'Extensions', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'The powerful functions of WordPress SEO can be extended with %1$sYoast premium plugins%2$s. These premium plugins require the installation of WordPress SEO or WordPress SEO Premium and add specific functionality. You can read all about the Yoast Premium Plugins on %1$shttp://yoast.com/wordpress/plugins/%2$s.', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/wordpress/plugins/#utm_source=wpseo_licenses&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Licenses', 'wordpress-seo' ) . '</strong><br/>' . __( 'Once you’ve purchased WordPress SEO Premium or any other premium Yoast plugin, you’ll have to enter a license key. You can do so on the Licenses-tab. Once you’ve activated your premium plugin, you can use all its powerful features.', 'wordpress-seo' ) . '</p>'
|
||||
. '<p><strong>' . __( 'Like this plugin?', 'wordpress-seo' ) . '</strong><br/>' . sprintf( __( 'So, we’ve come to the end of the tour. If you like the plugin, please %srate it 5 stars on WordPress.org%s!', 'wordpress-seo' ), '<a target="_blank" href="https://wordpress.org/plugins/wordpress-seo/">', '</a>' ) . '</p>'
|
||||
. '<p>' . sprintf( __( 'Thank you for using my plugin and good luck with your SEO!<br/><br/>Best,<br/>Team Yoast - %1$sYoast.com%2$s', 'wordpress-seo' ), '<a target="_blank" href="' . esc_url( 'https://yoast.com/#utm_source=wpseo_licenses&utm_medium=wpseo_tour&utm_campaign=tour' ) . '">', '</a>' ) . '</p>',
|
||||
'prev' => __( 'Previous', 'wordpress-seo' ),
|
||||
'prev_function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_files' ) . '";',
|
||||
),
|
||||
);
|
||||
|
||||
// Skip tour about wpseo_files page if file editing is disallowed or if the site is a multisite and the current user isn't a superadmin
|
||||
if ( false === wpseo_allow_system_file_edit() ) {
|
||||
unset( $adminpages['wpseo_files'] );
|
||||
$adminpages['wpseo_bulk-editor']['function'] = 'window.location="' . admin_url( 'admin.php?page=wpseo_licenses' ) . '";';
|
||||
}
|
||||
|
||||
$page = '';
|
||||
if ( isset( $_GET['page'] ) ) {
|
||||
$page = $_GET['page'];
|
||||
}
|
||||
|
||||
$button_array = array(
|
||||
'button1' => array(
|
||||
'text' => __( 'Close', 'wordpress-seo' ),
|
||||
'function' => '',
|
||||
)
|
||||
);
|
||||
$opt_arr = array();
|
||||
$id = '#wpseo-title';
|
||||
if ( 'admin.php' != $pagenow || ! array_key_exists( $page, $adminpages ) ) {
|
||||
$id = 'li.toplevel_page_wpseo_dashboard';
|
||||
$content = '<h3>' . __( 'Congratulations!', 'wordpress-seo' ) . '</h3>';
|
||||
$content .= '<p>' . __( 'You’ve just installed WordPress SEO by Yoast! Click “Start Tour” to view a quick introduction of this plugin’s core functionality.', 'wordpress-seo' ) . '</p>';
|
||||
$opt_arr = array(
|
||||
'content' => $content,
|
||||
'position' => array( 'edge' => 'bottom', 'align' => 'center' )
|
||||
else {
|
||||
if ( '' != $page && in_array( $page, array_keys( $admin_pages ) ) ) {
|
||||
$align = ( is_rtl() ) ? 'left' : 'right';
|
||||
$default_position = array(
|
||||
'edge' => 'top',
|
||||
'align' => $align,
|
||||
);
|
||||
$button_array['button2']['text'] = __( 'Start Tour', 'wordpress-seo' );
|
||||
$button_array['button2']['function'] = 'document.location="' . admin_url( 'admin.php?page=wpseo_dashboard' ) . '";';
|
||||
} else {
|
||||
if ( '' != $page && in_array( $page, array_keys( $adminpages ) ) ) {
|
||||
$align = ( is_rtl() ) ? 'left' : 'right';
|
||||
$opt_arr = array(
|
||||
'content' => $adminpages[$page]['content'],
|
||||
'position' => ( isset ( $adminpages[$page]['position'] ) ) ? ( $adminpages[$page]['position'] ) : array( 'edge' => 'top', 'align' => $align ),
|
||||
'pointerWidth' => 450,
|
||||
$opt_arr = array(
|
||||
'content' => $admin_pages[ $page ]['content'],
|
||||
'position' => ( isset ( $admin_pages[ $page ]['position'] ) ) ? ( $admin_pages[ $page ]['position'] ) : $default_position,
|
||||
'pointerWidth' => 450,
|
||||
);
|
||||
if ( isset( $admin_pages[ $page ]['next_page'] ) ) {
|
||||
$button_array['button2'] = array(
|
||||
'text' => __( 'Next', 'wordpress-seo' ),
|
||||
'function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_' . $admin_pages[ $page ]['next_page'] ) . '";',
|
||||
);
|
||||
}
|
||||
if ( isset( $admin_pages[ $page ]['prev_page'] ) ) {
|
||||
$button_array['button3'] = array(
|
||||
'text' => __( 'Previous', 'wordpress-seo' ),
|
||||
'function' => 'window.location="' . admin_url( 'admin.php?page=wpseo_' . $admin_pages[ $page ]['prev_page'] ) . '";',
|
||||
);
|
||||
if ( isset( $adminpages[$page]['next'] ) && isset( $adminpages[$page]['next_function'] ) ) {
|
||||
$button_array['button2'] = array(
|
||||
'text' => $adminpages[$page]['next'],
|
||||
'function' => $adminpages[$page]['next_function'],
|
||||
);
|
||||
}
|
||||
if ( isset( $adminpages[$page]['prev'] ) && isset( $adminpages[$page]['prev_function'] ) ) {
|
||||
$button_array['button3'] = array(
|
||||
'text' => $adminpages[$page]['prev'],
|
||||
'function' => $adminpages[$page]['prev_function'],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->print_scripts( $id, $opt_arr, $button_array );
|
||||
}
|
||||
|
||||
$this->print_scripts( $id, $opt_arr, $button_array );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the pointer script
|
||||
*
|
||||
* @param string $selector The CSS selector the pointer is attached to.
|
||||
* @param array $options The options for the pointer.
|
||||
* @param array $button_array The options for the buttons.
|
||||
*/
|
||||
function print_scripts( $selector, $options, $button_array ) {
|
||||
$button_array_defaults = array(
|
||||
'button1' => array(
|
||||
'text' => false,
|
||||
'function' => '',
|
||||
),
|
||||
'button2' => array(
|
||||
'text' => false,
|
||||
'function' => '',
|
||||
),
|
||||
'button3' => array(
|
||||
'text' => false,
|
||||
'function' => '',
|
||||
),
|
||||
);
|
||||
$button_array = wp_parse_args( $button_array, $button_array_defaults );
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
(function ($) {
|
||||
// Don't show the tour on screens with an effective width smaller than 1024px or an effective height smaller than 768px.
|
||||
if (jQuery(window).width() < 1024 || jQuery(window).availWidth < 1024 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var wpseo_pointer_options = <?php echo json_encode( $options ); ?>, setup;
|
||||
/**
|
||||
* Prints the pointer script
|
||||
*
|
||||
* @param string $selector The CSS selector the pointer is attached to.
|
||||
* @param array $options The options for the pointer.
|
||||
* @param array $button_array The options for the buttons.
|
||||
*/
|
||||
function print_scripts( $selector, $options, $button_array ) {
|
||||
$button_array_defaults = array(
|
||||
'button1' => array(
|
||||
'text' => false,
|
||||
'function' => '',
|
||||
),
|
||||
'button2' => array(
|
||||
'text' => false,
|
||||
'function' => '',
|
||||
),
|
||||
'button3' => array(
|
||||
'text' => false,
|
||||
'function' => '',
|
||||
),
|
||||
);
|
||||
$button_array = wp_parse_args( $button_array, $button_array_defaults );
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
(function ($) {
|
||||
// Don't show the tour on screens with an effective width smaller than 1024px or an effective height smaller than 768px.
|
||||
if (jQuery(window).width() < 1024 || jQuery(window).availWidth < 1024) {
|
||||
return;
|
||||
}
|
||||
|
||||
function wpseo_store_answer(input, nonce) {
|
||||
var wpseo_tracking_data = {
|
||||
action : 'wpseo_allow_tracking',
|
||||
allow_tracking: input,
|
||||
nonce : nonce
|
||||
};
|
||||
jQuery.post(ajaxurl, wpseo_tracking_data, function () {
|
||||
jQuery('#wp-pointer-0').remove();
|
||||
});
|
||||
}
|
||||
var wpseo_pointer_options = <?php echo json_encode( $options ); ?>, setup;
|
||||
|
||||
wpseo_pointer_options = $.extend(wpseo_pointer_options, {
|
||||
buttons: function (event, t) {
|
||||
var button = jQuery('<a id="pointer-close" style="margin:0 5px;" class="button-secondary">' + '<?php echo $button_array['button1']['text']; ?>' + '</a>');
|
||||
button.bind('click.pointer', function () {
|
||||
t.element.pointer('close');
|
||||
});
|
||||
return button;
|
||||
},
|
||||
close : function () {
|
||||
}
|
||||
});
|
||||
|
||||
setup = function () {
|
||||
$('<?php echo $selector; ?>').pointer(wpseo_pointer_options).pointer('open');
|
||||
<?php if ( $button_array['button2']['text'] ) { ?>
|
||||
jQuery('#pointer-close').after('<a id="pointer-primary" class="button-primary">' + '<?php echo $button_array['button2']['text']; ?>' + '</a>');
|
||||
jQuery('#pointer-primary').click(function () {
|
||||
<?php echo $button_array['button2']['function']; ?>
|
||||
});
|
||||
<?php if ( $button_array['button3']['text'] ) { ?>
|
||||
jQuery('#pointer-primary').after('<a id="pointer-ternary" style="float: left;" class="button-secondary">' + '<?php echo $button_array['button3']['text']; ?>' + '</a>');
|
||||
jQuery('#pointer-ternary').click(function () {
|
||||
<?php echo $button_array['button3']['function']; ?>
|
||||
});
|
||||
<?php } ?>
|
||||
jQuery('#pointer-close').click(function () {
|
||||
<?php if ( $button_array['button1']['function'] == '' ) { ?>
|
||||
wpseo_setIgnore("tour", "wp-pointer-0", "<?php echo esc_js( wp_create_nonce( 'wpseo-ignore' ) ); ?>");
|
||||
<?php } else { ?>
|
||||
<?php echo $button_array['button1']['function']; ?>
|
||||
<?php } ?>
|
||||
});
|
||||
<?php } else if ( $button_array['button3']['text'] ) { ?>
|
||||
jQuery('#pointer-close').after('<a id="pointer-ternary" style="float: left;" class="button-secondary">' + '<?php echo $button_array['button3']['text']; ?>' + '</a>');
|
||||
jQuery('#pointer-ternary').click(function () {
|
||||
<?php echo $button_array['button3']['function']; ?>
|
||||
});
|
||||
<?php } ?>
|
||||
function wpseo_store_answer(input, nonce) {
|
||||
var wpseo_tracking_data = {
|
||||
action: 'wpseo_allow_tracking',
|
||||
allow_tracking: input,
|
||||
nonce: nonce
|
||||
};
|
||||
jQuery.post(ajaxurl, wpseo_tracking_data, function () {
|
||||
jQuery('#wp-pointer-0').remove();
|
||||
});
|
||||
}
|
||||
|
||||
if (wpseo_pointer_options.position && wpseo_pointer_options.position.defer_loading)
|
||||
$(window).bind('load.wp-pointers', setup);
|
||||
else
|
||||
$(document).ready(setup);
|
||||
})(jQuery);
|
||||
//]]>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
wpseo_pointer_options = $.extend(wpseo_pointer_options, {
|
||||
buttons: function (event, t) {
|
||||
var button = jQuery('<a id="pointer-close" style="margin:0 5px;" class="button-secondary">' + '<?php echo $button_array['button1']['text']; ?>' + '</a>');
|
||||
button.bind('click.pointer', function () {
|
||||
t.element.pointer('close');
|
||||
});
|
||||
return button;
|
||||
},
|
||||
close: function () {
|
||||
}
|
||||
});
|
||||
|
||||
setup = function () {
|
||||
$('<?php echo $selector; ?>').pointer(wpseo_pointer_options).pointer('open');
|
||||
<?php if ( $button_array['button2']['text'] ) : ?>
|
||||
jQuery('#pointer-close').after('<a id="pointer-primary" class="button-primary">' + '<?php echo $button_array['button2']['text']; ?>' + '</a>');
|
||||
jQuery('#pointer-primary').click(function () {
|
||||
<?php echo $button_array['button2']['function']; ?>
|
||||
});
|
||||
<?php if ( $button_array['button3']['text'] ) { ?>
|
||||
jQuery('#pointer-primary').after('<a id="pointer-ternary" style="float: left;" class="button-secondary">' + '<?php echo $button_array['button3']['text']; ?>' + '</a>');
|
||||
jQuery('#pointer-ternary').click(function () {
|
||||
<?php echo $button_array['button3']['function']; ?>
|
||||
});
|
||||
<?php } ?>
|
||||
jQuery('#pointer-close').click(function () {
|
||||
<?php if ( $button_array['button1']['function'] == '' ) : ?>
|
||||
wpseo_setIgnore("tour", "wp-pointer-0", "<?php echo esc_js( wp_create_nonce( 'wpseo-ignore' ) ); ?>");
|
||||
<?php else : ?>
|
||||
<?php echo $button_array['button1']['function']; ?>
|
||||
<?php endif; ?>
|
||||
});
|
||||
<?php elseif ( $button_array['button3']['text'] ) : ?>
|
||||
jQuery('#pointer-close').after('<a id="pointer-ternary" style="float: left;" class="button-secondary">' + '<?php echo $button_array['button3']['text']; ?>' + '</a>');
|
||||
jQuery('#pointer-ternary').click(function () {
|
||||
<?php echo $button_array['button3']['function']; ?>
|
||||
});
|
||||
<?php endif; ?>
|
||||
};
|
||||
|
||||
if (wpseo_pointer_options.position && wpseo_pointer_options.position.defer_loading)
|
||||
$(window).bind('load.wp-pointers', setup);
|
||||
else
|
||||
$(document).ready(setup);
|
||||
})(jQuery);
|
||||
//]]>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load a tiny bit of CSS in the head
|
||||
*
|
||||
* @deprecated 1.5.0, now handled by css
|
||||
*/
|
||||
function admin_head() {
|
||||
_deprecated_function( __METHOD__, 'WPSEO 1.5.0' );
|
||||
/**
|
||||
* Load a tiny bit of CSS in the head
|
||||
*
|
||||
* @deprecated 1.5.0, now handled by css
|
||||
*/
|
||||
function admin_head() {
|
||||
_deprecated_function( __METHOD__, 'WPSEO 1.5.0' );
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
} /* End of class */
|
||||
|
||||
} /* End of class-exists wrapper */
|
||||
} /* End of class */
|
||||
@@ -1,89 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* @package XML_Sitemaps
|
||||
* @package WPSEO\Admin\XML Sitemaps
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Class that handles the Admin side of XML sitemaps
|
||||
*/
|
||||
class WPSEO_Sitemaps_Admin {
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Sitemaps_Admin' ) ) {
|
||||
/**
|
||||
* Class that handles the Admin side of XML sitemaps
|
||||
* Class constructor
|
||||
*/
|
||||
class WPSEO_Sitemaps_Admin {
|
||||
function __construct() {
|
||||
add_action( 'transition_post_status', array( $this, 'status_transition' ), 10, 3 );
|
||||
add_action( 'admin_init', array( $this, 'delete_sitemaps' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
function __construct() {
|
||||
add_action( 'transition_post_status', array( $this, 'status_transition' ), 10, 3 );
|
||||
add_action( 'admin_init', array( $this, 'delete_sitemaps' ) );
|
||||
}
|
||||
/**
|
||||
* Find sitemaps residing on disk as they will block our rewrite.
|
||||
*
|
||||
* @todo issue #561 https://github.com/Yoast/wordpress-seo/issues/561
|
||||
*/
|
||||
function delete_sitemaps() {
|
||||
$options = WPSEO_Options::get_all();
|
||||
if ( $options['enablexmlsitemap'] === true ) {
|
||||
|
||||
/**
|
||||
* Find sitemaps residing on disk as they will block our rewrite.
|
||||
*
|
||||
* @todo issue #561 https://github.com/Yoast/wordpress-seo/issues/561
|
||||
*/
|
||||
function delete_sitemaps() {
|
||||
$options = WPSEO_Options::get_all();
|
||||
if ( $options['enablexmlsitemap'] === true ) {
|
||||
$file_to_check_for = array(
|
||||
// ABSPATH . 'sitemap.xml',
|
||||
// ABSPATH . 'sitemap.xslt',
|
||||
// ABSPATH . 'sitemap.xsl',
|
||||
ABSPATH . 'sitemap_index.xml',
|
||||
);
|
||||
|
||||
$file_to_check_for = array(
|
||||
//ABSPATH . 'sitemap.xml',
|
||||
//ABSPATH . 'sitemap.xslt',
|
||||
//ABSPATH . 'sitemap.xsl',
|
||||
ABSPATH . 'sitemap_index.xml',
|
||||
);
|
||||
$new_files_found = false;
|
||||
|
||||
$new_files_found = false;
|
||||
|
||||
foreach ( $file_to_check_for as $file ) {
|
||||
if ( ( $options['blocking_files'] === array() || ( $options['blocking_files'] !== array() && in_array( $file, $options['blocking_files'] ) === false ) ) && file_exists( $file ) ) {
|
||||
$options['blocking_files'][] = $file;
|
||||
$new_files_found = true;
|
||||
}
|
||||
}
|
||||
if ( $new_files_found === true ) {
|
||||
update_option( 'wpseo', $options );
|
||||
foreach ( $file_to_check_for as $file ) {
|
||||
if ( ( $options['blocking_files'] === array() || ( $options['blocking_files'] !== array() && in_array( $file, $options['blocking_files'] ) === false ) ) && file_exists( $file ) ) {
|
||||
$options['blocking_files'][] = $file;
|
||||
$new_files_found = true;
|
||||
}
|
||||
}
|
||||
unset( $file );
|
||||
|
||||
if ( $new_files_found === true ) {
|
||||
update_option( 'wpseo', $options );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooked into transition_post_status. Will initiate search engine pings
|
||||
* if the post is being published, is a post type that a sitemap is built for
|
||||
* and is a post that is included in sitemaps.
|
||||
*/
|
||||
function status_transition( $new_status, $old_status, $post ) {
|
||||
if ( $new_status != 'publish' ) {
|
||||
return;
|
||||
/**
|
||||
* Hooked into transition_post_status. Will initiate search engine pings
|
||||
* if the post is being published, is a post type that a sitemap is built for
|
||||
* and is a post that is included in sitemaps.
|
||||
*
|
||||
* @param string $new_status New post status.
|
||||
* @param string $old_status Old post status.
|
||||
* @param \WP_Post $post Post object.
|
||||
|
||||
*/
|
||||
function status_transition( $new_status, $old_status, $post ) {
|
||||
if ( $new_status != 'publish' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_cache_delete( 'lastpostmodified:gmt:' . $post->post_type, 'timeinfo' ); // #17455
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
if ( isset( $options[ 'post_types-' . $post->post_type . '-not_in_sitemap' ] ) && $options[ 'post_types-' . $post->post_type . '-not_in_sitemap' ] === true ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( WP_CACHE ) {
|
||||
wp_schedule_single_event( ( time() + 300 ), 'wpseo_hit_sitemap_index' );
|
||||
}
|
||||
|
||||
// Allow the pinging to happen slightly after the hit sitemap index so the sitemap is fully regenerated when the ping happens.
|
||||
if ( WPSEO_Meta::get_value( 'sitemap-include', $post->ID ) !== 'never' ) {
|
||||
if ( defined( 'YOAST_SEO_PING_IMMEDIATELY' ) && YOAST_SEO_PING_IMMEDIATELY ) {
|
||||
wpseo_ping_search_engines();
|
||||
}
|
||||
|
||||
wp_cache_delete( 'lastpostmodified:gmt:' . $post->post_type, 'timeinfo' ); // #17455
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
if ( isset( $options[ 'post_types-' . $post->post_type . '-not_in_sitemap' ] ) && $options[ 'post_types-' . $post->post_type . '-not_in_sitemap' ] === true ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( WP_CACHE ) {
|
||||
wp_schedule_single_event( time() + 300, 'wpseo_hit_sitemap_index' );
|
||||
}
|
||||
|
||||
// Allow the pinging to happen slightly after the hit sitemap index so the sitemap is fully regenerated when the ping happens.
|
||||
if ( WPSEO_Meta::get_value( 'sitemap-include', $post->ID ) !== 'never' ) {
|
||||
if ( defined( 'YOAST_SEO_PING_IMMEDIATELY' ) && YOAST_SEO_PING_IMMEDIATELY ) {
|
||||
wpseo_ping_search_engines();
|
||||
}
|
||||
else {
|
||||
wp_schedule_single_event( ( time() + 300 ), 'wpseo_ping_search_engines' );
|
||||
}
|
||||
else {
|
||||
wp_schedule_single_event( ( time() + 300 ), 'wpseo_ping_search_engines' );
|
||||
}
|
||||
}
|
||||
} /* End of class */
|
||||
}
|
||||
} /* End of class */
|
||||
|
||||
} /* End of class-exists wrapper */
|
||||
@@ -1,156 +1,163 @@
|
||||
<?php
|
||||
if ( ! class_exists( 'WPSEO_Snippet_Preview' ) ) {
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
* @since 1.6.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* class WPSEO_Snippet_Preview
|
||||
*
|
||||
* Generates a Google Search snippet preview.
|
||||
*
|
||||
* Takes a $post, $title and $description
|
||||
*
|
||||
*/
|
||||
class WPSEO_Snippet_Preview {
|
||||
/**
|
||||
* class WPSEO_Snippet_Preview
|
||||
*
|
||||
* Generates a Google Search snippet preview.
|
||||
*
|
||||
* Takes a $post, $title and $description
|
||||
*
|
||||
* @var string The dynamically generated html for the snippet preview.
|
||||
*/
|
||||
class WPSEO_Snippet_Preview {
|
||||
/**
|
||||
* @var string The dynamically generated html for the snippet preview.
|
||||
*/
|
||||
protected $content;
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
* @var array The WPSEO options.
|
||||
*/
|
||||
protected $options;
|
||||
/**
|
||||
* @var array The WPSEO options.
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* @var object The post for which we want to generate the snippet preview.
|
||||
*/
|
||||
protected $post;
|
||||
/**
|
||||
* @var object The post for which we want to generate the snippet preview.
|
||||
*/
|
||||
protected $post;
|
||||
|
||||
/**
|
||||
* @var string The title that is shown in the snippet.
|
||||
*/
|
||||
protected $title;
|
||||
/**
|
||||
* @var string The title that is shown in the snippet.
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @var string The description that is shown in the snippet.
|
||||
*/
|
||||
protected $description;
|
||||
/**
|
||||
* @var string The description that is shown in the snippet.
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* @var string The date that is shown at the beginning of the description in the snippet.
|
||||
*/
|
||||
protected $date = '';
|
||||
/**
|
||||
* @var string The date that is shown at the beginning of the description in the snippet.
|
||||
*/
|
||||
protected $date = '';
|
||||
|
||||
/**
|
||||
* @var string The url that is shown in the snippet.
|
||||
*/
|
||||
protected $url;
|
||||
/**
|
||||
* @var string The url that is shown in the snippet.
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @var string The slug of the url that is shown in the snippet.
|
||||
*/
|
||||
protected $slug = '';
|
||||
/**
|
||||
* @var string The slug of the url that is shown in the snippet.
|
||||
*/
|
||||
protected $slug = '';
|
||||
|
||||
/**
|
||||
* Generates the html for the snippet preview containing dynamically generated text components.
|
||||
* Those components are included as properties which are set in the constructor.
|
||||
*
|
||||
* @param object $post
|
||||
* @param string $title
|
||||
* @param string $description
|
||||
*/
|
||||
public function __construct( $post, $title, $description ) {
|
||||
$this->options = WPSEO_Options::get_all();
|
||||
$this->post = $post;
|
||||
$this->title = esc_html( $title );
|
||||
$this->description = esc_html( $description );
|
||||
/**
|
||||
* Generates the html for the snippet preview containing dynamically generated text components.
|
||||
* Those components are included as properties which are set in the constructor.
|
||||
*
|
||||
* @param object $post
|
||||
* @param string $title
|
||||
* @param string $description
|
||||
*/
|
||||
public function __construct( $post, $title, $description ) {
|
||||
$this->options = WPSEO_Options::get_all();
|
||||
$this->post = $post;
|
||||
$this->title = esc_html( $title );
|
||||
$this->description = esc_html( $description );
|
||||
|
||||
$this->set_date();
|
||||
$this->set_url();
|
||||
$this->set_content();
|
||||
$this->set_date();
|
||||
$this->set_url();
|
||||
$this->set_content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for $this->content
|
||||
* @return string html for snippet preview
|
||||
*/
|
||||
public function get_content() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets date if available
|
||||
*/
|
||||
protected function set_date() {
|
||||
if ( is_object( $this->post ) && isset( $this->options[ 'showdate-' . $this->post->post_type ] ) && $this->options[ 'showdate-' . $this->post->post_type ] === true ) {
|
||||
$date = $this->get_post_date();
|
||||
$this->date = '<span class="date">' . $date . ' - </span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a post date when post is published, or return current date when it's not.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_post_date() {
|
||||
if ( isset( $this->post->post_date ) && $this->post->post_status == 'publish' ) {
|
||||
$date = date_i18n( 'j M Y', strtotime( $this->post->post_date ) );
|
||||
}
|
||||
else {
|
||||
$date = date_i18n( 'j M Y' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for $this->content
|
||||
* @return string html for snippet preview
|
||||
*/
|
||||
public function get_content() {
|
||||
return $this->content;
|
||||
return (string) $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the url that is displayed in the snippet preview.
|
||||
*/
|
||||
protected function set_url() {
|
||||
$this->url = str_replace( array( 'http://', 'https://' ), '', get_bloginfo( 'url' ) ) . '/';
|
||||
$this->set_slug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the slug and adds it to the url if the post has been published and the post name exists.
|
||||
*
|
||||
* If the post is set to be the homepage the slug is also not included.
|
||||
*/
|
||||
protected function set_slug() {
|
||||
$frontpage_post_id = (int) ( get_option( 'page_on_front' ) );
|
||||
|
||||
if ( is_object( $this->post ) && isset( $this->post->post_name ) && $this->post->post_name !== '' && $this->post->ID !== $frontpage_post_id ) {
|
||||
$this->slug = sanitize_title( $this->title );
|
||||
$this->url .= esc_html( $this->slug );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets date if available
|
||||
*/
|
||||
protected function set_date() {
|
||||
if ( is_object( $this->post ) && isset( $this->options['showdate-' . $this->post->post_type] ) && $this->options['showdate-' . $this->post->post_type] === true ) {
|
||||
$date = $this->get_post_date();
|
||||
$this->date = '<span class="date">' . $date . ' - </span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a post date when post is published, or return current date when it's not.
|
||||
*
|
||||
* @param object $post Post to retrieve the date for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_post_date() {
|
||||
if ( isset( $this->post->post_date ) && $this->post->post_status == 'publish' ) {
|
||||
$date = date_i18n( 'j M Y', strtotime( $this->post->post_date ) );
|
||||
} else {
|
||||
$date = date_i18n( 'j M Y' );
|
||||
}
|
||||
|
||||
return (string) $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the url that is displayed in the snippet preview.
|
||||
*/
|
||||
protected function set_url() {
|
||||
$this->url = str_replace( array( 'http://', 'https://' ), '', get_bloginfo( 'url' ) ) . '/';
|
||||
$this->set_slug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the slug and adds it to the url if the post has been published and the post name exists.
|
||||
*
|
||||
* If the post is set to be the homepage the slug is also not included.
|
||||
*/
|
||||
protected function set_slug() {
|
||||
$frontpage_post_id = (int) ( get_option( 'page_on_front' ) );
|
||||
|
||||
if ( is_object( $this->post ) && isset( $this->post->post_name ) && $this->post->post_name !== '' && $this->post->ID !== $frontpage_post_id ) {
|
||||
$this->slug = sanitize_title( $this->title );
|
||||
$this->url .= esc_html( $this->slug );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the html for the snippet preview and assign it to $this->content.
|
||||
*/
|
||||
protected function set_content() {
|
||||
$content = <<<HTML
|
||||
/**
|
||||
* Generates the html for the snippet preview and assign it to $this->content.
|
||||
*/
|
||||
protected function set_content() {
|
||||
$content = <<<HTML
|
||||
<div id="wpseosnippet">
|
||||
<a class="title" id="wpseosnippet_title" href="#">$this->title</a>
|
||||
<span class="url">$this->url</span>
|
||||
<p class="desc">$this->date<span class="autogen"></span><span class="content">$this->description</span></p>
|
||||
</div>
|
||||
HTML;
|
||||
$this->set_content_through_filter( $content );
|
||||
}
|
||||
$this->set_content_through_filter( $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the html for the snippet preview through a filter
|
||||
*
|
||||
* @param string $content
|
||||
*/
|
||||
protected function set_content_through_filter( $content ) {
|
||||
$properties = get_object_vars( $this );
|
||||
|
||||
// Backward compatibility for functions hooking into the wpseo_snippet filter
|
||||
$properties['desc'] = $properties['description'];
|
||||
|
||||
/**
|
||||
* Sets the html for the snippet preview through a filter
|
||||
* Filter: 'wpseo_snippet' - Allow changing the html for the snippet preview.
|
||||
*
|
||||
* Passing in the post twice because of backwards compatibility.
|
||||
*/
|
||||
protected function set_content_through_filter( $content ) {
|
||||
$properties = get_object_vars( $this );
|
||||
|
||||
/**
|
||||
* Filter: 'wpseo_snippet' - Allow changing the html for the snippet preview.
|
||||
*
|
||||
* Passing in the post twice because of backwards compatibility.
|
||||
*/
|
||||
$this->content = apply_filters( 'wpseo_snippet', $content, $this->post, $properties );
|
||||
}
|
||||
$this->content = apply_filters( 'wpseo_snippet', $content, $this->post, $properties );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO
|
||||
* @subpackage Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Facebook insights class, this will add some listeners to fetch GET params
|
||||
*/
|
||||
class Yoast_Social_Facebook {
|
||||
|
||||
/**
|
||||
* @var array - The options for social
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Setting the options and define the listener to fetch $_GET values
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->options = get_option( 'wpseo_social' );
|
||||
|
||||
$this->get_listener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output from the form class
|
||||
*
|
||||
*/
|
||||
public function show_form() {
|
||||
$form = new Yoast_Social_Facebook_Form();
|
||||
$form->show_form();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will hook into the defined get params
|
||||
*
|
||||
*/
|
||||
private function get_listener() {
|
||||
if ( $delfbadmin = filter_input( INPUT_GET, 'delfbadmin' ) ) {
|
||||
$this->delete_admin( $delfbadmin );
|
||||
}
|
||||
elseif ( filter_input( INPUT_GET, 'fbclearall' ) ) {
|
||||
$this->clear_all();
|
||||
}
|
||||
elseif ( $key = filter_input( INPUT_GET, 'key' ) ) {
|
||||
$this->handle_user( $key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the admin from the options
|
||||
*
|
||||
* @param string $delfbadmin
|
||||
*/
|
||||
private function delete_admin( $delfbadmin ) {
|
||||
$this->verify_nonce( 'delfbadmin' );
|
||||
|
||||
$admin_id = sanitize_text_field( $delfbadmin );
|
||||
if ( isset( $this->options['fb_admins'][ $admin_id ] ) ) {
|
||||
$fbadmin = $this->options['fb_admins'][ $admin_id ]['name'];
|
||||
unset( $this->options['fb_admins'][ $admin_id ] );
|
||||
|
||||
$this->save_options();
|
||||
$this->success_notice( sprintf( __( 'Successfully removed admin %s', 'wordpress-seo' ), $fbadmin ) );
|
||||
|
||||
unset( $fbadmin );
|
||||
}
|
||||
|
||||
unset( $admin_id );
|
||||
|
||||
// Clean up the referrer url for later use
|
||||
if ( filter_input( INPUT_SERVER, 'REQUEST_URI' ) ) {
|
||||
$this->cleanup_referrer_url( 'nonce', 'delfbadmin' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all the facebook that has been set already
|
||||
*
|
||||
*/
|
||||
private function clear_all() {
|
||||
$this->verify_nonce( 'fbclearall' );
|
||||
|
||||
// Reset to defaults, don't unset as otherwise the old values will be retained
|
||||
$this->options['fb_admins'] = WPSEO_Options::get_default( 'wpseo_social', 'fb_admins' );
|
||||
|
||||
$this->save_options();
|
||||
$this->success_notice( __( 'Successfully cleared all Facebook Data', 'wordpress-seo' ) );
|
||||
|
||||
// Clean up the referrer url for later use
|
||||
if ( filter_input( INPUT_SERVER, 'REQUEST_URI' ) ) {
|
||||
$this->cleanup_referrer_url( 'nonce', 'fbclearall' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adding a new facebook admin
|
||||
*
|
||||
* @param string $key_value
|
||||
*/
|
||||
private function handle_user( $key_value ) {
|
||||
if ( $key_value === $this->options['fbconnectkey'] && $user_id = filter_input( INPUT_GET, 'userid', FILTER_CALLBACK, array( 'options' => 'sanitize_text_field' ) ) ) {
|
||||
if ( ! isset( $this->options['fb_admins'][ $user_id ] ) ) {
|
||||
$this->options['fb_admins'][ $user_id ]['name'] = sanitize_text_field( urldecode( filter_input( INPUT_GET, 'userrealname' ) ) );
|
||||
$this->options['fb_admins'][ $user_id ]['link'] = sanitize_text_field( urldecode( filter_input( INPUT_GET, 'link' ) ) );
|
||||
|
||||
$this->save_options();
|
||||
$this->success_notice(
|
||||
sprintf( __( 'Successfully added %s as a Facebook Admin!', 'wordpress-seo' ), '<a href="' . esc_url( $this->options['fb_admins'][ $user_id ]['link'] ) . '">' . esc_html( $this->options['fb_admins'][ $user_id ]['name'] ) . '</a>' )
|
||||
);
|
||||
}
|
||||
else {
|
||||
add_settings_error(
|
||||
'yoast_wpseo_social_options',
|
||||
'error',
|
||||
sprintf(
|
||||
__( '%s already exists as a Facebook Admin.', 'wordpress-seo' ),
|
||||
'<a href="' . esc_url( $this->options['fb_admins'][ $user_id ]['link'] ) . '">' . esc_html( $this->options['fb_admins'][ $user_id ]['name'] ) . '</a>'
|
||||
),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
|
||||
unset( $user_id );
|
||||
}
|
||||
|
||||
// Clean up the referrer url for later use
|
||||
if ( filter_input( INPUT_SERVER, 'REQUEST_URI' ) ) {
|
||||
$this->cleanup_referrer_url( 'key', 'userid', 'userrealname', 'link' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the request_uri. The given params are the params that will be removed from the URL
|
||||
*/
|
||||
private function cleanup_referrer_url() {
|
||||
$_SERVER['REQUEST_URI'] = remove_query_arg(
|
||||
func_get_args(),
|
||||
filter_input(
|
||||
INPUT_SERVER, 'REQUEST_URI', FILTER_CALLBACK, array( 'options' => 'sanitize_text_field' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When something is going well, show a success notice
|
||||
*
|
||||
* @param string $notice_text
|
||||
*/
|
||||
private function success_notice( $notice_text ) {
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'success', $notice_text, 'updated' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the nonce from the URL with the saved nonce
|
||||
*
|
||||
* @param string $nonce_name
|
||||
*/
|
||||
private function verify_nonce( $nonce_name ) {
|
||||
if ( wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), $nonce_name ) != 1 ) {
|
||||
die( "I don't think that's really nice of you!." );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving the options
|
||||
*/
|
||||
private function save_options() {
|
||||
update_option( 'wpseo_social', $this->options );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This will display the HTML for the facebook insights part
|
||||
*/
|
||||
class Yoast_Social_Facebook_Form {
|
||||
|
||||
/**
|
||||
* @var array - The options for social
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @var array - The repository for the buttons that will be shown
|
||||
*/
|
||||
private $buttons = array();
|
||||
|
||||
/**
|
||||
* @var string - The URL to link to
|
||||
*/
|
||||
private $admin_url = 'admin.php?page=wpseo_social';
|
||||
|
||||
/**
|
||||
* Setting the options and call the methods to display everything
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->options = get_option( 'wpseo_social' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output-property
|
||||
*/
|
||||
public function show_form() {
|
||||
$this
|
||||
->form_head()
|
||||
->manage_user_admin()
|
||||
->show_buttons()
|
||||
->manage_app_as_admin();
|
||||
}
|
||||
|
||||
/**
|
||||
* SHow the top of the social insights part of the page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function form_head() {
|
||||
echo '<p><strong>' . esc_html__( 'Facebook Insights and Admins', 'wordpress-seo' ) . '</strong><br />';
|
||||
echo sprintf(
|
||||
esc_html__(
|
||||
'To be able to access %sFacebook Insights%s for your site, you need to specify a Facebook Admin. This can be a user. If you have an app for your site, you could use that as well.', 'wordpress-seo'
|
||||
),
|
||||
'<a href="https://www.facebook.com/insights">',
|
||||
'</a>'
|
||||
);
|
||||
echo'</p>';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the buttons to add an admin or add another admin from Facebook and display the admin that has been added already.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function manage_user_admin() {
|
||||
$button_text = __( 'Add Facebook Admin', 'wordpress-seo' );
|
||||
|
||||
if ( is_array( $this->options['fb_admins'] ) && $this->options['fb_admins'] !== array() ) {
|
||||
$nonce = wp_create_nonce( 'delfbadmin' );
|
||||
$button_text = __( 'Add Another Facebook Admin', 'wordpress-seo' );
|
||||
|
||||
echo '<p>' . __( 'Currently connected Facebook admins:', 'wordpress-seo' ) . '</p>';
|
||||
echo '<ul>';
|
||||
$this->show_user_admins( $nonce );
|
||||
echo '</ul>';
|
||||
|
||||
unset( $admin_id, $admin, $nonce );
|
||||
}
|
||||
|
||||
$this->add_button(
|
||||
'https://yoast.com/fb-connect/?key=' . urlencode( $this->options['fbconnectkey'] ) . '&redirect=' . urlencode( admin_url( $this->admin_url ) ),
|
||||
$button_text,'',
|
||||
true
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show input field to set a facebook apps as an admin
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function manage_app_as_admin() {
|
||||
echo '<div class="clear"></div><br />';
|
||||
Yoast_Form::get_instance()->textinput( 'fbadminapp', __( 'Facebook App ID', 'wordpress-seo' ) );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through the fb-admins to parse the output for them
|
||||
*
|
||||
* @param string $nonce
|
||||
*/
|
||||
private function show_user_admins( $nonce ) {
|
||||
foreach ( $this->options['fb_admins'] as $admin_id => $admin ) {
|
||||
echo '<li><a href="' . esc_url( $admin['link'] ) . '">' . esc_html( $admin['name'] ) . '</a>';
|
||||
echo ' - <strong><a href="' . $this->admin_delete_link( $admin_id, $nonce ) . '">X</a></strong></li>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsing the link that directs to the admin removal
|
||||
*
|
||||
* @param string $admin_id
|
||||
* @param string $nonce
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function admin_delete_link( $admin_id, $nonce ) {
|
||||
return esc_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'delfbadmin' => esc_attr( $admin_id ),
|
||||
'nonce' => $nonce,
|
||||
),
|
||||
admin_url( $this->admin_url . '#top#facebook' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adding a button to the button property
|
||||
*
|
||||
* @param string $button_url
|
||||
* @param string $button_value
|
||||
* @param string $button_class
|
||||
* @param string $button_id
|
||||
*/
|
||||
private function add_button( $button_url, $button_value, $button_class = '', $button_id = '' ) {
|
||||
$this->buttons[] = '<a id="' .esc_attr( $button_id ). '" class="button' . esc_attr( $button_class ) . '" href="' . esc_url( $button_url ) . '">' . esc_html( $button_value ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Showing the buttons
|
||||
*/
|
||||
private function show_buttons() {
|
||||
if ( $this->get_clearall() ) {
|
||||
$this->add_button(
|
||||
esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'fbclearall' ), 'fbclearall' => 'true', ), admin_url( $this->admin_url . '#top#facebook' ) ) ),
|
||||
__( 'Clear all Facebook Data', 'wordpress-seo' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( is_array( $this->buttons ) && $this->buttons !== array() ) {
|
||||
echo '<p class="fb-buttons">' . implode( '', $this->buttons ) . '</p>';
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the clear button should be displayed. This is based on the the set options
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function get_clearall() {
|
||||
return is_array( $this->options['fb_admins'] ) && $this->options['fb_admins'] !== array();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,285 +1,296 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Class that handles the edit boxes on taxonomy edit pages.
|
||||
*/
|
||||
class WPSEO_Taxonomy {
|
||||
|
||||
|
||||
if ( ! class_exists( 'WPSEO_Taxonomy' ) ) {
|
||||
/**
|
||||
* Class that handles the edit boxes on taxonomy edit pages.
|
||||
* @var array Options array for the no-index options, including translated labels
|
||||
*/
|
||||
class WPSEO_Taxonomy {
|
||||
public $no_index_options = array();
|
||||
|
||||
/**
|
||||
* @var array Options array for the no-index options, including translated labels
|
||||
*/
|
||||
public $no_index_options = array();
|
||||
/**
|
||||
* @var array Options array for the sitemap_include options, including translated labels
|
||||
*/
|
||||
public $sitemap_include_options = array();
|
||||
|
||||
/**
|
||||
* @var array Options array for the sitemap_include options, including translated labels
|
||||
*/
|
||||
public $sitemap_include_options = array();
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
function __construct() {
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
function __construct() {
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
if ( is_admin() && ( isset( $_GET['taxonomy'] ) && $_GET['taxonomy'] !== '' ) &&
|
||||
( ! isset( $options[ 'hideeditbox-tax-' . $_GET['taxonomy'] ] ) || $options[ 'hideeditbox-tax-' . $_GET['taxonomy'] ] === false )
|
||||
) {
|
||||
add_action( sanitize_text_field( $_GET['taxonomy'] ) . '_edit_form', array( $this, 'term_seo_form' ), 90, 1 );
|
||||
}
|
||||
|
||||
add_action( 'edit_term', array( $this, 'update_term' ), 99, 3 );
|
||||
|
||||
add_action( 'init', array( $this, 'custom_category_descriptions_allow_html' ) );
|
||||
add_filter( 'category_description', array( $this, 'custom_category_descriptions_add_shortcode_support' ) );
|
||||
add_action( 'admin_init', array( $this, 'translate_meta_options' ) );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
if ( is_admin() && ( isset( $_GET['taxonomy'] ) && $_GET['taxonomy'] !== '' ) &&
|
||||
( ! isset( $options[ 'hideeditbox-tax-' . $_GET['taxonomy'] ] ) || $options[ 'hideeditbox-tax-' . $_GET['taxonomy'] ] === false )
|
||||
) {
|
||||
add_action( sanitize_text_field( $_GET['taxonomy'] ) . '_edit_form', array(
|
||||
$this,
|
||||
'term_seo_form',
|
||||
), 90, 1 );
|
||||
}
|
||||
|
||||
add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 );
|
||||
add_action( 'edit_term', array( $this, 'update_term' ), 99, 3 );
|
||||
|
||||
/**
|
||||
* Translate options text strings for use in the select fields
|
||||
*
|
||||
* @internal IMPORTANT: if you want to add a new string (option) somewhere, make sure you add
|
||||
* that array key to the main options definition array in the class WPSEO_Taxonomy_Meta() as well!!!!
|
||||
*/
|
||||
public function translate_meta_options() {
|
||||
$this->no_index_options = WPSEO_Taxonomy_Meta::$no_index_options;
|
||||
$this->sitemap_include_options = WPSEO_Taxonomy_Meta::$sitemap_include_options;
|
||||
add_action( 'init', array( $this, 'custom_category_descriptions_allow_html' ) );
|
||||
add_filter( 'category_description', array( $this, 'custom_category_descriptions_add_shortcode_support' ) );
|
||||
add_action( 'admin_init', array( $this, 'translate_meta_options' ) );
|
||||
|
||||
$this->no_index_options['default'] = __( 'Use %s default (Currently: %s)', 'wordpress-seo' );
|
||||
$this->no_index_options['index'] = __( 'Always index', 'wordpress-seo' );
|
||||
$this->no_index_options['noindex'] = __( 'Always noindex', 'wordpress-seo' );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
}
|
||||
|
||||
$this->sitemap_include_options['-'] = __( 'Auto detect', 'wordpress-seo' );
|
||||
$this->sitemap_include_options['always'] = __( 'Always include', 'wordpress-seo' );
|
||||
$this->sitemap_include_options['never'] = __( 'Never include', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test whether we are on a public taxonomy - no metabox actions needed if we are not
|
||||
* Unfortunately we have to hook most everything in before the point where all taxonomies are registered and
|
||||
* we know which taxonomy is being requested, so we need to use this check in nearly every hooked in function.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
function tax_is_public() {
|
||||
// Don't make static as taxonomies may still be added during the run
|
||||
$taxonomies = get_taxonomies( array( 'public' => true ), 'names' );
|
||||
|
||||
return ( isset( $_GET['taxonomy'] ) && in_array( $_GET['taxonomy'], $taxonomies ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add our admin css file
|
||||
*/
|
||||
function admin_enqueue_scripts() {
|
||||
global $pagenow;
|
||||
|
||||
if ( $pagenow === 'edit-tags.php' && ( isset( $_GET['action'] ) && $_GET['action'] === 'edit' ) ) {
|
||||
wp_enqueue_style( 'yoast-taxonomy-css', plugins_url( 'css/taxonomy-meta' . WPSEO_CSSJS_SUFFIX . '.css', WPSEO_FILE ), array(), WPSEO_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a row in the form table.
|
||||
*
|
||||
* @param string $var Variable the row controls.
|
||||
* @param string $label Label for the variable.
|
||||
* @param string $desc Description of the use of the variable.
|
||||
* @param array $tax_meta Taxonomy meta value.
|
||||
* @param string $type Type of form row to create.
|
||||
* @param array $options Options to use when form row is a select box.
|
||||
*/
|
||||
function form_row( $var, $label, $desc, $tax_meta, $type = 'text', $options = array() ) {
|
||||
$val = '';
|
||||
if ( isset( $tax_meta[ $var ] ) && $tax_meta[ $var ] !== '' ) {
|
||||
$val = $tax_meta[ $var ];
|
||||
}
|
||||
|
||||
$esc_var = esc_attr( $var );
|
||||
$field = '';
|
||||
|
||||
if ( $type == 'text' ) {
|
||||
$field .= '
|
||||
<input name="' . $esc_var . '" id="' . $esc_var . '" type="text" value="' . esc_attr( $val ) . '" size="40"/>';
|
||||
}
|
||||
elseif ( $type == 'checkbox' ) {
|
||||
$field .= '
|
||||
<input name="' . $esc_var . '" id="' . $esc_var . '" type="checkbox" ' . checked( $val ) . '/>';
|
||||
}
|
||||
elseif ( $type == 'select' ) {
|
||||
if ( is_array( $options ) && $options !== array() ) {
|
||||
$field .= '
|
||||
<select name="' . $esc_var . '" id="' . $esc_var . '">';
|
||||
|
||||
foreach ( $options as $option => $option_label ) {
|
||||
$selected = selected( $option, $val, false );
|
||||
$field .= '
|
||||
<option ' . $selected . ' value="' . esc_attr( $option ) . '">' . esc_html( $option_label ) . '</option>';
|
||||
}
|
||||
|
||||
$field .= '
|
||||
</select>';
|
||||
}
|
||||
}
|
||||
elseif ( $type == 'hidden' ) {
|
||||
$field .= '
|
||||
<input name="' . $esc_var . '" id="hidden_' . $esc_var . '" type="hidden" value="' . esc_attr( $val ) . '" />';
|
||||
}
|
||||
|
||||
if ( $field !== '' && ( is_string( $desc ) && $desc !== '' ) ) {
|
||||
$field .= '
|
||||
<p class="description">' . $desc . '</p>';
|
||||
}
|
||||
|
||||
echo '
|
||||
<tr class="form-field">
|
||||
<th scope="row">' . ( '' !== $label ? '<label for="' . $esc_var . '">' . esc_html( $label ) . ':</label>' : '' ) . '</th>
|
||||
<td>' . $field . '</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the SEO inputs for term.
|
||||
*
|
||||
* @param object $term Term to show the edit boxes for.
|
||||
*/
|
||||
function term_seo_form( $term ) {
|
||||
if ( $this->tax_is_public() === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tax_meta = WPSEO_Taxonomy_Meta::get_term_meta( (int) $term->term_id, $term->taxonomy );
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
|
||||
echo '<h2>' . __( 'Yoast WordPress SEO Settings', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<table class="form-table wpseo-taxonomy-form">';
|
||||
|
||||
$this->form_row( 'wpseo_title', __( 'SEO Title', 'wordpress-seo' ), esc_html__( 'The SEO title is used on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
$this->form_row( 'wpseo_desc', __( 'SEO Description', 'wordpress-seo' ), esc_html__( 'The SEO description is used for the meta description on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
$this->form_row( 'wpseo_metakey', __( 'Meta keywords', 'wordpress-seo' ), esc_html__( 'Meta keywords used on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
}
|
||||
|
||||
$this->form_row( 'wpseo_canonical', __( 'Canonical', 'wordpress-seo' ), esc_html__( 'The canonical link is shown on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
|
||||
if ( $options['breadcrumbs-enable'] === true ) {
|
||||
$this->form_row( 'wpseo_bctitle', __( 'Breadcrumbs title', 'wordpress-seo' ), sprintf( esc_html__( 'The Breadcrumbs title is used in the breadcrumbs where this %s appears.', 'wordpress-seo' ), $term->taxonomy ), $tax_meta );
|
||||
}
|
||||
|
||||
$current = 'index';
|
||||
if ( isset( $options[ 'noindex-tax-' . $term->taxonomy ] ) && $options[ 'noindex-tax-' . $term->taxonomy ] === true ) {
|
||||
$current = 'noindex';
|
||||
}
|
||||
|
||||
$noindex_options = $this->no_index_options;
|
||||
$noindex_options['default'] = sprintf( $noindex_options['default'], $term->taxonomy, $current );
|
||||
|
||||
$desc = sprintf( esc_html__( 'This %s follows the indexation rules set under Metas and Titles, you can override it here.', 'wordpress-seo' ), $term->taxonomy );
|
||||
if ( '0' == get_option( 'blog_public' ) ) {
|
||||
$desc .= '<br /><span class="error-message">' . esc_html__( 'Warning: even though you can set the meta robots setting here, the entire site is set to noindex in the sitewide privacy settings, so these settings won\'t have an effect.', 'wordpress-seo' ) . '</span>';
|
||||
}
|
||||
|
||||
$this->form_row( 'wpseo_noindex', sprintf( __( 'Noindex this %s', 'wordpress-seo' ), $term->taxonomy ), $desc, $tax_meta, 'select', $noindex_options );
|
||||
unset( $current, $no_index_options, $desc );
|
||||
|
||||
|
||||
$this->form_row( 'wpseo_sitemap_include', __( 'Include in sitemap?', 'wordpress-seo' ), '', $tax_meta, 'select', $this->sitemap_include_options );
|
||||
|
||||
echo '</table>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the taxonomy meta data on save.
|
||||
*
|
||||
* @param int $term_id ID of the term to save data for
|
||||
* @param int $tt_id The taxonomy_term_id for the term.
|
||||
* @param string $taxonomy The taxonomy the term belongs to.
|
||||
*/
|
||||
function update_term( $term_id, $tt_id, $taxonomy ) {
|
||||
$tax_meta = get_option( 'wpseo_taxonomy_meta' );
|
||||
|
||||
/* Create post array with only our values */
|
||||
$new_meta_data = array();
|
||||
foreach ( WPSEO_Taxonomy_Meta::$defaults_per_term as $key => $default ) {
|
||||
if ( isset( $_POST[ $key ] ) ) {
|
||||
$new_meta_data[ $key ] = $_POST[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate the post values */
|
||||
$old = WPSEO_Taxonomy_Meta::get_term_meta( $term_id, $taxonomy );
|
||||
$clean = WPSEO_Taxonomy_Meta::validate_term_meta_data( $new_meta_data, $old );
|
||||
|
||||
/* Add/remove the result to/from the original option value */
|
||||
if ( $clean !== array() ) {
|
||||
$tax_meta[ $taxonomy ][ $term_id ] = $clean;
|
||||
}
|
||||
else {
|
||||
unset( $tax_meta[ $taxonomy ][ $term_id ] );
|
||||
if ( isset( $tax_meta[ $taxonomy ] ) && $tax_meta[ $taxonomy ] === array() ) {
|
||||
unset( $tax_meta[ $taxonomy ] );
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent complete array validation
|
||||
$tax_meta['wpseo_already_validated'] = true;
|
||||
/**
|
||||
* Makes sure the taxonomy meta is updated when a taxonomy term is split.
|
||||
*
|
||||
* @link https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/ Article explaining the taxonomy term splitting in WP 4.2
|
||||
*
|
||||
* @param string $old_term_id Old term id of the taxonomy term that was splitted.
|
||||
* @param string $new_term_id New term id of the taxonomy term that was splitted.
|
||||
* @param string $term_taxonomy_id Term taxonomy id for the taxonomy that was affected.
|
||||
* @param string $taxonomy The taxonomy that the taxonomy term was splitted for.
|
||||
*/
|
||||
public function split_shared_term( $old_term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
|
||||
$tax_meta = get_option( 'wpseo_taxonomy_meta', array() );
|
||||
|
||||
if ( ! empty( $tax_meta[ $taxonomy ][ $old_term_id ] ) ) {
|
||||
$tax_meta[ $taxonomy ][ $new_term_id ] = $tax_meta[ $taxonomy ][ $old_term_id ];
|
||||
unset( $tax_meta[ $taxonomy ][ $old_term_id ]);
|
||||
update_option( 'wpseo_taxonomy_meta', $tax_meta );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate options text strings for use in the select fields
|
||||
*
|
||||
* @internal IMPORTANT: if you want to add a new string (option) somewhere, make sure you add
|
||||
* that array key to the main options definition array in the class WPSEO_Taxonomy_Meta() as well!!!!
|
||||
*/
|
||||
public function translate_meta_options() {
|
||||
$this->no_index_options = WPSEO_Taxonomy_Meta::$no_index_options;
|
||||
$this->sitemap_include_options = WPSEO_Taxonomy_Meta::$sitemap_include_options;
|
||||
|
||||
$this->no_index_options['default'] = __( 'Use %s default (Currently: %s)', 'wordpress-seo' );
|
||||
$this->no_index_options['index'] = __( 'Always index', 'wordpress-seo' );
|
||||
$this->no_index_options['noindex'] = __( 'Always noindex', 'wordpress-seo' );
|
||||
|
||||
$this->sitemap_include_options['-'] = __( 'Auto detect', 'wordpress-seo' );
|
||||
$this->sitemap_include_options['always'] = __( 'Always include', 'wordpress-seo' );
|
||||
$this->sitemap_include_options['never'] = __( 'Never include', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allows HTML in descriptions
|
||||
*/
|
||||
function custom_category_descriptions_allow_html() {
|
||||
$filters = array(
|
||||
'pre_term_description',
|
||||
'pre_link_description',
|
||||
'pre_link_notes',
|
||||
'pre_user_description',
|
||||
);
|
||||
/**
|
||||
* Test whether we are on a public taxonomy - no metabox actions needed if we are not
|
||||
* Unfortunately we have to hook most everything in before the point where all taxonomies are registered and
|
||||
* we know which taxonomy is being requested, so we need to use this check in nearly every hooked in function.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
function tax_is_public() {
|
||||
// Don't make static as taxonomies may still be added during the run
|
||||
$taxonomies = get_taxonomies( array( 'public' => true ), 'names' );
|
||||
|
||||
foreach ( $filters as $filter ) {
|
||||
remove_filter( $filter, 'wp_filter_kses' );
|
||||
return ( isset( $_GET['taxonomy'] ) && in_array( $_GET['taxonomy'], $taxonomies ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add our admin css file
|
||||
*/
|
||||
function admin_enqueue_scripts() {
|
||||
if ( $GLOBALS['pagenow'] === 'edit-tags.php' && ( isset( $_GET['action'] ) && $_GET['action'] === 'edit' ) ) {
|
||||
wp_enqueue_style( 'yoast-taxonomy-css', plugins_url( 'css/taxonomy-meta' . WPSEO_CSSJS_SUFFIX . '.css', WPSEO_FILE ), array(), WPSEO_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a row in the form table.
|
||||
*
|
||||
* @param string $var Variable the row controls.
|
||||
* @param string $label Label for the variable.
|
||||
* @param string $desc Description of the use of the variable.
|
||||
* @param array $tax_meta Taxonomy meta value.
|
||||
* @param string $type Type of form row to create.
|
||||
* @param array $options Options to use when form row is a select box.
|
||||
*/
|
||||
function form_row( $var, $label, $desc, $tax_meta, $type = 'text', $options = array() ) {
|
||||
$val = '';
|
||||
if ( isset( $tax_meta[ $var ] ) && $tax_meta[ $var ] !== '' ) {
|
||||
$val = $tax_meta[ $var ];
|
||||
}
|
||||
|
||||
$esc_var = esc_attr( $var );
|
||||
$field = '';
|
||||
|
||||
if ( $type == 'text' ) {
|
||||
$field .= '
|
||||
<input name="' . $esc_var . '" id="' . $esc_var . '" type="text" value="' . esc_attr( $val ) . '" size="40"/>';
|
||||
}
|
||||
elseif ( $type == 'checkbox' ) {
|
||||
$field .= '
|
||||
<input name="' . $esc_var . '" id="' . $esc_var . '" type="checkbox" ' . checked( $val ) . '/>';
|
||||
}
|
||||
elseif ( $type == 'select' ) {
|
||||
if ( is_array( $options ) && $options !== array() ) {
|
||||
$field .= '
|
||||
<select name="' . $esc_var . '" id="' . $esc_var . '">';
|
||||
|
||||
foreach ( $options as $option => $option_label ) {
|
||||
$selected = selected( $option, $val, false );
|
||||
$field .= '
|
||||
<option ' . $selected . ' value="' . esc_attr( $option ) . '">' . esc_html( $option_label ) . '</option>';
|
||||
}
|
||||
unset( $option, $option_label, $selected );
|
||||
|
||||
$field .= '
|
||||
</select>';
|
||||
}
|
||||
remove_filter( 'term_description', 'wp_kses_data' );
|
||||
}
|
||||
elseif ( $type == 'hidden' ) {
|
||||
$field .= '
|
||||
<input name="' . $esc_var . '" id="hidden_' . $esc_var . '" type="hidden" value="' . esc_attr( $val ) . '" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds shortcode support to category descriptions.
|
||||
*
|
||||
* @param string $desc String to add shortcodes in.
|
||||
* @return string
|
||||
*/
|
||||
function custom_category_descriptions_add_shortcode_support( $desc ) {
|
||||
// Wrap in output buffering to prevent shortcodes that echo stuff instead of return from breaking things.
|
||||
ob_start();
|
||||
$desc = do_shortcode( $desc );
|
||||
ob_end_clean();
|
||||
|
||||
return $desc;
|
||||
if ( $field !== '' && ( is_string( $desc ) && $desc !== '' ) ) {
|
||||
$field .= '
|
||||
<p class="description">' . $desc . '</p>';
|
||||
}
|
||||
} /* End of class */
|
||||
|
||||
} /* End of class-exists wrapper */
|
||||
echo '
|
||||
<tr class="form-field">
|
||||
<th scope="row">' . ( ( '' !== $label ) ? '<label for="' . $esc_var . '">' . esc_html( $label ) . ':</label>' : '' ) . '</th>
|
||||
<td>' . $field . '</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the SEO inputs for term.
|
||||
*
|
||||
* @param object $term Term to show the edit boxes for.
|
||||
*/
|
||||
function term_seo_form( $term ) {
|
||||
if ( $this->tax_is_public() === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tax_meta = WPSEO_Taxonomy_Meta::get_term_meta( (int) $term->term_id, $term->taxonomy );
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
|
||||
echo '<h2>', __( 'Yoast WordPress SEO Settings', 'wordpress-seo' ), '</h2>';
|
||||
echo '<table class="form-table wpseo-taxonomy-form">';
|
||||
|
||||
$this->form_row( 'wpseo_title', __( 'SEO Title', 'wordpress-seo' ), esc_html__( 'The SEO title is used on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
$this->form_row( 'wpseo_desc', __( 'SEO Description', 'wordpress-seo' ), esc_html__( 'The SEO description is used for the meta description on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
$this->form_row( 'wpseo_metakey', __( 'Meta keywords', 'wordpress-seo' ), esc_html__( 'Meta keywords used on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
}
|
||||
|
||||
$this->form_row( 'wpseo_canonical', __( 'Canonical', 'wordpress-seo' ), esc_html__( 'The canonical link is shown on the archive page for this term.', 'wordpress-seo' ), $tax_meta );
|
||||
|
||||
if ( $options['breadcrumbs-enable'] === true ) {
|
||||
$this->form_row( 'wpseo_bctitle', __( 'Breadcrumbs title', 'wordpress-seo' ), sprintf( esc_html__( 'The Breadcrumbs title is used in the breadcrumbs where this %s appears.', 'wordpress-seo' ), $term->taxonomy ), $tax_meta );
|
||||
}
|
||||
|
||||
$current = 'index';
|
||||
if ( isset( $options[ 'noindex-tax-' . $term->taxonomy ] ) && $options[ 'noindex-tax-' . $term->taxonomy ] === true ) {
|
||||
$current = 'noindex';
|
||||
}
|
||||
|
||||
$noindex_options = $this->no_index_options;
|
||||
$noindex_options['default'] = sprintf( $noindex_options['default'], $term->taxonomy, $current );
|
||||
|
||||
$desc = sprintf( esc_html__( 'This %s follows the indexation rules set under Metas and Titles, you can override it here.', 'wordpress-seo' ), $term->taxonomy );
|
||||
if ( '0' == get_option( 'blog_public' ) ) {
|
||||
$desc .= '<br /><span class="error-message">' . esc_html__( 'Warning: even though you can set the meta robots setting here, the entire site is set to noindex in the sitewide privacy settings, so these settings won\'t have an effect.', 'wordpress-seo' ) . '</span>';
|
||||
}
|
||||
|
||||
$this->form_row( 'wpseo_noindex', sprintf( __( 'Noindex this %s', 'wordpress-seo' ), $term->taxonomy ), $desc, $tax_meta, 'select', $noindex_options );
|
||||
unset( $current, $no_index_options, $desc );
|
||||
|
||||
|
||||
$this->form_row( 'wpseo_sitemap_include', __( 'Include in sitemap?', 'wordpress-seo' ), '', $tax_meta, 'select', $this->sitemap_include_options );
|
||||
|
||||
echo '</table>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the taxonomy meta data on save.
|
||||
*
|
||||
* @param int $term_id ID of the term to save data for
|
||||
* @param int $tt_id The taxonomy_term_id for the term.
|
||||
* @param string $taxonomy The taxonomy the term belongs to.
|
||||
*/
|
||||
function update_term( $term_id, $tt_id, $taxonomy ) {
|
||||
$tax_meta = get_option( 'wpseo_taxonomy_meta' );
|
||||
|
||||
/* Create post array with only our values */
|
||||
$new_meta_data = array();
|
||||
foreach ( WPSEO_Taxonomy_Meta::$defaults_per_term as $key => $default ) {
|
||||
if ( isset( $_POST[ $key ] ) ) {
|
||||
$new_meta_data[ $key ] = $_POST[ $key ];
|
||||
}
|
||||
}
|
||||
unset( $key, $default );
|
||||
|
||||
/* Validate the post values */
|
||||
$old = WPSEO_Taxonomy_Meta::get_term_meta( $term_id, $taxonomy );
|
||||
$clean = WPSEO_Taxonomy_Meta::validate_term_meta_data( $new_meta_data, $old );
|
||||
|
||||
/* Add/remove the result to/from the original option value */
|
||||
if ( $clean !== array() ) {
|
||||
$tax_meta[ $taxonomy ][ $term_id ] = $clean;
|
||||
}
|
||||
else {
|
||||
unset( $tax_meta[ $taxonomy ][ $term_id ] );
|
||||
if ( isset( $tax_meta[ $taxonomy ] ) && $tax_meta[ $taxonomy ] === array() ) {
|
||||
unset( $tax_meta[ $taxonomy ] );
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent complete array validation
|
||||
$tax_meta['wpseo_already_validated'] = true;
|
||||
|
||||
update_option( 'wpseo_taxonomy_meta', $tax_meta );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allows HTML in descriptions
|
||||
*/
|
||||
function custom_category_descriptions_allow_html() {
|
||||
$filters = array(
|
||||
'pre_term_description',
|
||||
'pre_link_description',
|
||||
'pre_link_notes',
|
||||
'pre_user_description',
|
||||
);
|
||||
|
||||
foreach ( $filters as $filter ) {
|
||||
remove_filter( $filter, 'wp_filter_kses' );
|
||||
}
|
||||
remove_filter( 'term_description', 'wp_kses_data' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds shortcode support to category descriptions.
|
||||
*
|
||||
* @param string $desc String to add shortcodes in.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function custom_category_descriptions_add_shortcode_support( $desc ) {
|
||||
// Wrap in output buffering to prevent shortcodes that echo stuff instead of return from breaking things.
|
||||
ob_start();
|
||||
$desc = do_shortcode( $desc );
|
||||
ob_end_clean();
|
||||
|
||||
return $desc;
|
||||
}
|
||||
} /* End of class */
|
||||
@@ -1,6 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* Contains the Tracking class and filtering specific to WordPress SEO for the tracking class.
|
||||
*
|
||||
* If the class is instatiated from another plugin, the filtering still works.
|
||||
*
|
||||
* @package WPSEO\Admin\Tracking
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -9,165 +13,164 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Yoast_Tracking' ) ) {
|
||||
/**
|
||||
* Class that creates the tracking functionality for WP SEO, as the core class might be used in more plugins,
|
||||
* it's checked for existence first.
|
||||
*
|
||||
* NOTE: this functionality is opt-in. Disabling the tracking in the settings or saying no when asked will cause
|
||||
* this file to not even be loaded.
|
||||
*
|
||||
* @todo [JRF => testers] check if tracking still works if an old version of the Yoast Tracking class was loaded
|
||||
* (i.e. another plugin loaded their version first)
|
||||
*/
|
||||
class Yoast_Tracking {
|
||||
|
||||
/**
|
||||
* Class that creates the tracking functionality for WP SEO, as the core class might be used in more plugins,
|
||||
* it's checked for existence first.
|
||||
*
|
||||
* NOTE: this functionality is opt-in. Disabling the tracking in the settings or saying no when asked will cause
|
||||
* this file to not even be loaded.
|
||||
*
|
||||
* @todo [JRF => testers] check if tracking still works if an old version of the Yoast Tracking class was loaded
|
||||
* (i.e. another plugin loaded their version first)
|
||||
* @var object Instance of this class
|
||||
*/
|
||||
class Yoast_Tracking {
|
||||
|
||||
/**
|
||||
* @var object Instance of this class
|
||||
*/
|
||||
public static $instance;
|
||||
public static $instance;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
function __construct() {
|
||||
// Constructor is called from WP SEO
|
||||
if ( current_filter( 'yoast_tracking' ) ) {
|
||||
$this->tracking();
|
||||
} // Backward compatibility - constructor is called from other Yoast plugin
|
||||
elseif ( ! has_action( 'yoast_tracking', array( $this, 'tracking' ) ) ) {
|
||||
add_action( 'yoast_tracking', array( $this, 'tracking' ) );
|
||||
}
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
function __construct() {
|
||||
// Constructor is called from WP SEO
|
||||
if ( current_filter( 'yoast_tracking' ) ) {
|
||||
$this->tracking();
|
||||
} // Backward compatibility - constructor is called from other Yoast plugin
|
||||
elseif ( ! has_action( 'yoast_tracking', array( $this, 'tracking' ) ) ) {
|
||||
add_action( 'yoast_tracking', array( $this, 'tracking' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
/**
|
||||
* Main tracking function.
|
||||
*/
|
||||
function tracking() {
|
||||
|
||||
$transient_key = 'yoast_tracking_cache';
|
||||
$data = get_transient( $transient_key );
|
||||
|
||||
// bail if transient is set and valid
|
||||
if ( $data !== false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main tracking function.
|
||||
*/
|
||||
function tracking() {
|
||||
// Make sure to only send tracking data once a week
|
||||
set_transient( $transient_key, 1, WEEK_IN_SECONDS );
|
||||
|
||||
$transient_key = 'yoast_tracking_cache';
|
||||
$data = get_transient( $transient_key );
|
||||
// Start of Metrics
|
||||
global $wpdb;
|
||||
|
||||
// bail if transient is set and valid
|
||||
if ( $data !== false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure to only send tracking data once a week
|
||||
set_transient( $transient_key, 1, WEEK_IN_SECONDS );
|
||||
|
||||
// Start of Metrics
|
||||
global $blog_id, $wpdb;
|
||||
|
||||
$hash = get_option( 'Yoast_Tracking_Hash', false );
|
||||
|
||||
if ( ! $hash || empty( $hash ) ) {
|
||||
// create and store hash
|
||||
$hash = md5( site_url() );
|
||||
update_option( 'Yoast_Tracking_Hash', $hash );
|
||||
}
|
||||
|
||||
$pts = array();
|
||||
$post_types = get_post_types( array( 'public' => true ) );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
foreach ( $post_types as $post_type ) {
|
||||
$count = wp_count_posts( $post_type );
|
||||
$pts[ $post_type ] = $count->publish;
|
||||
}
|
||||
}
|
||||
unset( $post_types );
|
||||
|
||||
$comments_count = wp_count_comments();
|
||||
|
||||
$theme_data = wp_get_theme();
|
||||
$theme = array(
|
||||
'name' => $theme_data->display( 'Name', false, false ),
|
||||
'theme_uri' => $theme_data->display( 'ThemeURI', false, false ),
|
||||
'version' => $theme_data->display( 'Version', false, false ),
|
||||
'author' => $theme_data->display( 'Author', false, false ),
|
||||
'author_uri' => $theme_data->display( 'AuthorURI', false, false ),
|
||||
);
|
||||
$theme_template = $theme_data->get_template();
|
||||
if ( $theme_template !== '' && $theme_data->parent() ) {
|
||||
$theme['template'] = array(
|
||||
'version' => $theme_data->parent()->display( 'Version', false, false ),
|
||||
'name' => $theme_data->parent()->display( 'Name', false, false ),
|
||||
'theme_uri' => $theme_data->parent()->display( 'ThemeURI', false, false ),
|
||||
'author' => $theme_data->parent()->display( 'Author', false, false ),
|
||||
'author_uri' => $theme_data->parent()->display( 'AuthorURI', false, false ),
|
||||
);
|
||||
} else {
|
||||
$theme['template'] = '';
|
||||
}
|
||||
unset( $theme_template );
|
||||
|
||||
|
||||
$plugins = array();
|
||||
$active_plugin = get_option( 'active_plugins' );
|
||||
foreach ( $active_plugin as $plugin_path ) {
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
$plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_path );
|
||||
|
||||
$slug = str_replace( '/' . basename( $plugin_path ), '', $plugin_path );
|
||||
$plugins[ $slug ] = array(
|
||||
'version' => $plugin_info['Version'],
|
||||
'name' => $plugin_info['Name'],
|
||||
'plugin_uri' => $plugin_info['PluginURI'],
|
||||
'author' => $plugin_info['AuthorName'],
|
||||
'author_uri' => $plugin_info['AuthorURI'],
|
||||
);
|
||||
}
|
||||
unset( $active_plugins, $plugin_path );
|
||||
|
||||
|
||||
$data = array(
|
||||
'site' => array(
|
||||
'hash' => $hash,
|
||||
'version' => get_bloginfo( 'version' ),
|
||||
'multisite' => is_multisite(),
|
||||
'users' => $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->users INNER JOIN $wpdb->usermeta ON ({$wpdb->users}.ID = {$wpdb->usermeta}.user_id) WHERE 1 = 1 AND ( {$wpdb->usermeta}.meta_key = %s )", 'wp_' . $blog_id . '_capabilities' ) ),
|
||||
'lang' => get_locale(),
|
||||
),
|
||||
'pts' => $pts,
|
||||
'comments' => array(
|
||||
'total' => $comments_count->total_comments,
|
||||
'approved' => $comments_count->approved,
|
||||
'spam' => $comments_count->spam,
|
||||
'pings' => $wpdb->get_var( "SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_type = 'pingback'" ),
|
||||
),
|
||||
'options' => apply_filters( 'yoast_tracking_filters', array() ),
|
||||
'theme' => $theme,
|
||||
'plugins' => $plugins,
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'body' => $data,
|
||||
'blocking' => false,
|
||||
'sslverify' => false,
|
||||
);
|
||||
|
||||
wp_remote_post( 'https://tracking.yoast.com/', $args );
|
||||
$hash = get_option( 'Yoast_Tracking_Hash', false );
|
||||
|
||||
if ( ! $hash || empty( $hash ) ) {
|
||||
// create and store hash
|
||||
$hash = md5( site_url() );
|
||||
update_option( 'Yoast_Tracking_Hash', $hash );
|
||||
}
|
||||
} /* End of class */
|
||||
} /* End of class-exists wrapper */
|
||||
|
||||
$pts = array();
|
||||
$post_types = get_post_types( array( 'public' => true ) );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
foreach ( $post_types as $post_type ) {
|
||||
$count = wp_count_posts( $post_type );
|
||||
$pts[ $post_type ] = $count->publish;
|
||||
}
|
||||
}
|
||||
unset( $post_types, $post_type, $count );
|
||||
|
||||
$comments_count = wp_count_comments();
|
||||
|
||||
$theme_data = wp_get_theme();
|
||||
$theme = array(
|
||||
'name' => $theme_data->display( 'Name', false, false ),
|
||||
'theme_uri' => $theme_data->display( 'ThemeURI', false, false ),
|
||||
'version' => $theme_data->display( 'Version', false, false ),
|
||||
'author' => $theme_data->display( 'Author', false, false ),
|
||||
'author_uri' => $theme_data->display( 'AuthorURI', false, false ),
|
||||
);
|
||||
$theme_template = $theme_data->get_template();
|
||||
if ( $theme_template !== '' && $theme_data->parent() ) {
|
||||
$theme['template'] = array(
|
||||
'version' => $theme_data->parent()->display( 'Version', false, false ),
|
||||
'name' => $theme_data->parent()->display( 'Name', false, false ),
|
||||
'theme_uri' => $theme_data->parent()->display( 'ThemeURI', false, false ),
|
||||
'author' => $theme_data->parent()->display( 'Author', false, false ),
|
||||
'author_uri' => $theme_data->parent()->display( 'AuthorURI', false, false ),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$theme['template'] = '';
|
||||
}
|
||||
unset( $theme_template );
|
||||
|
||||
|
||||
$plugins = array();
|
||||
$active_plugins = get_option( 'active_plugins' );
|
||||
foreach ( $active_plugins as $plugin_path ) {
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
$plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_path );
|
||||
|
||||
$slug = str_replace( '/' . basename( $plugin_path ), '', $plugin_path );
|
||||
$plugins[ $slug ] = array(
|
||||
'version' => $plugin_info['Version'],
|
||||
'name' => $plugin_info['Name'],
|
||||
'plugin_uri' => $plugin_info['PluginURI'],
|
||||
'author' => $plugin_info['AuthorName'],
|
||||
'author_uri' => $plugin_info['AuthorURI'],
|
||||
);
|
||||
}
|
||||
unset( $active_plugins, $plugin_path, $plugin_info, $slug );
|
||||
|
||||
|
||||
$data = array(
|
||||
'site' => array(
|
||||
'hash' => $hash,
|
||||
'version' => get_bloginfo( 'version' ),
|
||||
'multisite' => is_multisite(),
|
||||
'users' => $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->users INNER JOIN $wpdb->usermeta ON ({$wpdb->users}.ID = {$wpdb->usermeta}.user_id) WHERE 1 = 1 AND ( {$wpdb->usermeta}.meta_key = %s )", 'wp_' . $GLOBALS['blog_id'] . '_capabilities' ) ),
|
||||
'lang' => get_locale(),
|
||||
),
|
||||
'pts' => $pts,
|
||||
'comments' => array(
|
||||
'total' => $comments_count->total_comments,
|
||||
'approved' => $comments_count->approved,
|
||||
'spam' => $comments_count->spam,
|
||||
'pings' => $wpdb->get_var( "SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_type = 'pingback'" ),
|
||||
),
|
||||
'options' => apply_filters( 'yoast_tracking_filters', array() ),
|
||||
'theme' => $theme,
|
||||
'plugins' => $plugins,
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'body' => $data,
|
||||
'blocking' => false,
|
||||
'sslverify' => false,
|
||||
);
|
||||
|
||||
wp_remote_post( 'https://tracking.yoast.com/', $args );
|
||||
|
||||
}
|
||||
} /* End of class */
|
||||
|
||||
/**
|
||||
* Adds tracking parameters for WP SEO settings. Outside of the main class as the class could also be in use in other plugins.
|
||||
@@ -179,7 +182,8 @@ if ( ! class_exists( 'Yoast_Tracking' ) ) {
|
||||
function wpseo_tracking_additions( $options ) {
|
||||
if ( function_exists( 'curl_version' ) ) {
|
||||
$curl = curl_version();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$curl = null;
|
||||
}
|
||||
|
||||
@@ -199,23 +203,17 @@ function wpseo_tracking_additions( $options ) {
|
||||
'wmt_pinterest' => ( ! empty( $opt['pinterestverify'] ) ) ? 1 : 0,
|
||||
'wmt_yandex' => ( ! empty( $opt['yandexverify'] ) ) ? 1 : 0,
|
||||
'permalinks_clean' => ( $opt['cleanpermalinks'] == 1 ) ? 1 : 0,
|
||||
|
||||
'site_db_charset' => DB_CHARSET,
|
||||
|
||||
'webserver_apache' => wpseo_is_apache() ? 1 : 0,
|
||||
'webserver_apache' => WPSEO_Utils::is_apache() ? 1 : 0,
|
||||
'webserver_apache_version' => function_exists( 'apache_get_version' ) ? apache_get_version() : 0,
|
||||
'webserver_nginx' => wpseo_is_nginx() ? 1 : 0,
|
||||
|
||||
'webserver_nginx' => WPSEO_Utils::is_nginx() ? 1 : 0,
|
||||
'webserver_server_software' => $_SERVER['SERVER_SOFTWARE'],
|
||||
'webserver_gateway_interface' => $_SERVER['GATEWAY_INTERFACE'],
|
||||
'webserver_server_protocol' => $_SERVER['SERVER_PROTOCOL'],
|
||||
|
||||
'php_version' => phpversion(),
|
||||
|
||||
'php_max_execution_time' => ini_get( 'max_execution_time' ),
|
||||
'php_memory_limit' => ini_get( 'memory_limit' ),
|
||||
'php_open_basedir' => ini_get( 'open_basedir' ),
|
||||
|
||||
'php_bcmath_enabled' => extension_loaded( 'bcmath' ) ? 1 : 0,
|
||||
'php_ctype_enabled' => extension_loaded( 'ctype' ) ? 1 : 0,
|
||||
'php_curl_enabled' => extension_loaded( 'curl' ) ? 1 : 0,
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Admin form class.
|
||||
*/
|
||||
class Yoast_Form {
|
||||
|
||||
/**
|
||||
* @var object Instance of this class
|
||||
*/
|
||||
public static $instance;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $option_name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $options;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the header for admin pages
|
||||
*
|
||||
* @param bool $form Whether or not the form start tag should be included.
|
||||
* @param string $option The short name of the option to use for the current page.
|
||||
* @param bool $contains_files Whether the form should allow for file uploads.
|
||||
* @param bool $option_long_name
|
||||
*/
|
||||
public function admin_header( $form = true, $option = 'wpseo', $contains_files = false, $option_long_name = false ) {
|
||||
if ( ! $option_long_name ) {
|
||||
$option_long_name = WPSEO_Options::get_group_name( $option );
|
||||
}
|
||||
?>
|
||||
<div class="wrap wpseo-admin-page page-<?php echo $option; ?>">
|
||||
<?php
|
||||
/**
|
||||
* Display the updated/error messages
|
||||
* Only needed as our settings page is not under options, otherwise it will automatically be included
|
||||
* @see settings_errors()
|
||||
*/
|
||||
require_once( ABSPATH . 'wp-admin/options-head.php' );
|
||||
?>
|
||||
<h2 id="wpseo-title"><?php echo esc_html( get_admin_page_title() ); ?></h2>
|
||||
<div class="wpseo_content_wrapper">
|
||||
<div class="wpseo_content_cell" id="wpseo_content_top">
|
||||
<?php
|
||||
if ( $form === true ) {
|
||||
$enctype = ( $contains_files ) ? ' enctype="multipart/form-data"' : '';
|
||||
echo '<form action="' . esc_url( admin_url( 'options.php' ) ) . '" method="post" id="wpseo-conf"' . $enctype . ' accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
settings_fields( $option_long_name );
|
||||
}
|
||||
$this->set_option( $option );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the option used in output for form elements
|
||||
*
|
||||
* @param string $option_name
|
||||
*/
|
||||
public function set_option( $option_name ) {
|
||||
$this->option_name = $option_name;
|
||||
$this->options = $this->get_option();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve options based on whether we're on multisite or not.
|
||||
*
|
||||
* @since 1.2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_option() {
|
||||
if ( is_network_admin() ) {
|
||||
return get_site_option( $this->option_name );
|
||||
}
|
||||
|
||||
return get_option( $this->option_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the footer for admin pages
|
||||
*
|
||||
* @param bool $submit Whether or not a submit button and form end tag should be shown.
|
||||
* @param bool $show_sidebar Whether or not to show the banner sidebar - used by premium plugins to disable it
|
||||
*/
|
||||
public function admin_footer( $submit = true, $show_sidebar = true ) {
|
||||
if ( $submit ) {
|
||||
submit_button();
|
||||
|
||||
echo '
|
||||
</form>';
|
||||
}
|
||||
|
||||
do_action( 'wpseo_admin_footer' );
|
||||
|
||||
echo '
|
||||
</div><!-- end of div wpseo_content_top -->';
|
||||
|
||||
if ( $show_sidebar ) {
|
||||
$this->admin_sidebar();
|
||||
}
|
||||
|
||||
echo '</div><!-- end of div wpseo_content_wrapper -->';
|
||||
|
||||
|
||||
if ( ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) ) {
|
||||
$xdebug = ( extension_loaded( 'xdebug' ) ? true : false );
|
||||
echo '
|
||||
<div id="poststuff">
|
||||
<div id="wpseo-debug-info" class="postbox">
|
||||
|
||||
<h3 class="hndle"><span>' . __( 'Debug Information', 'wordpress-seo' ) . '</span></h3>
|
||||
<div class="inside">
|
||||
<h4>' . esc_html( __( 'Current option:', 'wordpress-seo' ) ) . ' <span class="wpseo-debug">' . esc_html( $this->option_name ) . '</span></h4>
|
||||
' . ( ( $xdebug ) ? '' : '<pre>' );
|
||||
var_dump( $this->get_option() );
|
||||
echo '
|
||||
' . ( ( $xdebug ) ? '' : '</pre>' ) . '
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</div><!-- end of wrap -->';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the sidebar for admin pages.
|
||||
*/
|
||||
public function admin_sidebar() {
|
||||
|
||||
// No banners in Premium
|
||||
if ( class_exists( 'WPSEO_Product_Premium' ) ) {
|
||||
$license_manager = new Yoast_Plugin_License_Manager( new WPSEO_Product_Premium() );
|
||||
if ( $license_manager->license_is_valid() ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$service_banners = array(
|
||||
array(
|
||||
'url' => 'https://yoast.com/hire-us/website-review/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=website-review-banner',
|
||||
'img' => 'banner-website-review.png',
|
||||
'alt' => 'Website Review banner',
|
||||
),
|
||||
);
|
||||
|
||||
$plugin_banners = array(
|
||||
array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/seo-premium/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=premium-seo-banner',
|
||||
'img' => 'banner-premium-seo.png',
|
||||
'alt' => 'Banner WordPress SEO Premium',
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! class_exists( 'wpseo_Video_Sitemap' ) ) {
|
||||
$plugin_banners[] = array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/video-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=video-seo-banner',
|
||||
'img' => 'banner-video-seo.png',
|
||||
'alt' => 'Banner WordPress SEO Video SEO extension',
|
||||
);
|
||||
}
|
||||
|
||||
if ( class_exists( 'Woocommerce' ) && ! class_exists( 'Yoast_WooCommerce_SEO' ) ) {
|
||||
$plugin_banners[] = array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=woocommerce-seo-banner',
|
||||
'img' => 'banner-woocommerce-seo.png',
|
||||
'alt' => 'Banner WooCommerce SEO plugin',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! defined( 'WPSEO_LOCAL_VERSION' ) ) {
|
||||
$plugin_banners[] = array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/local-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=local-seo-banner',
|
||||
'img' => 'banner-local-seo.png',
|
||||
'alt' => 'Banner Local SEO plugin',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WPSEO_News' ) ) {
|
||||
$plugin_banners[] = array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/news-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=news-seo-banner',
|
||||
'img' => 'banner-news-seo.png',
|
||||
'alt' => 'Banner News SEO',
|
||||
);
|
||||
}
|
||||
|
||||
shuffle( $service_banners );
|
||||
shuffle( $plugin_banners );
|
||||
?>
|
||||
<div class="wpseo_content_cell" id="sidebar-container">
|
||||
<div id="sidebar">
|
||||
<?php
|
||||
|
||||
$service_banner = $service_banners[0];
|
||||
|
||||
echo '<a target="_blank" href="' . esc_url( $service_banner['url'] ) . '"><img width="261" height="190" src="' . plugins_url( 'images/' . $service_banner['img'], WPSEO_FILE ) . '" alt="' . esc_attr( $service_banner['alt'] ) . '"/></a><br/><br/>';
|
||||
|
||||
$i = 0;
|
||||
foreach ( $plugin_banners as $banner ) {
|
||||
if ( $i == 2 ) {
|
||||
break;
|
||||
}
|
||||
echo '<a target="_blank" href="' . esc_url( $banner['url'] ) . '"><img width="261" src="' . plugins_url( 'images/' . $banner['img'], WPSEO_FILE ) . '" alt="' . esc_attr( $banner['alt'] ) . '"/></a><br/><br/>';
|
||||
$i ++;
|
||||
}
|
||||
?>
|
||||
<strong><?php _e( 'Remove these ads?', 'wordpress-seo' ); ?></strong><br/>
|
||||
<a target="_blank" href="https://yoast.com/wordpress/plugins/seo-premium/#utm_source=wordpress-seo-config&utm_medium=textlink&utm_campaign=remove-ads-link"><?php _e( 'Upgrade to WordPress SEO Premium »', 'wordpress-seo' ); ?></a><br/><br/>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a label element
|
||||
*
|
||||
* @param string $text
|
||||
* @param array $attr
|
||||
*/
|
||||
public function label( $text, $attr ) {
|
||||
$attr = wp_parse_args( $attr, array(
|
||||
'class' => 'checkbox',
|
||||
'close' => true,
|
||||
'for' => '',
|
||||
)
|
||||
);
|
||||
echo "<label class='" . $attr['class'] . "' for='" . esc_attr( $attr['for'] ) . "'>$text";
|
||||
if ( $attr['close'] ) {
|
||||
echo '</label>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Checkbox input field.
|
||||
*
|
||||
* @param string $var The variable within the option to create the checkbox for.
|
||||
* @param string $label The label to show for the variable.
|
||||
* @param bool $label_left Whether the label should be left (true) or right (false).
|
||||
*/
|
||||
public function checkbox( $var, $label, $label_left = false ) {
|
||||
if ( ! isset( $this->options[ $var ] ) ) {
|
||||
$this->options[ $var ] = false;
|
||||
}
|
||||
|
||||
if ( $this->options[ $var ] === true ) {
|
||||
$this->options[ $var ] = 'on';
|
||||
}
|
||||
|
||||
$class = '';
|
||||
if ( $label_left !== false ) {
|
||||
if ( ! empty( $label_left ) ) {
|
||||
$label_left .= ':';
|
||||
}
|
||||
$this->label( $label_left, array( 'for' => $var ) );
|
||||
}
|
||||
else {
|
||||
$class = 'double';
|
||||
}
|
||||
|
||||
echo '<input class="checkbox ', esc_attr( $class ), '" type="checkbox" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $this->options[ $var ], 'on', false ), '/>';
|
||||
|
||||
if ( ! empty( $label ) ) {
|
||||
$this->label( $label, array( 'for' => $var ) );
|
||||
}
|
||||
|
||||
echo '<br class="clear" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Text input field.
|
||||
*
|
||||
* @param string $var The variable within the option to create the text input field for.
|
||||
* @param string $label The label to show for the variable.
|
||||
* @param array|string $attr Extra class to add to the input field
|
||||
*/
|
||||
public function textinput( $var, $label, $attr = array() ) {
|
||||
if ( ! is_array( $attr ) ) {
|
||||
$attr = array(
|
||||
'class' => $attr,
|
||||
);
|
||||
}
|
||||
$attr = wp_parse_args( $attr, array(
|
||||
'placeholder' => '',
|
||||
'class' => '',
|
||||
) );
|
||||
$val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
|
||||
|
||||
$this->label( $label . ':', array( 'for' => $var ) );
|
||||
echo '<input class="textinput ' . esc_attr( $attr['class'] ) . ' " placeholder="' . esc_attr( $attr['placeholder'] ) . '" type="text" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="', esc_attr( $val ), '"/>', '<br class="clear" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textarea.
|
||||
*
|
||||
* @param string $var The variable within the option to create the textarea for.
|
||||
* @param string $label The label to show for the variable.
|
||||
* @param array $attr The CSS class to assign to the textarea.
|
||||
*/
|
||||
public function textarea( $var, $label, $attr = array() ) {
|
||||
if ( ! is_array( $attr ) ) {
|
||||
$attr = array(
|
||||
'class' => $attr,
|
||||
);
|
||||
}
|
||||
$attr = wp_parse_args( $attr, array(
|
||||
'cols' => '',
|
||||
'rows' => '',
|
||||
'class' => '',
|
||||
) );
|
||||
$val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
|
||||
|
||||
$this->label( $label . ':', array( 'for' => $var, 'class' => 'textinput' ) );
|
||||
echo '<textarea cols="' . esc_attr( $attr['cols'] ) . '" rows="' . esc_attr( $attr['rows'] ) . '" class="textinput ' . esc_attr( $attr['class'] ) . '" id="' . esc_attr( $var ) . '" name="' . esc_attr( $this->option_name ) . '[' . esc_attr( $var ) . ']">' . esc_textarea( $val ) . '</textarea>' . '<br class="clear" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hidden input field.
|
||||
*
|
||||
* @param string $var The variable within the option to create the hidden input for.
|
||||
* @param string $id The ID of the element
|
||||
*/
|
||||
public function hidden( $var, $id = '' ) {
|
||||
$val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
|
||||
if ( is_bool( $val ) ) {
|
||||
$val = ( $val === true ) ? 'true' : 'false';
|
||||
}
|
||||
|
||||
if ( '' === $id ) {
|
||||
$id = 'hidden_' . $var;
|
||||
}
|
||||
|
||||
echo '<input type="hidden" id="' . esc_attr( $id ) . '" name="' . esc_attr( $this->option_name ) . '[' . esc_attr( $var ) . ']" value="' . esc_attr( $val ) . '"/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Select Box.
|
||||
*
|
||||
* @param string $var The variable within the option to create the select for.
|
||||
* @param string $label The label to show for the variable.
|
||||
* @param array $values The select options to choose from.
|
||||
*/
|
||||
public function select( $var, $label, $values ) {
|
||||
if ( ! is_array( $values ) || $values === array() ) {
|
||||
return;
|
||||
}
|
||||
$val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
|
||||
|
||||
$this->label( $label . ':', array( 'for' => $var, 'class' => 'select' ) );
|
||||
echo '<select class="select" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" id="', esc_attr( $var ), '">';
|
||||
|
||||
foreach ( $values as $value => $label ) {
|
||||
if ( ! empty( $label ) ) {
|
||||
echo '<option value="', esc_attr( $value ), '"', selected( $val, $value, false ), '>', $label, '</option>';
|
||||
}
|
||||
}
|
||||
echo '</select>';
|
||||
|
||||
echo '<br class="clear"/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a File upload field.
|
||||
*
|
||||
* @param string $var The variable within the option to create the file upload field for.
|
||||
* @param string $label The label to show for the variable.
|
||||
*/
|
||||
public function file_upload( $var, $label ) {
|
||||
$val = '';
|
||||
if ( isset( $this->options[ $var ] ) && is_array( $this->options[ $var ] ) ) {
|
||||
$val = $this->options[ $var ]['url'];
|
||||
}
|
||||
|
||||
$var_esc = esc_attr( $var );
|
||||
$this->label( $label . ':', array( 'for' => $var, 'class' => 'select' ) );
|
||||
echo '<input type="file" value="' . esc_attr( $val ) . '" class="textinput" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" id="' . $var_esc . '"/>';
|
||||
|
||||
// Need to save separate array items in hidden inputs, because empty file inputs type will be deleted by settings API.
|
||||
if ( ! empty( $this->options[ $var ] ) ) {
|
||||
$this->hidden( 'file', $this->option_name . '_file' );
|
||||
$this->hidden( 'url', $this->option_name . '_url' );
|
||||
$this->hidden( 'type', $this->option_name . '_type' );
|
||||
}
|
||||
echo '<br class="clear"/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Media input
|
||||
*
|
||||
* @param string $var
|
||||
* @param string $label
|
||||
*/
|
||||
public function media_input( $var, $label ) {
|
||||
$val = '';
|
||||
if ( isset( $this->options[ $var ] ) ) {
|
||||
$val = $this->options[ $var ];
|
||||
}
|
||||
|
||||
$var_esc = esc_attr( $var );
|
||||
|
||||
$this->label( $label . ':', array( 'for' => 'wpseo_' . $var, 'class' => 'select' ) );
|
||||
echo '<input class="textinput" id="wpseo_', $var_esc, '" type="text" size="36" name="', esc_attr( $this->option_name ), '[', $var_esc, ']" value="', esc_attr( $val ), '" />';
|
||||
echo '<input id="wpseo_', $var_esc, '_button" class="wpseo_image_upload_button button" type="button" value="', __( 'Upload Image', 'wordpress-seo' ), '" />';
|
||||
echo '<br class="clear"/>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Radio input field.
|
||||
*
|
||||
* @param string $var The variable within the option to create the file upload field for.
|
||||
* @param array $values The radio options to choose from.
|
||||
* @param string $label The label to show for the variable.
|
||||
*/
|
||||
public function radio( $var, $values, $label ) {
|
||||
if ( ! is_array( $values ) || $values === array() ) {
|
||||
return;
|
||||
}
|
||||
if ( ! isset( $this->options[ $var ] ) ) {
|
||||
$this->options[ $var ] = false;
|
||||
}
|
||||
|
||||
$var_esc = esc_attr( $var );
|
||||
|
||||
echo '<br/><div class="wpseo_radio_block" id="' . $var_esc . '">';
|
||||
if ( is_string( $label ) && $label !== '' ) {
|
||||
$this->label( $label . ':', array( 'class' => 'select' ) );
|
||||
}
|
||||
|
||||
foreach ( $values as $key => $value ) {
|
||||
$key_esc = esc_attr( $key );
|
||||
echo '<input type="radio" class="radio" id="' . $var_esc . '-' . $key_esc . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $this->options[ $var ], $key_esc, false ) . ' />';
|
||||
$this->label( $value, array( 'for' => $var_esc . '-' . $key_esc, 'class' => 'radio' ) );
|
||||
}
|
||||
echo '<div class="clear"></div>';
|
||||
echo '</div><br/>';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles notifications storage and display.
|
||||
*/
|
||||
class Yoast_Notification_Center {
|
||||
|
||||
const TRANSIENT_KEY = 'yoast_notifications';
|
||||
|
||||
/**
|
||||
* The singleton instance of this object
|
||||
*
|
||||
* @var \Yoast_Notification_Center
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $notifications = array();
|
||||
|
||||
/**
|
||||
@@ -105,10 +119,8 @@ class Yoast_Notification_Center {
|
||||
}
|
||||
|
||||
// Set the cookie with notifications
|
||||
set_transient( self::TRANSIENT_KEY, json_encode( $arr_notifications ), MINUTE_IN_SECONDS * 10 );
|
||||
|
||||
set_transient( self::TRANSIENT_KEY, json_encode( $arr_notifications ), ( MINUTE_IN_SECONDS * 10 ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +146,6 @@ class Yoast_Notification_Center {
|
||||
|
||||
// Clear the local stored notifications
|
||||
$this->clear_notifications();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
* @since 1.5.3
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements individual notification.
|
||||
*/
|
||||
class Yoast_Notification {
|
||||
|
||||
/**
|
||||
* @var string The notification message
|
||||
*/
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* @var string The notification type, i.e. 'updated' or 'error'
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
@@ -60,7 +74,7 @@ class Yoast_Notification {
|
||||
* Output the message
|
||||
*/
|
||||
public function output() {
|
||||
echo '<div class="yoast-notice ' . $this->get_type() . '">' . wpautop( $this->get_message() ) . '</div>' . PHP_EOL;
|
||||
echo '<div class="yoast-notice ', esc_attr( $this->get_type() ), '">', wpautop( $this->get_message() ), '</div>', PHP_EOL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,251 +1,269 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
/**
|
||||
* Base class for handling plugin conflicts.
|
||||
*/
|
||||
class Yoast_Plugin_Conflict {
|
||||
|
||||
if ( ! class_exists( 'Yoast_Plugin_Conflict' ) ) {
|
||||
/**
|
||||
* The plugins must be grouped per section.
|
||||
*
|
||||
* It's possible to check for each section if there are conflicting plugin
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $plugins = array();
|
||||
|
||||
class Yoast_Plugin_Conflict {
|
||||
/**
|
||||
* All the current active plugins will be stored in this private var
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $all_active_plugins = array();
|
||||
|
||||
/**
|
||||
* The plugins must be grouped per section.
|
||||
*
|
||||
* It's possible to check for each section if there are conflicting plugin
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $plugins = array();
|
||||
/**
|
||||
* After searching for active plugins that are in $this->plugins the active plugins will be stored in this
|
||||
* property
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $active_plugins = array();
|
||||
|
||||
/**
|
||||
* All the current active plugins will be stored in this private var
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $all_active_plugins = array();
|
||||
/**
|
||||
* Property for holding instance of itself
|
||||
*
|
||||
* @var Yoast_Plugin_Conflict
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* After searching for active plugins that are in $this->plugins the active plugins will be stored in this
|
||||
* property
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $active_plugins = array();
|
||||
/**
|
||||
* For the use of singleton pattern. Create instance of itself and return his instance
|
||||
*
|
||||
* @param string $class_name Give the classname to initialize. If classname is false (empty) it will use it's own __CLASS__
|
||||
*
|
||||
* @return Yoast_Plugin_Conflict
|
||||
*/
|
||||
public static function get_instance( $class_name = '' ) {
|
||||
|
||||
/**
|
||||
* Property for holding instance of itself
|
||||
*
|
||||
* @var Yoast_Plugin_Conflict
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* For the use of singleton pattern. Create instance of itself and return his instance
|
||||
*
|
||||
* @param bool|string $classname Give the classname to initialize. If classname is false (empty) it will use it's own __CLASS__
|
||||
*
|
||||
* @return Yoast_Plugin_Conflict
|
||||
*/
|
||||
public static function get_instance( $class_name = false ) {
|
||||
|
||||
if ( is_null( self::$instance ) ) {
|
||||
if ( empty( $class_name ) ) {
|
||||
$class_name = __CLASS__;
|
||||
}
|
||||
|
||||
self::$instance = new $class_name();
|
||||
if ( is_null( self::$instance ) ) {
|
||||
if ( ! is_string( $class_name ) || $class_name === '' ) {
|
||||
$class_name = __CLASS__;
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
self::$instance = new $class_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting instance, all active plugins and search for active plugins
|
||||
*
|
||||
* Protected constructor to prevent creating a new instance of the
|
||||
* *Singleton* via the `new` operator from outside of this class.
|
||||
*
|
||||
*/
|
||||
protected function __construct() {
|
||||
// Set active plugins
|
||||
$this->all_active_plugins = get_option( 'active_plugins' );
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
// Search for active plugins
|
||||
$this->search_active_plugins();
|
||||
/**
|
||||
* Setting instance, all active plugins and search for active plugins
|
||||
*
|
||||
* Protected constructor to prevent creating a new instance of the
|
||||
* *Singleton* via the `new` operator from outside of this class.
|
||||
*
|
||||
*/
|
||||
protected function __construct() {
|
||||
// Set active plugins
|
||||
$this->all_active_plugins = get_option( 'active_plugins' );
|
||||
|
||||
// Search for active plugins
|
||||
$this->search_active_plugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are conflicting plugins for given $plugin_section
|
||||
*
|
||||
* @param string $plugin_section
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function check_for_conflicts( $plugin_section ) {
|
||||
|
||||
static $sections_checked;
|
||||
|
||||
if ( $sections_checked == null ) {
|
||||
$sections_checked = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are conflicting plugins for given $plugin_section
|
||||
*
|
||||
* @param string $plugin_section
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function check_for_conflicts( $plugin_section ) {
|
||||
if ( ! in_array( $plugin_section, $sections_checked ) ) {
|
||||
$sections_checked[] = $plugin_section;
|
||||
$has_conflicts = ( ! empty( $this->active_plugins[ $plugin_section ] ) );
|
||||
|
||||
static $sections_checked;
|
||||
return $has_conflicts;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $sections_checked == null ) {
|
||||
$sections_checked = array();
|
||||
}
|
||||
/**
|
||||
* Get plugin name from file
|
||||
*
|
||||
* @param string $plugin
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function get_plugin_name( $plugin ) {
|
||||
$plugin_details = get_plugin_data( ABSPATH . '/wp-content/plugins/' . $plugin );
|
||||
|
||||
if ( ! in_array($plugin_section, $sections_checked ) ) {
|
||||
$sections_checked[] = $plugin_section;
|
||||
$has_conflicts = ( ! empty( $this->active_plugins[$plugin_section] ) );
|
||||
if ( $plugin_details['Name'] != '' ) {
|
||||
return $plugin_details['Name'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return $has_conflicts;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Getting all the conflicting plugins and return them as a string.
|
||||
*
|
||||
* This method will loop through all conflicting plugins to get the details of each plugin. The plugin name
|
||||
* will be taken from the details to parse a comma separated string, which can be use for by example a notice
|
||||
*
|
||||
* @param string $plugin_section
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_conflicting_plugins_as_string( $plugin_section ) {
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting all the conflicting plugins and return them as a string.
|
||||
*
|
||||
* This method will loop through all conflicting plugins to get the details of each plugin. The plugin name
|
||||
* will be taken from the details to parse a comma separated string, which can be use for by example a notice
|
||||
*
|
||||
* @param string $plugin_section
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_conflicting_plugins_as_string( $plugin_section ) {
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
||||
}
|
||||
// Getting the active plugins by given section
|
||||
$plugins = $this->active_plugins[ $plugin_section ];
|
||||
|
||||
// Getting the active plugins by given section
|
||||
$plugins = $this->active_plugins[$plugin_section];
|
||||
|
||||
$plugin_names = array();
|
||||
foreach ( $plugins AS $plugin ) {
|
||||
$plugin_details = get_plugin_data( ABSPATH . '/wp-content/plugins/' . $plugin );
|
||||
|
||||
if ( $plugin_details['Name'] != '' ) {
|
||||
$plugin_names[] = $plugin_details['Name'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $plugin_names ) ) {
|
||||
return implode( ', ', $plugin_names );
|
||||
$plugin_names = array();
|
||||
foreach ( $plugins as $plugin ) {
|
||||
if ( $name = $this->get_plugin_name( $plugin ) ) {
|
||||
$plugin_names[] = '<em>' . $name . '</em>';
|
||||
}
|
||||
}
|
||||
unset( $plugins, $plugin );
|
||||
|
||||
/**
|
||||
* Checks for given $plugin_sections for conflicts
|
||||
*
|
||||
* @param array $plugin_sections
|
||||
*/
|
||||
public function check_plugin_conflicts( $plugin_sections ) {
|
||||
foreach ( $plugin_sections AS $plugin_section => $readable_plugin_section ) {
|
||||
// Check for conflicting plugins and show error if there are conflicts
|
||||
if ( $this->check_for_conflicts( $plugin_section ) ) {
|
||||
$this->set_error( $plugin_section, $readable_plugin_section );
|
||||
}
|
||||
if ( ! empty( $plugin_names ) ) {
|
||||
return implode( ' & ', $plugin_names );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for given $plugin_sections for conflicts
|
||||
*
|
||||
* @param array $plugin_sections
|
||||
*/
|
||||
public function check_plugin_conflicts( $plugin_sections ) {
|
||||
foreach ( $plugin_sections as $plugin_section => $readable_plugin_section ) {
|
||||
// Check for conflicting plugins and show error if there are conflicts
|
||||
if ( $this->check_for_conflicts( $plugin_section ) ) {
|
||||
$this->set_error( $plugin_section, $readable_plugin_section );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting an error on the screen
|
||||
*
|
||||
* @param string $plugin_section
|
||||
* @param string $readable_plugin_section This is the value for the translation
|
||||
*/
|
||||
protected function set_error( $plugin_section, $readable_plugin_section ) {
|
||||
/**
|
||||
* Setting an error on the screen
|
||||
*
|
||||
* @param string $plugin_section
|
||||
* @param string $readable_plugin_section This is the value for the translation
|
||||
*/
|
||||
protected function set_error( $plugin_section, $readable_plugin_section ) {
|
||||
|
||||
$plugins_as_string = $this->get_conflicting_plugins_as_string( $plugin_section );
|
||||
$error_message = sprintf( __( 'The following plugins might cause (%1s) issues with Yoast WordPress SEO: %2s', 'wordpress-seo' ), $readable_plugin_section, $plugins_as_string );
|
||||
$plugins_as_string = $this->get_conflicting_plugins_as_string( $plugin_section );
|
||||
$error_message = '<h3>' . __( 'Warning!', 'wordpress-seo' ) . '</h3>';
|
||||
|
||||
// Add the message to the notifications center
|
||||
Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $error_message, 'error' ) );
|
||||
/* translators: %s: 'Facebook & Open Graph' plugin name(s) of possibly conflicting plugin(s) */
|
||||
$error_message .= '<p>' . sprintf( __( 'The %s plugin(s) might cause issues when used in conjunction with Yoast WordPress SEO.', 'wordpress-seo' ), $plugins_as_string ) . '</p>';
|
||||
$error_message .= sprintf( $readable_plugin_section, $plugins_as_string ) . '<br/><br/>';
|
||||
$error_message .= '<p><strong>' . __( 'Recommended solution', 'wordpress-seo' ) . '</strong><br/>';
|
||||
|
||||
/* translators: %s: 'Facebook & Open Graph' plugin name(s) of possibly conflicting plugin(s) */
|
||||
$error_message .= sprintf( __( 'We recommend you deactivate %s and have another look at your WordPress SEO configuration using the button above.', 'wordpress-seo' ), $plugins_as_string ) . '</p>';
|
||||
foreach ( $this->active_plugins[ $plugin_section ] as $plugin_file ) {
|
||||
|
||||
/* translators: %s: 'Facebook' plugin name of possibly conflicting plugin */
|
||||
$error_message .= '<a target="_blank" class="button-primary" href="' . wp_nonce_url( 'plugins.php?action=deactivate&plugin=' . $plugin_file . '&plugin_status=all', 'deactivate-plugin_' . $plugin_file ) . '">' . sprintf( __( 'Deactivate %s', 'wordpress-seo' ), $this->get_plugin_name( $plugin_file ) ) . '</a> ';
|
||||
}
|
||||
$error_message .= '<p class="alignright"><small>' . __( 'This warning is generated by WordPress SEO by Yoast.', 'wordpress-seo' ) . '</small></p><div class="clear"></div>';
|
||||
|
||||
/**
|
||||
* Loop through the $this->plugins to check if one of the plugins is active.
|
||||
*
|
||||
* This method will store the active plugins in $this->active_plugins.
|
||||
*/
|
||||
protected function search_active_plugins() {
|
||||
foreach ( $this->plugins AS $plugin_section => $plugins ) {
|
||||
$this->check_plugins_active( $plugins, $plugin_section );
|
||||
// Add the message to the notifications center
|
||||
Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $error_message, 'error' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through the $this->plugins to check if one of the plugins is active.
|
||||
*
|
||||
* This method will store the active plugins in $this->active_plugins.
|
||||
*/
|
||||
protected function search_active_plugins() {
|
||||
foreach ( $this->plugins as $plugin_section => $plugins ) {
|
||||
$this->check_plugins_active( $plugins, $plugin_section );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through plugins and check if each plugin is active
|
||||
*
|
||||
* @param array $plugins
|
||||
* @param string $plugin_section
|
||||
*/
|
||||
protected function check_plugins_active( $plugins, $plugin_section ) {
|
||||
foreach ( $plugins as $plugin ) {
|
||||
if ( $this->check_plugin_is_active( $plugin ) ) {
|
||||
$this->add_active_plugin( $plugin_section, $plugin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through plugins and check if each plugin is active
|
||||
*
|
||||
* @param array $plugins
|
||||
* @param string $plugin_section
|
||||
*/
|
||||
protected function check_plugins_active( $plugins, $plugin_section ) {
|
||||
foreach ( $plugins AS $plugin ) {
|
||||
if ( $this->check_plugin_is_active( $plugin ) ) {
|
||||
$this->add_active_plugin( $plugin_section, $plugin );
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check if given plugin exists in array with all_active_plugins
|
||||
*
|
||||
* @param string $plugin
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function check_plugin_is_active( $plugin ) {
|
||||
return in_array( $plugin, $this->all_active_plugins );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add plugin to the list of active plugins.
|
||||
*
|
||||
* This method will check first if key $plugin_section exists, if not it will create an empty array
|
||||
* If $plugin itself doesn't exist it will be added.
|
||||
*
|
||||
* @param string $plugin_section
|
||||
* @param string $plugin
|
||||
*/
|
||||
protected function add_active_plugin( $plugin_section, $plugin ) {
|
||||
|
||||
if ( ! array_key_exists( $plugin_section, $this->active_plugins ) ) {
|
||||
$this->active_plugins[ $plugin_section ] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given plugin exists in array with all_active_plugins
|
||||
*
|
||||
* @param string $plugin
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function check_plugin_is_active( $plugin ) {
|
||||
|
||||
$is_plugin_active = in_array( $plugin, $this->all_active_plugins );
|
||||
|
||||
return $is_plugin_active;
|
||||
if ( ! in_array( $plugin, $this->active_plugins[ $plugin_section ] ) ) {
|
||||
$this->active_plugins[ $plugin_section ][] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add plugin to the list of active plugins.
|
||||
*
|
||||
* This method will check first if key $plugin_section exists, if not it will create an empty array
|
||||
* If $plugin itself doesn't exist it will be added.
|
||||
*
|
||||
* @param string $plugin_section
|
||||
* @param string $plugin
|
||||
*/
|
||||
protected function add_active_plugin( $plugin_section, $plugin ) {
|
||||
/**
|
||||
* Search in $this->plugins for the given $plugin
|
||||
*
|
||||
* If there is a result it will return the plugin category
|
||||
*
|
||||
* @param string $plugin
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
protected function find_plugin_category( $plugin ) {
|
||||
|
||||
if ( ! array_key_exists( $plugin_section, $this->active_plugins ) ) {
|
||||
$this->active_plugins[$plugin_section] = array();
|
||||
foreach ( $this->plugins as $plugin_section => $plugins ) {
|
||||
if ( in_array( $plugin, $plugins ) ) {
|
||||
return $plugin_section;
|
||||
}
|
||||
|
||||
if ( ! in_array( $plugin, $this->active_plugins[$plugin_section] ) ) {
|
||||
$this->active_plugins[$plugin_section][] = $plugin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Search in $this->plugins for the given $plugin
|
||||
*
|
||||
* If there is a result it will return the plugin category
|
||||
*
|
||||
* @param string $plugin
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
protected function find_plugin_category( $plugin ) {
|
||||
|
||||
foreach ( $this->plugins AS $plugin_section => $plugins ) {
|
||||
if ( in_array( $plugin, $plugins ) ) {
|
||||
return $plugin_section;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,675 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
[](https://codeclimate.com/github/Yoast/i18n-module)
|
||||
|
||||
# Yoast i18n module
|
||||
Promote your own translation site for people who are using your plugin in another language than `en_US`.
|
||||
|
||||
## Example of the rendered promo box
|
||||
|
||||

|
||||
|
||||
The image, the name of your plugin and the name of your translation project are all configurable (see example below). The name of the language is retrieved from your GlotPress install, as is the percentage translated. The box doesn't display when a language has been translated for 90% or more.
|
||||
|
||||
## How to use this module
|
||||
Just include the library as a submodule, make sure the class is loaded and instantiate it like this:
|
||||
|
||||
```php
|
||||
$wpseo_i18n = new yoast_i18n(
|
||||
array(
|
||||
'textdomain' => 'wordpress-seo',
|
||||
'project_slug' => 'wordpress-seo',
|
||||
'plugin_name' => 'WordPress SEO by Yoast',
|
||||
'hook' => 'wpseo_admin_footer',
|
||||
'glotpress_url' => 'http://translate.yoast.com',
|
||||
'glotpress_name' => 'Yoast Translate',
|
||||
'glotpress_logo' => 'https://cdn.yoast.com/wp-content/uploads/i18n-images/Yoast_Translate.svg',
|
||||
'register_url ' => 'http://translate.yoast.com/projects#utm_source=plugin&utm_medium=promo-box&utm_campaign=i18n-promo',
|
||||
)
|
||||
);
|
||||
```
|
||||
@@ -1,278 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class defines a promo box and checks your translation site's API for stats about it, then shows them to the user.
|
||||
*/
|
||||
class yoast_i18n {
|
||||
|
||||
/**
|
||||
* Your translation site's logo
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $glotpress_logo;
|
||||
|
||||
/**
|
||||
* Your translation site's name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $glotpress_name;
|
||||
|
||||
/**
|
||||
* Your translation site's URL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $glotpress_url;
|
||||
|
||||
/**
|
||||
* Hook where you want to show the promo box
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $hook;
|
||||
|
||||
/**
|
||||
* Will contain the site's locale
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $locale;
|
||||
|
||||
/**
|
||||
* Will contain the locale's name, obtained from yoru translation site
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $locale_name;
|
||||
|
||||
/**
|
||||
* Will contain the percentage translated for the plugin translation project in the locale
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
private $percent_translated;
|
||||
|
||||
/**
|
||||
* Name of your plugin
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $plugin_name;
|
||||
|
||||
/**
|
||||
* Project slug for the project on your translation site
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $project_slug;
|
||||
|
||||
/**
|
||||
* URL to point to for registration links
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $register_url;
|
||||
|
||||
/**
|
||||
* Your plugins textdomain
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $textdomain;
|
||||
|
||||
/**
|
||||
* Indicates whether there's a translation available at all.
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
private $translation_exists;
|
||||
|
||||
/**
|
||||
* Indicates whether the translation's loaded.
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
private $translation_loaded;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param array $args Contains the settings for the class.
|
||||
*/
|
||||
public function __construct( $args ) {
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->locale = get_locale();
|
||||
if ( 'en_US' === $this->locale ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->init( $args );
|
||||
|
||||
if ( ! $this->hide_promo() ) {
|
||||
add_action( $this->hook, array( $this, 'promo' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where you decide where to display the messages and where you set the plugin specific variables.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
private function init( $args ) {
|
||||
foreach ( $args as $key => $arg ) {
|
||||
$this->$key = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the promo should be hidden or not
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hide_promo() {
|
||||
$hide_promo = get_transient( 'yoast_i18n_' . $this->project_slug . '_promo_hide' );
|
||||
if ( ! $hide_promo ) {
|
||||
if ( filter_input( INPUT_GET, 'remove_i18n_promo', FILTER_NULL_ON_FAILURE ) ) {
|
||||
// No expiration time, so this would normally not expire, but it wouldn't be copied to other sites etc.
|
||||
set_transient( 'yoast_i18n_' . $this->project_slug . '_promo_hide', true );
|
||||
$hide_promo = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $hide_promo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a promo message
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return bool|string $message
|
||||
*/
|
||||
private function promo_message() {
|
||||
$message = false;
|
||||
|
||||
if ( $this->translation_loaded && $this->percent_translated < 90 ) {
|
||||
$message = __( 'As you can see, there is a translation of this plugin in %1$s. This translation is currently %3$d%% complete. We need your help to make it complete and to fix any errors. Please register at %4$s to help complete the translation to %1$s!', $this->textdomain );
|
||||
} else if ( ! $this->translation_loaded && $this->translation_exists ) {
|
||||
$message = __( 'You\'re using WordPress in %1$s. While %2$s has been translated to %1$s for %3$d%%, it\'s not been shipped with the plugin yet. You can help! Register at %4$s to help complete the translation to %1$s!', $this->textdomain );
|
||||
} else if ( ! $this->translation_loaded && ! $this->translation_exists ) {
|
||||
$message = __( 'You\'re using WordPress in a language we don\'t support yet. We\'d love for %2$s to be translated in that language too, but unfortunately, it isn\'t right now. You can change that! Register at %4$s to help translate it!', $this->textdomain );
|
||||
}
|
||||
|
||||
$registration_link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $this->register_url ), esc_html( $this->glotpress_name ) );
|
||||
$message = sprintf( $message, esc_html( $this->locale_name ), esc_html( $this->plugin_name ), $this->percent_translated, $registration_link );
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a promo box
|
||||
*/
|
||||
public function promo() {
|
||||
$this->translation_details();
|
||||
|
||||
$message = $this->promo_message();
|
||||
|
||||
if ( $message ) {
|
||||
echo '<div id="i18n_promo_box" style="border:1px solid #ccc;background-color:#fff;padding:10px;max-width:650px;">';
|
||||
echo '<a href="' . add_query_arg( array( 'remove_i18n_promo' => '1' ) ) . '" style="color:#333;text-decoration:none;font-weight:bold;font-size:16px;border:1px solid #ccc;padding:1px 4px;" class="alignright">X</a>';
|
||||
echo '<h2>' . sprintf( __( 'Translation of %s', $this->textdomain ), $this->plugin_name ) . '</h2>';
|
||||
if ( isset( $this->glotpress_logo ) && '' != $this->glotpress_logo ) {
|
||||
echo '<a href="' . $this->register_url . '"><img class="alignright" style="margin:15px 5px 5px 5px;width:200px;" src="' . $this->glotpress_logo . '" alt="' . $this->glotpress_name . '"/></a>';
|
||||
}
|
||||
echo '<p>' . $message . '</p>';
|
||||
echo '<p><a href="' . $this->register_url . '">' . __( 'Register now »', $this->textdomain ) . '</a></p>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find the transient for the translation set or retrieve them.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return object|null
|
||||
*/
|
||||
private function find_or_initialize_translation_details() {
|
||||
$set = get_transient( 'yoast_i18n_' . $this->project_slug );
|
||||
|
||||
if ( ! $set ) {
|
||||
$set = $this->retrieve_translation_details();
|
||||
set_transient( 'yoast_i18n_' . $this->project_slug, $set, DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get translation details from cache, otherwise retrieve them, then parse them.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function translation_details() {
|
||||
$set = $this->find_or_initialize_translation_details();
|
||||
|
||||
$this->translation_exists = ! is_null( $set );
|
||||
$this->translation_loaded = is_textdomain_loaded( $this->textdomain );
|
||||
|
||||
$this->parse_translation_set( $set );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the translation details from Yoast Translate
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return object|null
|
||||
*/
|
||||
private function retrieve_translation_details() {
|
||||
$api_url = trailingslashit( $this->glotpress_url ) . 'api/projects/' . $this->project_slug;
|
||||
|
||||
$resp = wp_remote_get( $api_url );
|
||||
$body = wp_remote_retrieve_body( $resp );
|
||||
unset( $resp );
|
||||
|
||||
if ( $body ) {
|
||||
$body = json_decode( $body );
|
||||
foreach ( $body->translation_sets as $set ) {
|
||||
if ( $this->locale == $set->wp_locale ) {
|
||||
return $set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the needed private variables based on the results from Yoast Translate
|
||||
*
|
||||
* @param object $set The translation set
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function parse_translation_set( $set ) {
|
||||
if ( $this->translation_exists ) {
|
||||
$this->locale_name = $set->name;
|
||||
$this->percent_translated = $set->percent_translated;
|
||||
} else {
|
||||
$this->locale_name = '';
|
||||
$this->percent_translated = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
Yoast License Manager
|
||||
=====================
|
||||
|
||||
This library will take care of the following.
|
||||
|
||||
- Managing license related options
|
||||
- Setting license key from a constant
|
||||
- Obfuscasting (valid) license keys
|
||||
- Remote license activation / deactivation
|
||||
- Checking for plugin or theme updates
|
||||
|
||||
## Usage
|
||||
|
||||
### Inside Plugins
|
||||
|
||||
A sample plugin is included, [have a look at its source](https://github.com/Yoast/License-Manager/blob/master/samples/sample-plugin.php).
|
||||
|
||||
### Inside Themes
|
||||
|
||||
A sample theme `functions.php` file is included, [have a look here](https://github.com/Yoast/License-Manager/blob/master/samples/sample-theme-functions.php).
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( ! class_exists( "Yoast_API_Request", false ) ) {
|
||||
|
||||
/**
|
||||
* Handles requests to the Yoast EDD API
|
||||
*/
|
||||
class Yoast_API_Request {
|
||||
|
||||
/**
|
||||
* @var string Request URL
|
||||
*/
|
||||
private $url = '';
|
||||
|
||||
/**
|
||||
* @var array Request parameters
|
||||
*/
|
||||
private $args = array(
|
||||
'method' => 'GET',
|
||||
'timeout' => 10,
|
||||
'sslverify' => false,
|
||||
'headers' => array(
|
||||
'Accept-Encoding' => '*',
|
||||
'X-Yoast-EDD' => '1'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $success = false;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $error_message = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string url
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $url, array $args = array() ) {
|
||||
|
||||
// set api url
|
||||
$this->url = $url;
|
||||
|
||||
// set request args (merge with defaults)
|
||||
$this->args = wp_parse_args( $args, $this->args );
|
||||
|
||||
// fire the request
|
||||
$this->success = $this->fire();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires the request, automatically called from constructor
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function fire() {
|
||||
|
||||
// fire request to shop
|
||||
$response = wp_remote_request( $this->url, $this->args );
|
||||
|
||||
// validate raw response
|
||||
if( $this->validate_raw_response( $response ) === false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// decode the response
|
||||
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
// response should be an object
|
||||
if( ! is_object( $this->response ) ) {
|
||||
$this->error_message = 'No JSON object was returned.';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $response
|
||||
* @return boolean
|
||||
*/
|
||||
private function validate_raw_response( $response ) {
|
||||
|
||||
// make sure response came back okay
|
||||
if( is_wp_error( $response ) ) {
|
||||
$this->error_message = $response->get_error_message();
|
||||
return false;
|
||||
}
|
||||
|
||||
// check response code, should be 200
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
|
||||
if( false === strstr( $response_code, '200' ) ) {
|
||||
|
||||
$response_message = wp_remote_retrieve_response_message( $response );
|
||||
$this->error_message = "{$response_code} {$response_message}";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was a valid response returned?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_valid() {
|
||||
return ( $this->success === true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_error_message() {
|
||||
return $this->error_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object
|
||||
*/
|
||||
public function get_response() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,570 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( ! interface_exists( 'iYoast_License_Manager', false ) ) {
|
||||
|
||||
interface iYoast_License_Manager {
|
||||
|
||||
public function specific_hooks();
|
||||
public function setup_auto_updater();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( ! class_exists( 'Yoast_License_Manager', false ) ) {
|
||||
|
||||
/**
|
||||
* Class Yoast_License_Manager
|
||||
*
|
||||
* @todo Maybe create a license class that contains key and option
|
||||
* @todo Not sure if Yoast_License_Manager is a good name for this class, it's more managing the product (plugin or theme)
|
||||
*/
|
||||
abstract class Yoast_License_Manager implements iYoast_License_Manager {
|
||||
|
||||
/**
|
||||
* @const VERSION The version number of the License_Manager class
|
||||
*/
|
||||
const VERSION = 1;
|
||||
|
||||
/**
|
||||
* @var Yoast_License The license
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $license_constant_name = '';
|
||||
|
||||
/**
|
||||
* @var boolean True if license is defined with a constant
|
||||
*/
|
||||
private $license_constant_is_defined = false;
|
||||
|
||||
/**
|
||||
* @var boolean True if remote license activation just failed
|
||||
*/
|
||||
private $remote_license_activation_failed = false;
|
||||
|
||||
/**
|
||||
* @var array Array of license related options
|
||||
*/
|
||||
private $options = array();
|
||||
|
||||
/**
|
||||
* @var string Used to prefix ID's, option names, etc..
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* @var bool Boolean indicating whether this plugin is network activated
|
||||
*/
|
||||
protected $is_network_activated = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Yoast_Product $product
|
||||
*/
|
||||
public function __construct( Yoast_Product $product ) {
|
||||
|
||||
// Set the license
|
||||
$this->product = $product;
|
||||
|
||||
// set prefix
|
||||
$this->prefix = sanitize_title_with_dashes( $this->product->get_item_name() . '_', null, 'save' );
|
||||
|
||||
// maybe set license key from constant
|
||||
$this->maybe_set_license_key_from_constant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*
|
||||
*/
|
||||
public function setup_hooks() {
|
||||
|
||||
// show admin notice if license is not active
|
||||
add_action( 'admin_notices', array( $this, 'display_admin_notices' ) );
|
||||
|
||||
// catch POST requests from license form
|
||||
add_action( 'admin_init', array( $this, 'catch_post_request') );
|
||||
|
||||
// setup item type (plugin|theme) specific hooks
|
||||
$this->specific_hooks();
|
||||
|
||||
// setup the auto updater
|
||||
$this->setup_auto_updater();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display license specific admin notices, namely:
|
||||
*
|
||||
* - License for the product isn't activated
|
||||
* - External requests are blocked through WP_HTTP_BLOCK_EXTERNAL
|
||||
*/
|
||||
public function display_admin_notices() {
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// show notice if license is invalid
|
||||
if( ! $this->license_is_valid() ) {
|
||||
if( $this->get_license_key() == '' ) {
|
||||
$message = '<b>Warning!</b> You didn\'t set your %s license key yet, which means you\'re missing out on updates and support! <a href="%s">Enter your license key</a> or <a href="%s" target="_blank">get a license here</a>.';
|
||||
} else {
|
||||
$message = '<b>Warning!</b> Your %s license is inactive which means you\'re missing out on updates and support! <a href="%s">Activate your license</a> or <a href="%s" target="_blank">get a license here</a>.';
|
||||
}
|
||||
?>
|
||||
<div class="error">
|
||||
<p><?php printf( __( $message, $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url(), $this->product->get_tracking_url( 'activate-license-notice' ) ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
// show notice if external requests are blocked through the WP_HTTP_BLOCK_EXTERNAL constant
|
||||
if( defined( "WP_HTTP_BLOCK_EXTERNAL" ) && WP_HTTP_BLOCK_EXTERNAL === true ) {
|
||||
|
||||
// check if our API endpoint is in the allowed hosts
|
||||
$host = parse_url( $this->product->get_api_url(), PHP_URL_HOST );
|
||||
|
||||
if( ! defined( "WP_ACCESSIBLE_HOSTS" ) || stristr( WP_ACCESSIBLE_HOSTS, $host ) === false ) {
|
||||
?>
|
||||
<div class="error">
|
||||
<p><?php printf( __( '<b>Warning!</b> You\'re blocking external requests which means you won\'t be able to get %s updates. Please add %s to %s.', $this->product->get_text_domain() ), $this->product->get_item_name(), '<strong>' . $host . '</strong>', '<code>WP_ACCESSIBLE_HOSTS</code>'); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a notice to display in the admin area
|
||||
*
|
||||
* @param string $type error|updated
|
||||
* @param string $message The message to display
|
||||
*/
|
||||
protected function set_notice( $message, $success = true ) {
|
||||
$css_class = ( $success ) ? 'updated' : 'error';
|
||||
add_settings_error( $this->prefix . 'license', 'license-notice', $message, $css_class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remotely activate License
|
||||
* @return boolean True if the license is now activated, false if not
|
||||
*/
|
||||
public function activate_license() {
|
||||
|
||||
$result = $this->call_license_api( 'activate' );
|
||||
|
||||
|
||||
if( $result ) {
|
||||
|
||||
// story expiry date
|
||||
if( isset( $result->expires ) ) {
|
||||
$this->set_license_expiry_date( $result->expires );
|
||||
$expiry_date = strtotime( $result->expires );
|
||||
} else {
|
||||
$expiry_date = false;
|
||||
}
|
||||
|
||||
// show success notice if license is valid
|
||||
if($result->license === 'valid') {
|
||||
|
||||
$message = sprintf( __( "Your %s license has been activated. ", $this->product->get_text_domain() ), $this->product->get_item_name() );
|
||||
|
||||
// show a custom notice if users have an unlimited license
|
||||
if( $result->license_limit == 0 ) {
|
||||
$message .= __( "You have an unlimited license. ", $this->product->get_text_domain() );
|
||||
} else {
|
||||
$message .= sprintf( __( "You have used %d/%d activations. ", $this->product->get_text_domain() ), $result->site_count, $result->license_limit );
|
||||
}
|
||||
|
||||
// add upgrade notice if user has less than 3 activations left
|
||||
if( $result->license_limit > 0 && ( $result->license_limit - $result->site_count ) <= 3 ) {
|
||||
$message .= sprintf( __( '<a href="%s">Did you know you can upgrade your license?</a>', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-nearing-limit-notice' ) );
|
||||
// add extend notice if license is expiring in less than 1 month
|
||||
} elseif( $expiry_date !== false && $expiry_date < strtotime( "+1 month" ) ) {
|
||||
$days_left = round( ( $expiry_date - strtotime( "now" ) ) / 86400 );
|
||||
$message .= sprintf( __( '<a href="%s">Your license is expiring in %d days, would you like to extend it?</a>', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-expiring-notice' ), $days_left );
|
||||
}
|
||||
|
||||
$this->set_notice( $message, true );
|
||||
|
||||
} else {
|
||||
|
||||
if( isset($result->error) && $result->error === 'no_activations_left' ) {
|
||||
// show notice if user is at their activation limit
|
||||
$this->set_notice( sprintf( __('You\'ve reached your activation limit. You must <a href="%s">upgrade your license</a> to use it on this site.', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-at-limit-notice' ) ), false );
|
||||
} elseif( isset($result->error) && $result->error == "expired" ) {
|
||||
// show notice if the license is expired
|
||||
$this->set_notice( sprintf( __('Your license has expired. You must <a href="%s">extend your license</a> in order to use it again.', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-expired-notice' ) ), false );
|
||||
} else {
|
||||
// show a general notice if it's any other error
|
||||
$this->set_notice( __( "Failed to activate your license, your license key seems to be invalid.", $this->product->get_text_domain() ), false );
|
||||
}
|
||||
|
||||
$this->remote_license_activation_failed = true;
|
||||
}
|
||||
|
||||
$this->set_license_status( $result->license );
|
||||
}
|
||||
|
||||
return ( $this->license_is_valid() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remotely deactivate License
|
||||
* @return boolean True if the license is now deactivated, false if not
|
||||
*/
|
||||
public function deactivate_license () {
|
||||
|
||||
$result = $this->call_license_api( 'deactivate' );
|
||||
|
||||
if( $result ) {
|
||||
|
||||
// show notice if license is deactivated
|
||||
if( $result->license === 'deactivated' ) {
|
||||
$this->set_notice( sprintf( __( "Your %s license has been deactivated.", $this->product->get_text_domain() ), $this->product->get_item_name() ) );
|
||||
} else {
|
||||
$this->set_notice( sprintf( __( "Failed to deactivate your %s license.", $this->product->get_text_domain() ), $this->product->get_item_name() ), false );
|
||||
}
|
||||
|
||||
$this->set_license_status( $result->license );
|
||||
}
|
||||
|
||||
return ( $this->get_license_status() === 'deactivated' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action activate|deactivate
|
||||
* @return mixed
|
||||
*/
|
||||
protected function call_license_api( $action ) {
|
||||
|
||||
// don't make a request if license key is empty
|
||||
if( $this->get_license_key() === '' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// data to send in our API request
|
||||
$api_params = array(
|
||||
'edd_action' => $action . '_license',
|
||||
'license' => $this->get_license_key(),
|
||||
'item_name' => urlencode( trim( $this->product->get_item_name() ) ),
|
||||
'url' => get_option( 'home' ) // grab the URL straight from the option to prevent filters from breaking it.
|
||||
);
|
||||
|
||||
// create api request url
|
||||
$url = add_query_arg( $api_params, $this->product->get_api_url() );
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class-api-request.php';
|
||||
$request = new Yoast_API_Request( $url );
|
||||
|
||||
if( $request->is_valid() !== true ) {
|
||||
$this->set_notice( sprintf( __( "Request error: \"%s\" (%scommon license notices%s)", $this->product->get_text_domain() ), $request->get_error_message(), '<a href="http://kb.yoast.com/article/13-license-activation-notices">', '</a>' ), false );
|
||||
}
|
||||
|
||||
// get response
|
||||
$response = $request->get_response();
|
||||
|
||||
// update license status
|
||||
$license_data = $response;
|
||||
|
||||
return $license_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the license status
|
||||
*
|
||||
* @param string $license_status
|
||||
*/
|
||||
public function set_license_status( $license_status ) {
|
||||
$this->set_option( 'status', $license_status );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the license status
|
||||
*
|
||||
* @return string $license_status;
|
||||
*/
|
||||
public function get_license_status() {
|
||||
$license_status = $this->get_option( 'status' );
|
||||
return trim( $license_status );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the license key
|
||||
*
|
||||
* @param string $license_key
|
||||
*/
|
||||
public function set_license_key( $license_key ) {
|
||||
$this->set_option( 'key', $license_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the license key from constant or option
|
||||
*
|
||||
* @return string $license_key
|
||||
*/
|
||||
public function get_license_key() {
|
||||
$license_key = $this->get_option( 'key' );
|
||||
return trim( $license_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the license expiry date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_license_expiry_date() {
|
||||
return $this->get_option( 'expiry_date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the license expiry date
|
||||
*/
|
||||
public function set_license_expiry_date( $expiry_date ) {
|
||||
$this->set_option( 'expiry_date', $expiry_date );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the license status is active
|
||||
*
|
||||
* @return boolean True if license is active
|
||||
*/
|
||||
public function license_is_valid() {
|
||||
return ( $this->get_license_status() === 'valid' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all license related options
|
||||
*
|
||||
* @return array Array of license options
|
||||
*/
|
||||
protected function get_options() {
|
||||
|
||||
// create option name
|
||||
$option_name = $this->prefix . 'license';
|
||||
|
||||
// get array of options from db
|
||||
if( $this->is_network_activated ) {
|
||||
$options = get_site_option( $option_name, array( ) );
|
||||
} else {
|
||||
$options = get_option( $option_name, array( ) );
|
||||
}
|
||||
|
||||
// setup array of defaults
|
||||
$defaults = array(
|
||||
'key' => '',
|
||||
'status' => '',
|
||||
'expiry_date' => ''
|
||||
);
|
||||
|
||||
// merge options with defaults
|
||||
$this->options = wp_parse_args( $options, $defaults );
|
||||
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set license related options
|
||||
*
|
||||
* @param array $options Array of new license options
|
||||
*/
|
||||
protected function set_options( array $options ) {
|
||||
// create option name
|
||||
$option_name = $this->prefix . 'license';
|
||||
|
||||
// update db
|
||||
if( $this->is_network_activated ) {
|
||||
update_site_option( $option_name, $options );
|
||||
} else {
|
||||
update_option( $option_name, $options );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a license related option
|
||||
*
|
||||
* @param string $name The option name
|
||||
* @return mixed The option value
|
||||
*/
|
||||
protected function get_option( $name ) {
|
||||
$options = $this->get_options();
|
||||
return $options[ $name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a license related option
|
||||
*
|
||||
* @param string $name The option name
|
||||
* @param mixed $value The option value
|
||||
*/
|
||||
protected function set_option( $name, $value ) {
|
||||
// get options
|
||||
$options = $this->get_options();
|
||||
|
||||
// update option
|
||||
$options[ $name ] = $value;
|
||||
|
||||
// save options
|
||||
$this->set_options( $options );
|
||||
}
|
||||
|
||||
public function show_license_form_heading() {
|
||||
?>
|
||||
<h3>
|
||||
<?php printf( __( "%s: License Settings", $this->product->get_text_domain() ), $this->product->get_item_name() ); ?>
|
||||
</h3>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a form where users can enter their license key
|
||||
*
|
||||
* @param boolean $embedded Boolean indicating whether this form is embedded in another form?
|
||||
*/
|
||||
public function show_license_form( $embedded = true ) {
|
||||
|
||||
$key_name = $this->prefix . 'license_key';
|
||||
$nonce_name = $this->prefix . 'license_nonce';
|
||||
$action_name = $this->prefix . 'license_action';
|
||||
|
||||
|
||||
$visible_license_key = $this->get_license_key();
|
||||
|
||||
// obfuscate license key
|
||||
$obfuscate = ( strlen( $this->get_license_key() ) > 5 && ( $this->license_is_valid() || ! $this->remote_license_activation_failed ) );
|
||||
|
||||
if($obfuscate) {
|
||||
$visible_license_key = str_repeat('*', strlen( $this->get_license_key() ) - 4) . substr( $this->get_license_key(), -4 );
|
||||
}
|
||||
|
||||
// make license key readonly when license key is valid or license is defined with a constant
|
||||
$readonly = ( $this->license_is_valid() || $this->license_constant_is_defined );
|
||||
|
||||
require dirname( __FILE__ ) . '/views/form.php';
|
||||
|
||||
// enqueue script in the footer
|
||||
add_action( 'admin_footer', array( $this, 'output_script'), 99 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the license form has been submitted
|
||||
*/
|
||||
public function catch_post_request() {
|
||||
|
||||
$name = $this->prefix . 'license_key';
|
||||
|
||||
// check if license key was posted and not empty
|
||||
if( ! isset( $_POST[$name] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// run a quick security check
|
||||
$nonce_name = $this->prefix . 'license_nonce';
|
||||
|
||||
if ( ! check_admin_referer( $nonce_name, $nonce_name ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @TODO: check for user cap?
|
||||
|
||||
// get key from posted value
|
||||
$license_key = $_POST[$name];
|
||||
|
||||
// check if license key doesn't accidentally contain asterisks
|
||||
if( strstr($license_key, '*') === false ) {
|
||||
|
||||
// sanitize key
|
||||
$license_key = trim( sanitize_key( $_POST[$name] ) );
|
||||
|
||||
// save license key
|
||||
$this->set_license_key( $license_key );
|
||||
}
|
||||
|
||||
// does user have an activated valid license
|
||||
if( ! $this->license_is_valid() ) {
|
||||
|
||||
// try to auto-activate license
|
||||
return $this->activate_license();
|
||||
|
||||
}
|
||||
|
||||
$action_name = $this->prefix . 'license_action';
|
||||
|
||||
// was one of the action buttons clicked?
|
||||
if( isset( $_POST[ $action_name ] ) ) {
|
||||
|
||||
$action = trim( $_POST[ $action_name ] );
|
||||
|
||||
switch($action) {
|
||||
|
||||
case 'activate':
|
||||
return $this->activate_license();
|
||||
break;
|
||||
|
||||
case 'deactivate':
|
||||
return $this->deactivate_license();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the script containing the YoastLicenseManager JS Object
|
||||
*
|
||||
* This takes care of disabling the 'activate' and 'deactivate' buttons
|
||||
*/
|
||||
public function output_script() {
|
||||
require_once dirname( __FILE__ ) . '/views/script.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constant used to define the license
|
||||
*
|
||||
* @param string $license_constant_name The license constant name
|
||||
*/
|
||||
public function set_license_constant_name( $license_constant_name ) {
|
||||
$this->license_constant_name = trim( $license_constant_name );
|
||||
$this->maybe_set_license_key_from_constant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe set license key from a defined constant
|
||||
*/
|
||||
private function maybe_set_license_key_from_constant( ) {
|
||||
|
||||
if( empty( $this->license_constant_name ) ) {
|
||||
// generate license constant name
|
||||
$this->set_license_constant_name( strtoupper( str_replace( array(' ', '-' ), '', sanitize_key( $this->product->get_item_name() ) ) ) . '_LICENSE');
|
||||
}
|
||||
|
||||
// set license key from constant
|
||||
if( defined( $this->license_constant_name ) ) {
|
||||
|
||||
$license_constant_value = constant( $this->license_constant_name );
|
||||
|
||||
// update license key value with value of constant
|
||||
if( $this->get_license_key() !== $license_constant_value ) {
|
||||
$this->set_license_key( $license_constant_value );
|
||||
}
|
||||
|
||||
$this->license_constant_is_defined = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( class_exists( 'Yoast_License_Manager' ) && ! class_exists( "Yoast_Plugin_License_Manager", false ) ) {
|
||||
|
||||
class Yoast_Plugin_License_Manager extends Yoast_License_Manager {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Yoast_Product $product
|
||||
*/
|
||||
public function __construct( Yoast_Product $product ) {
|
||||
|
||||
parent::__construct( $product );
|
||||
|
||||
// Check if plugin is network activated. We should use site(wide) options in that case.
|
||||
if( is_admin() && is_multisite() ) {
|
||||
|
||||
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
||||
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
$this->is_network_activated = is_plugin_active_for_network( $product->get_slug() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup auto updater for plugins
|
||||
*/
|
||||
public function setup_auto_updater() {
|
||||
if ( $this->license_is_valid() ) {
|
||||
// setup auto updater
|
||||
require_once( dirname( __FILE__ ) . '/class-update-manager.php' );
|
||||
require_once( dirname( __FILE__ ) . '/class-plugin-update-manager.php' );
|
||||
new Yoast_Plugin_Update_Manager( $this->product, $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*/
|
||||
public function specific_hooks() {
|
||||
|
||||
// deactivate the license remotely on plugin deactivation
|
||||
register_deactivation_hook( $this->product->get_slug(), array( $this, 'deactivate_license' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a form where users can enter their license key
|
||||
* Takes Multisites into account
|
||||
*
|
||||
* @param bool $embedded
|
||||
* @return null
|
||||
*/
|
||||
public function show_license_form( $embedded = true ) {
|
||||
|
||||
// For non-multisites, always show the license form
|
||||
if( ! is_multisite() ) {
|
||||
parent::show_license_form( $embedded );
|
||||
return;
|
||||
}
|
||||
|
||||
// Plugin is network activated
|
||||
if( $this->is_network_activated ) {
|
||||
|
||||
// We're on the network admin
|
||||
if( is_network_admin() ) {
|
||||
parent::show_license_form( $embedded );
|
||||
} else {
|
||||
// We're not in the network admin area, show a notice
|
||||
parent::show_license_form_heading();
|
||||
if ( is_super_admin() ) {
|
||||
echo "<p>" . sprintf( __( '%s is network activated, you can manage your license in the <a href="%s">network admin license page</a>.', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url() ) . "</p>";
|
||||
} else {
|
||||
echo "<p>" . sprintf( __( '%s is network activated, please contact your site administrator to manage the license.', $this->product->get_text_domain() ), $this->product->get_item_name() ) . "</p>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if( false == is_network_admin() ) {
|
||||
parent::show_license_form( $embedded );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
//set_site_transient( 'update_plugins', null );
|
||||
|
||||
if( class_exists( 'Yoast_Update_Manager' ) && ! class_exists( "Yoast_Plugin_Update_Manager", false ) ) {
|
||||
|
||||
class Yoast_Plugin_Update_Manager extends Yoast_Update_Manager {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $api_url
|
||||
* @param string $item_name
|
||||
* @param string $license_key
|
||||
* @param string $slug The path to the main plugin file, relative to plugins dir
|
||||
* @param string $version
|
||||
* @param string $author (optional)
|
||||
* @param string $text_domain
|
||||
*/
|
||||
public function __construct( Yoast_Product $product, $license_key ) {
|
||||
parent::__construct( $product, $license_key );
|
||||
|
||||
// setup hooks
|
||||
$this->setup_hooks();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*/
|
||||
private function setup_hooks() {
|
||||
|
||||
// check for updates
|
||||
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'set_updates_available_data' ) );
|
||||
|
||||
// get correct plugin information (when viewing details)
|
||||
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for updates and if so, add to "updates available" data
|
||||
*
|
||||
* @param object $data
|
||||
* @return object $data
|
||||
*/
|
||||
public function set_updates_available_data( $data ) {
|
||||
|
||||
if ( empty( $data ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// send of API request to check for updates
|
||||
$remote_data = $this->get_remote_data();
|
||||
|
||||
// did we get a response?
|
||||
if( $remote_data === false ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// compare local version with remote version
|
||||
if ( version_compare( $this->product->get_version(), $remote_data->new_version, '<' ) ) {
|
||||
|
||||
// remote version is newer, add to data
|
||||
$data->response[ $this->product->get_slug() ] = $remote_data;
|
||||
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets new plugin version details (view version x.x.x details)
|
||||
*
|
||||
* @uses api_request()
|
||||
*
|
||||
* @param object $data
|
||||
* @param string $action
|
||||
* @param object $args (optional)
|
||||
*
|
||||
* @return object $data
|
||||
*/
|
||||
public function plugins_api_filter( $data, $action = '', $args = null ) {
|
||||
|
||||
// only do something if we're checking for our plugin
|
||||
if ( $action !== 'plugin_information' || ! isset( $args->slug ) || $args->slug !== $this->product->get_slug() ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$api_response = $this->get_remote_data();
|
||||
|
||||
// did we get a response?
|
||||
if ( $api_response === false ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// return api response
|
||||
return $api_response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( ! class_exists( "Yoast_Product", false ) ) {
|
||||
|
||||
/**
|
||||
* Class Yoast_Product
|
||||
*
|
||||
* @todo create a license class and store an object of it in this class
|
||||
*/
|
||||
class Yoast_Product {
|
||||
|
||||
/**
|
||||
* @var string The URL of the shop running the EDD API.
|
||||
*/
|
||||
protected $api_url;
|
||||
|
||||
/**
|
||||
* @var string The item name in the EDD shop.
|
||||
*/
|
||||
protected $item_name;
|
||||
|
||||
/**
|
||||
* @var string The theme slug or plugin file
|
||||
*/
|
||||
protected $slug;
|
||||
|
||||
/**
|
||||
* @var string The version number of the item
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* @var string The absolute url on which users can purchase a license
|
||||
*/
|
||||
protected $item_url;
|
||||
|
||||
/**
|
||||
* @var string Absolute admin URL on which users can enter their license key.
|
||||
*/
|
||||
protected $license_page_url;
|
||||
|
||||
/**
|
||||
* @var string The text domain used for translating strings
|
||||
*/
|
||||
protected $text_domain;
|
||||
|
||||
/**
|
||||
* @var string The item author
|
||||
*/
|
||||
protected $author;
|
||||
|
||||
public function __construct( $api_url, $item_name, $slug, $version, $item_url = '', $license_page_url = '#', $text_domain = 'yoast', $author = 'Yoast' ) {
|
||||
$this->api_url = $api_url;
|
||||
$this->item_name = $item_name;
|
||||
$this->slug = $slug;
|
||||
$this->version = $version;
|
||||
$this->item_url = $item_url;
|
||||
$this->license_page_url = admin_url( $license_page_url );
|
||||
$this->text_domain = $text_domain;
|
||||
$this->author = $author;
|
||||
|
||||
// Fix possible empty item url
|
||||
if ( $this->item_url === '' ) {
|
||||
$this->item_url = $this->api_url;
|
||||
}
|
||||
|
||||
if( is_admin() && is_multisite() ) {
|
||||
|
||||
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
||||
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
if( is_plugin_active_for_network( $slug ) ) {
|
||||
$this->license_page_url = network_admin_url( $license_page_url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $api_url
|
||||
*/
|
||||
public function set_api_url( $api_url ) {
|
||||
$this->api_url = $api_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_api_url() {
|
||||
return $this->api_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $author
|
||||
*/
|
||||
public function set_author( $author ) {
|
||||
$this->author = $author;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_author() {
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $item_name
|
||||
*/
|
||||
public function set_item_name( $item_name ) {
|
||||
$this->item_name = $item_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_item_name() {
|
||||
return $this->item_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $item_url
|
||||
*/
|
||||
public function set_item_url( $item_url ) {
|
||||
$this->item_url = $item_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_item_url() {
|
||||
return $this->item_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $license_page_url
|
||||
*/
|
||||
public function set_license_page_url( $license_page_url ) {
|
||||
$this->license_page_url = admin_page( $license_page_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_license_page_url() {
|
||||
return $this->license_page_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*/
|
||||
public function set_slug( $slug ) {
|
||||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_slug() {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dirname of the slug and limits it to 15 chars
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_transient_prefix() {
|
||||
return substr( dirname( $this->slug ), 0, 15 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text_domain
|
||||
*/
|
||||
public function set_text_domain( $text_domain ) {
|
||||
$this->text_domain = $text_domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_text_domain() {
|
||||
return $this->text_domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*/
|
||||
public function set_version( $version ) {
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_version() {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Google Analytics Campaign url for this product
|
||||
*
|
||||
* @param string $link_identifier
|
||||
* @return string The full URL
|
||||
*/
|
||||
public function get_tracking_url( $link_identifier = '' ) {
|
||||
|
||||
$tracking_vars = array(
|
||||
'utm_campaign' => $this->get_item_name() . ' licensing',
|
||||
'utm_medium' => 'link',
|
||||
'utm_source' => $this->get_item_name(),
|
||||
'utm_content' => $link_identifier
|
||||
);
|
||||
|
||||
// url encode tracking vars
|
||||
$tracking_vars = urlencode_deep( $tracking_vars );
|
||||
|
||||
$query_string = build_query( $tracking_vars );
|
||||
|
||||
|
||||
return $this->get_item_url() . '#' . $query_string;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( class_exists( 'Yoast_License_Manager' ) && ! class_exists( "Yoast_Theme_License_Manager", false ) ) {
|
||||
|
||||
class Yoast_Theme_License_Manager extends Yoast_License_Manager {
|
||||
|
||||
/**
|
||||
* Setup auto updater for themes
|
||||
*/
|
||||
public function setup_auto_updater() {
|
||||
if ( $this->license_is_valid() ) {
|
||||
// setup auto updater
|
||||
require_once dirname( __FILE__ ) . '/class-update-manager.php';
|
||||
require_once dirname( __FILE__ ) . '/class-theme-update-manager.php'; // @TODO: Autoload?
|
||||
new Yoast_Theme_Update_Manager( $this->product, $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*/
|
||||
public function specific_hooks() {
|
||||
// remotely deactivate license upon switching away from this theme
|
||||
add_action( 'switch_theme', array( $this, 'deactivate_license' ) );
|
||||
|
||||
// Add the license menu
|
||||
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add license page and add it to Themes menu
|
||||
*/
|
||||
public function add_license_menu() {
|
||||
$theme_page = add_theme_page( sprintf( __( '%s License', $this->product->get_text_domain() ), $this->product->get_item_name() ), __( 'Theme License', $this->product->get_text_domain() ), 'manage_options', 'theme-license', array( $this, 'show_license_page' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows license page
|
||||
*/
|
||||
public function show_license_page() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<?php settings_errors(); ?>
|
||||
|
||||
<?php $this->show_license_form( false ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( class_exists( 'Yoast_Update_Manager' ) && ! class_exists( "Yoast_Theme_Update_Manager", false ) ) {
|
||||
|
||||
class Yoast_Theme_Update_Manager extends Yoast_Update_Manager {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $api_url
|
||||
* @param string $item_name
|
||||
* @param string $license_key
|
||||
* @param string $slug
|
||||
* @param string $theme_version
|
||||
* @param string $author (optional)
|
||||
*/
|
||||
public function __construct( Yoast_Product $product, $license_key ) {
|
||||
|
||||
parent::__construct( $product, $license_key );
|
||||
|
||||
// setup hooks
|
||||
$this->setup_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current theme version
|
||||
*
|
||||
* @return string The version number
|
||||
*/
|
||||
private function get_theme_version() {
|
||||
|
||||
// if version was not set, get it from the Theme stylesheet
|
||||
if( $this->product->get_version() === '' ) {
|
||||
$theme = wp_get_theme( $this->product->get_slug() );
|
||||
return $theme->get( 'Version' );
|
||||
}
|
||||
|
||||
return $this->product->get_version();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*/
|
||||
private function setup_hooks() {
|
||||
add_filter( 'site_transient_update_themes', array( $this, 'set_theme_update_transient' ) );
|
||||
add_action( 'load-themes.php', array( $this, 'load_themes_screen' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set "updates available" transient
|
||||
*/
|
||||
public function set_theme_update_transient( $value ) {
|
||||
|
||||
$update_data = $this->get_update_data();
|
||||
|
||||
if( $update_data === false ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// add update data to "updates available" array. convert object to array.
|
||||
$value->response[ $this->product->get_slug() ] = (array) $update_data;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks and scripts to the Appearance > Themes screen
|
||||
*/
|
||||
public function load_themes_screen() {
|
||||
|
||||
$update_data = $this->get_update_data();
|
||||
|
||||
// only do if an update is available
|
||||
if( $update_data === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_thickbox();
|
||||
add_action( 'admin_notices', array( $this, 'show_update_details' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show update link.
|
||||
* Opens Thickbox with Changelog.
|
||||
*/
|
||||
public function show_update_details() {
|
||||
|
||||
$update_data = $this->get_update_data();
|
||||
|
||||
// only show if an update is available
|
||||
if( $update_data === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$update_url = wp_nonce_url( 'update.php?action=upgrade-theme&theme=' . urlencode( $this->product->get_slug() ), 'upgrade-theme_' . $this->product->get_slug() );
|
||||
$update_onclick = ' onclick="if ( confirm(\'' . esc_js( __( "Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update." ) ) . '\') ) {return true;}return false;"';
|
||||
?>
|
||||
<div id="update-nag">
|
||||
<?php
|
||||
printf(
|
||||
__( '<strong>%s version %s</strong> is available. <a href="%s" class="thickbox" title="%s">Check out what\'s new</a> or <a href="%s" %s>update now</a>.' ),
|
||||
$this->product->get_item_name(),
|
||||
$update_data->new_version,
|
||||
'#TB_inline?width=640&inlineId=' . $this->product->get_slug() . '_changelog',
|
||||
$this->get_item_name(),
|
||||
$update_url,
|
||||
$update_onclick
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<div id="<?php echo $this->product->get_slug(); ?>_changelog" style="display: none;">
|
||||
<?php echo wpautop( $update_data->sections['changelog'] ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get update data
|
||||
*
|
||||
* This gets the update data from a transient (12 hours), if set.
|
||||
* If not, it will make a remote request and get the update data.
|
||||
*
|
||||
* @return object $update_data Object containing the update data
|
||||
*/
|
||||
public function get_update_data() {
|
||||
|
||||
$api_response = $this->get_remote_data();
|
||||
|
||||
if( false === $api_response ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$update_data = $api_response;
|
||||
|
||||
// check if a new version is available.
|
||||
if ( version_compare( $this->get_theme_version(), $update_data->new_version, '>=' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// an update is available
|
||||
return $update_data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( ! class_exists( "Yoast_Update_Manager", false ) ) {
|
||||
|
||||
class Yoast_Update_Manager {
|
||||
|
||||
/**
|
||||
* @var Yoast_Product
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* @var Yoast_License_Manager
|
||||
*/
|
||||
protected $license_manager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $error_message = '';
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
protected $update_response = null;
|
||||
|
||||
/**
|
||||
* @var string The transient name storing the API response
|
||||
*/
|
||||
private $response_transient_key = '';
|
||||
|
||||
/**
|
||||
* @var string The transient name that stores failed request tries
|
||||
*/
|
||||
private $request_failed_transient_key = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $api_url The url to the EDD shop
|
||||
* @param string $item_name The item name in the EDD shop
|
||||
* @param string $license_key The (valid) license key
|
||||
* @param string $slug The slug. This is either the plugin main file path or the theme slug.
|
||||
* @param string $version The current plugin or theme version
|
||||
* @param string $author (optional) The item author.
|
||||
*/
|
||||
public function __construct( Yoast_Product $product, $license_manager ) {
|
||||
$this->product = $product;
|
||||
$this->license_manager = $license_manager;
|
||||
|
||||
// generate transient names
|
||||
$this->response_transient_key = $this->product->get_transient_prefix() . '-update-response';
|
||||
$this->request_failed_transient_key = $this->product->get_transient_prefix() . '-update-request-failed';
|
||||
|
||||
// maybe delete transient
|
||||
$this->maybe_delete_transients();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the various transients
|
||||
* If we're on the update-core.php?force-check=1 page
|
||||
*/
|
||||
private function maybe_delete_transients() {
|
||||
global $pagenow;
|
||||
|
||||
if( $pagenow === 'update-core.php' && isset( $_GET['force-check'] ) ) {
|
||||
delete_transient( $this->response_transient_key );
|
||||
delete_transient( $this->request_failed_transient_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the update check returned a WP_Error, show it to the user
|
||||
*/
|
||||
public function show_update_error() {
|
||||
|
||||
if ( $this->error_message === '' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="error">
|
||||
<p><?php printf( __( '%s failed to check for updates because of the following error: <em>%s</em>', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->error_message ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the API and, if successfull, returns the object delivered by the API.
|
||||
*
|
||||
* @uses get_bloginfo()
|
||||
* @uses wp_remote_post()
|
||||
* @uses is_wp_error()
|
||||
*
|
||||
* @return false||object
|
||||
*/
|
||||
private function call_remote_api() {
|
||||
|
||||
// only check if the failed transient is not set (or if it's expired)
|
||||
if( get_transient( $this->request_failed_transient_key ) !== false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// start request process
|
||||
global $wp_version;
|
||||
|
||||
// set a transient to prevent failed update checks on every page load
|
||||
// this transient will be removed if a request succeeds
|
||||
set_transient( $this->request_failed_transient_key, 'failed', 10800 );
|
||||
|
||||
// setup api parameters
|
||||
$api_params = array(
|
||||
'edd_action' => 'get_version',
|
||||
'license' => $this->license_manager->get_license_key(),
|
||||
'item_name' => $this->product->get_item_name(),
|
||||
'wp_version' => $wp_version,
|
||||
'item_version' => $this->product->get_version(),
|
||||
'url' => home_url(),
|
||||
'slug' => $this->product->get_slug()
|
||||
);
|
||||
|
||||
// setup request parameters
|
||||
$request_params = array(
|
||||
'method' => 'POST',
|
||||
'body' => $api_params
|
||||
);
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class-api-request.php';
|
||||
$request = new Yoast_API_Request( $this->product->get_api_url(), $request_params );
|
||||
|
||||
if( $request->is_valid() !== true ) {
|
||||
|
||||
// show error message
|
||||
$this->error_message = $request->get_error_message();
|
||||
add_action( 'admin_notices', array( $this, 'show_update_error' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// request succeeded, delete transient indicating a request failed
|
||||
delete_transient( $this->request_failed_transient_key );
|
||||
|
||||
// decode response
|
||||
$response = $request->get_response();
|
||||
|
||||
// check if response returned that a given site was inactive
|
||||
if( isset( $response->license_check ) && ! empty( $response->license_check ) && $response->license_check != 'valid' ) {
|
||||
|
||||
// deactivate local license
|
||||
$this->license_manager->set_license_status( 'invalid' );
|
||||
|
||||
// show notice to let the user know we deactivated his/her license
|
||||
$this->error_message = __( "This site has not been activated properly on yoast.com and thus cannot check for future updates. Please activate your site with a valid license key.", $this->product->get_text_domain() );
|
||||
add_action( 'admin_notices', array( $this, 'show_update_error' ) );
|
||||
}
|
||||
|
||||
$response->sections = maybe_unserialize( $response->sections );
|
||||
|
||||
// store response
|
||||
set_transient( $this->response_transient_key, $response, 10800 );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remote product data (from the EDD API)
|
||||
*
|
||||
* - If it was previously fetched in the current requests, this gets it from the instance property
|
||||
* - Next, it tries the 3-hour transient
|
||||
* - Next, it calls the remote API and stores the result
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
protected function get_remote_data() {
|
||||
|
||||
// always use property if it's set
|
||||
if( null !== $this->update_response ) {
|
||||
return $this->update_response;
|
||||
}
|
||||
|
||||
// get cached remote data
|
||||
$data = $this->get_cached_remote_data();
|
||||
|
||||
// if cache is empty or expired, call remote api
|
||||
if( $data === false ) {
|
||||
$data = $this->call_remote_api();
|
||||
}
|
||||
|
||||
$this->update_response = $data;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remote product data from a 3-hour transient
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private function get_cached_remote_data() {
|
||||
|
||||
$data = get_transient( $this->response_transient_key );
|
||||
|
||||
if( $data ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
Plugin Name: Sample Plugin
|
||||
Version: 1.0
|
||||
Plugin URI: https://yoast.com/
|
||||
Description: A sample plugin to test the License Manager
|
||||
Author: Yoast, DvanKooten
|
||||
Author URI: http://yoast.com/
|
||||
Text Domain: sample-plugin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Sample_Plugin
|
||||
*
|
||||
*/
|
||||
class Sample_Plugin {
|
||||
|
||||
public function __construct() {
|
||||
|
||||
// we only need license stuff inside the admin area
|
||||
if ( is_admin() ) {
|
||||
|
||||
// add menu item
|
||||
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
||||
|
||||
// load license class
|
||||
$this->load_license_manager();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the License_Plugin_Manager class
|
||||
*
|
||||
* The class will take care of the rest: notices, license (de)activations, updates, etc..
|
||||
*/
|
||||
public function load_license_manager() {
|
||||
|
||||
// Instantiate license class
|
||||
$license_manager = new Yoast_Plugin_License_Manager( new Sample_Product() );
|
||||
|
||||
// Setup the required hooks
|
||||
$license_manager->setup_hooks();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add license page and add it to Themes menu
|
||||
*/
|
||||
public function add_license_menu() {
|
||||
$theme_page = add_options_page( sprintf( __( '%s License', $this->text_domain ), $this->item_name ), sprintf( __( '%s License', $this->text_domain ), $this->item_name ), 'manage_options', $this->text_domain . '-license', array( $this, 'show_license_page' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows license page
|
||||
*/
|
||||
public function show_license_page() {
|
||||
|
||||
// Instantiate license class
|
||||
$license_manager = new Yoast_Plugin_License_Manager( new Sample_Product() );
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<?php //settings_errors(); ?>
|
||||
|
||||
<?php $license_manager->show_license_form( false ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
new Sample_Plugin();
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class Sample_Product
|
||||
*
|
||||
* Our sample product class
|
||||
*/
|
||||
class Sample_Product extends Yoast_Product {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(
|
||||
'https://yoast.com',
|
||||
'Sample Product',
|
||||
'sample-product',
|
||||
'1.0',
|
||||
'https://yoast.com/wordpress/plugins/sample-product/',
|
||||
'admin.php?page=sample-product',
|
||||
'sample-product',
|
||||
'Yoast'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
if( is_admin() ) {
|
||||
|
||||
// Instantiate license class
|
||||
$license_manager = new Yoast_Theme_License_Manager( new Sample_Product() );
|
||||
|
||||
// Setup the required hooks
|
||||
$license_manager->setup_hooks();
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
header( 'HTTP/1.0 403 Forbidden' );
|
||||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Yoast_Product $product
|
||||
*/
|
||||
$product = $this->product;
|
||||
|
||||
$this->show_license_form_heading();
|
||||
|
||||
// Output form tags if we're not embedded in another form
|
||||
if( ! $embedded ) {
|
||||
echo '<form method="post" action="">';
|
||||
}
|
||||
|
||||
wp_nonce_field( $nonce_name, $nonce_name ); ?>
|
||||
<table class="form-table yoast-license-form">
|
||||
<tbody>
|
||||
<tr valign="top">
|
||||
<th scope="row" valign="top"><?php _e( 'License status', $product->get_text_domain() ); ?></th>
|
||||
<td>
|
||||
<?php if( $this->license_is_valid() ) { ?>
|
||||
<span style="color: white; background: limegreen; padding:3px 6px;">ACTIVE</span> - you are receiving updates.
|
||||
<?php } else { ?>
|
||||
<span style="color:white; background: red; padding: 3px 6px;">INACTIVE</span> - you are <strong>not</strong> receiving updates.
|
||||
<?php } ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row" valign="top"><?php _e('Toggle license status', $product->get_text_domain() ); ?></th>
|
||||
<td class="yoast-license-toggler">
|
||||
|
||||
<?php if( $this->license_is_valid() ) { ?>
|
||||
<button name="<?php echo esc_attr( $action_name ); ?>" type="submit" class="button-secondary yoast-license-deactivate" value="deactivate"><?php echo esc_html_e( 'Deactivate License', $product->get_text_domain() ); ?></button>
|
||||
<small><?php _e( '(deactivate your license so you can activate it on another WordPress site)', $product->get_text_domain() ); ?></small>
|
||||
<?php } else {
|
||||
|
||||
if( $this->get_license_key() !== '') { ?>
|
||||
<button name="<?php echo esc_attr( $action_name ); ?>" type="submit" class="button-secondary yoast-license-activate" value="activate" /><?php echo esc_html_e('Activate License', $product->get_text_domain() ); ?></button>
|
||||
<?php } else {
|
||||
_e( 'Please enter a license key in the field below first.', $product->get_text_domain() );
|
||||
}
|
||||
|
||||
} ?>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row" valign="top"><?php _e( 'License Key', $product->get_text_domain() ); ?></th>
|
||||
<td>
|
||||
<input name="<?php echo esc_attr( $key_name ); ?>" type="text" class="regular-text yoast-license-key-field <?php if( $obfuscate ) { ?>yoast-license-obfuscate<?php } ?>" value="<?php echo esc_attr( $visible_license_key ); ?>" placeholder="<?php echo esc_attr( sprintf( __( 'Paste your %s license key here..', $product->get_text_domain() ), $product->get_item_name() ) ); ?>" <?php if( $readonly ) { echo 'readonly="readonly"'; } ?> />
|
||||
<?php if( $this->license_constant_is_defined ) { ?>
|
||||
<p class="help"><?php printf( __( "You defined your license key using the %s PHP constant.", $product->get_text_domain() ), '<code>' . $this->license_constant_name . '</code>' ); ?></p>
|
||||
<?php } ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
|
||||
if( $this->license_is_valid() ) {
|
||||
|
||||
$expiry_date = strtotime( $this->get_license_expiry_date() );
|
||||
|
||||
if( $expiry_date !== false ) {
|
||||
echo '<p>';
|
||||
|
||||
printf( __( 'Your %s license will expire on %s.', $product->get_text_domain() ), $product->get_item_name(), date('F jS Y', $expiry_date ) );
|
||||
|
||||
if( strtotime( '+3 months' ) > $expiry_date ) {
|
||||
printf( ' ' . __('%sRenew your license now%s.', $product->get_text_domain() ), '<a href="'. $this->product->get_tracking_url( 'renewal' ) .'">', '</a>' );
|
||||
}
|
||||
|
||||
echo '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
// Only show a "Save Changes" button and end form if we're not embedded in another form.
|
||||
if( ! $embedded ) {
|
||||
|
||||
// only show "Save Changes" button if license is not activated and not defined with a constant
|
||||
if( $readonly === false ) {
|
||||
submit_button();
|
||||
}
|
||||
|
||||
echo '</form>';
|
||||
}
|
||||
|
||||
$product = null;
|
||||
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
header( 'HTTP/1.0 403 Forbidden' );
|
||||
die;
|
||||
}
|
||||
?><script type="text/javascript">
|
||||
(function($) {
|
||||
|
||||
if( typeof YoastLicenseManager !== "undefined" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.YoastLicenseManager = (function () {
|
||||
|
||||
function init() {
|
||||
var $keyInputs = $(".yoast-license-key-field.yoast-license-obfuscate");
|
||||
var $actionButtons = $('.yoast-license-toggler button');
|
||||
var $submitButtons = $('input[type="submit"], button[type="submit"]');
|
||||
|
||||
$submitButtons.click( addDisableEvent );
|
||||
$actionButtons.click( actOnLicense );
|
||||
$keyInputs.click( setEmptyValue );
|
||||
}
|
||||
|
||||
function setEmptyValue() {
|
||||
if( ! $(this).is('[readonly]') ) {
|
||||
$(this).val('');
|
||||
}
|
||||
}
|
||||
|
||||
function actOnLicense() {
|
||||
var $formScope = $(this).closest('form');
|
||||
var $actionButton = $formScope.find('.yoast-license-toggler button');
|
||||
|
||||
// fake input field with exact same name => value
|
||||
$("<input />")
|
||||
.attr('type', 'hidden')
|
||||
.attr( 'name', $(this).attr('name') )
|
||||
.val( $(this).val() )
|
||||
.appendTo( $formScope );
|
||||
|
||||
// change button text to show we're working..
|
||||
var text = ( $actionButton.hasClass('yoast-license-activate') ) ? "Activating..." : "Deactivating...";
|
||||
$actionButton.text( text );
|
||||
}
|
||||
|
||||
function addDisableEvent() {
|
||||
var $formScope = $(this).closest('form');
|
||||
$formScope.submit(disableButtons);
|
||||
}
|
||||
|
||||
function disableButtons() {
|
||||
var $formScope = $(this).closest('form');
|
||||
var $submitButton = $formScope.find('input[type="submit"], button[type="submit"]');
|
||||
$submitButton.prop( 'disabled', true );
|
||||
}
|
||||
|
||||
return {
|
||||
init: init
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
YoastLicenseManager.init();
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
$active_tab = filter_input( INPUT_GET, 'tab' );
|
||||
|
||||
$tabs = array(
|
||||
'breadcrumbs' => array(
|
||||
'label' => __( 'Breadcrumbs', 'wordpress-seo' ),
|
||||
'opt_group' => 'wpseo_internallinks',
|
||||
),
|
||||
'permalinks' => array(
|
||||
'label' => __( 'Permalinks', 'wordpress-seo' ),
|
||||
'opt_group' => 'wpseo_permalinks',
|
||||
),
|
||||
'rss' => array(
|
||||
'label' => __( 'RSS', 'wordpress-seo' ),
|
||||
'opt_group' => 'wpseo_rss',
|
||||
),
|
||||
);
|
||||
|
||||
if ( '' === $active_tab || ! in_array( $active_tab, array_keys( $tabs ) ) ) {
|
||||
$active_tab = 'breadcrumbs';
|
||||
}
|
||||
|
||||
Yoast_Form::get_instance()->admin_header( true, $tabs[ $active_tab ]['opt_group'] );
|
||||
|
||||
?>
|
||||
<h2 class="nav-tab-wrapper">
|
||||
<?php
|
||||
foreach ( $tabs as $tab_key => $tab_opt ) {
|
||||
$active = '';
|
||||
if ( $active_tab == $tab_key ) {
|
||||
$active = ' nav-tab-active';
|
||||
}
|
||||
echo '<a class="nav-tab' . $active . '" id="' . $tab_key . '-tab" href="' . admin_url( 'admin.php?page=wpseo_advanced&tab=' . $tab_key ) . '">' . $tab_opt['label'] . '</a>';
|
||||
}
|
||||
?>
|
||||
</h2>
|
||||
<br/>
|
||||
<?php
|
||||
|
||||
require_once WPSEO_PATH . 'admin/views/tab-' . $active_tab . '.php';
|
||||
|
||||
Yoast_Form::get_instance()->admin_footer();
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -11,18 +9,15 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
if ( filter_input( INPUT_GET, 'intro' ) ) {
|
||||
require WPSEO_PATH . 'admin/views/about.php';
|
||||
return;
|
||||
}
|
||||
|
||||
$options = get_option( 'wpseo' );
|
||||
|
||||
if ( isset( $_GET['allow_tracking'] ) && check_admin_referer( 'wpseo_activate_tracking', 'nonce' ) ) {
|
||||
$options['tracking_popup_done'] = true;
|
||||
if ( $_GET['allow_tracking'] == 'yes' ) {
|
||||
$options['yoast_tracking'] = true;
|
||||
}
|
||||
else {
|
||||
$options['yoast_tracking'] = false;
|
||||
}
|
||||
$options['yoast_tracking'] = ( $_GET['allow_tracking'] == 'yes' );
|
||||
update_option( 'wpseo', $options );
|
||||
|
||||
if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
|
||||
@@ -61,7 +56,7 @@ if ( isset( $_GET['fixmetadesc'] ) && check_admin_referer( 'wpseo-fix-metadesc',
|
||||
$header_file = fopen( $path . '/header.php', 'w+' );
|
||||
if ( $header_file ) {
|
||||
if ( fwrite( $header_file, $fcontent ) !== false ) {
|
||||
$msg .= __( 'Removed hardcoded meta description.', 'wordpress-seo' );
|
||||
$msg .= __( 'Removed hardcoded meta description.', 'wordpress-seo' );
|
||||
$options['theme_has_description'] = false;
|
||||
$options['theme_description_found'] = '';
|
||||
update_option( 'wpseo', $options );
|
||||
@@ -98,75 +93,147 @@ if ( isset( $_GET['checkmetadesc'] ) ) {
|
||||
$_SERVER['REQUEST_URI'] = remove_query_arg( array( 'nonce', 'checkmetadesc' ), $_SERVER['REQUEST_URI'] );
|
||||
}
|
||||
}
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
|
||||
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo' ), 'wpseo' );
|
||||
$yform->admin_header( true, 'wpseo' );
|
||||
|
||||
do_action( 'wpseo_all_admin_notices' );
|
||||
|
||||
if ( is_array( $options['blocking_files'] ) && count( $options['blocking_files'] ) > 0 ) {
|
||||
echo '<p id="blocking_files" class="wrong">'
|
||||
. '<a href="javascript:wpseo_killBlockingFiles(\'' . esc_js( wp_create_nonce( 'wpseo-blocking-files' ) ) . '\')" class="button fixit">' . __( 'Fix it.', 'wordpress-seo' ) . '</a>'
|
||||
. __( 'The following file(s) is/are blocking your XML sitemaps from working properly:', 'wordpress-seo' ) . '<br />';
|
||||
echo '<p id="blocking_files" class="wrong">';
|
||||
echo '<a href="javascript:wpseo_killBlockingFiles(\'', esc_js( wp_create_nonce( 'wpseo-blocking-files' ) ), '\')" class="button fixit">', __( 'Fix it.', 'wordpress-seo' ), '</a>';
|
||||
echo __( 'The following file(s) is/are blocking your XML sitemaps from working properly:', 'wordpress-seo' ), '<br />';
|
||||
foreach ( $options['blocking_files'] as $file ) {
|
||||
echo esc_html( $file ) . '<br/>';
|
||||
echo esc_html( $file ), '<br/>';
|
||||
}
|
||||
echo __( 'Either delete them (this can be done with the "Fix it" button) or disable WP SEO XML sitemaps.', 'wordpress-seo' );
|
||||
echo '</p>';
|
||||
unset( $file );
|
||||
echo '
|
||||
', __( 'Either delete them (this can be done with the "Fix it" button) or disable WP SEO XML sitemaps.', 'wordpress-seo' ), '
|
||||
</p>';
|
||||
}
|
||||
|
||||
|
||||
if ( $options['theme_description_found'] !== '' ) {
|
||||
echo '<p id="metadesc_found notice" class="wrong settings_error">'
|
||||
. '<a href="' . esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'wpseo-fix-metadesc' ) ), admin_url( 'admin.php?page=wpseo_dashboard&fixmetadesc' ) ) ) . '" class="button fixit">' . __( 'Fix it.', 'wordpress-seo' ) . '</a>'
|
||||
. ' <a href="' . esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'wpseo-check-metadesc' ) ), admin_url( 'admin.php?page=wpseo_dashboard&checkmetadesc' ) ) ) . '" class="button checkit">' . __( 'Re-check theme.', 'wordpress-seo' ) . '</a>'
|
||||
. __( 'Your theme contains a meta description, which blocks WordPress SEO from working properly, please delete the following line, or press fix it:', 'wordpress-seo' ) . '<br />';
|
||||
echo '<code>' . esc_html( $options['theme_description_found'] ) . '</code>';
|
||||
echo '<p id="metadesc_found notice" class="wrong settings_error">';
|
||||
echo '<a href="', esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'wpseo-fix-metadesc' ) ), admin_url( 'admin.php?page=wpseo_dashboard&fixmetadesc' ) ) ), '" class="button fixit">', __( 'Fix it.', 'wordpress-seo' ), '</a>';
|
||||
echo ' <a href="', esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'wpseo-check-metadesc' ) ), admin_url( 'admin.php?page=wpseo_dashboard&checkmetadesc' ) ) ), '" class="button checkit">', __( 'Re-check theme.', 'wordpress-seo' ), '</a>';
|
||||
echo __( 'Your theme contains a meta description, which blocks WordPress SEO from working properly, please delete the following line, or press fix it:', 'wordpress-seo' ), '<br />';
|
||||
echo '<code>', esc_html( $options['theme_description_found'] ), '</code>';
|
||||
echo '</p>';
|
||||
}
|
||||
|
||||
|
||||
if ( strpos( get_option( 'permalink_structure' ), '%postname%' ) === false && $options['ignore_permalink'] === false ) {
|
||||
echo '<p id="wrong_permalink" class="wrong">'
|
||||
. '<a href="' . esc_url( admin_url( 'options-permalink.php' ) ) . '" class="button fixit">' . __( 'Fix it.', 'wordpress-seo' ) . '</a>'
|
||||
. '<a href="javascript:wpseo_setIgnore(\'permalink\',\'wrong_permalink\',\'' . esc_js( wp_create_nonce( 'wpseo-ignore' ) ) . '\');" class="button fixit">' . __( 'Ignore.', 'wordpress-seo' ) . '</a>'
|
||||
. __( 'You do not have your postname in the URL of your posts and pages, it is highly recommended that you do. Consider setting your permalink structure to <strong>/%postname%/</strong>.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p id="wrong_permalink" class="wrong">';
|
||||
echo '<a href="', esc_url( admin_url( 'options-permalink.php' ) ), '" class="button fixit">', __( 'Fix it.', 'wordpress-seo' ), '</a>';
|
||||
echo '<a href="javascript:wpseo_setIgnore(\'permalink\',\'wrong_permalink\',\'', esc_js( wp_create_nonce( 'wpseo-ignore' ) ), '\');" class="button fixit">', __( 'Ignore.', 'wordpress-seo' ), '</a>';
|
||||
echo __( 'You do not have your postname in the URL of your posts and pages, it is highly recommended that you do. Consider setting your permalink structure to <strong>/%postname%/</strong>.', 'wordpress-seo' ), '</p>';
|
||||
}
|
||||
|
||||
if ( get_option( 'page_comments' ) && $options['ignore_page_comments'] === false ) {
|
||||
echo '<p id="wrong_page_comments" class="wrong">'
|
||||
. '<a href="javascript:setWPOption(\'page_comments\',\'0\',\'wrong_page_comments\',\'' . esc_js( wp_create_nonce( 'wpseo-setoption' ) ) . '\');" class="button fixit">' . __( 'Fix it.', 'wordpress-seo' ) . '</a>'
|
||||
. '<a href="javascript:wpseo_setIgnore(\'page_comments\',\'wrong_page_comments\',\'' . esc_js( wp_create_nonce( 'wpseo-ignore' ) ) . '\');" class="button fixit">' . __( 'Ignore.', 'wordpress-seo' ) . '</a>'
|
||||
. __( 'Paging comments is enabled, this is not needed in 999 out of 1000 cases, so the suggestion is to disable it, to do that, simply uncheck the box before "Break comments into pages..."', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p id="wrong_page_comments" class="wrong">';
|
||||
echo '<a href="javascript:setWPOption(\'page_comments\',\'0\',\'wrong_page_comments\',\'', esc_js( wp_create_nonce( 'wpseo-setoption' ) ), '\');" class="button fixit">', __( 'Fix it.', 'wordpress-seo' ), '</a>';
|
||||
echo '<a href="javascript:wpseo_setIgnore(\'page_comments\',\'wrong_page_comments\',\'', esc_js( wp_create_nonce( 'wpseo-ignore' ) ), '\');" class="button fixit">', __( 'Ignore.', 'wordpress-seo' ), '</a>';
|
||||
echo __( 'Paging comments is enabled, this is not needed in 999 out of 1000 cases, so the suggestion is to disable it, to do that, simply uncheck the box before "Break comments into pages..."', 'wordpress-seo' ), '</p>';
|
||||
}
|
||||
|
||||
echo '<h2>' . __( 'General', 'wordpress-seo' ) . '</h2>';
|
||||
?>
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab nav-tab-active" id="general-tab"
|
||||
href="#top#general"><?php _e( 'General', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="knowledge-graph-tab"
|
||||
href="#top#knowledge-graph"><?php echo ( 'company' === $options['company_or_person'] ) ? __( 'Company Info', 'wordpress-seo' ) : __( 'Your Info', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="webmaster-tools-tab"
|
||||
href="#top#webmaster-tools"><?php _e( 'Webmaster Tools', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="security-tab" href="#top#security"><?php _e( 'Security', 'wordpress-seo' ); ?></a>
|
||||
</h2>
|
||||
|
||||
if ( $options['ignore_tour'] === true ) {
|
||||
echo '<label class="select">' . __( 'Introduction Tour:', 'wordpress-seo' ) . '</label><a class="button-secondary" href="' . esc_url( admin_url( 'admin.php?page=wpseo_dashboard&wpseo_restart_tour' ) ) . '">' . __( 'Start Tour', 'wordpress-seo' ) . '</a>';
|
||||
echo '<p class="desc label">' . __( 'Take this tour to quickly learn about the use of this plugin.', 'wordpress-seo' ) . '</p>';
|
||||
}
|
||||
<div id="general" class="wpseotab">
|
||||
<p>
|
||||
<strong><?php _e( 'Tracking', 'wordpress-seo' ); ?></strong><br/>
|
||||
<?php _e( "To maintain a plugin as big as WordPress SEO, we need to know what we're dealing with: what kinds of other plugins our users are using, what themes, etc. Please allow us to track that data from your install. It will not track <em>any</em> user details, so your security and privacy are safe with us.", 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
<?php $yform->checkbox( 'yoast_tracking', __( 'Allow tracking of this WordPress install\'s anonymous data.', 'wordpress-seo' ) ); ?>
|
||||
|
||||
echo '<label class="select">' . __( 'Default Settings:', 'wordpress-seo' ) . '</label><a onclick="if( !confirm(\'' . __( 'Are you sure you want to reset your SEO settings?', 'wordpress-seo' ) . '\') ) return false;" class="button-secondary" href="' . esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'wpseo_reset_defaults' ) ), admin_url( 'admin.php?page=wpseo_dashboard&wpseo_reset_defaults' ) ) ) . '">' . __( 'Reset Default Settings', 'wordpress-seo' ) . '</a>';
|
||||
echo '<p class="desc label">' . __( 'If you want to restore a site to the default WordPress SEO settings, press this button.', 'wordpress-seo' ) . '</p>';
|
||||
<br/>
|
||||
|
||||
echo '<h2>' . __( 'Tracking', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->checkbox( 'yoast_tracking', __( 'Allow tracking of this WordPress install\'s anonymous data.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( "To maintain a plugin as big as WordPress SEO, we need to know what we're dealing with: what kinds of other plugins our users are using, what themes, etc. Please allow us to track that data from your install. It will not track <em>any</em> user details, so your security and privacy are safe with us.", 'wordpress-seo' ) . '</p>';
|
||||
<?php if ( $options['ignore_tour'] === true ) { ?>
|
||||
<p>
|
||||
<strong><?php _e( 'Introduction Tour', 'wordpress-seo' ); ?></strong><br/>
|
||||
<?php _e( 'Take this tour to quickly learn about the use of this plugin.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
<p>
|
||||
<?php $yform->label( __( 'Introduction Tour:', 'wordpress-seo' ), array( 'class' => 'select' ) ); ?>
|
||||
<a class="button-secondary"
|
||||
href="<?php echo esc_url( admin_url( 'admin.php?page=wpseo_dashboard&wpseo_restart_tour=1' ) ); ?>"><?php _e( 'Start Tour', 'wordpress-seo' ); ?></a>
|
||||
</p>
|
||||
<?php } ?>
|
||||
|
||||
echo '<h2>' . __( 'Security', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->checkbox( 'disableadvanced_meta', __( 'Disable the Advanced part of the WordPress SEO meta box', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'Unchecking this box allows authors and editors to redirect posts, noindex them and do other things you might not want if you don\'t trust your authors.', 'wordpress-seo' ) . '</p>';
|
||||
<br/>
|
||||
|
||||
echo '<h2>' . __( 'Webmaster Tools', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<p>' . __( 'You can use the boxes below to verify with the different Webmaster Tools, if your site is already verified, you can just forget about these. Enter the verify meta values for:', 'wordpress-seo' ) . '</p>';
|
||||
echo $wpseo_admin_pages->textinput( 'alexaverify', '<a target="_blank" href="http://www.alexa.com/siteowners/claim">' . __( 'Alexa Verification ID', 'wordpress-seo' ) . '</a>' );
|
||||
echo $wpseo_admin_pages->textinput( 'msverify', '<a target="_blank" href="' . esc_url( 'http://www.bing.com/webmaster/?rfp=1#/Dashboard/?url=' . urlencode( str_replace( 'http://', '', get_bloginfo( 'url' ) ) ) ) . '">' . __( 'Bing Webmaster Tools', 'wordpress-seo' ) . '</a>' );
|
||||
echo $wpseo_admin_pages->textinput( 'googleverify', '<a target="_blank" href="' . esc_url( 'https://www.google.com/webmasters/verification/verification?hl=en&siteUrl=' . urlencode( get_bloginfo( 'url' ) ) . '/' ) . '">' . __( 'Google Webmaster Tools', 'wordpress-seo' ) . '</a>' );
|
||||
echo $wpseo_admin_pages->textinput( 'pinterestverify', '<a target="_blank" href="https://help.pinterest.com/entries/22488487-Verify-with-HTML-meta-tags">' . __( 'Pinterest', 'wordpress-seo' ) . '</a>' );
|
||||
echo $wpseo_admin_pages->textinput( 'yandexverify', '<a target="_blank" href="http://help.yandex.com/webmaster/service/rights.xml#how-to">' . __( 'Yandex Webmaster Tools', 'wordpress-seo' ) . '</a>' );
|
||||
<p>
|
||||
<strong><?php _e( 'Restore Default Settings', 'wordpress-seo' ); ?></strong><br/>
|
||||
<?php _e( 'If you want to restore a site to the default WordPress SEO settings, press this button.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<?php $yform->label( __( 'Default Settings:', 'wordpress-seo' ), array( 'class' => 'select' ) ); ?>
|
||||
<a onclick="if( !confirm('<?php _e( 'Are you sure you want to reset your SEO settings?', 'wordpress-seo' ); ?>') ) return false;" class="button" href="<?php echo esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'wpseo_reset_defaults' ) ), admin_url( 'admin.php?page=wpseo_dashboard&wpseo_reset_defaults=1' ) ) ); ?>"><?php _e( 'Reset Default Settings', 'wordpress-seo' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="knowledge-graph" class="wpseotab">
|
||||
<h3><?php _e( 'Website name', 'wordpress-seo' ); ?></h3>
|
||||
<p>
|
||||
<?php
|
||||
_e( 'Google shows your website\'s name in the search results, we will default to your site name but you can adapt it here. You can also provide an alternate website name you want Google to consider.', 'wordpress-seo' );
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
$yform->textinput( 'website_name', __( 'Website name', 'wordpress-seo' ), array( 'placeholder' => get_bloginfo( 'name' ) ) );
|
||||
$yform->textinput( 'alternate_website_name', __( 'Alternate name', 'wordpress-seo' ) );
|
||||
?>
|
||||
<h3><?php _e( 'Company or person', 'wordpress-seo' ); ?></h3>
|
||||
<p>
|
||||
<?php
|
||||
// @todo add KB link - JdV
|
||||
_e( 'This data is shown as metadata in your site. It is intended to appear in Google\'s Knowledge Graph. You can be either a company, or a person, choose either:', 'wordpress-seo' );
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
$yform->select( 'company_or_person', __( 'Company or person', 'wordpress-seo' ), array(
|
||||
'' => __( 'Choose whether you\'re a company or person', 'wordpress-seo' ),
|
||||
'company' => __( 'Company', 'wordpress-seo' ),
|
||||
'person' => __( 'Person', 'wordpress-seo' ),
|
||||
) );
|
||||
?>
|
||||
<div id="knowledge-graph-company">
|
||||
<h2><?php _e( 'Company', 'wordpress-seo' ); ?></h2>
|
||||
<?php
|
||||
$yform->textinput( 'company_name', __( 'Company Name', 'wordpress-seo' ) );
|
||||
$yform->media_input( 'company_logo', __( 'Company Logo', 'wordpress-seo' ) );
|
||||
?>
|
||||
</div>
|
||||
<div id="knowledge-graph-person">
|
||||
<h2><?php _e( 'Person', 'wordpress-seo' ); ?></h2>
|
||||
<?php $yform->textinput( 'person_name', __( 'Your name', 'wordpress-seo' ) ); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="webmaster-tools" class="wpseotab">
|
||||
<?php
|
||||
echo '<p>', __( 'You can use the boxes below to verify with the different Webmaster Tools, if your site is already verified, you can just forget about these. Enter the verify meta values for:', 'wordpress-seo' ), '</p>';
|
||||
$yform->textinput( 'alexaverify', '<a target="_blank" href="http://www.alexa.com/siteowners/claim">' . __( 'Alexa Verification ID', 'wordpress-seo' ) . '</a>' );
|
||||
$yform->textinput( 'msverify', '<a target="_blank" href="' . esc_url( 'http://www.bing.com/webmaster/?rfp=1#/Dashboard/?url=' . urlencode( str_replace( 'http://', '', get_bloginfo( 'url' ) ) ) ) . '">' . __( 'Bing Webmaster Tools', 'wordpress-seo' ) . '</a>' );
|
||||
$yform->textinput( 'googleverify', '<a target="_blank" href="' . esc_url( 'https://www.google.com/webmasters/verification/verification?hl=en&siteUrl=' . urlencode( get_bloginfo( 'url' ) ) . '/' ) . '">' . __( 'Google Webmaster Tools', 'wordpress-seo' ) . '</a>' );
|
||||
$yform->textinput( 'yandexverify', '<a target="_blank" href="http://help.yandex.com/webmaster/service/rights.xml#how-to">' . __( 'Yandex Webmaster Tools', 'wordpress-seo' ) . '</a>' );
|
||||
?>
|
||||
</div>
|
||||
<div id="security" class="wpseotab">
|
||||
<?php
|
||||
$yform->checkbox( 'disableadvanced_meta', __( 'Disable the Advanced part of the WordPress SEO meta box', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">', __( 'Unchecking this box allows authors and editors to redirect posts, noindex them and do other things you might not want if you don\'t trust your authors.', 'wordpress-seo' ), '</p>';
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
do_action( 'wpseo_dashboard' );
|
||||
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
$yform->admin_footer();
|
||||
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$robots_file = get_home_path() . 'robots.txt';
|
||||
$ht_access_file = get_home_path() . '.htaccess';
|
||||
|
||||
if ( isset( $_POST['create_robots'] ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
die( __( 'You cannot create a robots.txt file.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpseo_create_robots' );
|
||||
|
||||
ob_start();
|
||||
error_reporting( 0 );
|
||||
do_robots();
|
||||
$robots_content = ob_get_clean();
|
||||
|
||||
$f = fopen( $robots_file, 'x' );
|
||||
fwrite( $f, $robots_content );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['submitrobots'] ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
die( __( 'You cannot edit the robots.txt file.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpseo-robotstxt' );
|
||||
|
||||
if ( file_exists( $robots_file ) ) {
|
||||
$robotsnew = stripslashes( $_POST['robotsnew'] );
|
||||
if ( is_writable( $robots_file ) ) {
|
||||
$f = fopen( $robots_file, 'w+' );
|
||||
fwrite( $f, $robotsnew );
|
||||
fclose( $f );
|
||||
$msg = __( 'Updated Robots.txt', 'wordpress-seo' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['submithtaccess'] ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
die( __( 'You cannot edit the .htaccess file.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpseo-htaccess' );
|
||||
|
||||
if ( file_exists( $ht_access_file ) ) {
|
||||
$ht_access_new = stripslashes( $_POST['htaccessnew'] );
|
||||
if ( is_writeable( $ht_access_file ) ) {
|
||||
$f = fopen( $ht_access_file, 'w+' );
|
||||
fwrite( $f, $ht_access_new );
|
||||
fclose( $f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$wpseo_admin_pages->admin_header( false );
|
||||
if ( isset( $msg ) && ! empty( $msg ) ) {
|
||||
echo '<div id="message" style="width:94%;" class="updated fade"><p>' . esc_html( $msg ) . '</p></div>';
|
||||
}
|
||||
|
||||
$action_url = network_admin_url( 'admin.php?page=wpseo_files' ); // auto-falls back on admin_url for non-multisite
|
||||
|
||||
if ( ! file_exists( $robots_file ) ) {
|
||||
if ( is_writable( get_home_path() ) ) {
|
||||
$content = '<form action="' . esc_url( $action_url ) . '" method="post" id="robotstxtcreateform">';
|
||||
$content .= wp_nonce_field( 'wpseo_create_robots', '_wpnonce', true, false );
|
||||
$content .= '<p>' . __( 'You don\'t have a robots.txt file, create one here:', 'wordpress-seo' ) . '</p>';
|
||||
$content .= '<input type="submit" class="button" name="create_robots" value="' . __( 'Create robots.txt file', 'wordpress-seo' ) . '">';
|
||||
$content .= '</form>';
|
||||
}
|
||||
else {
|
||||
$content = '<p>' . __( 'If you had a robots.txt file and it was editable, you could edit it from here.', 'wordpress-seo' );
|
||||
}
|
||||
}
|
||||
else {
|
||||
$f = fopen( $robots_file, 'r' );
|
||||
|
||||
$content = '';
|
||||
if ( filesize( $robots_file ) > 0 ) {
|
||||
$content = fread( $f, filesize( $robots_file ) );
|
||||
}
|
||||
$robots_txt_content = esc_textarea( $content );
|
||||
|
||||
if ( ! is_writable( $robots_file ) ) {
|
||||
$content = '<p><em>' . __( 'If your robots.txt were writable, you could edit it from here.', 'wordpress-seo' ) . '</em></p>';
|
||||
$content .= '<textarea class="large-text code" disabled="disabled" rows="15" name="robotsnew">' . $robots_txt_content . '</textarea><br/>';
|
||||
} else {
|
||||
$content = '<form action="' . esc_url( $action_url ) . '" method="post" id="robotstxtform">';
|
||||
$content .= wp_nonce_field( 'wpseo-robotstxt', '_wpnonce', true, false );
|
||||
$content .= '<p>' . __( 'Edit the content of your robots.txt:', 'wordpress-seo' ) . '</p>';
|
||||
$content .= '<textarea class="large-text code" rows="15" name="robotsnew">' . $robots_txt_content . '</textarea><br/>';
|
||||
$content .= '<div class="submit"><input class="button" type="submit" name="submitrobots" value="' . __( 'Save changes to Robots.txt', 'wordpress-seo' ) . '" /></div>';
|
||||
$content .= '</form>';
|
||||
}
|
||||
}
|
||||
|
||||
$wpseo_admin_pages->postbox( 'robotstxt', __( 'Robots.txt', 'wordpress-seo' ), $content );
|
||||
|
||||
if ( ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stristr( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) === false ) && file_exists( $ht_access_file ) ) {
|
||||
$f = fopen( $ht_access_file, 'r' );
|
||||
|
||||
$contentht = '';
|
||||
if ( filesize( $ht_access_file ) > 0 ) {
|
||||
$contentht = fread( $f, filesize( $ht_access_file ) );
|
||||
}
|
||||
$contentht = esc_textarea( $contentht );
|
||||
|
||||
if ( ! is_writable( $ht_access_file ) ) {
|
||||
$content = '<p><em>' . __( 'If your .htaccess were writable, you could edit it from here.', 'wordpress-seo' ) . '</em></p>';
|
||||
$content .= '<textarea class="large-text code" disabled="disabled" rows="15" name="robotsnew">' . $contentht . '</textarea><br/>';
|
||||
} else {
|
||||
$content = '<form action="' . esc_url( $action_url ) . '" method="post" id="htaccessform">';
|
||||
$content .= wp_nonce_field( 'wpseo-htaccess', '_wpnonce', true, false );
|
||||
$content .= '<p>' . __( 'Edit the content of your .htaccess:', 'wordpress-seo' ) . '</p>';
|
||||
$content .= '<textarea class="large-text code" rows="15" name="htaccessnew">' . $contentht . '</textarea><br/>';
|
||||
$content .= '<div class="submit"><input class="button" type="submit" name="submithtaccess" value="' . __( 'Save changes to .htaccess', 'wordpress-seo' ) . '" /></div>';
|
||||
$content .= '</form>';
|
||||
}
|
||||
$wpseo_admin_pages->postbox( 'htaccess', __( '.htaccess file', 'wordpress-seo' ), $content );
|
||||
} elseif ( ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stristr( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) === false ) && ! file_exists( $ht_access_file ) ) {
|
||||
$content = '<p>' . __( 'If you had a .htaccess file and it was editable, you could edit it from here.', 'wordpress-seo' );
|
||||
$wpseo_admin_pages->postbox( 'htaccess', __( '.htaccess file', 'wordpress-seo' ), $content );
|
||||
}
|
||||
|
||||
$wpseo_admin_pages->admin_footer( false );
|
||||
@@ -1,508 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo [JRF => testers] Extensively test the export & import of the (new) settings!
|
||||
* If that all works fine, getting testers to export before and after upgrade will make testing easier.
|
||||
*
|
||||
* @todo [Yoast] The import for the RSS Footer plugin checks for data already entered via WP SEO,
|
||||
* the other import routines should do that too.
|
||||
*/
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$msg = '';
|
||||
if ( isset( $_POST['import'] ) || isset( $_GET['import'] ) ) {
|
||||
|
||||
check_admin_referer( 'wpseo-import' );
|
||||
|
||||
global $wpdb;
|
||||
$replace = false;
|
||||
$deletekw = false;
|
||||
|
||||
if ( isset( $_POST['wpseo']['deleteolddata'] ) && $_POST['wpseo']['deleteolddata'] == 'on' ) {
|
||||
$replace = true;
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importwoo'] ) ) {
|
||||
WPSEO_Options::initialize();
|
||||
|
||||
$sep = get_option( 'seo_woo_seperator' );
|
||||
$options = get_option( 'wpseo_titles' );
|
||||
|
||||
switch ( get_option( 'seo_woo_home_layout' ) ) {
|
||||
case 'a':
|
||||
$options['title-home-wpseo'] = '%%sitename%% ' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
case 'b':
|
||||
$options['title-home-wpseo'] = '%%sitename%% ' . get_option( 'seo_woo_paged_var' ) . ' %%pagenum%%';
|
||||
break;
|
||||
case 'c':
|
||||
$options['title-home-wpseo'] = '%%sitedesc%%';
|
||||
break;
|
||||
}
|
||||
if ( $replace ) {
|
||||
delete_option( 'seo_woo_home_layout' );
|
||||
}
|
||||
|
||||
switch ( get_option( 'seo_woo_single_layout' ) ) {
|
||||
case 'a':
|
||||
$options['title-post'] = '%%title%% ' . $sep . ' %%sitename%%';
|
||||
break;
|
||||
case 'b':
|
||||
$options['title-post'] = '%%title%%';
|
||||
break;
|
||||
case 'c':
|
||||
$options['title-post'] = '%%sitename%% ' . $sep . ' %%title%%';
|
||||
break;
|
||||
case 'd':
|
||||
$options['title-post'] = '%%title%% ' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
case 'e':
|
||||
$options['title-post'] = '%%sitename%% ' . $sep . ' %%title%% ' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
}
|
||||
if ( $replace ) {
|
||||
delete_option( 'seo_woo_single_layout' );
|
||||
}
|
||||
|
||||
switch ( get_option( 'seo_woo_page_layout' ) ) {
|
||||
case 'a':
|
||||
$options['title-page'] = '%%title%% ' . $sep . ' %%sitename%%';
|
||||
break;
|
||||
case 'b':
|
||||
$options['title-page'] = '%%title%%';
|
||||
break;
|
||||
case 'c':
|
||||
$options['title-page'] = '%%sitename%% ' . $sep . ' %%title%%';
|
||||
break;
|
||||
case 'd':
|
||||
$options['title-page'] = '%%title%% ' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
case 'e':
|
||||
$options['title-page'] = '%%sitename%% ' . $sep . ' %%title%% ' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
}
|
||||
if ( $replace ) {
|
||||
delete_option( 'seo_woo_page_layout' );
|
||||
}
|
||||
|
||||
$template = WPSEO_Options::get_default( 'wpseo_titles', 'title-tax-post' ); // the default is the same for all taxonomies, so post will do
|
||||
switch ( get_option( 'seo_woo_archive_layout' ) ) {
|
||||
case 'a':
|
||||
$template = '%%term_title%% ' . $sep . ' %%page%% ' . $sep . ' %%sitename%%';
|
||||
break;
|
||||
case 'b':
|
||||
$template = '%%term_title%%';
|
||||
break;
|
||||
case 'c':
|
||||
$template = '%%sitename%% ' . $sep . ' %%term_title%% ' . $sep . ' %%page%%';
|
||||
break;
|
||||
case 'd':
|
||||
$template = '%%term_title%% ' . $sep . ' %%page%%' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
case 'e':
|
||||
$template = '%%sitename%% ' . $sep . ' %%term_title%% ' . $sep . ' %%page%% ' . $sep . ' %%sitedesc%%';
|
||||
break;
|
||||
}
|
||||
$taxonomies = get_taxonomies( array( 'public' => true ), 'names' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
$options['title-tax-' . $tax] = $template;
|
||||
}
|
||||
}
|
||||
unset( $taxonomies, $tax, $template );
|
||||
if ( $replace ) {
|
||||
delete_option( 'seo_woo_archive_layout' );
|
||||
}
|
||||
|
||||
// Import the custom homepage description
|
||||
if ( 'c' == get_option( 'seo_woo_meta_home_desc' ) ) {
|
||||
$options['metadesc-home-wpseo'] = get_option( 'seo_woo_meta_home_desc_custom' );
|
||||
}
|
||||
if ( $replace ) {
|
||||
delete_option( 'seo_woo_meta_home_desc' );
|
||||
}
|
||||
|
||||
// Import the custom homepage keywords
|
||||
if ( 'c' == get_option( 'seo_woo_meta_home_key' ) ) {
|
||||
$options['metakey-home-wpseo'] = get_option( 'seo_woo_meta_home_key_custom' );
|
||||
}
|
||||
if ( $replace ) {
|
||||
delete_option( 'seo_woo_meta_home_key' );
|
||||
}
|
||||
|
||||
// If WooSEO is set to use the Woo titles, import those
|
||||
if ( 'true' == get_option( 'seo_woo_wp_title' ) ) {
|
||||
WPSEO_Meta::replace_meta( 'seo_title', WPSEO_Meta::$meta_prefix . 'title', $replace );
|
||||
}
|
||||
|
||||
// If WooSEO is set to use the Woo meta descriptions, import those
|
||||
if ( 'b' == get_option( 'seo_woo_meta_single_desc' ) ) {
|
||||
WPSEO_Meta::replace_meta( 'seo_description', WPSEO_Meta::$meta_prefix . 'metadesc', $replace );
|
||||
}
|
||||
|
||||
// If WooSEO is set to use the Woo meta keywords, import those
|
||||
if ( 'b' == get_option( 'seo_woo_meta_single_key' ) ) {
|
||||
WPSEO_Meta::replace_meta( 'seo_keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $replace );
|
||||
}
|
||||
|
||||
/* @todo [JRF => whomever] verify how WooSEO sets these metas ( 'noindex', 'follow' )
|
||||
* and if the values saved are concurrent with the ones we use (i.e. 0/1/2) */
|
||||
WPSEO_Meta::replace_meta( 'seo_follow', WPSEO_Meta::$meta_prefix . 'meta-robots-nofollow', $replace );
|
||||
WPSEO_Meta::replace_meta( 'seo_noindex', WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', $replace );
|
||||
|
||||
update_option( 'wpseo_titles', $options );
|
||||
$msg .= __( 'WooThemes SEO framework settings & data successfully imported.', 'wordpress-seo' );
|
||||
unset( $options, $sep );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importheadspace'] ) ) {
|
||||
WPSEO_Meta::replace_meta( '_headspace_description', WPSEO_Meta::$meta_prefix . 'metadesc', $replace );
|
||||
WPSEO_Meta::replace_meta( '_headspace_keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $replace );
|
||||
WPSEO_Meta::replace_meta( '_headspace_page_title', WPSEO_Meta::$meta_prefix . 'title', $replace );
|
||||
/* @todo [JRF => whomever] verify how headspace sets these metas ( 'noindex', 'nofollow', 'noarchive', 'noodp', 'noydir' )
|
||||
* and if the values saved are concurrent with the ones we use (i.e. 0/1/2) */
|
||||
WPSEO_Meta::replace_meta( '_headspace_noindex', WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', $replace );
|
||||
WPSEO_Meta::replace_meta( '_headspace_nofollow', WPSEO_Meta::$meta_prefix . 'meta-robots-nofollow', $replace );
|
||||
|
||||
/* @todo - [JRF => whomever] check if this can be done more efficiently by querying only the meta table
|
||||
* possibly directly changing it using concat on the existing values
|
||||
*/
|
||||
$posts = $wpdb->get_results( "SELECT ID FROM $wpdb->posts" );
|
||||
if ( is_array( $posts ) && $posts !== array() ) {
|
||||
foreach ( $posts as $post ) {
|
||||
$custom = get_post_custom( $post->ID );
|
||||
$robotsmeta_adv = '';
|
||||
if ( isset( $custom['_headspace_noarchive'] ) ) {
|
||||
$robotsmeta_adv .= 'noarchive,';
|
||||
}
|
||||
if ( isset( $custom['_headspace_noodp'] ) ) {
|
||||
$robotsmeta_adv .= 'noodp,';
|
||||
}
|
||||
if ( isset( $custom['_headspace_noydir'] ) ) {
|
||||
$robotsmeta_adv .= 'noydir';
|
||||
}
|
||||
$robotsmeta_adv = preg_replace( '`,$`', '', $robotsmeta_adv );
|
||||
WPSEO_Meta::set_value( 'meta-robots-adv', $robotsmeta_adv, $post->ID );
|
||||
}
|
||||
}
|
||||
unset( $posts, $post, $custom, $robotsmeta_adv );
|
||||
|
||||
if ( $replace ) {
|
||||
foreach ( array( 'noarchive', 'noodp', 'noydir' ) as $meta ) {
|
||||
delete_post_meta_by_key( '_headspace_' . $meta );
|
||||
}
|
||||
unset( $meta );
|
||||
}
|
||||
$msg .= __( 'HeadSpace2 data successfully imported', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
// @todo [JRF => whomever] how does this correlate with the routine on the dashboard page ? isn't one superfluous ?
|
||||
if ( isset( $_POST['wpseo']['importaioseo'] ) || isset( $_GET['importaioseo'] ) ) {
|
||||
WPSEO_Meta::replace_meta( '_aioseop_description', WPSEO_Meta::$meta_prefix . 'metadesc', $replace );
|
||||
WPSEO_Meta::replace_meta( '_aioseop_keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $replace );
|
||||
WPSEO_Meta::replace_meta( '_aioseop_title', WPSEO_Meta::$meta_prefix . 'title', $replace );
|
||||
$options_aiosep = get_option( 'aioseop_options' );
|
||||
|
||||
if ( isset( $options_aiosep['aiosp_google_analytics_id'] ) ) {
|
||||
/**
|
||||
* The Google Analytics settings are used
|
||||
*/
|
||||
$ga_universal = 0;
|
||||
$ga_trackoutbound = 0;
|
||||
$ga_anomip = 0;
|
||||
|
||||
if ( $options_aiosep['aiosp_ga_use_universal_analytics'] == 'on' ) {
|
||||
$ga_universal = 1;
|
||||
}
|
||||
if ( $options_aiosep['aiosp_ga_track_outbound_links'] == 'on' ) {
|
||||
$ga_trackoutbound = 1;
|
||||
}
|
||||
if( $options_aiosep['aiosp_ga_anonymize_ip'] == 'on' ){
|
||||
|
||||
}
|
||||
|
||||
$ga_settings = array(
|
||||
'manual_ua_code' => (int) 1,
|
||||
'manual_ua_code_field' => $options_aiosep['aiosp_google_analytics_id'],
|
||||
'enable_universal' => (int) $ga_universal,
|
||||
'track_outbound' => (int) $ga_trackoutbound,
|
||||
'ignore_users' => (array) $options_aiosep['aiosp_ga_exclude_users'],
|
||||
'anonymize_ips' => (int) $ga_anomip,
|
||||
);
|
||||
|
||||
if( get_option('yst_ga') == false ){
|
||||
$options['ga_general'] = $ga_settings;
|
||||
update_option( 'yst_ga', $options );
|
||||
}
|
||||
|
||||
$plugin_install_nonce = wp_create_nonce('install-plugin_google-analytics-for-wordpress'); // Use the old name because that's the WordPress.org repo
|
||||
|
||||
$msg .= __( sprintf(
|
||||
'All in One SEO data successfully imported. Would you like to %sdisable the All in One SEO plugin%s. You\'ve had Google Analytics enabled in All in One SEO, would you like to install our %sGoogle Analytics plugin%s?',
|
||||
'<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_import&deactivate_aioseo=1' ) ) . '">',
|
||||
'</a>',
|
||||
'<a href="' . esc_url( admin_url( 'update.php?action=install-plugin&plugin=google-analytics-for-wordpress&_wpnonce=' . $plugin_install_nonce ) ) . '">',
|
||||
'</a>'
|
||||
), 'wordpress-seo' );
|
||||
} else {
|
||||
$msg .= __( sprintf( 'All in One SEO data successfully imported. Would you like to %sdisable the All in One SEO plugin%s.', '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_import&deactivate_aioseo=1' ) ) . '">', '</a>' ), 'wordpress-seo' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importaioseoold'] ) ) {
|
||||
WPSEO_Meta::replace_meta( 'description', WPSEO_Meta::$meta_prefix . 'metadesc', $replace );
|
||||
WPSEO_Meta::replace_meta( 'keywords', WPSEO_Meta::$meta_prefix . 'metakeywords', $replace );
|
||||
WPSEO_Meta::replace_meta( 'title', WPSEO_Meta::$meta_prefix . 'title', $replace );
|
||||
$msg .= __( 'All in One SEO (Old version) data successfully imported.', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importrobotsmeta'] ) || isset( $_GET['importrobotsmeta'] ) ) {
|
||||
$posts = $wpdb->get_results( "SELECT ID, robotsmeta FROM $wpdb->posts" );
|
||||
if ( is_array( $posts ) && $posts !== array() ) {
|
||||
foreach ( $posts as $post ) {
|
||||
// sync all possible settings
|
||||
if ( $post->robotsmeta ) {
|
||||
$pieces = explode( ',', $post->robotsmeta );
|
||||
foreach ( $pieces as $meta ) {
|
||||
switch ( $meta ) {
|
||||
case 'noindex':
|
||||
WPSEO_Meta::set_value( 'meta-robots-noindex', '1', $post->ID );
|
||||
break;
|
||||
|
||||
case 'index':
|
||||
WPSEO_Meta::set_value( 'meta-robots-noindex', '2', $post->ID );
|
||||
break;
|
||||
|
||||
case 'nofollow':
|
||||
WPSEO_Meta::set_value( 'meta-robots-nofollow', '1', $post->ID );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( $posts, $post, $pieces, $meta );
|
||||
$msg .= __( sprintf( 'Robots Meta values imported. We recommend %sdisabling the Robots-Meta plugin%s to avoid any conflicts.', '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_import&deactivate_robots_meta=1' ) ) . '">', '</a>' ), 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importrssfooter'] ) ) {
|
||||
$optold = get_option( 'RSSFooterOptions' );
|
||||
$optnew = get_option( 'wpseo_rss' );
|
||||
if ( $optold['position'] == 'after' ) {
|
||||
if ( $optnew['rssafter'] === '' || $optnew['rssafter'] === WPSEO_Options::get_default( 'wpseo_rss', 'rssafter' ) ) {
|
||||
$optnew['rssafter'] = $optold['footerstring'];
|
||||
}
|
||||
} else {
|
||||
/* @internal Uncomment the second part if a default would be given to the rssbefore value */
|
||||
if ( $optnew['rssbefore'] === '' /*|| $optnew['rssbefore'] === WPSEO_Options::get_default( 'wpseo_rss', 'rssbefore' )*/ ) {
|
||||
$optnew['rssbefore'] = $optold['footerstring'];
|
||||
}
|
||||
}
|
||||
update_option( 'wpseo_rss', $optnew );
|
||||
unset( $optold, $optnew );
|
||||
$msg .= __( 'RSS Footer options imported successfully.', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importbreadcrumbs'] ) ) {
|
||||
$optold = get_option( 'yoast_breadcrumbs' );
|
||||
$optnew = get_option( 'wpseo_internallinks' );
|
||||
|
||||
if ( is_array( $optold ) && $optold !== array() ) {
|
||||
foreach ( $optold as $opt => $val ) {
|
||||
if ( is_bool( $val ) && $val == true ) {
|
||||
$optnew['breadcrumbs-' . $opt] = true;
|
||||
} else {
|
||||
$optnew['breadcrumbs-' . $opt] = $val;
|
||||
}
|
||||
}
|
||||
unset( $opt, $val );
|
||||
update_option( 'wpseo_internallinks', $optnew );
|
||||
$msg .= __( 'Yoast Breadcrumbs options imported successfully.', 'wordpress-seo' );
|
||||
} else {
|
||||
$msg .= __( 'Yoast Breadcrumbs options could not be found', 'wordpress-seo' );
|
||||
}
|
||||
unset( $optold, $optnew );
|
||||
}
|
||||
|
||||
// Allow custom import actions
|
||||
do_action( 'wpseo_handle_import' );
|
||||
|
||||
/**
|
||||
* Allow customization of import&export message
|
||||
* @api string $msg The message.
|
||||
*/
|
||||
$msg = apply_filters( 'wpseo_import_message', $msg );
|
||||
|
||||
// Check if we've deleted old data and adjust message to match it
|
||||
if ( $replace ) {
|
||||
$msg .= __( ', and old data deleted.', 'wordpress-seo' );
|
||||
}
|
||||
if ( $deletekw ) {
|
||||
$msg .= __( ', and meta keywords data deleted.', 'wordpress-seo' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$wpseo_admin_pages->admin_header( false );
|
||||
if ( $msg != '' ) {
|
||||
echo '<div id="message" class="message updated" style="width:94%;"><p>' . $msg . '</p></div>';
|
||||
}
|
||||
|
||||
$content = '<p>' . __( 'No doubt you\'ve used an SEO plugin before if this site isn\'t new. Let\'s make it easy on you, you can import the data below. If you want, you can import first, check if it was imported correctly, and then import & delete. No duplicate data will be imported.', 'wordpress-seo' ) . '</p>';
|
||||
$content .= '<p>' . sprintf( __( 'If you\'ve used another SEO plugin, try the %sSEO Data Transporter%s plugin to move your data into this plugin, it rocks!', 'wordpress-seo' ), '<a href="https://wordpress.org/plugins/seo-data-transporter/">', '</a>' ) . '</p>';
|
||||
// @todo [JRF => whomever] add action for form tag
|
||||
$content .= '<form action="" method="post" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
$content .= wp_nonce_field( 'wpseo-import', '_wpnonce', true, false );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importheadspace', __( 'Import from HeadSpace2?', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importaioseo', __( 'Import from All-in-One SEO?', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importaioseoold', __( 'Import from OLD All-in-One SEO?', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importwoo', __( 'Import from WooThemes SEO framework?', 'wordpress-seo' ) );
|
||||
$content .= '<br/>';
|
||||
$content .= $wpseo_admin_pages->checkbox( 'deleteolddata', __( 'Delete the old data after import? (recommended)', 'wordpress-seo' ) );
|
||||
$content .= '<br/>';
|
||||
$content .= '<input type="submit" class="button-primary" name="import" value="' . __( 'Import', 'wordpress-seo' ) . '" />';
|
||||
$content .= '<br/><br/>';
|
||||
|
||||
$content .= '<h2>' . __( 'Import settings from other plugins', 'wordpress-seo' ) . '</h2>';
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importrobotsmeta', __( 'Import from Robots Meta (by Yoast)?', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importrssfooter', __( 'Import from RSS Footer (by Yoast)?', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'importbreadcrumbs', __( 'Import from Yoast Breadcrumbs?', 'wordpress-seo' ) );
|
||||
|
||||
/**
|
||||
* Allow option of importing from other 'other' plugins
|
||||
* @api string $content The content containing all import and export methods
|
||||
*/
|
||||
$content = apply_filters( 'wpseo_import_other_plugins', $content );
|
||||
|
||||
$content .= '<br/>';
|
||||
$content .= '<input type="submit" class="button-primary" name="import" value="' . __( 'Import', 'wordpress-seo' ) . '" />';
|
||||
$content .= '</form><br/>';
|
||||
|
||||
$wpseo_admin_pages->postbox( 'import', __( 'Import', 'wordpress-seo' ), $content );
|
||||
|
||||
/**
|
||||
* Allow adding a custom import block
|
||||
* @api WPSEO_Admin $this The WPSEO_Admin object
|
||||
*/
|
||||
do_action( 'wpseo_import', $this );
|
||||
|
||||
// @todo [JRF => whomever] add action for form tag
|
||||
$content = '<h4>' . __( 'Export', 'wordpress-seo' ) . '</h4>';
|
||||
$content .= '<form action="" method="post" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
$content .= wp_nonce_field( 'wpseo-export', '_wpnonce', true, false );
|
||||
$content .= '<p>' . __( 'Export your WordPress SEO settings here, to import them again later or to import them on another site.', 'wordpress-seo' ) . '</p>';
|
||||
$content .= $wpseo_admin_pages->checkbox( 'include_taxonomy_meta', __( 'Include Taxonomy Metadata', 'wordpress-seo' ) );
|
||||
$content .= '<br/><input type="submit" class="button" name="wpseo_export" value="' . __( 'Export settings', 'wordpress-seo' ) . '"/>';
|
||||
$content .= '</form>';
|
||||
if ( isset( $_POST['wpseo_export'] ) ) {
|
||||
check_admin_referer( 'wpseo-export' );
|
||||
$include_taxonomy = false;
|
||||
if ( isset( $_POST['wpseo']['include_taxonomy_meta'] ) ) {
|
||||
$include_taxonomy = true;
|
||||
}
|
||||
$url = $wpseo_admin_pages->export_settings( $include_taxonomy );
|
||||
if ( $url ) {
|
||||
$GLOBALS['export_js'] = '
|
||||
<script type="text/javascript">
|
||||
document.location = \'' . $url . '\';
|
||||
</script>';
|
||||
add_action( 'admin_footer-' . $GLOBALS['hook_suffix'], 'wpseo_deliver_export_zip' );
|
||||
} else {
|
||||
$content .= 'Error: ' . $url;
|
||||
}
|
||||
}
|
||||
|
||||
$content .= '<h4>' . __( 'Import', 'wordpress-seo' ) . '</h4>';
|
||||
if ( ! isset( $_FILES['settings_import_file'] ) || empty( $_FILES['settings_import_file'] ) ) {
|
||||
$content .= '<p>' . __( 'Import settings by locating <em>settings.zip</em> and clicking', 'wordpress-seo' ) . ' "' . __( 'Import settings', 'wordpress-seo' ) . '":</p>';
|
||||
// @todo [JRF => whomever] add action for form tag
|
||||
$content .= '<form action="" method="post" enctype="multipart/form-data" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
$content .= wp_nonce_field( 'wpseo-import-file', '_wpnonce', true, false );
|
||||
$content .= '<input type="file" name="settings_import_file"/>';
|
||||
$content .= '<input type="hidden" name="action" value="wp_handle_upload"/>';
|
||||
$content .= '<input type="submit" class="button" value="' . __( 'Import settings', 'wordpress-seo' ) . '"/>';
|
||||
$content .= '</form><br/>';
|
||||
} elseif ( isset( $_FILES['settings_import_file'] ) ) {
|
||||
check_admin_referer( 'wpseo-import-file' );
|
||||
$file = wp_handle_upload( $_FILES['settings_import_file'] );
|
||||
|
||||
if ( isset( $file['file'] ) && ! is_wp_error( $file ) ) {
|
||||
$upload_dir = wp_upload_dir();
|
||||
|
||||
if ( ! defined( 'DIRECTORY_SEPARATOR' ) ) {
|
||||
define( 'DIRECTORY_SEPARATOR', '/' );
|
||||
}
|
||||
$p_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'wpseo-import' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if ( ! isset( $GLOBALS['wp_filesystem'] ) || ! is_object( $GLOBALS['wp_filesystem'] ) ) {
|
||||
WP_Filesystem();
|
||||
}
|
||||
|
||||
$unzipped = unzip_file( $file['file'], $p_path );
|
||||
if ( ! is_wp_error( $unzipped ) ) {
|
||||
$filename = $p_path . 'settings.ini';
|
||||
if ( @is_file( $filename ) && is_readable( $filename ) ) {
|
||||
$options = parse_ini_file( $filename, true );
|
||||
|
||||
if ( is_array( $options ) && $options !== array() ) {
|
||||
$old_wpseo_version = null;
|
||||
if ( isset( $options['wpseo']['version'] ) && $options['wpseo']['version'] !== '' ) {
|
||||
$old_wpseo_version = $options['wpseo']['version'];
|
||||
}
|
||||
foreach ( $options as $name => $optgroup ) {
|
||||
if ( $name === 'wpseo_taxonomy_meta' ) {
|
||||
$optgroup = json_decode( urldecode( $optgroup['wpseo_taxonomy_meta'] ), true );
|
||||
}
|
||||
|
||||
// Make sure that the imported options are cleaned/converted on import
|
||||
$option_instance = WPSEO_Options::get_option_instance( $name );
|
||||
if ( is_object( $option_instance ) && method_exists( $option_instance, 'import' ) ) {
|
||||
$optgroup = $option_instance->import( $optgroup, $old_wpseo_version, $options );
|
||||
} elseif ( WP_DEBUG === true || ( defined( 'WPSEO_DEBUG' ) && WPSEO_DEBUG === true ) ) {
|
||||
$content .= '<p><strong>' . sprintf( __( 'Setting "%s" is no longer used and has been discarded.', 'wordpress-seo' ), $name ) . '</strong></p>';
|
||||
|
||||
}
|
||||
}
|
||||
$content .= '<p><strong>' . __( 'Settings successfully imported.', 'wordpress-seo' ) . '</strong></p>';
|
||||
} else {
|
||||
$content .= '<p><strong>' . __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'No settings found in file.', 'wordpress-seo' ) . '</strong></p>';
|
||||
}
|
||||
unset( $options, $name, $optgroup );
|
||||
} else {
|
||||
$content .= '<p><strong>' . __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'Unzipping failed - file settings.ini not found.', 'wordpress-seo' ) . '</strong></p>';
|
||||
}
|
||||
@unlink( $filename );
|
||||
@unlink( $p_path );
|
||||
} else {
|
||||
$content .= '<p><strong>' . __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . sprintf( __( 'Unzipping failed with error "%s".', 'wordpress-seo' ), $unzipped->get_error_message() ) . '</strong></p>';
|
||||
}
|
||||
unset( $zip, $unzipped );
|
||||
@unlink( $file['file'] );
|
||||
} else {
|
||||
if ( is_wp_error( $file ) ) {
|
||||
$content .= '<p><strong>' . __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . $file->get_error_message() . '</strong></p>';
|
||||
} else {
|
||||
$content .= '<p><strong>' . __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'Upload failed.', 'wordpress-seo' ) . '</strong></p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$wpseo_admin_pages->postbox( 'wpseo_export', __( 'Export & Import SEO Settings', 'wordpress-seo' ), $content );
|
||||
|
||||
$wpseo_admin_pages->admin_footer( false );
|
||||
|
||||
|
||||
function wpseo_deliver_export_zip() {
|
||||
if ( isset( $GLOBALS['export_js'] ) && $GLOBALS['export_js'] !== '' ) {
|
||||
echo $GLOBALS['export_js'];
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo_internallinks' ), 'wpseo_internallinks' );
|
||||
|
||||
$content = $wpseo_admin_pages->checkbox( 'breadcrumbs-enable', __( 'Enable Breadcrumbs', 'wordpress-seo' ) );
|
||||
$content .= '<br/>';
|
||||
$content .= $wpseo_admin_pages->textinput( 'breadcrumbs-sep', __( 'Separator between breadcrumbs', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->textinput( 'breadcrumbs-home', __( 'Anchor text for the Homepage', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->textinput( 'breadcrumbs-prefix', __( 'Prefix for the breadcrumb path', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->textinput( 'breadcrumbs-archiveprefix', __( 'Prefix for Archive breadcrumbs', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->textinput( 'breadcrumbs-searchprefix', __( 'Prefix for Search Page breadcrumbs', 'wordpress-seo' ) );
|
||||
$content .= $wpseo_admin_pages->textinput( 'breadcrumbs-404crumb', __( 'Breadcrumb for 404 Page', 'wordpress-seo' ) );
|
||||
if ( get_option( 'show_on_front' ) == 'page' && get_option( 'page_for_posts' ) > 0 ) {
|
||||
$content .= $wpseo_admin_pages->checkbox( 'breadcrumbs-blog-remove', __( 'Remove Blog page from Breadcrumbs', 'wordpress-seo' ) );
|
||||
}
|
||||
$content .= $wpseo_admin_pages->checkbox( 'breadcrumbs-boldlast', __( 'Bold the last page in the breadcrumb', 'wordpress-seo' ) );
|
||||
$content .= '<br/><br/>';
|
||||
|
||||
|
||||
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
$content .= '<strong>' . __( 'Taxonomy to show in breadcrumbs for:', 'wordpress-seo' ) . '</strong><br/>';
|
||||
foreach ( $post_types as $pt ) {
|
||||
$taxonomies = get_object_taxonomies( $pt->name, 'objects' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
$values = array( 0 => __( 'None', 'wordpress-seo' ) );
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
$values[ $tax->name ] = $tax->labels->singular_name;
|
||||
}
|
||||
$content .= $wpseo_admin_pages->select( 'post_types-' . $pt->name . '-maintax', $pt->labels->name, $values );
|
||||
unset( $values, $tax );
|
||||
}
|
||||
unset( $taxonomies );
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
$content .= '<br/>';
|
||||
|
||||
|
||||
$taxonomies = get_taxonomies( array( 'public' => true, '_builtin' => false ), 'objects' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
$content .= '<strong>' . __( 'Post type archive to show in breadcrumbs for:', 'wordpress-seo' ) . '</strong><br/>';
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
$values = array( 0 => __( 'None', 'wordpress-seo' ) );
|
||||
if ( get_option( 'show_on_front' ) == 'page' && get_option( 'page_for_posts' ) > 0 ) {
|
||||
$values['post'] = __( 'Blog', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
foreach ( $post_types as $pt ) {
|
||||
if ( $pt->has_archive ) {
|
||||
$values[ $pt->name ] = $pt->labels->name;
|
||||
}
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
$content .= $wpseo_admin_pages->select( 'taxonomy-' . $tax->name . '-ptparent', $tax->labels->singular_name, $values );
|
||||
unset( $values, $tax );
|
||||
}
|
||||
}
|
||||
unset( $taxonomies, $post_types );
|
||||
|
||||
|
||||
$content .= '<br class="clear"/>';
|
||||
$content .= '<h4>' . __( 'How to insert breadcrumbs in your theme', 'wordpress-seo' ) . '</h4>';
|
||||
$content .= '<p>' . __( 'Usage of this breadcrumbs feature is explained <a href="https://yoast.com/wordpress/plugins/breadcrumbs/">here</a>. For the more code savvy, insert this in your theme:', 'wordpress-seo' ) . '</p>';
|
||||
$content .= '<pre><?php if ( function_exists('yoast_breadcrumb') ) {
|
||||
yoast_breadcrumb('<p id="breadcrumbs">','</p>');
|
||||
} ?></pre>';
|
||||
$wpseo_admin_pages->postbox( 'internallinks', __( 'Breadcrumbs Settings', 'wordpress-seo' ), $content );
|
||||
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @todo Add default content (when no premium plugins are activated)
|
||||
* @package WPSEO\Admin
|
||||
* @since 1.5.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -10,12 +10,63 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
$extensions = array(
|
||||
'seo-premium' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/seo-premium/',
|
||||
'title' => __( 'WordPress SEO Premium', 'wordpress-seo' ),
|
||||
'desc' => __( 'The premium version of WordPress SEO with more features & support.', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'video-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/video-seo/',
|
||||
'title' => __( 'Video SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Optimize your videos to show them off in search results and get more clicks!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'news-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/news-seo/',
|
||||
'title' => __( 'News SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Are you in Google News? Increase your traffic from Google News by optimizing for it!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'local-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/local-seo/',
|
||||
'title' => __( 'Local SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Rank better locally and in Google Maps, without breaking a sweat!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'woocommerce-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/',
|
||||
'title' => __( 'Yoast WooCommerce SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Seamlessly integrate WooCommerce with WordPress SEO and get extra features!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( class_exists( 'WPSEO_Premium' ) ) {
|
||||
$extensions['seo-premium']->installed = true;
|
||||
}
|
||||
if ( class_exists( 'wpseo_Video_Sitemap' ) ) {
|
||||
$extensions['video-seo']->installed = true;
|
||||
}
|
||||
if ( class_exists( 'WPSEO_News' ) ) {
|
||||
$extensions['news-seo']->installed = true;
|
||||
}
|
||||
if ( defined( 'WPSEO_LOCAL_VERSION' ) ) {
|
||||
$extensions['local-seo']->installed = true;
|
||||
}
|
||||
if ( ! class_exists( 'Woocommerce' ) ) {
|
||||
unset( $extensions['woocommerce-seo'] );
|
||||
}
|
||||
elseif ( class_exists( 'Yoast_WooCommerce_SEO' ) ) {
|
||||
$extensions['woocommerce-seo']->installed = true;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="wrap wpseo_table_page">
|
||||
|
||||
<h2 id="wpseo-title"><?php echo esc_html( get_admin_page_title() ); ?></h2>
|
||||
<h2 id="wpseo-title"><?php _e( 'WordPress SEO Extensions', 'wordpress-seo' ); ?></h2>
|
||||
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" id="extensions-tab" href="#top#extensions"><?php _e( 'Extensions', 'wordpress-seo' ); ?></a>
|
||||
@@ -25,59 +76,6 @@ global $wpseo_admin_pages;
|
||||
<div class="tabwrapper">
|
||||
<div id="extensions" class="wpseotab">
|
||||
<?php
|
||||
$extensions = array(
|
||||
'seo-premium' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/seo-premium/',
|
||||
'title' => __( 'WordPress SEO Premium', 'wordpress-seo' ),
|
||||
'desc' => __( 'The premium version of WordPress SEO with more features & support.', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'video-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/video-seo/',
|
||||
'title' => __( 'Video SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Optimize your videos to show them off in search results and get more clicks!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'news-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/news-seo/',
|
||||
'title' => __( 'News SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Are you in Google News? Increase your traffic from Google News by optimizing for it!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'local-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/local-seo/',
|
||||
'title' => __( 'Local SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Rank better locally and in Google Maps, without breaking a sweat!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
),
|
||||
'woocommerce-seo' => (object) array(
|
||||
'url' => 'https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/',
|
||||
'title' => __( 'Yoast WooCommerce SEO', 'wordpress-seo' ),
|
||||
'desc' => __( 'Seamlessly integrate WooCommerce with WordPress SEO and get extra features!', 'wordpress-seo' ),
|
||||
'installed' => false,
|
||||
)
|
||||
);
|
||||
|
||||
if ( class_exists( 'WPSEO_Premium' ) ) {
|
||||
$extensions['seo-premium']->installed = true;
|
||||
}
|
||||
if ( class_exists( 'wpseo_Video_Sitemap' ) ) {
|
||||
$extensions['video-seo']->installed = true;
|
||||
}
|
||||
if ( class_exists( 'WPSEO_News' ) ) {
|
||||
$extensions['news-seo']->installed = true;
|
||||
}
|
||||
if ( defined( 'WPSEO_LOCAL_VERSION' ) ) {
|
||||
$extensions['local-seo']->installed = true;
|
||||
}
|
||||
if ( ! class_exists( 'Woocommerce' ) ) {
|
||||
unset( $extensions['woocommerce-seo'] );
|
||||
} else {
|
||||
if ( class_exists( 'Yoast_WooCommerce_SEO' ) ) {
|
||||
$extensions['woocommerce-seo']->installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $extensions as $id => $extension ) {
|
||||
$utm = '#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=extension-page-banners';
|
||||
?>
|
||||
@@ -89,17 +87,18 @@ global $wpseo_admin_pages;
|
||||
<p><?php echo esc_html( $extension->desc ); ?></p>
|
||||
|
||||
<p>
|
||||
<?php if ( $extension->installed ) { ?>
|
||||
<?php if ( $extension->installed ) : ?>
|
||||
<button class="button-primary installed">Installed</button>
|
||||
<?php } else { ?>
|
||||
<?php else : ?>
|
||||
<a target="_blank" href="<?php echo esc_url( $extension->url . $utm ); ?>" class="button-primary">
|
||||
<?php esc_html_e( 'Get this extension', 'wordpress-seo' ); ?>
|
||||
<?php _e( 'Get this extension', 'wordpress-seo' ); ?>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
unset( $extensions, $id, $extension, $utm );
|
||||
?>
|
||||
</div>
|
||||
<div id="licenses" class="wpseotab">
|
||||
@@ -109,7 +108,12 @@ global $wpseo_admin_pages;
|
||||
* Display license page
|
||||
*/
|
||||
settings_errors();
|
||||
do_action( 'wpseo_licenses_forms' );
|
||||
if ( ! has_action( 'wpseo_licenses_forms' ) ) {
|
||||
echo '<div class="msg"><p>', __( 'This is where you would enter the license keys for one of our premium plugins, should you activate one.', 'wordpress-seo' ), '</p></div>';
|
||||
}
|
||||
else {
|
||||
do_action( 'wpseo_licenses_forms' );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -9,201 +9,215 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo_titles' ), 'wpseo_titles' );
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$yform->admin_header( true, 'wpseo_titles' );
|
||||
?>
|
||||
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'General', 'wordpress-seo' );?></a>
|
||||
<a class="nav-tab" id="home-tab" href="#top#home"><?php _e( 'Home', 'wordpress-seo' );?></a>
|
||||
<a class="nav-tab" id="post_types-tab" href="#top#post_types"><?php _e( 'Post Types', 'wordpress-seo' );?></a>
|
||||
<a class="nav-tab" id="taxonomies-tab" href="#top#taxonomies"><?php _e( 'Taxonomies', 'wordpress-seo' );?></a>
|
||||
<a class="nav-tab" id="archives-tab" href="#top#archives"><?php _e( 'Other', 'wordpress-seo' );?></a>
|
||||
</h2>
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'General', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="home-tab" href="#top#home"><?php _e( 'Homepage', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="post_types-tab" href="#top#post_types"><?php _e( 'Post Types', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="taxonomies-tab" href="#top#taxonomies"><?php _e( 'Taxonomies', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="archives-tab" href="#top#archives"><?php _e( 'Archives', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="other-tab" href="#top#other"><?php _e( 'Other', 'wordpress-seo' ); ?></a>
|
||||
</h2>
|
||||
|
||||
<div class="tabwrapper">
|
||||
<div id="general" class="wpseotab">
|
||||
<?php
|
||||
echo '<h2>' . __( 'Title settings', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->checkbox( 'forcerewritetitle', __( 'Force rewrite titles', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'WordPress SEO has auto-detected whether it needs to force rewrite the titles for your pages, if you think it\'s wrong and you know what you\'re doing, you can change the setting here.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo '<h2>' . __( 'Title Separator', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->radio( 'separator', WPSEO_Option_Titles::get_instance()->get_separator_options(), '' );
|
||||
echo '<p class="desc">' . __( 'Choose the symbol to use as your title separator. This will display, for instance, between your post title and site name.', 'wordpress-seo' ) . ' ' . __( 'Symbols are shown in the size they\'ll appear in in search results.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo '<h2>' . __( 'Sitewide <code>meta</code> settings', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->checkbox( 'noindex-subpages-wpseo', __( 'Noindex subpages of archives', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'If you want to prevent /page/2/ and further of any archive to show up in the search results, enable this.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo $wpseo_admin_pages->checkbox( 'usemetakeywords', __( 'Use <code>meta</code> keywords tag?', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'I don\'t know why you\'d want to use meta keywords, but if you want to, check this box.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo $wpseo_admin_pages->checkbox( 'noodp', __( 'Add <code>noodp</code> meta robots tag sitewide', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'Prevents search engines from using the DMOZ description for pages from this site in the search results.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo $wpseo_admin_pages->checkbox( 'noydir', __( 'Add <code>noydir</code> meta robots tag sitewide', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'Prevents search engines from using the Yahoo! directory description for pages from this site in the search results.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo '<h2>' . __( 'Clean up the <code><head></code>', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->checkbox( 'hide-rsdlink', __( 'Hide RSD Links', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'hide-wlwmanifest', __( 'Hide WLW Manifest Links', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'hide-shortlink', __( 'Hide Shortlink for posts', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'hide-feedlinks', __( 'Hide RSS Links', 'wordpress-seo' ) );
|
||||
?>
|
||||
</div>
|
||||
<div id="home" class="wpseotab">
|
||||
<?php
|
||||
if ( 'posts' == get_option( 'show_on_front' ) ) {
|
||||
echo '<h2>' . __( 'Homepage', 'wordpress-seo' ) . '</h2>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-home-wpseo', __( 'Title template', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textarea( 'metadesc-home-wpseo', __( 'Meta description template', 'wordpress-seo' ), '', 'metadesc' );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
echo $wpseo_admin_pages->textinput( 'metakey-home-wpseo', __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo '<h2>' . __( 'Homepage & Front page', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<p>' . sprintf( __( 'You can determine the title and description for the front page by %sediting the front page itself »%s', 'wordpress-seo' ), '<a href="' . esc_url( get_edit_post_link( get_option( 'page_on_front' ) ) ) . '">', '</a>' ) . '</p>';
|
||||
if ( get_option( 'page_for_posts' ) > 0 ) {
|
||||
echo '<p>' . sprintf( __( 'You can determine the title and description for the blog page by %sediting the blog page itself »%s', 'wordpress-seo' ), '<a href="' . esc_url( get_edit_post_link( get_option( 'page_for_posts' ) ) ) . '">', '</a>' ) . '</p>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div id="post_types" class="wpseotab">
|
||||
<?php
|
||||
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
foreach ( $post_types as $pt ) {
|
||||
$warn = false;
|
||||
if ( $options['redirectattachment'] === true && $pt->name == 'attachment' ) {
|
||||
echo '<div class="wpseo-warning">';
|
||||
$warn = true;
|
||||
<div class="tabwrapper">
|
||||
<div id="general" class="wpseotab">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th>
|
||||
<?php _e( 'Force rewrite titles', 'wordpress-seo' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<?php
|
||||
$yform->checkbox( 'forcerewritetitle', __( 'Enable force rewrite titles', 'wordpress-seo' ) );
|
||||
echo '<p class="description">', __( 'WordPress SEO has auto-detected whether it needs to force rewrite the titles for your pages, if you think it\'s wrong and you know what you\'re doing, you can change the setting here.', 'wordpress-seo' ), '</p>';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<?php _e( 'Title Separator', 'wordpress-seo' ); ?>
|
||||
</th>
|
||||
<td>
|
||||
<?php
|
||||
$yform->radio( 'separator', WPSEO_Option_Titles::get_instance()->get_separator_options(), '' );
|
||||
echo '<p class="description">', __( 'Choose the symbol to use as your title separator. This will display, for instance, between your post title and site name.', 'wordpress-seo' ), ' ', __( 'Symbols are shown in the size they\'ll appear in in search results.', 'wordpress-seo' ), '</p>';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="home" class="wpseotab">
|
||||
<?php
|
||||
if ( 'posts' == get_option( 'show_on_front' ) ) {
|
||||
echo '<p><strong>', __( 'Homepage', 'wordpress-seo' ), '</strong><br/>';
|
||||
$yform->textinput( 'title-home-wpseo', __( 'Title template', 'wordpress-seo' ), 'template homepage-template' );
|
||||
$yform->textarea( 'metadesc-home-wpseo', __( 'Meta description template', 'wordpress-seo' ), array( 'class' => 'template homepage-template' ) );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
$yform->textinput( 'metakey-home-wpseo', __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
echo '</p>';
|
||||
}
|
||||
|
||||
$name = $pt->name;
|
||||
echo '<h4 id="' . esc_attr( $name ) . '">' . esc_html( ucfirst( $pt->labels->name ) ) . '</h4>';
|
||||
if ( $warn === true ) {
|
||||
echo '<h4 class="error-message">' . __( 'Take note:', 'wordpress-seo' ) . '</h4>';
|
||||
|
||||
echo '<p class="error-message">' . __( 'As you are redirecting attachment URLs to parent post URLs, these settings will currently only have an effect on <strong>unattached</strong> media items!', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p class="error-message">' . sprintf( __( 'So remember: If you change the %sattachment redirection setting%s in the future, the below settings will take effect for *all* media items.', 'wordpress-seo' ), '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_permalinks' ) ) . '">', '</a>' ) . '</p>';
|
||||
else {
|
||||
echo '<p><strong>', __( 'Homepage & Front page', 'wordpress-seo' ), '</strong><br/>';
|
||||
printf( __( 'You can determine the title and description for the front page by %sediting the front page itself »%s', 'wordpress-seo' ), '<a href="' . esc_url( get_edit_post_link( get_option( 'page_on_front' ) ) ) . '">', '</a>' );
|
||||
echo '</p>';
|
||||
if ( get_option( 'page_for_posts' ) > 0 ) {
|
||||
echo '<p>', sprintf( __( 'You can determine the title and description for the blog page by %sediting the blog page itself »%s', 'wordpress-seo' ), '<a href="' . esc_url( get_edit_post_link( get_option( 'page_for_posts' ) ) ) . '">', '</a>' ), '</p>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div id="post_types" class="wpseotab">
|
||||
<?php
|
||||
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
foreach ( $post_types as $pt ) {
|
||||
$warn = false;
|
||||
if ( $options['redirectattachment'] === true && $pt->name == 'attachment' ) {
|
||||
echo '<div class="wpseo-warning">';
|
||||
$warn = true;
|
||||
}
|
||||
|
||||
echo $wpseo_admin_pages->textinput( 'title-' . $name, __( 'Title template', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textarea( 'metadesc-' . $name, __( 'Meta description template', 'wordpress-seo' ), '', 'metadesc' );
|
||||
$name = $pt->name;
|
||||
echo '<strong id="' . esc_attr( $name ) . '">' . esc_html( ucfirst( $pt->labels->name ) ) . '</strong><br/>';
|
||||
if ( $warn === true ) {
|
||||
echo '<h4 class="error-message">' . __( 'Take note:', 'wordpress-seo' ) . '</h4>';
|
||||
|
||||
echo '<p class="error-message">' . __( 'As you are redirecting attachment URLs to parent post URLs, these settings will currently only have an effect on <strong>unattached</strong> media items!', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p class="error-message">' . sprintf( __( 'So remember: If you change the %sattachment redirection setting%s in the future, the below settings will take effect for *all* media items.', 'wordpress-seo' ), '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_permalinks' ) ) . '">', '</a>' ) . '</p>';
|
||||
}
|
||||
|
||||
$yform->textinput( 'title-' . $name, __( 'Title template', 'wordpress-seo' ), 'template posttype-template' );
|
||||
$yform->textarea( 'metadesc-' . $name, __( 'Meta description template', 'wordpress-seo' ), array( 'class' => 'template posttype-template' ) );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
$yform->textinput( 'metakey-' . $name, __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
$yform->checkbox( 'noindex-' . $name, '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'showdate-' . $name, __( 'Show date in snippet preview?', 'wordpress-seo' ), __( 'Date in Snippet Preview', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'hideeditbox-' . $name, __( 'Hide', 'wordpress-seo' ), __( 'WordPress SEO Meta Box', 'wordpress-seo' ) );
|
||||
|
||||
/**
|
||||
* Allow adding a custom checkboxes to the admin meta page - Post Types tab
|
||||
* @api WPSEO_Admin_Pages $yform The WPSEO_Admin_Pages object
|
||||
* @api String $name The post type name
|
||||
*/
|
||||
do_action( 'wpseo_admin_page_meta_post_types', $yform, $name );
|
||||
|
||||
echo '<br/><br/>';
|
||||
if ( $warn === true ) {
|
||||
echo '</div>';
|
||||
}
|
||||
unset( $warn );
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
unset( $post_types );
|
||||
|
||||
|
||||
$post_types = get_post_types( array( '_builtin' => false, 'has_archive' => true ), 'objects' );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
echo '<h2>' . __( 'Custom Post Type Archives', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<p>' . __( 'Note: instead of templates these are the actual titles and meta descriptions for these custom post type archive pages.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
foreach ( $post_types as $pt ) {
|
||||
$name = $pt->name;
|
||||
|
||||
echo '<strong>' . esc_html( ucfirst( $pt->labels->name ) ) . '</strong><br/>';
|
||||
$yform->textinput( 'title-ptarchive-' . $name, __( 'Title', 'wordpress-seo' ), 'template posttype-template' );
|
||||
$yform->textarea( 'metadesc-ptarchive-' . $name, __( 'Meta description', 'wordpress-seo' ), array( 'class' => 'template posttype-template' ) );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
$yform->textinput( 'metakey-ptarchive-' . $name, __( 'Meta keywords', 'wordpress-seo' ) );
|
||||
}
|
||||
if ( $options['breadcrumbs-enable'] === true ) {
|
||||
$yform->textinput( 'bctitle-ptarchive-' . $name, __( 'Breadcrumbs title', 'wordpress-seo' ) );
|
||||
}
|
||||
$yform->checkbox( 'noindex-ptarchive-' . $name, '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
|
||||
echo '<br/><br/>';
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
unset( $post_types );
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div id="taxonomies" class="wpseotab">
|
||||
<?php
|
||||
$taxonomies = get_taxonomies( array( 'public' => true ), 'objects' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
echo '<strong>' . esc_html( ucfirst( $tax->labels->name ) ) . '</strong><br/>';
|
||||
$yform->textinput( 'title-tax-' . $tax->name, __( 'Title template', 'wordpress-seo' ), 'template taxonomy-template' );
|
||||
$yform->textarea( 'metadesc-tax-' . $tax->name, __( 'Meta description template', 'wordpress-seo' ), array( 'class' => 'template taxonomy-template' ) );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
$yform->textinput( 'metakey-tax-' . $tax->name, __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
$yform->checkbox( 'noindex-tax-' . $tax->name, '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'hideeditbox-tax-' . $tax->name, __( 'Hide', 'wordpress-seo' ), __( 'WordPress SEO Meta Box', 'wordpress-seo' ) );
|
||||
echo '<br/><br/>';
|
||||
}
|
||||
unset( $tax );
|
||||
}
|
||||
unset( $taxonomies );
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div id="archives" class="wpseotab">
|
||||
<?php
|
||||
echo '<strong>' . __( 'Author Archives', 'wordpress-seo' ) . '</strong><br/>';
|
||||
$yform->textinput( 'title-author-wpseo', __( 'Title template', 'wordpress-seo' ), 'template author-template' );
|
||||
$yform->textarea( 'metadesc-author-wpseo', __( 'Meta description template', 'wordpress-seo' ), array( 'class' => 'template author-template' ) );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
echo $wpseo_admin_pages->textinput( 'metakey-' . $name, __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'metakey-author-wpseo', __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
echo $wpseo_admin_pages->checkbox( 'noindex-' . $name, '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'showdate-' . $name, __( 'Show date in snippet preview?', 'wordpress-seo' ), __( 'Date in Snippet Preview', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'hideeditbox-' . $name, __( 'Hide', 'wordpress-seo' ), __( 'WordPress SEO Meta Box', 'wordpress-seo' ) );
|
||||
|
||||
/**
|
||||
* Allow adding a custom checkboxes to the admin meta page - Post Types tab
|
||||
* @api WPSEO_Admin_Pages $wpseo_admin_pages The WPSEO_Admin_Pages object
|
||||
* @api String $name The post type name
|
||||
*/
|
||||
do_action( 'wpseo_admin_page_meta_post_types', $wpseo_admin_pages, $name );
|
||||
|
||||
$yform->checkbox( 'noindex-author-wpseo', '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'disable-author', __( 'Disable the author archives', 'wordpress-seo' ), '' );
|
||||
echo '<p class="desc label">' . __( 'If you\'re running a one author blog, the author archive will always look exactly the same as your homepage. And even though you may not link to it, others might, to do you harm. Disabling them here will make sure any link to those archives will be 301 redirected to the homepage.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<br/>';
|
||||
if ( $warn === true ) {
|
||||
echo '</div>';
|
||||
}
|
||||
unset( $warn );
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
unset( $post_types );
|
||||
|
||||
|
||||
$post_types = get_post_types( array( 'public' => true, '_builtin' => false ), 'objects' );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
echo '<h2>' . __( 'Custom Post Type Archives', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<p>' . __( 'Note: instead of templates these are the actual titles and meta descriptions for these custom post type archive pages.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
foreach ( $post_types as $pt ) {
|
||||
if ( ! $pt->has_archive ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $pt->name;
|
||||
|
||||
echo '<h4>' . esc_html( ucfirst( $pt->labels->name ) ) . '</h4>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-ptarchive-' . $name, __( 'Title', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textarea( 'metadesc-ptarchive-' . $name, __( 'Meta description', 'wordpress-seo' ), '', 'metadesc' );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
echo $wpseo_admin_pages->textinput( 'metakey-ptarchive-' . $name, __( 'Meta keywords', 'wordpress-seo' ) );
|
||||
}
|
||||
if ( $options['breadcrumbs-enable'] === true ) {
|
||||
echo $wpseo_admin_pages->textinput( 'bctitle-ptarchive-' . $name, __( 'Breadcrumbs title', 'wordpress-seo' ) );
|
||||
}
|
||||
echo $wpseo_admin_pages->checkbox( 'noindex-ptarchive-' . $name, '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
unset( $post_types );
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div id="taxonomies" class="wpseotab">
|
||||
<?php
|
||||
$taxonomies = get_taxonomies( array( 'public' => true ), 'objects' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
echo '<h4>' . esc_html( ucfirst( $tax->labels->name ) ). '</h4>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-tax-' . $tax->name, __( 'Title template', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textarea( 'metadesc-tax-' . $tax->name, __( 'Meta description template', 'wordpress-seo' ), '', 'metadesc' );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
echo $wpseo_admin_pages->textinput( 'metakey-tax-' . $tax->name, __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
echo $wpseo_admin_pages->checkbox( 'noindex-tax-' . $tax->name, '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'hideeditbox-tax-' . $tax->name, __( 'Hide', 'wordpress-seo' ), __( 'WordPress SEO Meta Box', 'wordpress-seo' ) );
|
||||
echo '<strong>' . __( 'Date Archives', 'wordpress-seo' ) . '</strong><br/>';
|
||||
$yform->textinput( 'title-archive-wpseo', __( 'Title template', 'wordpress-seo' ), 'template date-template' );
|
||||
$yform->textarea( 'metadesc-archive-wpseo', __( 'Meta description template', 'wordpress-seo' ), array( 'class' => 'template date-template' ) );
|
||||
echo '<br/>';
|
||||
}
|
||||
unset( $tax );
|
||||
}
|
||||
unset( $taxonomies );
|
||||
$yform->checkbox( 'noindex-archive-wpseo', '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'disable-date', __( 'Disable the date-based archives', 'wordpress-seo' ), '' );
|
||||
echo '<p class="desc label">' . __( 'For the date based archives, the same applies: they probably look a lot like your homepage, and could thus be seen as duplicate content.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div id="archives" class="wpseotab">
|
||||
<?php
|
||||
echo '<h4>' . __( 'Author Archives', 'wordpress-seo' ) . '</h4>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-author-wpseo', __( 'Title template', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textarea( 'metadesc-author-wpseo', __( 'Meta description template', 'wordpress-seo' ), '', 'metadesc' );
|
||||
if ( $options['usemetakeywords'] === true ) {
|
||||
echo $wpseo_admin_pages->textinput( 'metakey-author-wpseo', __( 'Meta keywords template', 'wordpress-seo' ) );
|
||||
}
|
||||
echo $wpseo_admin_pages->checkbox( 'noindex-author-wpseo', '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'disable-author', __( 'Disable the author archives', 'wordpress-seo' ), '' );
|
||||
echo '<p class="desc label">' . __( 'If you\'re running a one author blog, the author archive will always look exactly the same as your homepage. And even though you may not link to it, others might, to do you harm. Disabling them here will make sure any link to those archives will be 301 redirected to the homepage.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<br/>';
|
||||
echo '<h4>' . __( 'Date Archives', 'wordpress-seo' ) . '</h4>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-archive-wpseo', __( 'Title template', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textarea( 'metadesc-archive-wpseo', __( 'Meta description template', 'wordpress-seo' ), '', 'metadesc' );
|
||||
echo '<br/>';
|
||||
echo $wpseo_admin_pages->checkbox( 'noindex-archive-wpseo', '<code>noindex, follow</code>', __( 'Meta Robots', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->checkbox( 'disable-date', __( 'Disable the date-based archives', 'wordpress-seo' ), '' );
|
||||
echo '<p class="desc label">' . __( 'For the date based archives, the same applies: they probably look a lot like your homepage, and could thus be seen as duplicate content.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<h2>' . __( 'Special Pages', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<p>' . __( 'These pages will be noindex, followed by default, so they will never show up in search results.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p><strong>' . __( 'Search pages', 'wordpress-seo' ) . '</strong><br/>';
|
||||
$yform->textinput( 'title-search-wpseo', __( 'Title template', 'wordpress-seo' ), 'template search-template' );
|
||||
echo '</p>';
|
||||
echo '<p><strong>' . __( '404 pages', 'wordpress-seo' ) . '</strong><br/>';
|
||||
$yform->textinput( 'title-404-wpseo', __( 'Title template', 'wordpress-seo' ), 'template error404-template' );
|
||||
echo '</p>';
|
||||
echo '<br class="clear"/>';
|
||||
?>
|
||||
</div>
|
||||
<div id="other" class="wpseotab">
|
||||
<strong><?php _e( 'Sitewide <code>meta</code> settings', 'wordpress-seo' ); ?></strong><br/>
|
||||
<br/>
|
||||
<?php
|
||||
$yform->checkbox( 'noindex-subpages-wpseo', __( 'Noindex subpages of archives', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">', __( 'If you want to prevent /page/2/ and further of any archive to show up in the search results, enable this.', 'wordpress-seo' ), '</p>';
|
||||
|
||||
echo '<h2>' . __( 'Special Pages', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<p>' . __( 'These pages will be noindex, followed by default, so they will never show up in search results.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<h4>' . __( 'Search pages', 'wordpress-seo' ) . '</h4>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-search-wpseo', __( 'Title template', 'wordpress-seo' ) );
|
||||
echo '<h4>' . __( '404 pages', 'wordpress-seo' ) . '</h4>';
|
||||
echo $wpseo_admin_pages->textinput( 'title-404-wpseo', __( 'Title template', 'wordpress-seo' ) );
|
||||
echo '<br class="clear"/>';
|
||||
?>
|
||||
</div>
|
||||
<div id="template_help" class="wpseotab">
|
||||
<?php
|
||||
$yform->checkbox( 'usemetakeywords', __( 'Use <code>meta</code> keywords tag?', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">', __( 'I don\'t know why you\'d want to use meta keywords, but if you want to, check this box.', 'wordpress-seo' ), '</p>';
|
||||
|
||||
echo '<h2>' . __( 'Variables', 'wordpress-seo' ) . '</h2>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
$yform->checkbox( 'noodp', __( 'Add <code>noodp</code> meta robots tag sitewide', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">', __( 'Prevents search engines from using the DMOZ description for pages from this site in the search results.', 'wordpress-seo' ), '</p>';
|
||||
|
||||
$yform->checkbox( 'noydir', __( 'Add <code>noydir</code> meta robots tag sitewide', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">', __( 'Prevents search engines from using the Yahoo! directory description for pages from this site in the search results.', 'wordpress-seo' ), '</p>';
|
||||
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
$yform->admin_footer();
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -9,7 +9,7 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$options = get_site_option( 'wpseo_ms' );
|
||||
|
||||
@@ -19,6 +19,7 @@ if ( isset( $_POST['wpseo_submit'] ) ) {
|
||||
foreach ( array( 'access', 'defaultblog' ) as $opt ) {
|
||||
$options[ $opt ] = $_POST['wpseo_ms'][ $opt ];
|
||||
}
|
||||
unset( $opt );
|
||||
WPSEO_Options::update_site_option( 'wpseo_ms', $options );
|
||||
add_settings_error( 'wpseo_ms', 'settings_updated', __( 'Settings Updated.', 'wordpress-seo' ), 'updated' );
|
||||
}
|
||||
@@ -26,7 +27,7 @@ if ( isset( $_POST['wpseo_submit'] ) ) {
|
||||
if ( isset( $_POST['wpseo_restore_blog'] ) ) {
|
||||
check_admin_referer( 'wpseo-network-restore' );
|
||||
if ( isset( $_POST['wpseo_ms']['restoreblog'] ) && is_numeric( $_POST['wpseo_ms']['restoreblog'] ) ) {
|
||||
$restoreblog = (int) WPSEO_Option::validate_int( $_POST['wpseo_ms']['restoreblog'] );
|
||||
$restoreblog = (int) WPSEO_Utils::validate_int( $_POST['wpseo_ms']['restoreblog'] );
|
||||
$blog = get_blog_details( $restoreblog );
|
||||
|
||||
if ( $blog ) {
|
||||
@@ -36,7 +37,7 @@ if ( isset( $_POST['wpseo_restore_blog'] ) ) {
|
||||
else {
|
||||
add_settings_error( 'wpseo_ms', 'settings_updated', sprintf( __( 'Blog %s not found.', 'wordpress-seo' ), esc_html( $restoreblog ) ), 'error' );
|
||||
}
|
||||
unset( $restoreblog );
|
||||
unset( $restoreblog, $blog );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,15 +81,14 @@ else {
|
||||
unset( $sites );
|
||||
}
|
||||
|
||||
$yform->admin_header( false, 'wpseo_ms' );
|
||||
|
||||
|
||||
$wpseo_admin_pages->admin_header( false, 'wpseo-network-settings', 'wpseo_ms' );
|
||||
|
||||
$content = '<form method="post" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
$content .= wp_nonce_field( 'wpseo-network-settings', '_wpnonce', true, false );
|
||||
echo '<h2>', __( 'MultiSite Settings', 'wordpress-seo' ), '</h2>';
|
||||
echo '<form method="post" accept-charset="', esc_attr( get_bloginfo( 'charset' ) ), '">';
|
||||
wp_nonce_field( 'wpseo-network-settings', '_wpnonce', true, true );
|
||||
|
||||
/* @internal Important: Make sure the options added to the array here are in line with the options set in the WPSEO_Option_MS::$allowed_access_options property */
|
||||
$content .= $wpseo_admin_pages->select(
|
||||
$yform->select(
|
||||
'access',
|
||||
__( 'Who should have access to the WordPress SEO settings', 'wordpress-seo' ),
|
||||
array(
|
||||
@@ -99,34 +99,32 @@ $content .= $wpseo_admin_pages->select(
|
||||
);
|
||||
|
||||
if ( $use_dropdown === true ) {
|
||||
$content .= $wpseo_admin_pages->select(
|
||||
$yform->select(
|
||||
'defaultblog',
|
||||
__( 'New sites in the network inherit their SEO settings from this site', 'wordpress-seo' ),
|
||||
$dropdown_input,
|
||||
'wpseo_ms'
|
||||
);
|
||||
$content .= '<p>' . __( 'Choose the site whose settings you want to use as default for all sites that are added to your network. If you choose \'None\', the normal plugin defaults will be used.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p>' . __( 'Choose the site whose settings you want to use as default for all sites that are added to your network. If you choose \'None\', the normal plugin defaults will be used.', 'wordpress-seo' ) . '</p>';
|
||||
}
|
||||
else {
|
||||
$content .= $wpseo_admin_pages->textinput( 'defaultblog', __( 'New sites in the network inherit their SEO settings from this site', 'wordpress-seo' ), 'wpseo_ms' );
|
||||
$content .= '<p>' . sprintf( __( 'Enter the %sSite ID%s for the site whose settings you want to use as default for all sites that are added to your network. Leave empty for none (i.e. the normal plugin defaults will be used).', 'wordpress-seo' ), '<a href="' . esc_url( network_admin_url( 'sites.php' ) ) . '">', '</a>' ) . '</p>';
|
||||
$yform->textinput( 'defaultblog', __( 'New sites in the network inherit their SEO settings from this site', 'wordpress-seo' ), 'wpseo_ms' );
|
||||
echo '<p>' . sprintf( __( 'Enter the %sSite ID%s for the site whose settings you want to use as default for all sites that are added to your network. Leave empty for none (i.e. the normal plugin defaults will be used).', 'wordpress-seo' ), '<a href="' . esc_url( network_admin_url( 'sites.php' ) ) . '">', '</a>' ) . '</p>';
|
||||
}
|
||||
$content .= '<p><strong>' . __( 'Take note:', 'wordpress-seo' ) . '</strong> ' . __( 'Privacy sensitive (FB admins and such), theme specific (title rewrite) and a few very site specific settings will not be imported to new blogs.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<p><strong>' . __( 'Take note:', 'wordpress-seo' ) . '</strong> ' . __( 'Privacy sensitive (FB admins and such), theme specific (title rewrite) and a few very site specific settings will not be imported to new blogs.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
|
||||
$content .= '<input type="submit" name="wpseo_submit" class="button-primary" value="' . __( 'Save MultiSite Settings', 'wordpress-seo' ) . '"/>';
|
||||
$content .= '</form>';
|
||||
echo '<input type="submit" name="wpseo_submit" class="button-primary" value="' . __( 'Save MultiSite Settings', 'wordpress-seo' ) . '"/>';
|
||||
echo '</form>';
|
||||
|
||||
$wpseo_admin_pages->postbox( 'wpseo_network_settings', __( 'MultiSite Settings', 'wordpress-seo' ), $content );
|
||||
|
||||
|
||||
$content = '<form method="post" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
$content .= wp_nonce_field( 'wpseo-network-restore', '_wpnonce', true, false );
|
||||
$content .= '<p>' . __( 'Using this form you can reset a site to the default SEO settings.', 'wordpress-seo' ) . '</p>';
|
||||
echo '<h2>' . __( 'Restore site to default settings', 'wordpress-seo' ) . '</h2>';
|
||||
echo '<form method="post" accept-charset="' . esc_attr( get_bloginfo( 'charset' ) ) . '">';
|
||||
wp_nonce_field( 'wpseo-network-restore', '_wpnonce', true, true );
|
||||
echo '<p>' . __( 'Using this form you can reset a site to the default SEO settings.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
if ( $use_dropdown === true ) {
|
||||
unset( $dropdown_input['-'] );
|
||||
$content .= $wpseo_admin_pages->select(
|
||||
$yform->select(
|
||||
'restoreblog',
|
||||
__( 'Site ID', 'wordpress-seo' ),
|
||||
$dropdown_input,
|
||||
@@ -134,12 +132,11 @@ if ( $use_dropdown === true ) {
|
||||
);
|
||||
}
|
||||
else {
|
||||
$content .= $wpseo_admin_pages->textinput( 'restoreblog', __( 'Blog ID', 'wordpress-seo' ), 'wpseo_ms' );
|
||||
$yform->textinput( 'restoreblog', __( 'Blog ID', 'wordpress-seo' ), 'wpseo_ms' );
|
||||
}
|
||||
|
||||
$content .= '<input type="submit" name="wpseo_restore_blog" value="' . __( 'Restore site to defaults', 'wordpress-seo' ) . '" class="button"/>';
|
||||
$content .= '</form>';
|
||||
echo '<input type="submit" name="wpseo_restore_blog" value="' . __( 'Restore site to defaults', 'wordpress-seo' ) . '" class="button"/>';
|
||||
echo '</form>';
|
||||
|
||||
$wpseo_admin_pages->postbox( 'wpseo-network-restore', __( 'Restore site to default settings', 'wordpress-seo' ), $content );
|
||||
|
||||
$wpseo_admin_pages->admin_footer( false );
|
||||
$yform->admin_footer( false );
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo_permalinks' ), 'wpseo_permalinks' );
|
||||
|
||||
$options = get_option( 'wpseo_permalinks' );
|
||||
|
||||
$content = '';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'stripcategorybase', __( 'Strip the category base (usually <code>/category/</code>) from the category URL.', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . sprintf( __( 'We suggest using %1$sFV Top Level Categories%2$s, if you insist on keeping this but do know that the feature is very error prone and not <em>that</em> important for your SEO.', 'wordpress-seo' ), '<a href="https://wordpress.org/plugins/fv-top-level-cats/">', '</a>' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'trailingslash', __( 'Enforce a trailing slash on all category and tag URL\'s', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'If you choose a permalink for your posts with <code>.html</code>, or anything else but a / on the end, this will force WordPress to add a trailing slash to non-post pages nonetheless.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'cleanslugs', __( 'Remove stop words from slugs.', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'This helps you to create cleaner URLs by automatically removing the stopwords from them.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'redirectattachment', __( 'Redirect attachment URL\'s to parent post URL.', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'Attachments to posts are stored in the database as posts, this means they\'re accessible under their own URL\'s if you do not redirect them, enabling this will redirect them to the post they were attached to.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'cleanreplytocom', __( 'Remove the <code>?replytocom</code> variables.', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'This prevents threaded replies from working when the user has JavaScript disabled, but on a large site can mean a <em>huge</em> improvement in crawl efficiency for search engines when you have a lot of comments.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'cleanpermalinks', __( 'Redirect ugly URL\'s to clean permalinks. (Not recommended in many cases!)', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'People make mistakes in their links towards you sometimes, or unwanted parameters are added to the end of your URLs, this allows you to redirect them all away. Please note that while this is a feature that is actively maintained, it is known to break several plugins, and should for that reason be the first feature you disable when you encounter issues after installing this plugin.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$wpseo_admin_pages->postbox( 'permalinks', __( 'Permalink Settings', 'wordpress-seo' ), $content );
|
||||
|
||||
/* @internal Important: Make sure the options added to the array here are in line with the options set in the WPSEO_Option_Permalinks::$force_transport_options property */
|
||||
$content = $wpseo_admin_pages->select( 'force_transport', __( 'Force Transport', 'wordpress-seo' ), array( 'default' => __( 'Leave default', 'wordpress-seo' ), 'http' => __( 'Force http', 'wordpress-seo' ), 'https' => __( 'Force https', 'wordpress-seo' ) ) );
|
||||
$content .= '<p class="desc label">' . __( 'Force the canonical to either http or https, when your blog runs under both.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$wpseo_admin_pages->postbox( 'canonical', __( 'Canonical Settings', 'wordpress-seo' ), $content );
|
||||
|
||||
|
||||
$content = $wpseo_admin_pages->checkbox( 'cleanpermalink-googlesitesearch', __( 'Prevent cleaning out Google Site Search URL\'s.', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'Google Site Search URL\'s look weird, and ugly, but if you\'re using Google Site Search, you probably do not want them cleaned out.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->checkbox( 'cleanpermalink-googlecampaign', __( 'Prevent cleaning out Google Analytics Campaign & Google AdWords Parameters.', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'If you use Google Analytics campaign parameters starting with <code>?utm_</code>, check this box. You shouldn\'t use these btw, you should instead use the hash tagged version instead.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$content .= $wpseo_admin_pages->textinput( 'cleanpermalink-extravars', __( 'Other variables not to clean', 'wordpress-seo' ) );
|
||||
$content .= '<p class="desc">' . __( 'You might have extra variables you want to prevent from cleaning out, add them here, comma separated.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$wpseo_admin_pages->postbox( 'cleanpermalinksdiv', __( 'Clean Permalink Settings', 'wordpress-seo' ), $content );
|
||||
|
||||
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$options = WPSEO_Options::get_all();
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo_rss' ), 'wpseo_rss' );
|
||||
|
||||
$content = '<p>' . __( "This feature is used to automatically add content to your RSS, more specifically, it's meant to add links back to your blog and your blog posts, so dumb scrapers will automatically add these links too, helping search engines identify you as the original source of the content.", 'wordpress-seo' ) . '</p>';
|
||||
$rows = array();
|
||||
|
||||
$rows[] = array(
|
||||
'id' => 'rssbefore',
|
||||
'label' => __( 'Content to put before each post in the feed', 'wordpress-seo' ),
|
||||
'desc' => __( '(HTML allowed)', 'wordpress-seo' ),
|
||||
'content' => '<textarea cols="50" rows="5" id="rssbefore" name="wpseo_rss[rssbefore]">' . esc_textarea( $options['rssbefore'] ) . '</textarea>',
|
||||
);
|
||||
$rows[] = array(
|
||||
'id' => 'rssafter',
|
||||
'label' => __( 'Content to put after each post in the feed', 'wordpress-seo' ),
|
||||
'desc' => __( '(HTML allowed)', 'wordpress-seo' ),
|
||||
'content' => '<textarea cols="50" rows="5" id="rssafter" name="wpseo_rss[rssafter]">' . esc_textarea( $options['rssafter'] ) . '</textarea>',
|
||||
);
|
||||
$rows[] = array(
|
||||
'label' => __( 'Explanation', 'wordpress-seo' ),
|
||||
'content' => '<p>' . __( 'You can use the following variables within the content, they will be replaced by the value on the right.', 'wordpress-seo' ) . '</p>' .
|
||||
'<table>' .
|
||||
'<tr><th><strong>%%AUTHORLINK%%</strong></th><td>' . __( 'A link to the archive for the post author, with the authors name as anchor text.', 'wordpress-seo' ) . '</td></tr>' .
|
||||
'<tr><th><strong>%%POSTLINK%%</strong></th><td>' . __( 'A link to the post, with the title as anchor text.', 'wordpress-seo' ) . '</td></tr>' .
|
||||
'<tr><th><strong>%%BLOGLINK%%</strong></th><td>' . __( "A link to your site, with your site's name as anchor text.", 'wordpress-seo' ) . '</td></tr>' .
|
||||
'<tr><th><strong>%%BLOGDESCLINK%%</strong></th><td>' . __( "A link to your site, with your site's name and description as anchor text.", 'wordpress-seo' ) . '</td></tr>' .
|
||||
'</table>'
|
||||
);
|
||||
$wpseo_admin_pages->postbox( 'rssfootercontent', __( 'Content of your RSS Feed', 'wordpress-seo' ), $content . $wpseo_admin_pages->form_table( $rows ) );
|
||||
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -9,225 +9,113 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$fbconnect = '
|
||||
<p><strong>' . esc_html__( 'Facebook Insights and Admins', 'wordpress-seo' ) . '</strong><br>
|
||||
' . sprintf( esc_html__( 'To be able to access your %sFacebook Insights%s for your site, you need to specify a Facebook Admin. This can be a user, but if you have an app for your site, you could use that. For most people a user will be "good enough" though.', 'wordpress-seo' ), '<a href="https://www.facebook.com/insights">', '</a>' ) . '</p>';
|
||||
$fbbuttons = array();
|
||||
$social_facebook = new Yoast_Social_Facebook( );
|
||||
|
||||
$clearall = false;
|
||||
|
||||
$options = get_option( 'wpseo_social' );
|
||||
|
||||
if ( isset( $_GET['delfbadmin'] ) ) {
|
||||
if ( wp_verify_nonce( $_GET['nonce'], 'delfbadmin' ) != 1 ) {
|
||||
die( 'I don\'t think that\'s really nice of you!.' );
|
||||
}
|
||||
|
||||
$id = sanitize_text_field( $_GET['delfbadmin'] );
|
||||
if ( isset( $options['fb_admins'][ $id ] ) ) {
|
||||
$fbadmin = $options['fb_admins'][ $id ]['name'];
|
||||
unset( $options['fb_admins'][ $id ] );
|
||||
update_option( 'wpseo_social', $options );
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'success', sprintf( __( 'Successfully removed admin %s', 'wordpress-seo' ), $fbadmin ), 'updated' );
|
||||
unset( $fbadmin );
|
||||
}
|
||||
unset( $id );
|
||||
|
||||
// Clean up the referrer url for later use
|
||||
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
$_SERVER['REQUEST_URI'] = remove_query_arg( array( 'nonce', 'delfbadmin' ), sanitize_text_field( $_SERVER['REQUEST_URI'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
elseif ( isset( $_GET['fbclearall'] ) ) {
|
||||
if ( wp_verify_nonce( $_GET['nonce'], 'fbclearall' ) != 1 ) {
|
||||
die( "I don't think that's really nice of you!." );
|
||||
}
|
||||
// Reset to defaults, don't unset as otherwise the old values will be retained
|
||||
$options['fb_admins'] = WPSEO_Options::get_default( 'wpseo_social', 'fb_admins' );
|
||||
$options['fbapps'] = WPSEO_Options::get_default( 'wpseo_social', 'fbapps' );
|
||||
$options['fbadminapp'] = WPSEO_Options::get_default( 'wpseo_social', 'fbadminapp' );
|
||||
update_option( 'wpseo_social', $options );
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'success', __( 'Successfully cleared all Facebook Data', 'wordpress-seo' ), 'updated' );
|
||||
|
||||
// Clean up the referrer url for later use
|
||||
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
$_SERVER['REQUEST_URI'] = remove_query_arg( array( 'nonce', 'fbclearall' ), sanitize_text_field( $_SERVER['REQUEST_URI'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
elseif ( isset( $_GET['key'] ) ) {
|
||||
if ( $_GET['key'] === $options['fbconnectkey'] ) {
|
||||
if ( isset( $_GET['userid'] ) ) {
|
||||
$user_id = sanitize_text_field( $_GET['userid'] );
|
||||
if ( ! isset( $options['fb_admins'][ $user_id ] ) ) {
|
||||
$options['fb_admins'][ $user_id ]['name'] = sanitize_text_field( urldecode( $_GET['userrealname'] ) );
|
||||
$options['fb_admins'][ $user_id ]['link'] = sanitize_text_field( urldecode( $_GET['link'] ) );
|
||||
update_option( 'wpseo_social', $options );
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'success', sprintf( __( 'Successfully added %s as a Facebook Admin!', 'wordpress-seo' ), '<a href="' . esc_url( $options['fb_admins'][ $user_id ]['link'] ) . '">' . esc_html( $options['fb_admins'][ $user_id ]['name'] ) . '</a>' ), 'updated' );
|
||||
}
|
||||
else {
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'error', sprintf( __( '%s already exists as a Facebook Admin.', 'wordpress-seo' ), '<a href="' . esc_url( $options['fb_admins'][ $user_id ]['link'] ) . '">' . esc_html( $options['fb_admins'][ $user_id ]['name'] ) . '</a>' ), 'error' );
|
||||
}
|
||||
unset( $user_id );
|
||||
}
|
||||
elseif ( isset( $_GET['apps'] ) ) {
|
||||
$apps = json_decode( stripslashes( $_GET['apps'] ), true );
|
||||
if ( is_array( $apps ) && $apps !== array() ) {
|
||||
$options['fbapps'] = array( '0' => __( 'Do not use a Facebook App as Admin', 'wordpress-seo' ) );
|
||||
foreach ( $apps as $app ) {
|
||||
$options['fbapps'][ $app['app_id'] ] = $app['display_name'];
|
||||
}
|
||||
update_option( 'wpseo_social', $options );
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'success', __( 'Successfully retrieved your apps from Facebook, now select an app to use as admin.', 'wordpress-seo' ), 'updated' );
|
||||
}
|
||||
else {
|
||||
add_settings_error( 'yoast_wpseo_social_options', 'error', __( 'Failed to retrieve your apps from Facebook.', 'wordpress-seo' ), 'error' );
|
||||
}
|
||||
unset( $apps, $app );
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the referrer url for later use
|
||||
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
$_SERVER['REQUEST_URI'] = remove_query_arg( array( 'key', 'userid', 'userrealname', 'link', 'apps' ), sanitize_text_field( $_SERVER['REQUEST_URI'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh option after updates
|
||||
$options = get_option( 'wpseo_social' );
|
||||
|
||||
if ( is_array( $options['fb_admins'] ) && $options['fb_admins'] !== array() ) {
|
||||
$clearall = true;
|
||||
}
|
||||
|
||||
if ( is_array( $options['fbapps'] ) && $options['fbapps'] !== array() ) {
|
||||
$clearall = true;
|
||||
}
|
||||
|
||||
$app_button_text = __( 'Use a Facebook App as Admin', 'wordpress-seo' );
|
||||
if ( is_array( $options['fbapps'] ) && $options['fbapps'] !== array() ) {
|
||||
// @todo [JRF => whomever] use WPSEO_Admin_Pages->select() method ?
|
||||
$fbconnect .= '
|
||||
<p>' . __( 'Select an app to use as Facebook admin:', 'wordpress-seo' ) . '</p>
|
||||
<select name="wpseo_social[fbadminapp]" id="fbadminapp">';
|
||||
|
||||
foreach ( $options['fbapps'] as $id => $app ) {
|
||||
$fbconnect .= '
|
||||
<option value="' . esc_attr( $id ) . '" ' . selected( $id, $options['fbadminapp'], false ) . '>' . esc_attr( $app ) . '</option>';
|
||||
}
|
||||
$fbconnect .= '
|
||||
</select>
|
||||
<div class="clear"></div><br/>';
|
||||
|
||||
$app_button_text = __( 'Update Facebook Apps', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( $options['fbadminapp'] == 0 ) {
|
||||
$button_text = __( 'Add Facebook Admin', 'wordpress-seo' );
|
||||
$primary = true;
|
||||
if ( is_array( $options['fb_admins'] ) && $options['fb_admins'] !== array() ) {
|
||||
$fbconnect .= '
|
||||
<p>' . __( 'Currently connected Facebook admins:', 'wordpress-seo' ) . '</p>
|
||||
<ul>';
|
||||
$nonce = wp_create_nonce( 'delfbadmin' );
|
||||
|
||||
foreach ( $options['fb_admins'] as $admin_id => $admin ) {
|
||||
$admin_id = esc_attr( $admin_id );
|
||||
$fbconnect .= '
|
||||
<li><a href="' . esc_url( $admin['link'] ) . '">' . esc_html( $admin['name'] ) . '</a> - <strong><a href="' . esc_url( add_query_arg( array( 'delfbadmin' => $admin_id, 'nonce' => $nonce ), admin_url( 'admin.php?page=wpseo_social' ) ) ) . '">X</a></strong></li>';
|
||||
}
|
||||
$fbconnect .= '
|
||||
</ul>';
|
||||
$button_text = __( 'Add Another Facebook Admin', 'wordpress-seo' );
|
||||
$primary = false;
|
||||
}
|
||||
$but_primary = '';
|
||||
if ( $primary ) {
|
||||
$but_primary = '-primary';
|
||||
}
|
||||
$fbbuttons[] = '
|
||||
<a class="button' . esc_attr( $but_primary ) . '" href="' . esc_url( 'https://yoast.com/fb-connect/?key=' . urlencode( $options['fbconnectkey'] ) . '&redirect=' . urlencode( admin_url( 'admin.php?page=wpseo_social' ) ) ) . '">' . $button_text . '</a>';
|
||||
}
|
||||
|
||||
$fbbuttons[] = '
|
||||
<a class="button" href="' . esc_url( 'https://yoast.com/fb-connect/?key=' . urlencode( $options['fbconnectkey'] ) . '&type=app&redirect=' . urlencode( admin_url( 'admin.php?page=wpseo_social' ) ) ) . '">' . esc_html( $app_button_text ) . '</a>';
|
||||
|
||||
if ( $clearall ) {
|
||||
$fbbuttons[] = '
|
||||
<a class="button" href="' . esc_url( add_query_arg( array( 'nonce' => wp_create_nonce( 'fbclearall' ), 'fbclearall' => 'true' ), admin_url( 'admin.php?page=wpseo_social' ) ) ) . '">' . __( 'Clear all Facebook Data', 'wordpress-seo' ) . '</a> ';
|
||||
}
|
||||
|
||||
if ( is_array( $fbbuttons ) && $fbbuttons !== array() ) {
|
||||
$fbconnect .= '
|
||||
<p class="fb-buttons">' . implode( '', $fbbuttons ) . '</p>';
|
||||
}
|
||||
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo_social' ), 'wpseo_social' );
|
||||
$yform->admin_header( true, 'wpseo_social' );
|
||||
?>
|
||||
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab nav-tab-active" id="facebook-tab" href="#top#facebook"><?php _e( 'Facebook', 'wordpress-seo' );?></a>
|
||||
<a class="nav-tab" id="twitterbox-tab" href="#top#twitterbox"><?php _e( 'Twitter', 'wordpress-seo' );?></a>
|
||||
<a class="nav-tab" id="google-tab" href="#top#google"><?php _e( 'Google+', 'wordpress-seo' );?></a>
|
||||
</h2>
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" id="accounts-tab" href="#top#accounts"><?php _e( 'Accounts', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="facebook-tab" href="#top#facebook"><span class="dashicons dashicons-facebook-alt"></span> <?php _e( 'Facebook', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="twitterbox-tab" href="#top#twitterbox"><span class="dashicons dashicons-twitter"></span> <?php _e( 'Twitter', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="pinterest-tab" href="#top#pinterest"><?php _e( 'Pinterest', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="google-tab" href="#top#google"><span class="dashicons dashicons-googleplus"></span> <?php _e( 'Google+', 'wordpress-seo' ); ?></a>
|
||||
</h2>
|
||||
|
||||
<div id="accounts" class="wpseotab">
|
||||
<p>
|
||||
<?php _e( 'To inform Google about your social profiles, we need to know their URLs.', 'wordpress-seo' ); ?>
|
||||
<?php _e( 'For each, pick the main account associated with this site and please enter them below:', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
<?php
|
||||
$yform->textinput( 'facebook_site', __( 'Facebook Page URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'twitter_site', __( 'Twitter Username', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'instagram_url', __( 'Instagram URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'linkedin_url', __( 'LinkedIn URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'myspace_url', __( 'MySpace URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'pinterest_url', __( 'Pinterest URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'youtube_url', __( 'YouTube URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'google_plus_url', __( 'Google+ URL', 'wordpress-seo' ) );
|
||||
|
||||
do_action( 'wpseo_admin_other_section' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div id="facebook" class="wpseotab">
|
||||
<p>
|
||||
<?php $yform->checkbox( 'opengraph', __( 'Add Open Graph meta data', 'wordpress-seo' ) ); ?>
|
||||
</p>
|
||||
|
||||
<p class="desc">
|
||||
<?php _e( 'Add Open Graph meta data to your site\'s <code><head></code> section. You can specify some of the ID\'s that are sometimes needed below:', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
<?php
|
||||
$social_facebook->show_form();
|
||||
|
||||
<div id="facebook" class="wpseotab">
|
||||
<?php
|
||||
echo '<p>';
|
||||
echo $wpseo_admin_pages->checkbox( 'opengraph', __( 'Add Open Graph meta data', 'wordpress-seo' ) );
|
||||
echo '</p>';
|
||||
echo'<p class="desc">' . __( 'Add Open Graph meta data to your site\'s <code><head></code> section. You can specify some of the ID\'s that are sometimes needed below:', 'wordpress-seo' ) . '</p>';
|
||||
echo $fbconnect;
|
||||
echo $wpseo_admin_pages->textinput( 'facebook_site', __( 'Facebook Page URL', 'wordpress-seo' ) );
|
||||
if ( 'posts' == get_option( 'show_on_front' ) ) {
|
||||
echo '<h4>' . esc_html__( 'Frontpage settings', 'wordpress-seo' ) . '</h4>';
|
||||
echo $wpseo_admin_pages->media_input( 'og_frontpage_image', __( 'Image URL', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textinput( 'og_frontpage_title', __( 'Title', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->textinput( 'og_frontpage_desc', __( 'Description', 'wordpress-seo' ) );
|
||||
echo '<p><strong>' . esc_html__( 'Frontpage settings', 'wordpress-seo' ) . '</strong></p>';
|
||||
$yform->media_input( 'og_frontpage_image', __( 'Image URL', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'og_frontpage_title', __( 'Title', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'og_frontpage_desc', __( 'Description', 'wordpress-seo' ) );
|
||||
|
||||
// Offer copying of meta description
|
||||
$meta_options = get_option( 'wpseo_titles' );
|
||||
echo '<input type="hidden" id="meta_description" value="' . $meta_options['metadesc-home-wpseo'] . '" />';
|
||||
echo '<p class="label desc" style="border:0;"><a href="javascript:;" onclick="copy_home_meta();" class="button">' . __( 'Copy home meta description', 'wordpress-seo' ) . '</a></p>';
|
||||
echo '<input type="hidden" id="meta_description" value="', esc_attr( $meta_options['metadesc-home-wpseo'] ), '" />';
|
||||
echo '<p class="label desc" style="border:0;"><a href="javascript:;" onclick="copy_home_meta();" class="button">', esc_html__( 'Copy home meta description', 'wordpress-seo' ), '</a></p>';
|
||||
|
||||
echo '<p class="desc label">' . esc_html__( 'These are the title, description and image used in the Open Graph meta tags on the front page of your site.', 'wordpress-seo' ) . '</p>';
|
||||
}
|
||||
echo '<h4>' . esc_html__( 'Default settings', 'wordpress-seo' ) . '</h4>';
|
||||
echo $wpseo_admin_pages->media_input( 'og_default_image', __( 'Image URL', 'wordpress-seo' ) );
|
||||
echo '<p class="desc label">' . esc_html__( 'This image is used if the post/page being shared does not contain any images.', 'wordpress-seo' ) . '</p>';
|
||||
do_action( 'wpseo_admin_opengraph_section' );
|
||||
?>
|
||||
</div>
|
||||
} ?>
|
||||
|
||||
<div id="twitterbox" class="wpseotab">
|
||||
<?php
|
||||
echo '<p><strong>';
|
||||
printf( esc_html__( 'Note that for the Twitter Cards to work, you have to check the box below and then validate your Twitter Cards through the %1$sTwitter Card Validator%2$s.', 'wordpress-seo' ), '<a target="_blank" href="https://dev.twitter.com/docs/cards/validation/validator">', '</a>' );
|
||||
echo '</p></strong>';
|
||||
echo '<p>';
|
||||
echo $wpseo_admin_pages->checkbox( 'twitter', __( 'Add Twitter card meta data', 'wordpress-seo' ) );
|
||||
echo '</p>';
|
||||
echo'<p class="desc">' . __( 'Add Twitter card meta data to your site\'s <code><head></code> section.', 'wordpress-seo' ) . '</p>';
|
||||
echo $wpseo_admin_pages->textinput( 'twitter_site', __( 'Site Twitter Username', 'wordpress-seo' ) );
|
||||
echo $wpseo_admin_pages->select( 'twitter_card_type', __( 'The default card type to use', 'wordpress-seo' ), WPSEO_Option_Social::$twitter_card_types );
|
||||
<p><strong><?php esc_html_e( 'Default settings', 'wordpress-seo' ); ?></strong></p>
|
||||
<?php $yform->media_input( 'og_default_image', __( 'Image URL', 'wordpress-seo' ) ); ?>
|
||||
<p class="desc label">
|
||||
<?php esc_html_e( 'This image is used if the post/page being shared does not contain any images.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
|
||||
<?php do_action( 'wpseo_admin_opengraph_section' ); ?>
|
||||
</div>
|
||||
|
||||
<div id="twitterbox" class="wpseotab">
|
||||
<p>
|
||||
<?php $yform->checkbox( 'twitter', __( 'Add Twitter card meta data', 'wordpress-seo' ) ); ?>
|
||||
</p>
|
||||
|
||||
<p class="desc">
|
||||
<?php _e( 'Add Twitter card meta data to your site\'s <code><head></code> section.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
<?php
|
||||
$yform->select( 'twitter_card_type', __( 'The default card type to use', 'wordpress-seo' ), WPSEO_Option_Social::$twitter_card_types );
|
||||
do_action( 'wpseo_admin_twitter_section' );
|
||||
?>
|
||||
</div>
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div id="google" class="wpseotab">
|
||||
<?php
|
||||
echo '<p>';
|
||||
echo $wpseo_admin_pages->checkbox( 'googleplus', __( 'Add Google+ specific post meta data', 'wordpress-seo' ) );
|
||||
echo '</p>';
|
||||
<div id="pinterest" class="wpseotab">
|
||||
<p>
|
||||
<?php _e( 'Pinterest uses Open Graph metadata just like Facebook, so be sure to keep the Open Graph checkbox on the Facebook tab checked if you want to optimize your site for Pinterest.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
|
||||
echo $wpseo_admin_pages->textinput( 'plus-publisher', __( 'Google Publisher Page', 'wordpress-seo' ) );
|
||||
echo '<p class="desc label">' . esc_html__( 'If you have a Google+ page for your business, add that URL here and link it on your Google+ page\'s about page.', 'wordpress-seo' ) . '</p>';
|
||||
do_action( 'wpseo_admin_googleplus_section' );
|
||||
?>
|
||||
</div>
|
||||
<?php $yform->textinput( 'pinterestverify', __( 'Pinterest verification', 'wordpress-seo' ) ); ?>
|
||||
<p class="desc label">
|
||||
<?php printf( __( 'To %1$sverify your site with Pinterest%2$s, add the meta tag here', 'wordpress-seo' ), '<a target="_blank" href="https://help.pinterest.com/en/articles/verify-your-website#meta_tag">', '</a>' ); ?>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
do_action( 'wpseo_admin_pinterest_section' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div id="google" class="wpseotab">
|
||||
<p>
|
||||
<?php $yform->checkbox( 'googleplus', __( 'Add Google+ specific post meta data', 'wordpress-seo' ) ); ?>
|
||||
</p>
|
||||
|
||||
<?php $yform->textinput( 'plus-publisher', __( 'Google Publisher Page', 'wordpress-seo' ) ); ?>
|
||||
<p class="desc label"><?php esc_html_e( 'If you have a Google+ page for your business, add that URL here and link it on your Google+ page\'s about page.', 'wordpress-seo' ); ?></p>
|
||||
|
||||
<?php do_action( 'wpseo_admin_googleplus_section' ); ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
$yform->admin_footer();
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
$tool_page = (string) filter_input( INPUT_GET, 'tool' );
|
||||
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$yform->admin_header( false );
|
||||
|
||||
if ( '' === $tool_page ) {
|
||||
$tools = array(
|
||||
'bulk-editor' => array(
|
||||
'title' => __( 'Bulk editor', 'wordpress-seo' ),
|
||||
'desc' => __( 'This tool allows you to quickly change titles and descriptions of your posts and pages without having to go into the editor for each page.', 'wordpress-seo' ),
|
||||
),
|
||||
'import-export' => array(
|
||||
'title' => __( 'Import and Export', 'wordpress-seo' ),
|
||||
'desc' => __( 'Import settings from other SEO plugins and export your settings for re-use on (another) blog.', 'wordpress-seo' ),
|
||||
),
|
||||
);
|
||||
if ( WPSEO_Utils::allow_system_file_edit() === true && ! is_multisite() ) {
|
||||
$tools['file-editor'] = array(
|
||||
'title' => __( 'File editor', 'wordpress-seo' ),
|
||||
'desc' => __( 'This tool allows you to quickly change important files for your SEO, like your robots.txt and, if you have one, your .htaccess file.', 'wordpress-seo' ),
|
||||
);
|
||||
}
|
||||
|
||||
echo '<p>', __( 'WordPress SEO by Yoast comes with some very powerful built-in tools:', 'wordpress-seo' ), '</p>';
|
||||
|
||||
asort( $tools );
|
||||
|
||||
echo '<ul class="ul-disc">';
|
||||
foreach ( $tools as $slug => $tool ) {
|
||||
echo '<li>';
|
||||
echo '<strong><a href="', admin_url( 'admin.php?page=wpseo_tools&tool=' . $slug ), '">', $tool['title'], '</a></strong><br/>';
|
||||
echo $tool['desc'];
|
||||
echo '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
|
||||
}
|
||||
else {
|
||||
echo '<a href="', admin_url( 'admin.php?page=wpseo_tools' ), '">', __( '« Back to Tools page', 'wordpress-seo' ), '</a>';
|
||||
require_once WPSEO_PATH . 'admin/views/tool-' . $tool_page . '.php';
|
||||
}
|
||||
|
||||
$yform->admin_footer( false );
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -18,85 +18,108 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$wpseo_admin_pages->admin_header( true, WPSEO_Options::get_group_name( 'wpseo_xml' ), 'wpseo_xml' );
|
||||
$yform->admin_header( true, 'wpseo_xml' );
|
||||
|
||||
$options = get_option( 'wpseo_xml' );
|
||||
|
||||
$content = $wpseo_admin_pages->checkbox( 'enablexmlsitemap', __( 'Check this box to enable XML sitemap functionality.', 'wordpress-seo' ), false );
|
||||
$content .= '<div id="sitemapinfo">';
|
||||
if ( wpseo_is_nginx() ) {
|
||||
$content .= '<div style="margin: 5px 0; padding: 3px 10px; background-color: #ffffe0; border: 1px solid #E6DB55; border-radius: 3px;">';
|
||||
$content .= '<p>' . __( 'As you\'re on NGINX, you\'ll need the following rewrites:', 'wordpress-seo' ) . '</p>';
|
||||
$content .= '<pre>rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
|
||||
rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;</pre>';
|
||||
$content .= '</div>';
|
||||
}
|
||||
echo '<br/>';
|
||||
|
||||
if ( $options['enablexmlsitemap'] === true ) {
|
||||
$content .= '<p>' . sprintf( esc_html__( 'You can find your XML Sitemap here: %sXML Sitemap%s', 'wordpress-seo' ), '<a target="_blank" class="button-secondary" href="' . esc_url( wpseo_xml_sitemaps_base_url( 'sitemap_index.xml' ) ) . '">', '</a>' ) . '<br/><br/>' . __( 'You do <strong>not</strong> need to generate the XML sitemap, nor will it take up time to generate after publishing a post.', 'wordpress-seo' ) . '</p>';
|
||||
} else {
|
||||
$content .= '<p>' . __( 'Save your settings to activate XML Sitemaps.', 'wordpress-seo' ) . '</p>';
|
||||
}
|
||||
$yform->checkbox( 'enablexmlsitemap', __( 'Check this box to enable XML sitemap functionality.', 'wordpress-seo' ), false );
|
||||
|
||||
// When we write the help tab for this we should definitely reference this plugin :https://wordpress.org/plugins/edit-author-slug/
|
||||
$content .= '<h2>' . __( 'User sitemap', 'wordpress-seo' ) . '</h2>';
|
||||
$content .= $wpseo_admin_pages->checkbox( 'disable_author_sitemap', __( 'Disable author/user sitemap', 'wordpress-seo' ), false );
|
||||
?>
|
||||
<div id="sitemapinfo">
|
||||
<br/>
|
||||
|
||||
$content .= '<div id="xml_user_block">';
|
||||
$content .= '<p><strong>' . __( 'Exclude users without posts', 'wordpress-seo' ) . '</strong><br/>';
|
||||
$content .= $wpseo_admin_pages->checkbox( 'disable_author_noposts', __( 'Disable all users with zero posts', 'wordpress-seo' ), false );
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'General', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="user-sitemap-tab"
|
||||
href="#top#user-sitemap"><?php _e( 'User sitemap', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="post-types-tab"
|
||||
href="#top#post-types"><?php _e( 'Post Types', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="taxonomies-tab"
|
||||
href="#top#taxonomies"><?php _e( 'Taxonomies', 'wordpress-seo' ); ?></a>
|
||||
</h2>
|
||||
|
||||
$roles = wpseo_get_roles();
|
||||
if ( is_array( $roles ) && $roles !== array() ) {
|
||||
$content .= '<p><strong>' . __( 'Exclude user roles', 'wordpress-seo' ) . '</strong><br/>';
|
||||
$content .= __( 'Please check the appropriate box below if there\'s a user role that you do <strong>NOT</strong> want to include in your sitemap:', 'wordpress-seo' ) . '</p>';
|
||||
foreach ( $roles as $role_key => $role_name ) {
|
||||
$content .= $wpseo_admin_pages->checkbox( 'user_role-' . $role_key . '-not_in_sitemap', $role_name );
|
||||
}
|
||||
}
|
||||
$content .= '</div>';
|
||||
<div id="general" class="wpseotab">
|
||||
<?php
|
||||
|
||||
$content .= '<br/>';
|
||||
$content .= '<h2>' . __( 'General settings', 'wordpress-seo' ) . '</h2>';
|
||||
$content .= '<p>' . __( 'After content publication, the plugin automatically pings Google and Bing, do you need it to ping other search engines too? If so, check the box:', 'wordpress-seo' ) . '</p>';
|
||||
$content .= $wpseo_admin_pages->checkbox( 'xml_ping_yahoo', __( 'Ping Yahoo!', 'wordpress-seo' ), false );
|
||||
$content .= $wpseo_admin_pages->checkbox( 'xml_ping_ask', __( 'Ping Ask.com', 'wordpress-seo' ), false );
|
||||
if ( $options['enablexmlsitemap'] === true ) {
|
||||
echo '<p>';
|
||||
printf( esc_html__( 'You can find your XML Sitemap here: %sXML Sitemap%s', 'wordpress-seo' ), '<a target="_blank" class="button-secondary" href="' . esc_url( wpseo_xml_sitemaps_base_url( 'sitemap_index.xml' ) ) . '">', '</a>' );
|
||||
echo '<br/>';
|
||||
echo '<br/>';
|
||||
_e( 'You do <strong>not</strong> need to generate the XML sitemap, nor will it take up time to generate after publishing a post.', 'wordpress-seo' );
|
||||
echo '</p>';
|
||||
}
|
||||
else {
|
||||
echo '<p>', __( 'Save your settings to activate XML Sitemaps.', 'wordpress-seo' ), '</p>';
|
||||
}
|
||||
?>
|
||||
|
||||
<p>
|
||||
<strong><?php _e( 'Entries per page', 'wordpress-seo' ); ?></strong><br/>
|
||||
<?php printf( __( 'Please enter the maximum number of entries per sitemap page (defaults to %s, you might want to lower this to prevent memory issues on some installs):', 'wordpress-seo' ), WPSEO_Options::get_default( 'wpseo_xml', 'entries-per-page' ) ); ?>
|
||||
</p>
|
||||
|
||||
$post_types = apply_filters( 'wpseo_sitemaps_supported_post_types', get_post_types( array( 'public' => true ), 'objects' ) );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
$content .= '<h2>' . __( 'Exclude post types', 'wordpress-seo' ) . '</h2>';
|
||||
$content .= '<p>' . __( 'Please check the appropriate box below if there\'s a post type that you do <strong>NOT</strong> want to include in your sitemap:', 'wordpress-seo' ) . '</p>';
|
||||
foreach ( $post_types as $pt ) {
|
||||
$content .= $wpseo_admin_pages->checkbox( 'post_types-' . $pt->name . '-not_in_sitemap', $pt->labels->name . ' (<code>' . $pt->name . '</code>)' );
|
||||
}
|
||||
}
|
||||
<?php
|
||||
$yform->textinput( 'entries-per-page', __( 'Max entries per sitemap', 'wordpress-seo' ) );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div id="user-sitemap" class="wpseotab">
|
||||
<?php
|
||||
$yform->checkbox( 'disable_author_sitemap', __( 'Disable author/user sitemap', 'wordpress-seo' ), false );
|
||||
?>
|
||||
<div id="xml_user_block">
|
||||
<p><strong><?php _e( 'Exclude users without posts', 'wordpress-seo' ); ?></strong><br/>
|
||||
<?php $yform->checkbox( 'disable_author_noposts', __( 'Disable all users with zero posts', 'wordpress-seo' ), false );
|
||||
|
||||
$taxonomies = apply_filters( 'wpseo_sitemaps_supported_taxonomies', get_taxonomies( array( 'public' => true ), 'objects' ) );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
$content .= '<h2>' . __( 'Exclude taxonomies', 'wordpress-seo' ) . '</h2>';
|
||||
$content .= '<p>' . __( 'Please check the appropriate box below if there\'s a taxonomy that you do <strong>NOT</strong> want to include in your sitemap:', 'wordpress-seo' ) . '</p>';
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
if ( isset( $tax->labels->name ) && trim( $tax->labels->name ) != '' ) {
|
||||
$content .= $wpseo_admin_pages->checkbox( 'taxonomies-' . $tax->name . '-not_in_sitemap', $tax->labels->name . ' (<code>' . $tax->name . '</code>)' );
|
||||
}
|
||||
}
|
||||
}
|
||||
$roles = WPSEO_Utils::get_roles();
|
||||
if ( is_array( $roles ) && $roles !== array() ) {
|
||||
echo '<p><strong>' . __( 'Exclude user roles', 'wordpress-seo' ) . '</strong><br/>';
|
||||
echo __( 'Please check the appropriate box below if there\'s a user role that you do <strong>NOT</strong> want to include in your sitemap:', 'wordpress-seo' ) . '</p>';
|
||||
foreach ( $roles as $role_key => $role_name ) {
|
||||
$yform->checkbox( 'user_role-' . $role_key . '-not_in_sitemap', $role_name );
|
||||
}
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="post-types" class="wpseotab">
|
||||
|
||||
$content .= '<br/>';
|
||||
$content .= '<h2>' . __( 'Entries per page', 'wordpress-seo' ) . '</h2>';
|
||||
$content .= '<p>' . sprintf( __( 'Please enter the maximum number of entries per sitemap page (defaults to %s, you might want to lower this to prevent memory issues on some installs):', 'wordpress-seo' ), WPSEO_Options::get_default( 'wpseo_xml', 'entries-per-page' ) ) . '</p>';
|
||||
$content .= $wpseo_admin_pages->textinput( 'entries-per-page', __( 'Max entries per sitemap page', 'wordpress-seo' ) );
|
||||
<?php
|
||||
$post_types = apply_filters( 'wpseo_sitemaps_supported_post_types', get_post_types( array( 'public' => true ), 'objects' ) );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
echo '<p>' . __( 'Please check the appropriate box below if there\'s a post type that you do <strong>NOT</strong> want to include in your sitemap:', 'wordpress-seo' ) . '</p>';
|
||||
foreach ( $post_types as $pt ) {
|
||||
$yform->checkbox( 'post_types-' . $pt->name . '-not_in_sitemap', $pt->labels->name . ' (<code>' . $pt->name . '</code>)' );
|
||||
}
|
||||
}
|
||||
|
||||
$content .= '<br class="clear"/>';
|
||||
$content .= '</div>';
|
||||
?>
|
||||
|
||||
$wpseo_admin_pages->postbox( 'xmlsitemaps', __( 'XML Sitemap', 'wordpress-seo' ), $content );
|
||||
</div>
|
||||
|
||||
<div id="taxonomies" class="wpseotab">
|
||||
|
||||
<?php
|
||||
$taxonomies = apply_filters( 'wpseo_sitemaps_supported_taxonomies', get_taxonomies( array( 'public' => true ), 'objects' ) );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
echo '<p>' . __( 'Please check the appropriate box below if there\'s a taxonomy that you do <strong>NOT</strong> want to include in your sitemap:', 'wordpress-seo' ) . '</p>';
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
if ( isset( $tax->labels->name ) && trim( $tax->labels->name ) != '' ) {
|
||||
$yform->checkbox( 'taxonomies-' . $tax->name . '-not_in_sitemap', $tax->labels->name . ' (<code>' . $tax->name . '</code>)' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
do_action( 'wpseo_xmlsitemaps_config' );
|
||||
|
||||
$wpseo_admin_pages->admin_footer();
|
||||
$yform->admin_footer();
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a list of contributors
|
||||
*
|
||||
* @param array $contributors
|
||||
*/
|
||||
function wpseo_display_contributors( $contributors ) {
|
||||
foreach ( $contributors as $username => $dev ) {
|
||||
echo '<li class="wp-person" id="wp-person-', $username, '">';
|
||||
echo '<a href="https://github.com/', $username, '"><img src="https://secure.gravatar.com/avatar/', $dev->gravatar, '?s=60" class="gravatar" alt="', $dev->name, '"></a>';
|
||||
echo '<a class="web" href="https://github.com/', $username, '">', $dev->name, '</a>';
|
||||
echo '<span class="title">', $dev->role, '</span></li>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="wrap about-wrap">
|
||||
|
||||
<h1><?php _e( 'Thank you for updating WordPress SEO by Yoast!', 'wordpress-seo' ); ?></h1>
|
||||
|
||||
<div class="about-text">
|
||||
<?php _e( 'On your way to better search rankings!', 'wordpress-seo' ); ?><br/>
|
||||
<br/>
|
||||
<?php _e( 'WordPress SEO by Yoast 2.0 helps you optimize your site by making you ready for Google\'s Knowledge Graph and simplifying the WordPress SEO by Yoast admin.', 'wordpress-seo' ); ?>
|
||||
</div>
|
||||
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" href="#top#new" id="new-tab">
|
||||
<?php
|
||||
/* translators: %s: '2.0' version number */
|
||||
echo sprintf( __( 'What’s New In %s', 'wordpress-seo' ), '2.0' );
|
||||
?>
|
||||
</a>
|
||||
<a class="nav-tab" href="#top#v21" id="v21-tab">2.1</a>
|
||||
<a class="nav-tab" href="#top#credits" id="credits-tab"><?php _e( 'Credits', 'wordpress-seo' ); ?></a>
|
||||
</h2>
|
||||
|
||||
<div id="new" class="wpseotab">
|
||||
<div class="changelog headline-feature">
|
||||
<h2><?php _e( 'Simplified Admin Menus', 'wordpress-seo' ); ?></h2>
|
||||
|
||||
<div class="feature-section">
|
||||
<div class="col">
|
||||
<h3><?php _e( 'We’ve merged several menu items to make the most important settings stand out more.', 'wordpress-seo' ); ?></h3>
|
||||
|
||||
<p><?php _e( 'Not all settings are created equal. Some require their own admin page and really need your attention. Others are more advanced and don’t need changing by everyone. This release helps you by focusing on what’s important.', 'wordpress-seo' ); ?></p>
|
||||
|
||||
<p><?php printf( esc_html__( 'Several settings were moved to the %1$sAdvanced page%2$s, the bulk editor, file editor and import & export tools were all moved to the %3$sTools page%2$s.', 'wordpress-seo' ), '<a href="' . admin_url( 'admin.php?page=wpseo_advanced' ) . '">', '</a>', '<a href="' . admin_url( 'admin.php?page=wpseo_tools' ) . '">' ); ?></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<img class="aligncenter" src="http://uploads.yoast.nl/seo-menu_1A752658.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="changelog headline-feature dfw">
|
||||
<h2><?php _e( 'Ready for Google’s Knowledge Graph', 'wordpress-seo' ); ?></h2>
|
||||
|
||||
<div class="feature-image">
|
||||
<div class="dfw-container">
|
||||
<img src="http://uploads.yoast.nl/knowledge-graph_1A752930.png"/>
|
||||
</div>
|
||||
<h3><?php _e( 'Knowledge Graph: We’ve got your back!', 'wordpress-seo' ); ?></h3>
|
||||
|
||||
<p>
|
||||
<?php printf( __( 'Google recently rolled out changes that let you specify you or your companies name, social profiles and logo<sup>*</sup>, to use in their %1$sKnowledge Graph%2$s boxes.', 'wordpress-seo' ), '<a href="http://yoa.st/knowledgegraph">', '</a>' ); ?>
|
||||
<?php printf( __( 'Decide whether you’re a company or a person and add the required info in the %1$sgeneral settings%2$s, then add your %3$ssocial profiles%2$s. We’ll do the rest.', 'wordpress-seo' ), '<a href="' . admin_url( 'admin.php?page=wpseo_dashboard#top#knowledge-graph' ) . '">', '</a>', '<a href="' . admin_url( 'admin.php?page=wpseo_social' ) . '">' ); ?>
|
||||
</p>
|
||||
|
||||
<p><sup>*</sup>
|
||||
<small><?php _e( 'Logo only works for companies.', 'wordpress-seo' ); ?></small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="changelog feature-list finer-points">
|
||||
<h2><?php _e( 'More in this release', 'wordpress-seo' ); ?></h2>
|
||||
|
||||
<div class="feature-section col two-col">
|
||||
<div>
|
||||
<span class="dashicons dashicons-twitter"></span>
|
||||
<h4><?php _e( 'Twitter Galleries', 'wordpress-seo' ); ?></h4>
|
||||
<h2>WordPress SEO 2.0.1</h2>
|
||||
<p><small>Release date: April 1st, 2015</small></p>
|
||||
<p>This update fixes a few small bugs:</p>
|
||||
<ul class="ul-disc">
|
||||
<li>Fixes an issue where (in rare cases) people upgrading to 2.0 got stuck in a redirect loop on their admin.</li>
|
||||
<li>Fixes a broken link in the Dutch translation, causing the Pinterest tab on the Social settings page to overflow into the Google+ tab.</li>
|
||||
<li>Fixes a small typo on the about page.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<?php printf( __( 'If you use galleries in your posts and have Twitter meta data enabled on %1$sSocial → Twitter%2$s, galleries will now be auto-detected and put out as Gallery Cards. All that’s left for your is to %3$sverify the cards with Twitter%2$s.', 'wordpress-seo' ), '<a href="' . admin_url( 'admin.php?page=wpseo_social#top#twitterbox' ) . '">', '</a>', '<a target="_blank" href="http://yoa.st/twittercardsverify">' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="last-feature">
|
||||
<span class="dashicons dashicons-performance"></span>
|
||||
<h4><?php _e( 'Performance Improvements', 'wordpress-seo' ); ?></h4>
|
||||
|
||||
<p>
|
||||
<?php _e( 'This release has made the code of WordPress SEO by Yoast that runs on the frontend of your site approximately 30% faster.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="dashicons dashicons-admin-generic"></span>
|
||||
<h4><?php _e( 'Improved Settings Screens', 'wordpress-seo' ); ?> </h4>
|
||||
|
||||
<p>
|
||||
<?php _e( 'All the settings screens have been updated to use exactly the same, tab-based, styling, making them much more comprehensible.', 'wordpress-seo' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="last-feature">
|
||||
<span class="dashicons dashicons-translation"></span>
|
||||
<h4><?php _e( 'More Translations', 'wordpress-seo' ); ?></h4>
|
||||
|
||||
<p>
|
||||
<?php printf( __( 'WordPress SEO by Yoast ships, at time of release, with 26 translations, of which 10 are complete. That\'s a huge improvement from last time, and we\'re improving every week. Join us at %1$stranslate.yoast.com%2$s!', 'wordpress-seo' ), '<a target="_blank" href="https://translate.yoast.com/projects/wordpress-seo">', '</a>' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="return-to-dashboard">
|
||||
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wpseo_dashboard' ) ); ?>"><?php _e( 'Go to The General settings page →', 'wordpress-seo' ); ?></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="v21" class="wpseotab">
|
||||
<h2>WordPress SEO 2.1</h2>
|
||||
<p><small>Release date: April 20th, 2015</small></p>
|
||||
<p>WordPress SEO 2.1 adds some more features on top of this release. Read the release notes for more info.</p>
|
||||
<ul class="ul-disc">
|
||||
<li>See the <a href="https://wordpress.org/plugins/wordpress-seo/changelog/" target="_blank">changelog</a> for a complete list of changes.</li>
|
||||
<li>Read our <a href="https://yoast.com/wordpress-seo-2-1-release-notes" target="_blank">release blogpost</a> for a more detailed explanation of the important changes in this release.</li>
|
||||
<li>Read our <a href="https://yoast.com/coordinated-security-release/" target="_blank">security blogpost</a> for the backstory about a security fix that was included in this release, in coordination with a significant part of the WordPress community.</li>
|
||||
<li>We've added support for Google's new URL representation in mobile search results. You can read more about it in <a href="https://yoast.com/changing-urls-in-search-results/" target="_blank">this blogpost</a>.</li>
|
||||
</ul>
|
||||
<h2>WordPress SEO 2.0.1</h2>
|
||||
<p><small>Release date: April 1st, 2015</small></p>
|
||||
<p>This update fixes a few small bugs:</p>
|
||||
<ul class="ul-disc">
|
||||
<li>Fixes an issue where (in rare cases) people upgrading to 2.0 got stuck in a redirect loop on their admin.</li>
|
||||
<li>Fixes a broken link in the Dutch translation, causing the Pinterest tab on the Social settings page to overflow into the Google+ tab.</li>
|
||||
<li>Fixes a small typo on the about page.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="credits" class="wpseotab">
|
||||
<p class="about-description">
|
||||
<?php
|
||||
printf( __( 'While most of the development team is at %1$sYoast%2$s in the Netherlands, WordPress SEO by Yoast is created by a worldwide team.', 'wordpress-seo' ), '<a target="_blank" href="https://yoast.com/">', '</a>' );
|
||||
echo ' ';
|
||||
printf( __( 'Want to help us develop? Read our %1$scontribution guidelines%2$s!', 'wordpress-seo' ), '<a target="_blank" href="http://yoa.st/wpseocontributionguidelines">', '</a>' );
|
||||
?>
|
||||
</p>
|
||||
|
||||
<h4 class="wp-people-group"><?php _e( 'Project Leaders', 'wordpress-seo' ); ?></h4>
|
||||
<ul class="wp-people-group " id="wp-people-group-project-leaders">
|
||||
<?php
|
||||
$leaders = array(
|
||||
'jdevalk' => (object) array(
|
||||
'name' => 'Joost de Valk',
|
||||
'role' => __( 'Project Lead', 'wordpress-seo' ),
|
||||
'gravatar' => 'f08c3c3253bf14b5616b4db53cea6b78',
|
||||
),
|
||||
'jrfnl' => (object) array(
|
||||
'name' => 'Juliette Reinders Folmer',
|
||||
'role' => __( 'Lead Developer', 'wordpress-seo' ),
|
||||
'gravatar' => 'cbbac3e529102364dc3b026af3cc2988',
|
||||
),
|
||||
'omarreiss' => (object) array(
|
||||
'name' => 'Omar Reiss',
|
||||
'role' => __( 'Lead Developer', 'wordpress-seo' ),
|
||||
'gravatar' => '86aaa606a1904e7e0cf9857a663c376e',
|
||||
),
|
||||
'tacoverdo' => (object) array(
|
||||
'name' => 'Taco Verdonschot',
|
||||
'role' => __( 'QA & Translations Manager', 'wordpress-seo' ),
|
||||
'gravatar' => 'd2d3ecb38cacd521926979b5c678297b',
|
||||
),
|
||||
);
|
||||
|
||||
wpseo_display_contributors( $leaders );
|
||||
?>
|
||||
</ul>
|
||||
<h4 class="wp-people-group"><?php _e( 'Contributing Developers', 'wordpress-seo' ); ?></h4>
|
||||
<ul class="wp-people-group " id="wp-people-group-core-developers">
|
||||
<?php
|
||||
$contributors = array(
|
||||
'andizer' => (object) array(
|
||||
'name' => 'Andy Meerwaldt',
|
||||
'role' => __( 'Developer', 'wordpress-seo' ),
|
||||
'gravatar' => 'a9b43e766915b48031eab78f9916ca8e',
|
||||
),
|
||||
'petervw' => (object) array(
|
||||
'name' => 'Peter van Wilderen',
|
||||
'role' => __( 'Developer', 'wordpress-seo' ),
|
||||
'gravatar' => 'e4662ebd4b59d3c196e2ba721d8a1efc',
|
||||
),
|
||||
'rarst' => (object) array(
|
||||
'name' => 'Andrey Savchenko',
|
||||
'role' => __( 'Developer', 'wordpress-seo' ),
|
||||
'gravatar' => 'ab89ce39f47b327f1c85e4019e865a71',
|
||||
),
|
||||
'CarolineGeven' => (object) array(
|
||||
'name' => 'Caroline Geven',
|
||||
'role' => __( 'Developer', 'wordpress-seo' ),
|
||||
'gravatar' => 'f2596a568c3974e35f051266a63d791f',
|
||||
),
|
||||
);
|
||||
|
||||
wpseo_display_contributors( $contributors );
|
||||
?>
|
||||
</ul>
|
||||
<h4 class="wp-people-group"><?php _e( 'Contributors to this release', 'wordpress-seo' ); ?></h4>
|
||||
<?php
|
||||
$patches_from = array(
|
||||
'Jack Neary' => 'https://github.com/xeeeveee',
|
||||
'Koen Van den Wijngaert' => 'https://github.com/vdwijngaert',
|
||||
'Ezra Pool' => 'https://github.com/Zae',
|
||||
'Andy Sozot' => 'https://github.com/sozot',
|
||||
);
|
||||
?>
|
||||
<p><?php _e( 'We\'re always grateful for patches from non-regular contributors, this release, patches from the following people made it in:', 'wordpress-seo' ); ?></p>
|
||||
<ul class="ul-square">
|
||||
<?php
|
||||
foreach ( $patches_from as $patcher => $link ) {
|
||||
echo '<li><a href="', esc_url( $link ), '">', $patcher, '</a></li>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$yform->currentoption = 'wpseo_internallinks';
|
||||
|
||||
$yform->checkbox( 'breadcrumbs-enable', __( 'Enable Breadcrumbs', 'wordpress-seo' ) );
|
||||
echo '<br/>';
|
||||
echo '<div id="breadcrumbsinfo">';
|
||||
$yform->textinput( 'breadcrumbs-sep', __( 'Separator between breadcrumbs', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'breadcrumbs-home', __( 'Anchor text for the Homepage', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'breadcrumbs-prefix', __( 'Prefix for the breadcrumb path', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'breadcrumbs-archiveprefix', __( 'Prefix for Archive breadcrumbs', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'breadcrumbs-searchprefix', __( 'Prefix for Search Page breadcrumbs', 'wordpress-seo' ) );
|
||||
$yform->textinput( 'breadcrumbs-404crumb', __( 'Breadcrumb for 404 Page', 'wordpress-seo' ) );
|
||||
echo '<br/>';
|
||||
if ( get_option( 'show_on_front' ) == 'page' && get_option( 'page_for_posts' ) > 0 ) {
|
||||
$yform->checkbox( 'breadcrumbs-blog-remove', __( 'Remove Blog page from Breadcrumbs', 'wordpress-seo' ) );
|
||||
}
|
||||
$yform->checkbox( 'breadcrumbs-boldlast', __( 'Bold the last page in the breadcrumb', 'wordpress-seo' ) );
|
||||
echo '<br/><br/>';
|
||||
|
||||
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
echo '<strong>' . __( 'Taxonomy to show in breadcrumbs for:', 'wordpress-seo' ) . '</strong><br/>';
|
||||
foreach ( $post_types as $pt ) {
|
||||
$taxonomies = get_object_taxonomies( $pt->name, 'objects' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
$values = array( 0 => __( 'None', 'wordpress-seo' ) );
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
$values[ $tax->name ] = $tax->labels->singular_name;
|
||||
}
|
||||
$yform->select( 'post_types-' . $pt->name . '-maintax', $pt->labels->name, $values );
|
||||
unset( $values, $tax );
|
||||
}
|
||||
unset( $taxonomies );
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
echo '<br/>';
|
||||
|
||||
$taxonomies = get_taxonomies( array( 'public' => true, '_builtin' => false ), 'objects' );
|
||||
if ( is_array( $taxonomies ) && $taxonomies !== array() ) {
|
||||
echo '<strong>' . __( 'Post type archive to show in breadcrumbs for:', 'wordpress-seo' ) . '</strong><br/>';
|
||||
foreach ( $taxonomies as $tax ) {
|
||||
$values = array( 0 => __( 'None', 'wordpress-seo' ) );
|
||||
if ( get_option( 'show_on_front' ) == 'page' && get_option( 'page_for_posts' ) > 0 ) {
|
||||
$values['post'] = __( 'Blog', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( is_array( $post_types ) && $post_types !== array() ) {
|
||||
foreach ( $post_types as $pt ) {
|
||||
if ( $pt->has_archive ) {
|
||||
$values[ $pt->name ] = $pt->labels->name;
|
||||
}
|
||||
}
|
||||
unset( $pt );
|
||||
}
|
||||
$yform->select( 'taxonomy-' . $tax->name . '-ptparent', $tax->labels->singular_name, $values );
|
||||
unset( $values, $tax );
|
||||
}
|
||||
}
|
||||
unset( $taxonomies, $post_types );
|
||||
|
||||
?>
|
||||
<br class="clear"/>
|
||||
</div>
|
||||
<p>
|
||||
<strong><?php _e( 'How to insert breadcrumbs in your theme', 'wordpress-seo' ); ?></strong><br/>
|
||||
<?php printf( __( 'Usage of this breadcrumbs feature is explained %1$shere%2$s. For the more code savvy, insert this in your theme:', 'wordpress-seo' ), '<a href="https://yoast.com/wordpress/plugins/breadcrumbs/" target="_blank">', '</a>' ); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php if ( function_exists('yoast_breadcrumb') ) {
|
||||
yoast_breadcrumb('<p id="breadcrumbs">','</p>');
|
||||
} ?>
|
||||
</pre>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
$yform = Yoast_Form::get_instance();
|
||||
$yform->currentoption = 'wpseo_permalinks';
|
||||
|
||||
echo '<p><strong>', __( 'Change URLs', 'wordpress-seo' ), '</strong></p>';
|
||||
$yform->checkbox( 'stripcategorybase', __( 'Strip the category base (usually <code>/category/</code>) from the category URL.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . sprintf( __( 'We suggest using %1$sFV Top Level Categories%2$s, if you insist on keeping this but do know that the feature is very error prone and not <em>that</em> important for your SEO.', 'wordpress-seo' ), '<a href="https://wordpress.org/plugins/fv-top-level-cats/">', '</a>' ) . '</p>';
|
||||
|
||||
$yform->checkbox( 'redirectattachment', __( 'Redirect attachment URL\'s to parent post URL.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'Attachments to posts are stored in the database as posts, this means they\'re accessible under their own URL\'s if you do not redirect them, enabling this will redirect them to the post they were attached to.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo '<p><strong>', __( 'Clean up permalinks', 'wordpress-seo' ), '</strong></p>';
|
||||
$yform->checkbox( 'cleanslugs', __( 'Remove stop words from slugs.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'This helps you to create cleaner URLs by automatically removing the stopwords from them.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$yform->checkbox( 'cleanreplytocom', __( 'Remove the <code>?replytocom</code> variables.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'This prevents threaded replies from working when the user has JavaScript disabled, but on a large site can mean a <em>huge</em> improvement in crawl efficiency for search engines when you have a lot of comments.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$yform->checkbox( 'trailingslash', __( 'Enforce a trailing slash on all category and tag URL\'s', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'If you choose a permalink for your posts with <code>.html</code>, or anything else but a / on the end, this will force WordPress to add a trailing slash to non-post pages nonetheless.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$yform->checkbox( 'cleanpermalinks', __( 'Redirect ugly URL\'s to clean permalinks. (Not recommended in many cases!)', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'People make mistakes in their links towards you sometimes, or unwanted parameters are added to the end of your URLs, this allows you to redirect them all away. Please note that while this is a feature that is actively maintained, it is known to break several plugins, and should for that reason be the first feature you disable when you encounter issues after installing this plugin.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
echo '<div id="cleanpermalinksdiv">';
|
||||
$yform->checkbox( 'cleanpermalink-googlesitesearch', __( 'Prevent cleaning out Google Site Search URL\'s.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'Google Site Search URL\'s look weird, and ugly, but if you\'re using Google Site Search, you probably do not want them cleaned out.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$yform->checkbox( 'cleanpermalink-googlecampaign', __( 'Prevent cleaning out Google Analytics Campaign & Google AdWords Parameters.', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'If you use Google Analytics campaign parameters starting with <code>?utm_</code>, check this box. You shouldn\'t use these btw, you should instead use the hash tagged version instead.', 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$yform->textinput( 'cleanpermalink-extravars', __( 'Other variables not to clean', 'wordpress-seo' ) );
|
||||
echo '<p class="desc">' . __( 'You might have extra variables you want to prevent from cleaning out, add them here, comma separated.', 'wordpress-seo' ) . '</p>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<p><strong>', __( 'Clean up the <code><head></code>', 'wordpress-seo' ), '</strong></p>';
|
||||
$yform->checkbox( 'hide-rsdlink', __( 'Hide RSD Links', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'hide-wlwmanifest', __( 'Hide WLW Manifest Links', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'hide-shortlink', __( 'Hide Shortlink for posts', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'hide-feedlinks', __( 'Hide RSS Links', 'wordpress-seo' ) );
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
$yform = Yoast_Form::get_instance();
|
||||
$yform->set_option( 'wpseo_rss' );
|
||||
|
||||
echo '<p>' . __( "This feature is used to automatically add content to your RSS, more specifically, it's meant to add links back to your blog and your blog posts, so dumb scrapers will automatically add these links too, helping search engines identify you as the original source of the content.", 'wordpress-seo' ) . '</p>';
|
||||
|
||||
$textarea_atts = array(
|
||||
'cols' => '50',
|
||||
'rows' => '5',
|
||||
);
|
||||
$yform->textarea( 'rssbefore', __( 'Content to put before each post in the feed', 'wordpress-seo' ), '', $textarea_atts );
|
||||
$yform->textarea( 'rssafter', __( 'Content to put after each post in the feed', 'wordpress-seo' ), '', $textarea_atts );
|
||||
?>
|
||||
|
||||
<p><?php _e( 'You can use the following variables within the content, they will be replaced by the value on the right.', 'wordpress-seo' ); ?></p>
|
||||
<table>
|
||||
<tr>
|
||||
<th><strong>%%AUTHORLINK%%</strong></th>
|
||||
<td><?php _e( 'A link to the archive for the post author, with the authors name as anchor text.', 'wordpress-seo' ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><strong>%%POSTLINK%%</strong></th>
|
||||
<td><?php _e( 'A link to the post, with the title as anchor text.', 'wordpress-seo' ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><strong>%%BLOGLINK%%</strong></th>
|
||||
<td><?php _e( "A link to your site, with your site's name as anchor text.", 'wordpress-seo' ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><strong>%%BLOGDESCLINK%%</strong></th>
|
||||
<td><?php _e( "A link to your site, with your site's name and description as anchor text.", 'wordpress-seo' ); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
+4
-6
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Admin
|
||||
* @package WPSEO\Admin
|
||||
* @since 1.5.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
@@ -9,8 +10,6 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
global $wpseo_admin_pages;
|
||||
|
||||
$options = get_option( 'wpseo' );
|
||||
|
||||
$wpseo_bulk_titles_table = new WPSEO_Bulk_Title_Editor_List_Table();
|
||||
@@ -30,11 +29,10 @@ if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
|
||||
|
||||
<div class="wrap wpseo_table_page">
|
||||
|
||||
<h2 id="wpseo-title"><?php echo esc_html( get_admin_page_title() ); ?></h2>
|
||||
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab" id="title-tab" href="#top#title"><?php _e( 'Title', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="description-tab" href="#top#description"><?php _e( 'Description', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="description-tab"
|
||||
href="#top#description"><?php _e( 'Description', 'wordpress-seo' ); ?></a>
|
||||
</h2>
|
||||
|
||||
<div class="tabwrapper">
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
$robots_file = get_home_path() . 'robots.txt';
|
||||
$ht_access_file = get_home_path() . '.htaccess';
|
||||
|
||||
if ( isset( $_POST['create_robots'] ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
die( __( 'You cannot create a robots.txt file.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpseo_create_robots' );
|
||||
|
||||
ob_start();
|
||||
error_reporting( 0 );
|
||||
do_robots();
|
||||
$robots_content = ob_get_clean();
|
||||
|
||||
$f = fopen( $robots_file, 'x' );
|
||||
fwrite( $f, $robots_content );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['submitrobots'] ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
die( __( 'You cannot edit the robots.txt file.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpseo-robotstxt' );
|
||||
|
||||
if ( file_exists( $robots_file ) ) {
|
||||
$robotsnew = stripslashes( $_POST['robotsnew'] );
|
||||
if ( is_writable( $robots_file ) ) {
|
||||
$f = fopen( $robots_file, 'w+' );
|
||||
fwrite( $f, $robotsnew );
|
||||
fclose( $f );
|
||||
$msg = __( 'Updated Robots.txt', 'wordpress-seo' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['submithtaccess'] ) ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
die( __( 'You cannot edit the .htaccess file.', 'wordpress-seo' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'wpseo-htaccess' );
|
||||
|
||||
if ( file_exists( $ht_access_file ) ) {
|
||||
$ht_access_new = stripslashes( $_POST['htaccessnew'] );
|
||||
if ( is_writeable( $ht_access_file ) ) {
|
||||
$f = fopen( $ht_access_file, 'w+' );
|
||||
fwrite( $f, $ht_access_new );
|
||||
fclose( $f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $msg ) && ! empty( $msg ) ) {
|
||||
echo '<div id="message" style="width:94%;" class="updated fade"><p>', esc_html( $msg ), '</p></div>';
|
||||
}
|
||||
|
||||
$action_url = network_admin_url( 'admin.php?page=wpseo_tools&tool=file-editor' ); // auto-falls back on admin_url for non-multisite
|
||||
|
||||
echo '<h2>', __( 'Robots.txt', 'wordpress-seo' ), '</h2>';
|
||||
|
||||
if ( ! file_exists( $robots_file ) ) {
|
||||
if ( is_writable( get_home_path() ) ) {
|
||||
echo '<form action="', esc_url( $action_url ), '" method="post" id="robotstxtcreateform">';
|
||||
wp_nonce_field( 'wpseo_create_robots', '_wpnonce', true, true );
|
||||
echo '<p>', __( 'You don\'t have a robots.txt file, create one here:', 'wordpress-seo' ), '</p>';
|
||||
echo '<input type="submit" class="button" name="create_robots" value="', __( 'Create robots.txt file', 'wordpress-seo' ), '">';
|
||||
echo '</form>';
|
||||
}
|
||||
else {
|
||||
echo '<p>', __( 'If you had a robots.txt file and it was editable, you could edit it from here.', 'wordpress-seo' ), '</p>';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$f = fopen( $robots_file, 'r' );
|
||||
|
||||
$content = '';
|
||||
if ( filesize( $robots_file ) > 0 ) {
|
||||
$content = fread( $f, filesize( $robots_file ) );
|
||||
}
|
||||
$robots_txt_content = esc_textarea( $content );
|
||||
|
||||
if ( ! is_writable( $robots_file ) ) {
|
||||
echo '<p><em>', __( 'If your robots.txt were writable, you could edit it from here.', 'wordpress-seo' ), '</em></p>';
|
||||
echo '<textarea class="large-text code" disabled="disabled" rows="15" name="robotsnew">', $robots_txt_content, '</textarea><br/>';
|
||||
}
|
||||
else {
|
||||
echo '<form action="', esc_url( $action_url ), '" method="post" id="robotstxtform">';
|
||||
wp_nonce_field( 'wpseo-robotstxt', '_wpnonce', true, true );
|
||||
echo '<p>', __( 'Edit the content of your robots.txt:', 'wordpress-seo' ), '</p>';
|
||||
echo '<textarea class="large-text code" rows="15" name="robotsnew">', $robots_txt_content, '</textarea><br/>';
|
||||
echo '<div class="submit"><input class="button" type="submit" name="submitrobots" value="', __( 'Save changes to Robots.txt', 'wordpress-seo' ), '" /></div>';
|
||||
echo '</form>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '<h2>', __( '.htaccess file', 'wordpress-seo' ), '</h2>';
|
||||
if ( ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stristr( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) === false ) && file_exists( $ht_access_file ) ) {
|
||||
$f = fopen( $ht_access_file, 'r' );
|
||||
|
||||
$contentht = '';
|
||||
if ( filesize( $ht_access_file ) > 0 ) {
|
||||
$contentht = fread( $f, filesize( $ht_access_file ) );
|
||||
}
|
||||
$contentht = esc_textarea( $contentht );
|
||||
|
||||
if ( ! is_writable( $ht_access_file ) ) {
|
||||
echo '<p><em>', __( 'If your .htaccess were writable, you could edit it from here.', 'wordpress-seo' ), '</em></p>';
|
||||
echo '<textarea class="large-text code" disabled="disabled" rows="15" name="robotsnew">', $contentht, '</textarea><br/>';
|
||||
}
|
||||
else {
|
||||
echo '<form action="', esc_url( $action_url ), '" method="post" id="htaccessform">';
|
||||
wp_nonce_field( 'wpseo-htaccess', '_wpnonce', true, true );
|
||||
echo '<p>', __( 'Edit the content of your .htaccess:', 'wordpress-seo' ), '</p>';
|
||||
echo '<textarea class="large-text code" rows="15" name="htaccessnew">', $contentht, '</textarea><br/>';
|
||||
echo '<div class="submit"><input class="button" type="submit" name="submithtaccess" value="', __( 'Save changes to .htaccess', 'wordpress-seo' ), '" /></div>';
|
||||
echo '</form>';
|
||||
}
|
||||
}
|
||||
elseif ( ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stristr( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) === false ) && ! file_exists( $ht_access_file ) ) {
|
||||
echo '<p>', __( 'If you had a .htaccess file and it was editable, you could edit it from here.', 'wordpress-seo' ), '</p>';
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WPSEO_VERSION' ) ) {
|
||||
header( 'Status: 403 Forbidden' );
|
||||
header( 'HTTP/1.1 403 Forbidden' );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo [JRF => testers] Extensively test the export & import of the (new) settings!
|
||||
* If that all works fine, getting testers to export before and after upgrade will make testing easier.
|
||||
*
|
||||
* @todo [Yoast] The import for the RSS Footer plugin checks for data already entered via WP SEO,
|
||||
* the other import routines should do that too.
|
||||
*/
|
||||
|
||||
$yform = Yoast_Form::get_instance();
|
||||
|
||||
$replace = false;
|
||||
|
||||
if ( isset( $_POST['import'] ) || isset( $_GET['import'] ) ) {
|
||||
|
||||
check_admin_referer( 'wpseo-import' );
|
||||
|
||||
if ( isset( $_POST['wpseo']['deleteolddata'] ) && $_POST['wpseo']['deleteolddata'] == 'on' ) {
|
||||
$replace = true;
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importwoo'] ) ) {
|
||||
$import = new WPSEO_Import_WooThemes_SEO( $replace );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importaioseo'] ) || isset( $_GET['importaioseo'] ) ) {
|
||||
$import = new WPSEO_Import_AIOSEO( $replace );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importheadspace'] ) ) {
|
||||
$import = new WPSEO_Import_External( $replace );
|
||||
$import->import_headspace();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importrobotsmeta'] ) || isset( $_GET['importrobotsmeta'] ) ) {
|
||||
$import = new WPSEO_Import_External( $replace );
|
||||
$import->import_robots_meta();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importrssfooter'] ) ) {
|
||||
$import = new WPSEO_Import_External( $replace );
|
||||
$import->import_rss_footer();
|
||||
}
|
||||
|
||||
if ( isset( $_POST['wpseo']['importbreadcrumbs'] ) ) {
|
||||
$import = new WPSEO_Import_External( $replace );
|
||||
$import->import_yoast_breadcrumbs();
|
||||
}
|
||||
|
||||
// Allow custom import actions
|
||||
do_action( 'wpseo_handle_import' );
|
||||
|
||||
}
|
||||
|
||||
if ( isset( $_FILES['settings_import_file'] ) ) {
|
||||
check_admin_referer( 'wpseo-import-file' );
|
||||
|
||||
$import = new WPSEO_Import();
|
||||
}
|
||||
|
||||
if ( isset( $import ) ) {
|
||||
/**
|
||||
* Allow customization of import&export message
|
||||
* @api string $msg The message.
|
||||
*/
|
||||
$msg = apply_filters( 'wpseo_import_message', $import->msg );
|
||||
|
||||
// Check if we've deleted old data and adjust message to match it
|
||||
if ( $replace ) {
|
||||
$msg .= ' ' . __( 'The old data of the imported plugin was deleted successfully.', 'wordpress-seo' );
|
||||
}
|
||||
|
||||
if ( $msg != '' ) {
|
||||
echo '<div id="message" class="message updated" style="width:94%;"><p>', $msg, '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<br/><br/>
|
||||
<h2 class="nav-tab-wrapper" id="wpseo-tabs">
|
||||
<a class="nav-tab nav-tab-active" id="wpseo-import-tab"
|
||||
href="#top#wpseo-import"><?php _e( 'Import', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="wpseo-export-tab" href="#top#wpseo-export"><?php _e( 'Export', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="import-seo-tab"
|
||||
href="#top#import-seo"><?php _e( 'Import from other SEO plugins', 'wordpress-seo' ); ?></a>
|
||||
<a class="nav-tab" id="import-other-tab"
|
||||
href="#top#import-other"><?php _e( 'Import from other plugins', 'wordpress-seo' ); ?></a>
|
||||
<?php
|
||||
/**
|
||||
* Allow adding a custom import tab header
|
||||
*/
|
||||
do_action( 'wpseo_import_tab_header' );
|
||||
?>
|
||||
</h2>
|
||||
|
||||
<div id="wpseo-import" class="wpseotab">
|
||||
<p><?php _e( 'Import settings by locating <em>settings.zip</em> and clicking "Import settings"', 'wordpress-seo' ); ?></p>
|
||||
|
||||
<form
|
||||
action="<?php echo esc_attr( admin_url( 'admin.php?page=wpseo_tools&tool=import-export#top#wpseo-import' ) ); ?>"
|
||||
method="post" enctype="multipart/form-data"
|
||||
accept-charset="<?php echo esc_attr( get_bloginfo( 'charset' ) ); ?>">
|
||||
<?php wp_nonce_field( 'wpseo-import-file', '_wpnonce', true, true ); ?>
|
||||
<input type="file" name="settings_import_file" accept="application/x-zip,application/x-zip-compressed,application/zip" />
|
||||
<input type="hidden" name="action" value="wp_handle_upload"/><br/>
|
||||
<br/>
|
||||
<input type="submit" class="button-primary" value="<?php _e( 'Import settings', 'wordpress-seo' ); ?>"/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="wpseo-export" class="wpseotab">
|
||||
<p><?php _e( 'Export your WordPress SEO settings here, to import them again later or to import them on another site.', 'wordpress-seo' ); ?></p>
|
||||
<?php $yform->checkbox( 'include_taxonomy_meta', __( 'Include Taxonomy Metadata', 'wordpress-seo' ) ); ?><br/>
|
||||
<button class="button-primary" id="export-button">Export your WordPress SEO settings</button>
|
||||
<script>
|
||||
var wpseo_export_nonce = '<?php echo wp_create_nonce( 'wpseo-export' ); ?>';
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="import-seo" class="wpseotab">
|
||||
<p><?php _e( 'No doubt you\'ve used an SEO plugin before if this site isn\'t new. Let\'s make it easy on you, you can import the data below. If you want, you can import first, check if it was imported correctly, and then import & delete. No duplicate data will be imported.', 'wordpress-seo' ); ?></p>
|
||||
|
||||
<p><?php printf( __( 'If you\'ve used another SEO plugin, try the %sSEO Data Transporter%s plugin to move your data into this plugin, it rocks!', 'wordpress-seo' ), '<a href="https://wordpress.org/plugins/seo-data-transporter/">', '</a>' ); ?></p>
|
||||
|
||||
<form
|
||||
action="<?php echo esc_attr( admin_url( 'admin.php?page=wpseo_tools&tool=import-export#top#import-seo' ) ); ?>"
|
||||
method="post" accept-charset="<?php echo esc_attr( get_bloginfo( 'charset' ) ); ?>">
|
||||
<?php
|
||||
wp_nonce_field( 'wpseo-import', '_wpnonce', true, true );
|
||||
$yform->checkbox( 'importheadspace', __( 'Import from HeadSpace2?', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'importaioseo', __( 'Import from All-in-One SEO?', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'importwoo', __( 'Import from WooThemes SEO framework?', 'wordpress-seo' ) );
|
||||
?>
|
||||
<br/>
|
||||
<?php
|
||||
$yform->checkbox( 'deleteolddata', __( 'Delete the old data after import? (recommended)', 'wordpress-seo' ) );
|
||||
?>
|
||||
<br/>
|
||||
<input type="submit" class="button-primary" name="import"
|
||||
value="<?php _e( 'Import', 'wordpress-seo' ); ?>"/>
|
||||
</form>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
|
||||
<div id="import-other" class="wpseotab">
|
||||
<p><?php _e( 'If you want to import data from (by now ancient) Yoast plugins, you can do so here:', 'wordpress-seo' ); ?></p>
|
||||
|
||||
<form
|
||||
action="<?php echo esc_attr( admin_url( 'admin.php?page=wpseo_tools&tool=import-export#top#import-other' ) ); ?>"
|
||||
method="post" accept-charset="<?php echo esc_attr( get_bloginfo( 'charset' ) ); ?>">
|
||||
<?php
|
||||
wp_nonce_field( 'wpseo-import', '_wpnonce', true, true );
|
||||
$yform->checkbox( 'importrobotsmeta', __( 'Import from Robots Meta (by Yoast)?', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'importrssfooter', __( 'Import from RSS Footer (by Yoast)?', 'wordpress-seo' ) );
|
||||
$yform->checkbox( 'importbreadcrumbs', __( 'Import from Yoast Breadcrumbs?', 'wordpress-seo' ) );
|
||||
|
||||
/**
|
||||
* Allow option of importing from other 'other' plugins
|
||||
* @api string $content The content containing all import and export methods
|
||||
*/
|
||||
echo apply_filters( 'wpseo_import_other_plugins', '' );
|
||||
|
||||
?>
|
||||
<br/>
|
||||
<input type="submit" class="button-primary" name="import" value="<?php _e( 'Import', 'wordpress-seo' ); ?>"/>
|
||||
</form>
|
||||
<br/>
|
||||
</div>
|
||||
<?php
|
||||
/**
|
||||
* Allow adding a custom import tab
|
||||
*/
|
||||
do_action( 'wpseo_import_tab_content' );
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPSEO\Admin
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<h3 id="wordpress-seo"><?php _e( 'WordPress SEO settings', 'wordpress-seo' ); ?></h3>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th>
|
||||
<label
|
||||
for="wpseo_author_title"><?php _e( 'Title to use for Author page', 'wordpress-seo' ); ?></label>
|
||||
</th>
|
||||
<td><input class="regular-text" type="text" id="wpseo_author_title" name="wpseo_author_title"
|
||||
value="<?php echo esc_attr( get_the_author_meta( 'wpseo_title', $user->ID ) ); ?>"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label
|
||||
for="wpseo_author_metadesc"><?php _e( 'Meta description to use for Author page', 'wordpress-seo' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<textarea rows="3" cols="30" id="wpseo_author_metadesc"
|
||||
name="wpseo_author_metadesc"><?php echo esc_textarea( get_the_author_meta( 'wpseo_metadesc', $user->ID ) ); ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ( $options['usemetakeywords'] === true ) { ?>
|
||||
<tr>
|
||||
<th>
|
||||
<label
|
||||
for="wpseo_author_metakey"><?php _e( 'Meta keywords to use for Author page', 'wordpress-seo' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input class="regular-text" type="text" id="wpseo_author_metakey"
|
||||
name="wpseo_author_metakey"
|
||||
value="<?php echo esc_attr( get_the_author_meta( 'wpseo_metakey', $user->ID ) ); ?>"/>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<th>
|
||||
<label
|
||||
for="wpseo_author_exclude"><?php _e( 'Exclude user from Author-sitemap', 'wordpress-seo' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input class="checkbox double" type="checkbox" id="wpseo_author_exclude"
|
||||
name="wpseo_author_exclude"
|
||||
value="on" <?php echo ( get_the_author_meta( 'wpseo_excludeauthorsitemap', $user->ID ) == 'on' ) ? 'checked' : ''; ?> />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
Reference in new issue
Block a user