0
Validation results

Seven SERP Theme

Seven SERP Theme

WordPress 5.8.2 theme
0
  • THEME TYPEWordPress theme 5.8.2
  • FILE NAMEsevenserp-theme.zip
  • FILE SIZE1253006 bytes
  • MD5976e01f506115a7a609e6f8f49a1e413
  • SHA15c6a8da945dc267566d5441badd62472961060ea
  • LICENSENone
  • FILES INCLUDEDCSS, PHP, XML, Bitmap images, Adobe Illustrator
  • VERSION0.87
  • TAGSsevenserp
  • CREATION DATE2021-10-30
  • LAST FILE UPDATE2021-10-30
  • LAST VALIDATION2021-10-30 14:15
This theme seems to be proprietary. Themecheck doesn't distribute commercial themes.
Critical alerts
  1. Customizer : Sanitization of Customizer settings Found a Customizer setting that did not have a sanitization callback function in file customization.php. Every call to the add_setting() method needs to have a sanitization callback function passed.Found a Customizer setting that did not have a sanitization callback function in file menu.php. Every call to the add_setting() method needs to have a sanitization callback function passed.
  2. Title : Title No reference to add_theme_support( "title-tag" ) was found in the theme.The theme needs to have <title> tags, ideally in the header.php file.The theme needs to have a call to wp_title(), ideally in the header.php file.The <title> tags can only contain a call to wp_title(). Use the wp_title filter to modify the output.The <title> tags can only contain a call to wp_title(). Use the wp_title filter to modify the output.The <title> tags can only contain a call to wp_title(). Use the wp_title filter to modify the output.The <title> tags can only contain a call to wp_title(). Use the wp_title filter to modify the output.
  3. Security breaches : Modification of PHP server settings Found ini_set in file helpers.php. 39: </button>'; } } if(!function_exists('replace_first')){ function replace_first($find, $replace, $subject){ return implode($replace, explode($find, $subject, 2)); } } if(!function_exists('str_replace_n')){ function str_replace_n($search, $replace, $subject, $occurrence){ return preg_replace('/^((?:(?:.*?$search){'.--$occurrence.'}.*?))$search/i', '$1$replace', $subject); } } if(!function_exists('clear_wp_string')){ function clear_wp_string($text=''){ return trim(str_replace([ '<p></p>', '<center></center>', '</div><br />', '</div><br/>', '</div><br>', '&nbsp; ' ], [ NULL, NULL, '</div>', '</div>', '</div>', NULL ], $text)); } } if(!function_exists('parametros')){ function obtenerPagina(){ return substr(@$_SERVER['REQUEST_URI'], 1, strlen(@$_SERVER['REQUEST_URI'])); } function obtenerUrl(){ return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://'.(@$_SERVER['HTTP_HOST']).(@$_SERVER['REQUEST_URI']); } function parametro($posicion, $parametro=''){ if(strlen($parametro) == 0 && strlen($posicion) > 0 && is_numeric($posicion)){ return obtener_parametro($posicion); } if(is_numeric($posicion) && strlen($parametro) > 0 && $posicion <= parametros()){ if(strcasecmp(obtener_parametro($posicion), $parametro) == 0){ return true; } } return false; } function obtener_ultimo_parametro(){ return obtener_parametro(parametros()); } function obtener_parametro($posicion=1, $pagina=NULL){ if($pagina==NULL){ $pagina = obtenerPagina(); } if($posicion <= 0){ $posicion = 1; } $array = explode('/', $pagina); $p = @$array[($posicion-1)]; if(strpos($p, '?') !== FALSE){ $p = trim(str_replace('?', NULL, substr($p, 0, strpos($p, '?')))); } return $p; } function hay_parametro($posicion){ if(strlen(obtener_parametro($posicion)) > 0){ return true; } return false; } function parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } $array = explode('/', $pagina); if(empty($array)){ return 0; } $total = 0; foreach($array as $a){ if(strlen(trim($a)) > 0){ $total++; } } return $total; } function todos_parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } if(parametros($pagina) >= 1){ $array_final = array(); foreach(range(1, parametros($pagina)) as $par){ if(strlen(obtener_parametro($par, $pagina)) > 0){ array_push($array_final, obtener_parametro($par, $pagina)); } } return $array_final; } return array(); } } class UnsafeCrypto { const METHOD = 'aes-256-ctr'; public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = mb_substr($message, 0, $nonceSize, '8bit'); $ciphertext = mb_substr($message, $nonceSize, null, '8bit'); $plaintext = openssl_decrypt( $ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); return $plaintext; } } class SaferCrypto extends UnsafeCrypto { const HASH_ALGO = 'sha256'; public static function encrypt($message, $key, $encode = false) { list($encKey, $authKey) = self::splitKeys($key); $ciphertext = parent::encrypt($message, $encKey); $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true); if ($encode) { return base64_encode($mac.$ciphertext); } return $mac.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { list($encKey, $authKey) = self::splitKeys($key); if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit'); $mac = mb_substr($message, 0, $hs, '8bit'); $ciphertext = mb_substr($message, $hs, null, '8bit'); $calculated = hash_hmac( self::HASH_ALGO, $ciphertext, $authKey, true ); if (!self::hashEquals($mac, $calculated)) { throw new Exception('Encryption failure'); } $plaintext = parent::decrypt($ciphertext, $encKey); return $plaintext; } protected static function splitKeys($masterKey) { return [ hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true), hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true) ]; } protected static function hashEquals($a, $b) { if (function_exists('hash_equals')) { return hash_equals($a, $b); } $nonce = openssl_random_pseudo_bytes(32); return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce); } } if(defined('WP_DEBUG') && WP_DEBUG){ if(!defined('WP_DEBUG_LOG')){ define('WP_DEBUG_LOG', false); } if(!defined('WP_DEBUG_DISPLAY')){ define('WP_DEBUG_DISPLAY', true); } if(function_exists('error_reporting')){ error_reporting(E_ALL); } if(function_exists('ini_set')){ @ini_set('display_errors', '1'); @ini_set('display_startup_errors', '1'); } Found ini_set in file security.php. 37: use Jaybizzle\CrawlerDetect\CrawlerDetect; if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!defined('PHP_INT_MIN')){ define('PHP_INT_MIN', ~PHP_INT_MAX); } if(!defined('FORCE_SSL_ADMIN')){ define('FORCE_SSL_ADMIN', TRUE); if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== FALSE){ $_SERVER['HTTPS']='on'; } } if(!defined('DISALLOW_FILE_EDIT')){ define('DISALLOW_FILE_EDIT', TRUE); } if(!defined('WP_POST_REVISIONS')){ define('WP_POST_REVISIONS', 3); } if(function_exists('expose_php')){ @ini_set('expose_php', 'Off'); } if(!class_exists('Seven_Security')){ class
  4. Security breaches : Use of base64_decode() Found base64_decode in file amazon.php. 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi; use Amazon\ProductAdvertisingAPI\v1\ApiException; use Amazon\ProductAdvertisingAPI\v1\Configuration; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException; define('AMAZON_DEFAULT_CACHE', 604800); add_action('admin_init', function(){ if(!get_option('az_refresh_time')){ add_option('az_refresh_time', AMAZON_DEFAULT_CACHE); } }); if(!class_exists('Amazon')){ class Amazon{ private $api_key=NULL; private $api_secret=NULL; private $aff_id=NULL; private $keyword=NULL; private $amazon_key=NULL; private $items=NULL; function __construct(){ $this->amazon_key = $this->get_amazon_key(); $this->api_key = $this->get_api_key(); $this->api_secret = $this->get_api_secret(); $this->aff_id = $this->get_id(); } public function setKeyword($kw=NULL){ $this->keyword=$kw; } public function setItemIds($items=[]){ $this->items=(array)$items; } public function cfg_valid(){ if($this->api_key!=NULL && $this->api_secret!=NULL && $this->aff_id!=NULL){ return true; } return false; } public function get_api_key(){ $key = get_option('az_api_key'); if(!$key || !is_string($key) || strlen(trim($key))==0){ return NULL; } return $key; } public function get_amazon_key(){ if($this->amazon_key>NULL) return $this->amazon_key; global $Seven_API; $cached_key = get_option('az_seven_key'); if(!$cached_key || ($cached_key && strlen(trim($cached_key))==0)){ if($Seven_API->no_license() || !$Seven_API->license_valid()){ return false; } $amazon_key = base64_encode(trim(microtime().time().rand(100,99999999999999))); delete_option('az_seven_key'); add_option('az_seven_key', $amazon_key); $cached_key = $amazon_key; } if($Seven_API->validate_license_format($cached_key)){ return trim(base64_decode($cached_key)); } return false; } public function get_cache_ti72: */ /* Automatically generated. DO NOT REMOVE. */ header('HTTP/1.0 403 Forbidden'); die(); ?>'); } return $amazon_cache; } public function get_result_cache($md5=NULL){ if(!is_string($md5) || !ctype_alnum($md5)) exit('wrong md5'); try{ $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; if(file_exists($dir)){ $diff = abs(time()-filemtime($dir)); if( $this->get_cache_time() != -1 && $diff > $this->get_cache_time() ){ return false; } $content = file_get_contents($dir); $decrypted = SaferCrypto::decrypt(base64_decode($content), $this->get_amazon_key()); return $decrypted; }elseFound base64_decode in file sevenserp-api.php. 110: if ($v_s == base64_decode('JSV2ZXJzaW9uc3RyaW5nJSU=')) return __('NULA', TRANSLATIONS);Found base64_decode in file helpers.php. 39: </button>'; } } if(!function_exists('replace_first')){ function replace_first($find, $replace, $subject){ return implode($replace, explode($find, $subject, 2)); } } if(!function_exists('str_replace_n')){ function str_replace_n($search, $replace, $subject, $occurrence){ return preg_replace('/^((?:(?:.*?$search){'.--$occurrence.'}.*?))$search/i', '$1$replace', $subject); } } if(!function_exists('clear_wp_string')){ function clear_wp_string($text=''){ return trim(str_replace([ '<p></p>', '<center></center>', '</div><br />', '</div><br/>', '</div><br>', '&nbsp; ' ], [ NULL, NULL, '</div>', '</div>', '</div>', NULL ], $text)); } } if(!function_exists('parametros')){ function obtenerPagina(){ return substr(@$_SERVER['REQUEST_URI'], 1, strlen(@$_SERVER['REQUEST_URI'])); } function obtenerUrl(){ return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://'.(@$_SERVER['HTTP_HOST']).(@$_SERVER['REQUEST_URI']); } function parametro($posicion, $parametro=''){ if(strlen($parametro) == 0 && strlen($posicion) > 0 && is_numeric($posicion)){ return obtener_parametro($posicion); } if(is_numeric($posicion) && strlen($parametro) > 0 && $posicion <= parametros()){ if(strcasecmp(obtener_parametro($posicion), $parametro) == 0){ return true; } } return false; } function obtener_ultimo_parametro(){ return obtener_parametro(parametros()); } function obtener_parametro($posicion=1, $pagina=NULL){ if($pagina==NULL){ $pagina = obtenerPagina(); } if($posicion <= 0){ $posicion = 1; } $array = explode('/', $pagina); $p = @$array[($posicion-1)]; if(strpos($p, '?') !== FALSE){ $p = trim(str_replace('?', NULL, substr($p, 0, strpos($p, '?')))); } return $p; } function hay_parametro($posicion){ if(strlen(obtener_parametro($posicion)) > 0){ return true; } return false; } function parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } $array = explode('/', $pagina); if(empty($array)){ return 0; } $total = 0; foreach($array as $a){ if(strlen(trim($a)) > 0){ $total++; } } return $total; } function todos_parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } if(parametros($pagina) >= 1){ $array_final = array(); foreach(range(1, parametros($pagina)) as $par){ if(strlen(obtener_parametro($par, $pagina)) > 0){ array_push($array_final, obtener_parametro($par, $pagina)); } } return $array_final; } return array(); } } class UnsafeCrypto { const METHOD = 'aes-256-ctr'; public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exceptio
  5. Security breaches : Use of base64_encode() Found base64_encode in file external-links.php.
     if(!defined('ABSPATH')){ die(); } if(!class_exists('Seven_Link')){ class Seven_Link{ private $anchor_text = ''; private $atts = []; function __construct($atts=[], $anchor_text=''){ if(is_string($anchor_text)){ $this->anchor_text = strip_tags(htmlentities($anchor_text)); unset($anchor_text); } if(is_array($atts)){ $this->atts = $atts; unset($atts); } } public function rel_list(){ return [ 'alternate', 'author', 'bookmark', 'ugc', 'external', 'help', 'license', 'next', 'nofollow', 'sponsored', 'noreferrer', 'noopener', 'prev', 'search', 'tag' ]; } private function valid_rel(){ if(isset($this->atts['rel']) && is_string($this->atts['rel'])){ $rel = trim($this->atts['rel']); if(strpos($rel, ' ') !== FALSE){ $rels = explode(' ', $rel); foreach($rels as $r){ if(strlen(trim($r))>0 && !in_array($r, $this->rel_list())) return false; } }else if(in_array($rel, $this->rel_list())){ return true; } } return false; } private function get_url(){ if(isset($this->atts['href']) || isset($this->atts['url'])){ if(isset($this->atts['href'])){ $url = $this->atts['href']; }else if(isset($this->atts['url'])){ $url = $this->atts['url']; }else{ return '#'; } return str_replace([''', '''], NULL, $url); } return '#'; } private function get_rel(){ if(isset($this->atts['rel']) && $this->valid_rel()){ return trim($this->atts['rel']); } return ''; } private function get_anchor_text(){ if(strlen(trim($this->anchor_text))>0){ return do_shortcode(html_entity_decode($this->anchor_text)); }else{ return '['.__('Enlace no válido', TRANSLATIONS).']'; } } public function render(){ if(!isset($this->atts['obfuscate']) && !isset($this->atts['ofuscar'])){ return '<a href=''.$this->get_url().''>'.$this->get_anchor_text().'</a>'; }else{ return '<span data-link-optimizer=''.base64_encode($this->get_url()).'''.(isset($this->atts['newtab']) && $this-
    Found base64_encode in file cache.php.
     if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_INT_MIN); } function get_cache_folder(): string{ return WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); } function create_cache_folder(){ $cache_dir = WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); if(!is_dir($cache_dir)){ $dir = mkdir($cache_dir); } unset($cache_dir); } private function get_last_route(): string{ return get_option(self::LAST_ROUTE); } function get_css_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $css_name = 'css-'.$route.'.css'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$css_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$css_name}'); } function get_js_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $js_name = 'app-'.$route.'.js'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$js_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$js_name}'); } function get_new_route(){ return md5(microtime().time().rand(1,9999)); } function generate_minified_css($new_route=''){ try{ $minifier = new Minify\CSS(); $bootstrap = LOC.'../assets/css/bootstrap-5.0.0.css'; if(file_exists($bootstrap)){ $minifier->add(file_get_contents($bootstrap)); } unset($boostrap); $file = LOC.'../assets/css/style.css'; if(file_exists($file)){ $css_content = file_get_contents($file); $css_content = str_replace([ '%%corp%%', '%%corp_secondary%%', '%%header_bg_color%%', '%%footer_bg_color%%', '%%shadows%%', '%%fontsize%%', '%%fontfamily%%', '%%fontfamily_head%%', '%%headerlink_color%%', '%%footerlink_color%%', '%%body_bg_color%%', '%%title_dots%%', '%%line_height%%', '%%blur%%', '%%logo_size%%', '%%header_inner_padding%%' ], [ (!get_theme_mod('corp_color') ? 'black' : get_theme_mod('corp_color')), (!get_theme_mod('corp_secondary_color') ? 'grey' : get_theme_mod('corp_secondary_color')), (!get_theme_mod('header_background_color') ? 'white' : get_theme_mod('header_background_color')), (!get_theme_mod('footer_background_color') ? 'white' : get_theme_mod('footer_background_color')), (!get_theme_mod('disable_shadows') ? '14px 14px 40px 0 rgba(118,126,173,.15)' : 'none'), (int)str_replace('px', NULL, (!get_theme_mod('font_size') ? '16' : get_theme_mod('font_size'))), (!get_theme_mod('font_family_main') ? 'Inter' : get_theme_mod('font_family_main')), (!get_theme_mod('font_family_head') ? (get_theme_mod('font_family_main') ? get_theme_mod('font_family_main') : 'Inter') : get_theme_mod('font_family_head')), (!get_theme_mod('menu_link_color') ? 'black' : get_theme_mod('menu_link_color')), (!get_theme_mod('footer_link_color') ? 'black' : get_theme_mod('footer_link_color')), (!get_theme_mod('body_background_color') ? 'white' : get_theme_mod('body_background_color')), ( !get_theme_mod('disable_title_dots') ? 'display:inline-block; content:''; width:8px; height:8px; border-radius:50%; background:var(--corp); margin-left:7px; position:relative; top:-2px;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('line_height') ? '25' : get_theme_mod('line_height'))), ( !get_theme_mod('disable_blur') ? 'position: absolute; top: 0; left: 0; height: 100%; width: 100%; content: ''; background: linear-gradient(180deg,transparent,rgba(255,255,255,.70) 90%); pointer-events: none; display: block;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('logo_size') ? '20' : get_theme_mod('logo_size'))), (!get_theme_mod('header_inner_padding') ? 'var(--defaultpadding)' : str_replace('px', NULL, get_theme_mod('header_inner_padding')).'px') ], $css_content); $minifier->add($css_content); unset($css_content); }else{ throw new Exception(__('El fichero crítico del CSS no existe.', TRANSLATIONS)); } unset($file); if(is_child_theme()){ $child_theme_stylesheet = get_stylesheet_directory().'/style.css'; if(file_exists($child_theme_stylesheet)){ $minifier->add(file_get_contents($child_theme_stylesheet)); } unset($child_theme_stylesheet); } try{ if(!is_string($new_route) || strlen(trim($new_route))==0){ return $minifier->minify(); }else{ $file = file_put_contents($this->get_css_route($new_route, true), '/* '.sprintf(__('Este archivo de caché ha sido creado por %s', TRANSLATIONS), (defined('WHITE_LABEL') ? WHITE_LABEL : THEME_PRINTABLE_NAME)).' */'.$minifier->minify()); } unset($minifier); }catch(Exception $ex){ } return (!$file ? false : true); }catch(Exception $ex){ return false; } return false; } function generate_minified_js($new_route=''){ try{ if(!is_string($new_route) || strlen(trim($new_route))==0){ throw new Exception(__('Especifica una ruta válida para minificar el fichero javascript.', TRANSLATIONS)); } $javascript_file = dirname(__FILE__).'/../assets/js/application.js'; if(file_exists($javascript_file)){ $code = file_get_contents($javascript_file); if(defined('CUSTOM_JAVASCRIPT_FILE')){ if(file_exists(CUSTOM_JAVASCRIPT_FILE)){ $code = str_replace('%%custom%%', file_get_contents(CUSTOM_JAVASCRIPT_FILE), $code); } } $code = str_replace('%%disablerightclick%%', (!empty(get_theme_mod('disable_right_click', '')) ? 'window.oncontextmenu=function(){return false;}' : NULL), $code); if(module_enabled('analytics')){ $hide_for_admins = get_option('hide_ganalytics_for_admin'); $google_analytics = get_option('ganalytics_id'); if(valid_analytics($google_analytics)){ if($hide_for_admins != 'on' || ($hide_for_admins == 'on' && !current_user_can('manage_options'))){ $analytics = 'loadJS(atob(''.base64_encode('https://www.googletagmanager.com/gtag/js?id=').'')+atob(''.b
     gtag(\'config\', atob(''.base64_encode($google_analytics).''));
    Found base64_encode in file amazon.php.
     if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi; use Amazon\ProductAdvertisingAPI\v1\ApiException; use Amazon\ProductAdvertisingAPI\v1\Configuration; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException; define('AMAZON_DEFAULT_CACHE', 604800); add_action('admin_init', function(){ if(!get_option('az_refresh_time')){ add_option('az_refresh_time', AMAZON_DEFAULT_CACHE); } }); if(!class_exists('Amazon')){ class Amazon{ private $api_key=NULL; private $api_secret=NULL; private $aff_id=NULL; private $keyword=NULL; private $amazon_key=NULL; private $items=NULL; function __construct(){ $this->amazon_key = $this->get_amazon_key(); $this->api_key = $this->get_api_key(); $this->api_secret = $this->get_api_secret(); $this->aff_id = $this->get_id(); } public function setKeyword($kw=NULL){ $this->keyword=$kw; } public function setItemIds($items=[]){ $this->items=(array)$items; } public function cfg_valid(){ if($this->api_key!=NULL && $this->api_secret!=NULL && $this->aff_id!=NULL){ return true; } return false; } public function get_api_key(){ $key = get_option('az_api_key'); if(!$key || !is_string($key) || strlen(trim($key))==0){ return NULL; } return $key; } public function get_amazon_key(){ if($this->amazon_key>NULL) return $this->amazon_key; global $Seven_API; $cached_key = get_option('az_seven_key'); if(!$cached_key || ($cached_key && strlen(trim($cached_key))==0)){ if($Seven_API->no_license() || !$Seven_API->license_valid()){ return false; } $amazon_key = base64_encode(trim(microtime().time().rand(100,99999999999999))); delete_op
     <div class='col-lg-4 az-title'>'.htmlentities($item->getItemInfo()->getTitle()->getDisplayValue()).'</div>'; } $html .= ($is_table ? '<div class='col-lg-4'>' : NULL).'<button class='az-button' data-link-optimizer=''.base64_encode($item->getDetailPageURL()).''>
    Found base64_encode in file menu.php.
     $attributes .= 'data-link-optimizer='' .base64_encode($value).''';
    Found base64_encode in file shortcodes.php.
     <div class='image' style=''.(isset($image) ? $image : 'background: rgb(35, 40, 45);').'' data-link-optimizer=''.base64_encode(get_the_permalink($recent->ID)).''>
    Found base64_encode in file random-authors.php.
     if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } function get_author_image($id=0, $base64=true){ $path = LOC.'../assets/images/author-placeholder-32x32.png'; $type = pathinfo($path, PATHINFO_EXTENSION); $data = file_get_contents($path); $base64 = 'data:image/'.$type.';base64,'.base64_encode($data); return $base64; } function seven_get_post_author($pos
    Found base64_encode in file helpers.php.
     </button>'; } } if(!function_exists('replace_first')){ function replace_first($find, $replace, $subject){ return implode($replace, explode($find, $subject, 2)); } } if(!function_exists('str_replace_n')){ function str_replace_n($search, $replace, $subject, $occurrence){ return preg_replace('/^((?:(?:.*?$search){'.--$occurrence.'}.*?))$search/i', '$1$replace', $subject); } } if(!function_exists('clear_wp_string')){ function clear_wp_string($text=''){ return trim(str_replace([ '<p></p>', '<center></center>', '</div><br />', '</div><br/>', '</div><br>', '&nbsp; ' ], [ NULL, NULL, '</div>', '</div>', '</div>', NULL ], $text)); } } if(!function_exists('parametros')){ function obtenerPagina(){ return substr(@$_SERVER['REQUEST_URI'], 1, strlen(@$_SERVER['REQUEST_URI'])); } function obtenerUrl(){ return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://'.(@$_SERVER['HTTP_HOST']).(@$_SERVER['REQUEST_URI']); } function parametro($posicion, $parametro=''){ if(strlen($parametro) == 0 && strlen($posicion) > 0 && is_numeric($posicion)){ return obtener_parametro($posicion); } if(is_numeric($posicion) && strlen($parametro) > 0 && $posicion <= parametros()){ if(strcasecmp(obtener_parametro($posicion), $parametro) == 0){ return true; } } return false; } function obtener_ultimo_parametro(){ return obtener_parametro(parametros()); } function obtener_parametro($posicion=1, $pagina=NULL){ if($pagina==NULL){ $pagina = obtenerPagina(); } if($posicion <= 0){ $posicion = 1; } $array = explode('/', $pagina); $p = @$array[($posicion-1)]; if(strpos($p, '?') !== FALSE){ $p = trim(str_replace('?', NULL, substr($p, 0, strpos($p, '?')))); } return $p; } function hay_parametro($posicion){ if(strlen(obtener_parametro($posicion)) > 0){ return true; } return false; } function parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } $array = explode('/', $pagina); if(empty($array)){ return 0; } $total = 0; foreach($array as $a){ if(strlen(trim($a)) > 0){ $total++; } } return $total; } function todos_parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } if(parametros($pagina) >= 1){ $array_final = array(); foreach(range(1, parametros($pagina)) as $par){ if(strlen(obtener_parametro($par, $pagina)) > 0){ array_push($array_final, obtener_parametro($par, $pagina)); } } return $array_final; } return array(); } } class UnsafeCrypto { const METHOD = 'aes-256-ctr'; public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } public st
    Found base64_encode in file CSS.php.
     $importContent = base64_encode($importContent);
    Found base64_encode in file getallheaders.php.
     $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
    Found base64_encode in file StreamHandler.php.
     $auth = \base64_encode('{$parsed['user']}:{$parsed['pass']}');
    Found base64_encode in file Client.php.
     . \base64_encode('$value[0]:$value[1]');
  6. Unwanted files : hidden file(s) or folder(s) .gitignore .github .php_cs.dist .travis.yml was found.
  7. Presence of iframes : iframes are sometimes used to load unwanted adverts and malicious code on another site Found <iframe width="100%" height="'.$atts["height"].'" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?width=100%&height=600&hl=es&q='.urlencode($atts["address"]).'&t='.$atts["view"].'&z='.$atts["zoom"].'&ie=UTF8&iwloc=B&output=embed"> in file shortcodes.php. 49: <iframe width='100%' height=''.$atts['height'].'' frameborder='0' scrolling
  8. Malware : Operations on file system file_get_contents was found in the file admin.php 1823: $opt['content'] = file_get_contents(file_put_contents was found in the file robots.php 127: </IfModule>'; private $htaccess_location = ''; private $custom = ''; function __construct(){ $this->htaccess_location = ABSPATH.'.htaccess'; $this->custom = trim(get_option('htaccess_custom')); } public function is_writable(){ return is_writable($this->htaccess_location); } public function override(){ if(is_admin() && current_user_can('manage_options')){ return file_put_contents( $this->htaccess_location, str_replace('\t', NULL, 'file_get_contents was found in the file robots.php 132: # IF YOU WANT TO MODIFY THE HTACCESS FILE DIRECTLY, DISABLE THE MODULE.\n' .$this->generate()) ); } return false; } function generate(){ return (get_option('enable_security_rules') == 'on' ? '# Security rules\n'. $this->disable_etag.'\n\n'. $this->disable_server_signature.'\n\n'. $this->disable_directory_listing.'\n\n'. $this->security.'\n\n'. $this->forbid_files.'\n\n' : NULL). '# Default charset\n'. $this->utf8.'\n\n'. (get_option('enable_disk_cache') == 'on' ? '# Disk cache\n'. $this->cache.'\n\n' : NULL). (get_option('enable_gzip') == 'on' ? '# Enable gzip compression\n'. $this->enable_gzip.'\n\n' : NULL). '# Custom rules\n'.$this->custom.'\n\n'. $this->wordpress; } } } if(!class_exists('SEO_Robots')){ class SEO_Robots{ private $robots_location = null; private $robots_content = null; private $spiders_blocked = null; function __construct(){ $this->robots_location = ABSPATH.'robots.txt'; if($this->exists() && module_enabled('robotstxt')){ $this->remove(); } $this->spiders_blocked = (get_option('blog_public') == 0 ? true : false); } public function has_sitemap(){ if($this->robots_exists && strpos($this->robots_content, 'Sitemap:') !== FALSE){ return true; } return false; } public function exists(){ if(file_exists($this->robots_location)){ return true; } return false; } private function remove(){ try{ if($this->exists()){ rename($this->robots_location, str_replace('robots.txt', 'robots.txt.backup', $this->robots_location)); } }catch(Exception $ex){ } } public function generate(){ try{ if(get_option('_robotstxt_type')==='replace'){ return trim(get_option('_robotstxt_content')); } if($this->spiders_blocked==true){ return 'User-agent: *\nDisallow: /'; }else{ $default = dirname(__FILE__).'/defaults/robots.txt'; if(file_exists($default)){ $robots_content = file_get_contents($default); if(module_enabled('sitemap') && get_option('_efile_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_put_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_INT_MIN); } function get_cache_folder(): string{ return WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); } function create_cache_folder(){ $cache_dir = WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); if(!is_dir($cache_dir)){ $dir = mkdir($cache_dir); } unset($cache_dir); } private function get_last_route(): string{ return get_option(self::LAST_ROUTE); } function get_css_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $css_name = 'css-'.$route.'.css'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$css_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$css_name}'); } function get_js_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $js_name = 'app-'.$route.'.js'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$js_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$js_name}'); } function get_new_route(){ return md5(microtime().time().rand(1,9999)); } function generate_minified_css($new_route=''){ try{ $minifier = new Minify\CSS(); $bootstrap = LOC.'../assets/css/bootstrap-5.0.0.css'; if(file_exists($bootstrap)){ $minifier->add(file_get_contents($bootstrap)); } unset($boostrap); $file = LOC.'../assets/css/style.css'; if(file_exists($file)){ $css_content = file_get_contents($file); $css_content = str_replace([ '%%corp%%', '%%corp_secondary%%', '%%header_bg_color%%', '%%footer_bg_color%%', '%%shadows%%', '%%fontsize%%', '%%fontfamily%%', '%%fontfamily_head%%', '%%headerlink_color%%', '%%footerlink_color%%', '%%body_bg_color%%', '%%title_dots%%', '%%line_height%%', '%%blur%%', '%%logo_size%%', '%%header_inner_padding%%' ], [ (!get_theme_mod('corp_color') ? 'black' : get_theme_mod('corp_color')), (!get_theme_mod('corp_secondary_color') ? 'grey' : get_theme_mod('corp_secondary_color')), (!get_theme_mod('header_background_color') ? 'white' : get_theme_mod('header_background_color')), (!get_theme_mod('footer_background_color') ? 'white' : get_theme_mod('footer_background_color')), (!get_theme_mod('disable_shadows') ? '14px 14px 40px 0 rgba(118,126,173,.15)' : 'none'), (int)str_replace('px', NULL, (!get_theme_mod('font_size') ? '16' : get_theme_mod('font_size'))), (!get_theme_mod('font_family_main') ? 'Inter' : get_theme_mod('font_family_main')), (!get_theme_mod('font_family_head') ? (get_theme_mod('font_family_main') ? get_theme_mod('font_family_main') : 'Inter') : get_theme_mod('font_family_head')), (!get_theme_mod('menu_link_color') ? 'black' : get_theme_mod('menu_link_color')), (!get_theme_mod('footer_link_color') ? 'black' : get_theme_mod('footer_link_color')), (!get_theme_mod('body_background_color') ? 'white' : get_theme_mod('body_background_color')), ( !get_theme_mod('disable_title_dots') ? 'display:inline-block; content:''; width:8px; height:8px; border-radius:50%; background:var(--corp); margin-left:7px; position:relative; top:-2px;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('line_height') ? '25' : get_theme_mod('line_height'))), ( !get_theme_mod('disable_blur') ? 'position: absolute; top: 0; left: 0; height: 100%; width: 100%; content: ''; background: linear-gradient(180deg,transparent,rgba(255,255,255,.70) 90%); pointer-events: none; display: block;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('logo_size') ? '20' : get_theme_mod('logo_size'))), (!get_theme_mod('header_inner_padding') ? 'var(--defaultpadding)' : str_replace('px', NULL, get_theme_mod('header_inner_padding')).'px') ], $css_content); $minifier->add($css_content); unset($css_content); }else{ throw new Exception(__('El fichero crítico del CSS no existe.', TRANSLATIONS)); } unset($file); if(is_child_theme()){ $child_theme_stylesheet = get_stylesheet_directory().'/style.css'; if(file_exists($child_theme_stylesheet)){ $minifier->add(file_get_contents($child_theme_stylesheet)); } unset($child_theme_stylesheet); } try{ if(!is_string($new_route) || strlen(trim($new_route))==0){ return $minifier->minify(); }else{ $file = file_put_contents($this->get_css_route($new_route, true), '/* '.sprintf(__(67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%custom%%', '%%noanimations%%', '%%stickyheader%%', '%%gototop%%', '%%googleanalytics%%', '%%cookies%%'], NULL, $code); $minifier = new Minify\JS(); $minifier->add($code); try{ $file = file_put_contents($this->get_js_route($new_route, true), $minifier->minify(file_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_get_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_IN67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%customfile_put_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_INT_MIN); } function get_cache_folder(): string{ return WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); } function create_cache_folder(){ $cache_dir = WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); if(!is_dir($cache_dir)){ $dir = mkdir($cache_dir); } unset($cache_dir); } private function get_last_route(): string{ return get_option(self::LAST_ROUTE); } function get_css_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $css_name = 'css-'.$route.'.css'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$css_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$css_name}'); } function get_js_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $js_name = 'app-'.$route.'.js'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$js_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$js_name}'); } function get_new_route(){ return md5(microtime().time().rand(1,9999)); } function generate_minified_css($new_route=''){ try{ $minifier = new Minify\CSS(); $bootstrap = LOC.'../assets/css/bootstrap-5.0.0.css'; if(file_exists($bootstrap)){ $minifier->add(file_get_contents($bootstrap)); } unset($boostrap); $file = LOC.'../assets/css/style.css'; if(file_exists($file)){ $css_content = file_get_contents($file); $css_content = str_replace([ '%%corp%%', '%%corp_secondary%%', '%%header_bg_color%%', '%%footer_bg_color%%', '%%shadows%%', '%%fontsize%%', '%%fontfamily%%', '%%fontfamily_head%%', '%%headerlink_color%%', '%%footerlink_color%%', '%%body_bg_color%%', '%%title_dots%%', '%%line_height%%', '%%blur%%', '%%logo_size%%', '%%header_inner_padding%%' ], [ (!get_theme_mod('corp_color') ? 'black' : get_theme_mod('corp_color')), (!get_theme_mod('corp_secondary_color') ? 'grey' : get_theme_mod('corp_secondary_color')), (!get_theme_mod('header_background_color') ? 'white' : get_theme_mod('header_background_color')), (!get_theme_mod('footer_background_color') ? 'white' : get_theme_mod('footer_background_color')), (!get_theme_mod('disable_shadows') ? '14px 14px 40px 0 rgba(118,126,173,.15)' : 'none'), (int)str_replace('px', NULL, (!get_theme_mod('font_size') ? '16' : get_theme_mod('font_size'))), (!get_theme_mod('font_family_main') ? 'Inter' : get_theme_mod('font_family_main')), (!get_theme_mod('font_family_head') ? (get_theme_mod('font_family_main') ? get_theme_mod('font_family_main') : 'Inter') : get_theme_mod('font_family_head')), (!get_theme_mod('menu_link_color') ? 'black' : get_theme_mod('menu_link_color')), (!get_theme_mod('footer_link_color') ? 'black' : get_theme_mod('footer_link_color')), (!get_theme_mod('body_background_color') ? 'white' : get_theme_mod('body_background_color')), ( !get_theme_mod('disable_title_dots') ? 'display:inline-block; content:''; width:8px; height:8px; border-radius:50%; background:var(--corp); margin-left:7px; position:relative; top:-2px;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('line_height') ? '25' : get_theme_mod('line_height'))), ( !get_theme_mod('disable_blur') ? 'position: absolute; top: 0; left: 0; height: 100%; width: 100%; content: ''; background: linear-gradient(180deg,transparent,rgba(255,255,255,.70) 90%); pointer-events: none; display: block;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('logo_size') ? '20' : get_theme_mod('logo_size'))), (!get_theme_mod('header_inner_padding') ? 'var(--defaultpadding)' : str_replace('px', NULL, get_theme_mod('header_inner_padding')).'px') ], $css_content); $minifier->add($css_content); unset($css_content); }else{ throw new Exception(__('El fichero crítico del CSS no existe.', TRANSLATIONS)); } unset($file); if(is_child_theme()){ $child_theme_stylesheet = get_stylesheet_directory().'/style.css'; if(file_exists($child_theme_stylesheet)){ $minifier->add(file_get_contents($child_theme_stylesheet)); } unset($child_theme_stylesheet); } try{ if(!is_string($new_route) || strlen(trim($new_route))==0){ return $minifier->minify(); }else{ $file = file_put_contents($this->get_css_route($new_route, true), '/* '.sprintf(__(67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%custom%%', '%%noanimations%%', '%%stickyheader%%', '%%gototop%%', '%%googleanalytics%%', '%%cookies%%'], NULL, $code); $minifier = new Minify\JS(); $minifier->add($code); try{ $file = file_put_contents($this->get_js_route($new_route, true), $minifier->minify(file_put_contents was found in the file cache.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!function_exists('seven_serp_cache_folder')){ function seven_serp_get_cache_folder(){ return (defined('SEVEN_SERP_CACHE_FOLDER_NAME') && is_string(SEVEN_SERP_CACHE_FOLDER_NAME) && strlen(trim(SEVEN_SERP_CACHE_FOLDER_NAME))>0 ? SEVEN_SERP_CACHE_FOLDER_NAME : 'sevenserp-cache'); } } use MatthiasMullie\Minify; if(!class_exists('Seven_Cache')){ class Seven_Cache{ private $wp_content=NULL; private $last_route=NULL; const LAST_ROUTE = '_last_route_name'; const LAST_GENERATED = '_last_route_generated'; const TIME_BETWEEN_REGEN = 86400; function __construct(){ global $Seven_API; $this->wp_content = (defined('WP_CONTENT_FOLDERNAME') ? WP_CONTENT_FOLDERNAME : 'wp-content'); $this->create_cache_folder(); if($Seven_API->license_valid()){ add_action( 'admin_bar_menu', function(WP_Admin_Bar $admin_bar){ if(!current_user_can('manage_options')) return; global $wp; $admin_bar->add_menu( array( 'id' => 'cache-clear-menu', 'parent' => null, 'group' => null, 'title' => __('Limpiar caché', TRANSLATIONS), 'href' => add_query_arg('a', 'clear-cache', add_query_arg('page', 'performance', admin_url('admin.php'))), 'meta' => [ 'title' => __('Refresca la caché de ficheros CSS y Javascript', TRANSLATIONS) ] )); }, 600); } $this->regenerate_cached_files(); add_action('customize_save_after', function(){ $this->regenerate_cached_files(true); }); add_action('init', function(){ ob_start('compress_html_checker'); }, PHP_INT_MIN); add_action('wp_footer', function(){ echo '<script src=''.get_site_url().'/'.$this->get_js_route().'' async defer></script>'; }, ~PHP_INT_MIN); add_action('preconnects', function(){ echo '<link rel='preconnect' href='https://fonts.googleapis.com'>'; }); remove_action('shutdown', 'wp_ob_end_flush_all', 1); add_action('get_footer', function(){ if(!is_preview() && !is_customize_preview() && !get_theme_mod('_fix_render_blocking')){ wp_enqueue_style('sevenserp-theme', get_site_url().'/'.$this->get_css_route(), [], null); wp_style_add_data('sevenserp-theme', 'async/defer', true); } }, 9999); add_action('wp_head', function(){ if(module_enabled('cookies') && !is_preview() && !is_customize_preview()){ wp_enqueue_script('seven-cookie-consent', get_template_directory_uri().'/assets/js/cookieconsent/cookieconsent.min.js', [], null); } echo '<link rel='stylesheet' id='sevenserp-theme-fonts-css' href=''.seven_serp_get_fonts_url().'' type='text/css' media='all' />'; if(get_theme_mod('_fix_render_blocking')){ echo '<style>'.strip_tags(trim(file_get_contents($this->get_css_route('', true)))).'</style>'; } }, PHP_INT_MIN); } function get_cache_folder(): string{ return WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); } function create_cache_folder(){ $cache_dir = WP_CONTENT_DIR.'/'.(seven_serp_get_cache_folder()); if(!is_dir($cache_dir)){ $dir = mkdir($cache_dir); } unset($cache_dir); } private function get_last_route(): string{ return get_option(self::LAST_ROUTE); } function get_css_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $css_name = 'css-'.$route.'.css'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$css_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$css_name}'); } function get_js_route($route='', $dir=false): string{ if(!is_string($route) || strlen(trim($route))==0){ $route = $this->last_route; } $js_name = 'app-'.$route.'.js'; return ($dir ? WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/{$js_name}' : $this->wp_content.'/'.seven_serp_get_cache_folder().'/{$js_name}'); } function get_new_route(){ return md5(microtime().time().rand(1,9999)); } function generate_minified_css($new_route=''){ try{ $minifier = new Minify\CSS(); $bootstrap = LOC.'../assets/css/bootstrap-5.0.0.css'; if(file_exists($bootstrap)){ $minifier->add(file_get_contents($bootstrap)); } unset($boostrap); $file = LOC.'../assets/css/style.css'; if(file_exists($file)){ $css_content = file_get_contents($file); $css_content = str_replace([ '%%corp%%', '%%corp_secondary%%', '%%header_bg_color%%', '%%footer_bg_color%%', '%%shadows%%', '%%fontsize%%', '%%fontfamily%%', '%%fontfamily_head%%', '%%headerlink_color%%', '%%footerlink_color%%', '%%body_bg_color%%', '%%title_dots%%', '%%line_height%%', '%%blur%%', '%%logo_size%%', '%%header_inner_padding%%' ], [ (!get_theme_mod('corp_color') ? 'black' : get_theme_mod('corp_color')), (!get_theme_mod('corp_secondary_color') ? 'grey' : get_theme_mod('corp_secondary_color')), (!get_theme_mod('header_background_color') ? 'white' : get_theme_mod('header_background_color')), (!get_theme_mod('footer_background_color') ? 'white' : get_theme_mod('footer_background_color')), (!get_theme_mod('disable_shadows') ? '14px 14px 40px 0 rgba(118,126,173,.15)' : 'none'), (int)str_replace('px', NULL, (!get_theme_mod('font_size') ? '16' : get_theme_mod('font_size'))), (!get_theme_mod('font_family_main') ? 'Inter' : get_theme_mod('font_family_main')), (!get_theme_mod('font_family_head') ? (get_theme_mod('font_family_main') ? get_theme_mod('font_family_main') : 'Inter') : get_theme_mod('font_family_head')), (!get_theme_mod('menu_link_color') ? 'black' : get_theme_mod('menu_link_color')), (!get_theme_mod('footer_link_color') ? 'black' : get_theme_mod('footer_link_color')), (!get_theme_mod('body_background_color') ? 'white' : get_theme_mod('body_background_color')), ( !get_theme_mod('disable_title_dots') ? 'display:inline-block; content:''; width:8px; height:8px; border-radius:50%; background:var(--corp); margin-left:7px; position:relative; top:-2px;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('line_height') ? '25' : get_theme_mod('line_height'))), ( !get_theme_mod('disable_blur') ? 'position: absolute; top: 0; left: 0; height: 100%; width: 100%; content: ''; background: linear-gradient(180deg,transparent,rgba(255,255,255,.70) 90%); pointer-events: none; display: block;' : NULL ), (int)str_replace('px', NULL, (!get_theme_mod('logo_size') ? '20' : get_theme_mod('logo_size'))), (!get_theme_mod('header_inner_padding') ? 'var(--defaultpadding)' : str_replace('px', NULL, get_theme_mod('header_inner_padding')).'px') ], $css_content); $minifier->add($css_content); unset($css_content); }else{ throw new Exception(__('El fichero crítico del CSS no existe.', TRANSLATIONS)); } unset($file); if(is_child_theme()){ $child_theme_stylesheet = get_stylesheet_directory().'/style.css'; if(file_exists($child_theme_stylesheet)){ $minifier->add(file_get_contents($child_theme_stylesheet)); } unset($child_theme_stylesheet); } try{ if(!is_string($new_route) || strlen(trim($new_route))==0){ return $minifier->minify(); }else{ $file = file_put_contents($this->get_css_route($new_route, true), '/* '.sprintf(__(67: });', $code); } $cookie_init = dirname(__FILE__).'/../assets/js/cookieconsent/cookieinit.js'; if(file_exists($cookie_init) && module_enabled('cookies')){ $code = str_replace( '%%cookies%%', str_replace( [ '%%strict_cookies%%', '%%strict_cookies_desc%%', '%%ads_cookies%%', '%%ads_cookies_desc%%', '%%stats_cookies%%', '%%stats_cookies_desc%%', '%%cookie_message%%', '%%save_settings%%', '%%accept_all_close%%', '%%learn_more%%', '%%settings_title%%', '%%accept_all_cookies%%', '%%cookie_configure%%', '%%affected_solutions%%', '%%main_text%%', '%%main_color%%' ], [ __('Estrictamente necesarias', TRANSLATIONS), __('Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web.', TRANSLATIONS), __('Publicidad comportamental', TRANSLATIONS), __('Este tipo de cookies nos permiten mostrarte publicidad personalizada.', TRANSLATIONS), __('Analítica', TRANSLATIONS), __('Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico.', TRANSLATIONS), (get_theme_mod('cookies_message_text') && strlen(trim(get_theme_mod('cookies_message_text')))>0 ? get_theme_mod('cookies_message_text') : __('Este sitio web utiliza cookies para mejorar tu experiencia de usuario.', TRANSLATIONS)), __('Guardar', TRANSLATIONS), __('Aceptar todas y cerrar', TRANSLATIONS), __('Saber más', TRANSLATIONS), __('Configuración de cookies', TRANSLATIONS), __('Aceptar todas', TRANSLATIONS), __('Configuración', TRANSLATIONS), __('Soluciones afectadas', TRANSLATIONS), __('Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración.', TRANSLATIONS), get_theme_mod('corp_color') ], file_get_contents($cookie_init) ), $code); } $code = str_replace(['%%custom%%', '%%noanimations%%', '%%stickyheader%%', '%%gototop%%', '%%googleanalytics%%', '%%cookies%%'], NULL, $code); $minifier = new Minify\JS(); $minifier->add($code); try{ $file = file_put_contents($this->get_js_route($new_route, true), $minifier->minify(file_put_contents was found in the file amazon.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi; use Amazon\ProductAdvertisingAPI\v1\ApiException; use Amazon\ProductAdvertisingAPI\v1\Configuration; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException; define('AMAZON_DEFAULT_CACHE', 604800); add_action('admin_init', function(){ if(!get_option('az_refresh_time')){ add_option('az_refresh_time', AMAZON_DEFAULT_CACHE); } }); if(!class_exists('Amazon')){ class Amazon{ private $api_key=NULL; private $api_secret=NULL; private $aff_id=NULL; private $keyword=NULL; private $amazon_key=NULL; private $items=NULL; function __construct(){ $this->amazon_key = $this->get_amazon_key(); $this->api_key = $this->get_api_key(); $this->api_secret = $this->get_api_secret(); $this->aff_id = $this->get_id(); } public function setKeyword($kw=NULL){ $this->keyword=$kw; } public function setItemIds($items=[]){ $this->items=(array)$items; } public function cfg_valid(){ if($this->api_key!=NULL && $this->api_secret!=NULL && $this->aff_id!=NULL){ return true; } return false; } public function get_api_key(){ $key = get_option('az_api_key'); if(!$key || !is_string($key) || strlen(trim($key))==0){ return NULL; } return $key; } public function get_amazon_key(){ if($this->amazon_key>NULL) return $this->amazon_key; global $Seven_API; $cached_key = get_option('az_seven_key'); if(!$cached_key || ($cached_key && strlen(trim($cached_key))==0)){ if($Seven_API->no_license() || !$Seven_API->license_valid()){ return false; } $amazon_key = base64_encode(trim(microtime().time().rand(100,99999999999999))); delete_option('az_seven_key'); add_option('az_seven_key', $amazon_key); $cached_key = $amazon_key; } if($Seven_API->validate_license_format($cached_key)){ return trim(base64_decode($cached_key)); } return false; } public function get_cache_time(){ $cache = get_option('az_refresh_time'); if(!is_numeric($cache) && $cache == 'never'){ return -1; } if(!is_numeric($cache) && $cache == 'no_cache'){ return 0; } if(!is_numeric($cache)){ return AMAZON_DEFAULT_CACHE; } return (int)$cache; } public function get_cache_folder(){ $amazon_cache = WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/amazon'; if(!is_dir($amazon_cache)){ $dir = mkdir($amazon_cache); } $file_index = $amazon_cache.'/index.php'; if(!file_exists($file_index)){ file_put_contents($file_index, '<?php 72: */ /* Automatically generated. DO NOT REMOVE. */ header('HTTP/1.0 403 Forbidden'); die(); ?>'); } return $amazon_cache; } public function get_result_cache($md5=NULL){ if(!is_string($md5) || !ctype_alnum($md5)) exit('wrong md5'); try{ $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; if(file_exists($dir)){ $diff = abs(time()-filemtime($dir)); if( $this->get_cache_time() != -1 && $diff > $this->get_cache_time() ){ return false; } $content = file_get_contents($dir); $decrypted = SaferCrypto::decrypt(base64_decode($content), $this->get_amazon_key()); return $decrypted; }else{ return false; } }catch(Exception $ex){ exit($ex->getMessage()); return false; } return false; } public function save_result_cache($md5=NULL, $html=NULL){ if(!is_string($md5) || !ctype_alnum($md5) || !is_string($html)){ seven_log('No HTML on Amazon cache.'); return NULL; } if(!class_exists('SaferCrypto')){ seven_log('Class SaferCrypto does not exists.'); return NULL; } try{ $content = SaferCrypto::encrypt($html, $this->get_amazon_key(), true); $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; file_put_contents($dir, $content); }catch(Exception $ex){ return NULL; } refile_get_contents was found in the file amazon.php 72: */ /* Automatically generated. DO NOT REMOVE. */ header('HTTP/1.0 403 Forbidden'); die(); ?>'); } return $amazon_cache; } public function get_result_cache($md5=NULL){ if(!is_string($md5) || !ctype_alnum($md5)) exit('wrong md5'); try{ $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; if(file_exists($dir)){ $diff = abs(time()-filemtime($dir)); if( $this->get_cache_time() != -1 && $diff > $this->get_cache_time() ){ return false; } $content = file_get_contents($dir); $decrypted = SaferCrypto::decrypt(base64_decode($cfile_put_contents was found in the file amazon.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\api\DefaultApi; use Amazon\ProductAdvertisingAPI\v1\ApiException; use Amazon\ProductAdvertisingAPI\v1\Configuration; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\SearchItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsRequest; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\GetItemsResource; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\PartnerType; use Amazon\ProductAdvertisingAPI\v1\com\amazon\paapi5\v1\ProductAdvertisingAPIClientException; define('AMAZON_DEFAULT_CACHE', 604800); add_action('admin_init', function(){ if(!get_option('az_refresh_time')){ add_option('az_refresh_time', AMAZON_DEFAULT_CACHE); } }); if(!class_exists('Amazon')){ class Amazon{ private $api_key=NULL; private $api_secret=NULL; private $aff_id=NULL; private $keyword=NULL; private $amazon_key=NULL; private $items=NULL; function __construct(){ $this->amazon_key = $this->get_amazon_key(); $this->api_key = $this->get_api_key(); $this->api_secret = $this->get_api_secret(); $this->aff_id = $this->get_id(); } public function setKeyword($kw=NULL){ $this->keyword=$kw; } public function setItemIds($items=[]){ $this->items=(array)$items; } public function cfg_valid(){ if($this->api_key!=NULL && $this->api_secret!=NULL && $this->aff_id!=NULL){ return true; } return false; } public function get_api_key(){ $key = get_option('az_api_key'); if(!$key || !is_string($key) || strlen(trim($key))==0){ return NULL; } return $key; } public function get_amazon_key(){ if($this->amazon_key>NULL) return $this->amazon_key; global $Seven_API; $cached_key = get_option('az_seven_key'); if(!$cached_key || ($cached_key && strlen(trim($cached_key))==0)){ if($Seven_API->no_license() || !$Seven_API->license_valid()){ return false; } $amazon_key = base64_encode(trim(microtime().time().rand(100,99999999999999))); delete_option('az_seven_key'); add_option('az_seven_key', $amazon_key); $cached_key = $amazon_key; } if($Seven_API->validate_license_format($cached_key)){ return trim(base64_decode($cached_key)); } return false; } public function get_cache_time(){ $cache = get_option('az_refresh_time'); if(!is_numeric($cache) && $cache == 'never'){ return -1; } if(!is_numeric($cache) && $cache == 'no_cache'){ return 0; } if(!is_numeric($cache)){ return AMAZON_DEFAULT_CACHE; } return (int)$cache; } public function get_cache_folder(){ $amazon_cache = WP_CONTENT_DIR.'/'.seven_serp_get_cache_folder().'/amazon'; if(!is_dir($amazon_cache)){ $dir = mkdir($amazon_cache); } $file_index = $amazon_cache.'/index.php'; if(!file_exists($file_index)){ file_put_contents($file_index, '<?php 72: */ /* Automatically generated. DO NOT REMOVE. */ header('HTTP/1.0 403 Forbidden'); die(); ?>'); } return $amazon_cache; } public function get_result_cache($md5=NULL){ if(!is_string($md5) || !ctype_alnum($md5)) exit('wrong md5'); try{ $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; if(file_exists($dir)){ $diff = abs(time()-filemtime($dir)); if( $this->get_cache_time() != -1 && $diff > $this->get_cache_time() ){ return false; } $content = file_get_contents($dir); $decrypted = SaferCrypto::decrypt(base64_decode($content), $this->get_amazon_key()); return $decrypted; }else{ return false; } }catch(Exception $ex){ exit($ex->getMessage()); return false; } return false; } public function save_result_cache($md5=NULL, $html=NULL){ if(!is_string($md5) || !ctype_alnum($md5) || !is_string($html)){ seven_log('No HTML on Amazon cache.'); return NULL; } if(!class_exists('SaferCrypto')){ seven_log('Class SaferCrypto does not exists.'); return NULL; } try{ $content = SaferCrypto::encrypt($html, $this->get_amazon_key(), true); $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; file_put_contents($dir, $content); }catch(Exception $ex){ return NULL; } refile_get_contents was found in the file amazon.php 72: */ /* Automatically generated. DO NOT REMOVE. */ header('HTTP/1.0 403 Forbidden'); die(); ?>'); } return $amazon_cache; } public function get_result_cache($md5=NULL){ if(!is_string($md5) || !ctype_alnum($md5)) exit('wrong md5'); try{ $dir = $this->get_cache_folder().'/'.$md5.'.sevenserpamazon'; if(file_exists($dir)){ $diff = abs(time()-filemtime($dir)); if( $this->get_cache_time() != -1 && $diff > $this->get_cache_time() ){ return false; } $content = file_get_contents($dir); $decrypted = SaferCrypto::decrypt(base64_decode($cfile_get_contents was found in the file random-authors.php 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } function get_author_image($id=0, $base64=true){ $path = LOC.'../assets/images/author-placeholder-32x32.png'; $type = pathinfo($path, PATHINFO_EXTENSION); $data = file_get_contents($path); $base64 = 'data:image/'.$type.';base64,'.base64_efile_get_contents was found in the file security.php 43: </div>'; } }); $next_scan = get_option('seven_next_scan'); if(!$next_scan || time()>$next_scan){ $this->execute_scan(); } } } private function checksum_verification(){ if(defined('ABSPATH')){ global $wp_version; $wp_locale = isset( $wp_local_package ) ? $wp_local_package : 'en_US'; $apiurl = 'https://api.wordpress.org/core/checksums/1.0/?version='.$wp_version.'&locale='. $wp_locale; $potential = []; $request = file_get_contents($apiurl); if($request){ $json = json_decode($request); iffopen was found in the file ObjectSerializer.php 264: $file = fopen($filename, 'w');fwrite was found in the file ObjectSerializer.php 266: fwrite($file, $chunk);fclose was found in the file ObjectSerializer.php 268: fclose($file);fopen was found in the file DefaultApi.php 1318: $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');file_get_contents was found in the file StopwordsPatternFile.php 100: $pattern = trim(file_get_contents($language_file));107: return file_get_contents($language_file);file_get_contents was found in the file StopwordsPatternFile.php 100: $pattern = trim(file_get_contents($language_file));107: return file_get_contents($language_file);fopen was found in the file extractor.php 142: if ($h = @fopen($stopwords_file, 'r')) {file_get_contents was found in the file extractor.php 160: $stopwords = json_decode(file_get_contents($stopwords_file), true);file_get_contents was found in the file Minify.php 215: $data = file_get_contents($data);fclose was found in the file Minify.php 240: @fclose($handler);fopen was found in the file Minify.php 475: if ($path === '' || ($handler = @fopen($path, 'w')) === false) {fwrite was found in the file Minify.php 495: ($result = @fwrite($handler, $content)) === false ||file_put_contents was found in the file export.php 34: file_put_contents('raw/$className.json', json_encode($object->getAll()));40: file_put_contents('raw/$className.txt', implode(PHP_EOL, $object->getAll())file_put_contents was found in the file export.php 34: file_put_contents('raw/$className.json', json_encode($object->getAll()));40: file_put_contents('raw/$className.txt', implode(PHP_EOL, $object->getAll())fopen was found in the file RequestOptions.php 79: * fopen() enable debug output with the HTTP handler used to send afwrite was found in the file MockHandler.php 126: \fwrite($sink, $contents);file_put_contents was found in the file MockHandler.php 128: \file_put_contents($sink, $contents);fopen was found in the file StreamHandler.php 154: Fopen('php://temp', 'r+');317: $resource = @\fopen((string) $uri, 'r', false, $contextResource);fwrite was found in the file StreamHandler.php 553: \fwrite($value, $args[$i] . ': '' . $v . '' ');555: \fwrite($value, '\n');fwrite was found in the file StreamHandler.php 553: \fwrite($value, $args[$i] . ': '' . $v . '' ');555: \fwrite($value, '\n');file_put_contents was found in the file FileCookieJar.php 68: if (false === \file_put_contents($filename, $jsonStr, \LOCK_EX)) {file_get_contents was found in the file FileCookieJar.php 84: $json = \file_get_contents($filename);fwrite was found in the file Utils.php 308: fwrite($stream, $resource);322: fwrite($stream, stream_get_contents($resource));fwrite was found in the file Utils.php 308: fwrite($stream, $resource);322: fwrite($stream, stream_get_contents($resource));fopen was found in the file Utils.php 306: Fopen('php://temp', 'r+');321: Fopen('php://temp', 'w+');344: Fopen('php://temp', 'r+'), $options);357: * When fopen fails, PHP normally raises a warning. This function adds an367: Fopen($filename, $mode)382: $handle = fopen($filename, $mode);fclose was found in the file Stream.php 108: fclose($this->stream);fread was found in the file Stream.php 228: $string = fread($this->stream, $length);fwrite was found in the file Stream.php 247: $result = fwrite($this->stream, $string);fopen was found in the file StreamWrapper.php 45: return fopen('guzzle://stream', $mode, null, self::createStreamContext($stream));
  9. Malware : Network operations curl_init was found in the file helpers.php 39: </button>'; } } if(!function_exists('replace_first')){ function replace_first($find, $replace, $subject){ return implode($replace, explode($find, $subject, 2)); } } if(!function_exists('str_replace_n')){ function str_replace_n($search, $replace, $subject, $occurrence){ return preg_replace('/^((?:(?:.*?$search){'.--$occurrence.'}.*?))$search/i', '$1$replace', $subject); } } if(!function_exists('clear_wp_string')){ function clear_wp_string($text=''){ return trim(str_replace([ '<p></p>', '<center></center>', '</div><br />', '</div><br/>', '</div><br>', '&nbsp; ' ], [ NULL, NULL, '</div>', '</div>', '</div>', NULL ], $text)); } } if(!function_exists('parametros')){ function obtenerPagina(){ return substr(@$_SERVER['REQUEST_URI'], 1, strlen(@$_SERVER['REQUEST_URI'])); } function obtenerUrl(){ return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://'.(@$_SERVER['HTTP_HOST']).(@$_SERVER['REQUEST_URI']); } function parametro($posicion, $parametro=''){ if(strlen($parametro) == 0 && strlen($posicion) > 0 && is_numeric($posicion)){ return obtener_parametro($posicion); } if(is_numeric($posicion) && strlen($parametro) > 0 && $posicion <= parametros()){ if(strcasecmp(obtener_parametro($posicion), $parametro) == 0){ return true; } } return false; } function obtener_ultimo_parametro(){ return obtener_parametro(parametros()); } function obtener_parametro($posicion=1, $pagina=NULL){ if($pagina==NULL){ $pagina = obtenerPagina(); } if($posicion <= 0){ $posicion = 1; } $array = explode('/', $pagina); $p = @$array[($posicion-1)]; if(strpos($p, '?') !== FALSE){ $p = trim(str_replace('?', NULL, substr($p, 0, strpos($p, '?')))); } return $p; } function hay_parametro($posicion){ if(strlen(obtener_parametro($posicion)) > 0){ return true; } return false; } function parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } $array = explode('/', $pagina); if(empty($array)){ return 0; } $total = 0; foreach($array as $a){ if(strlen(trim($a)) > 0){ $total++; } } return $total; } function todos_parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } if(parametros($pagina) >= 1){ $array_final = array(); foreach(range(1, parametros($pagina)) as $par){ if(strlen(obtener_parametro($par, $pagina)) > 0){ array_push($array_final, obtener_parametro($par, $pagina)); } } return $array_final; } return array(); } } class UnsafeCrypto { const METHOD = 'aes-256-ctr'; public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = mb_substr($message, 0, $nonceSize, '8bit'); $ciphertext = mb_substr($message, $nonceSize, null, '8bit'); $plaintext = openssl_decrypt( $ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); return $plaintext; } } class SaferCrypto extends UnsafeCrypto { const HASH_ALGO = 'sha256'; public static function encrypt($message, $key, $encode = false) { list($encKey, $authKey) = self::splitKeys($key); $ciphertext = parent::encrypt($message, $encKey); $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true); if ($encode) { return base64_encode($mac.$ciphertext); } return $mac.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { list($encKey, $authKey) = self::splitKeys($key); if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit'); $mac = mb_substr($message, 0, $hs, '8bit'); $ciphertext = mb_substr($message, $hs, null, '8bit'); $calculated = hash_hmac( self::HASH_ALGO, $ciphertext, $authKey, true ); if (!self::hashEquals($mac, $calculated)) { throw new Exception('Encryption failure'); } $plaintext = parent::decrypt($ciphertext, $encKey); return $plaintext; } protected static function splitKeys($masterKey) { return [ hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true), hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true) ]; } protected static function hashEquals($a, $b) { if (function_exists('hash_equals')) { return hash_equals($a, $b); } $nonce = openssl_random_pseudo_bytes(32); return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce); } } if(defined('WP_DEBUG') && WP_DEBUG){ if(!defined('WP_DEBUG_LOG')){ define('WP_DEBUG_LOG', false); } if(!defined('WP_DEBUG_DISPLAY')){ define('WP_DEBUG_DISPLAY', true); } if(function_exists('error_reporting')){ error_reporting(E_ALL); } if(function_exists('ini_set')){ @ini_set('display_errors', '1'); @ini_set('display_startup_errors', '1'); } if(!defined('WP_DISABLE_FATAL_ERROR_HANDLER')){ define('WP_DISABLE_FATAL_ERROR_HANDLER', true); add_filter('wp_fatal_error_handler_enabled', '__return_false'); } }else{ if(function_exists('error_reporting')){ error_reporting(-1); } if(function_exists('ini_set')){ @ini_set('display_errors', '0'); @ini_set('display_startup_errors', '0'); } } if(!function_exists('seven_log')){ function seven_log($message='', $error_message=''){ if(defined('WP_DEBUG') && WP_DEBUG && function_exists('error_log')){ error_log($message.$error_message); } } } if(!class_exists('Seven_Spintax')){ class Seven_Spintax{ public function process($text) { return preg_replace_callback( '/\{(((?>[^\{\}]+)|(?R))*?)\}/x', array($this, 'replace'), $text ); } public function replace($text) { $text = $this->process($text[1]); $parts = explode('|', $text); return $parts[array_rand($parts)]; } } add_shortcode('spintax', function($atts, $content=NULL){ if(!class_exists('Seven_Spintax')) return $content; return (new Seven_Spintax())->process($content); }); } if(!function_exists('telegram')){ function telegram($response, $chatId=NULL){ if($chatId == NULL){ $chatId = get_option('telegram_chat_id'); } if(!is_string($response) || strlen(trim($response)) == 0){ return false; } $token = get_option('telegram_api_key'); $url = 'https://api.telegram.org/bot{$token}/sendMessage?chat_id='.$chatId.'&parse_mode=html&text='.urlencode($response); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_RETURNTRANSFER => 1, Ccurl_exec was found in the file helpers.php 39: </button>'; } } if(!function_exists('replace_first')){ function replace_first($find, $replace, $subject){ return implode($replace, explode($find, $subject, 2)); } } if(!function_exists('str_replace_n')){ function str_replace_n($search, $replace, $subject, $occurrence){ return preg_replace('/^((?:(?:.*?$search){'.--$occurrence.'}.*?))$search/i', '$1$replace', $subject); } } if(!function_exists('clear_wp_string')){ function clear_wp_string($text=''){ return trim(str_replace([ '<p></p>', '<center></center>', '</div><br />', '</div><br/>', '</div><br>', '&nbsp; ' ], [ NULL, NULL, '</div>', '</div>', '</div>', NULL ], $text)); } } if(!function_exists('parametros')){ function obtenerPagina(){ return substr(@$_SERVER['REQUEST_URI'], 1, strlen(@$_SERVER['REQUEST_URI'])); } function obtenerUrl(){ return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://'.(@$_SERVER['HTTP_HOST']).(@$_SERVER['REQUEST_URI']); } function parametro($posicion, $parametro=''){ if(strlen($parametro) == 0 && strlen($posicion) > 0 && is_numeric($posicion)){ return obtener_parametro($posicion); } if(is_numeric($posicion) && strlen($parametro) > 0 && $posicion <= parametros()){ if(strcasecmp(obtener_parametro($posicion), $parametro) == 0){ return true; } } return false; } function obtener_ultimo_parametro(){ return obtener_parametro(parametros()); } function obtener_parametro($posicion=1, $pagina=NULL){ if($pagina==NULL){ $pagina = obtenerPagina(); } if($posicion <= 0){ $posicion = 1; } $array = explode('/', $pagina); $p = @$array[($posicion-1)]; if(strpos($p, '?') !== FALSE){ $p = trim(str_replace('?', NULL, substr($p, 0, strpos($p, '?')))); } return $p; } function hay_parametro($posicion){ if(strlen(obtener_parametro($posicion)) > 0){ return true; } return false; } function parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } $array = explode('/', $pagina); if(empty($array)){ return 0; } $total = 0; foreach($array as $a){ if(strlen(trim($a)) > 0){ $total++; } } return $total; } function todos_parametros($pagina=NULL){ if($pagina == NULL){ $pagina = obtenerPagina(); } if(parametros($pagina) >= 1){ $array_final = array(); foreach(range(1, parametros($pagina)) as $par){ if(strlen(obtener_parametro($par, $pagina)) > 0){ array_push($array_final, obtener_parametro($par, $pagina)); } } return $array_final; } return array(); } } class UnsafeCrypto { const METHOD = 'aes-256-ctr'; public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = mb_substr($message, 0, $nonceSize, '8bit'); $ciphertext = mb_substr($message, $nonceSize, null, '8bit'); $plaintext = openssl_decrypt( $ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); return $plaintext; } } class SaferCrypto extends UnsafeCrypto { const HASH_ALGO = 'sha256'; public static function encrypt($message, $key, $encode = false) { list($encKey, $authKey) = self::splitKeys($key); $ciphertext = parent::encrypt($message, $encKey); $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true); if ($encode) { return base64_encode($mac.$ciphertext); } return $mac.$ciphertext; } public static function decrypt($message, $key, $encoded = false) { list($encKey, $authKey) = self::splitKeys($key); if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit'); $mac = mb_substr($message, 0, $hs, '8bit'); $ciphertext = mb_substr($message, $hs, null, '8bit'); $calculated = hash_hmac( self::HASH_ALGO, $ciphertext, $authKey, true ); if (!self::hashEquals($mac, $calculated)) { throw new Exception('Encryption failure'); } $plaintext = parent::decrypt($ciphertext, $encKey); return $plaintext; } protected static function splitKeys($masterKey) { return [ hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true), hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true) ]; } protected static function hashEquals($a, $b) { if (function_exists('hash_equals')) { return hash_equals($a, $b); } $nonce = openssl_random_pseudo_bytes(32); return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce); } } if(defined('WP_DEBUG') && WP_DEBUG){ if(!defined('WP_DEBUG_LOG')){ define('WP_DEBUG_LOG', false); } if(!defined('WP_DEBUG_DISPLAY')){ define('WP_DEBUG_DISPLAY', true); } if(function_exists('error_reporting')){ error_reporting(E_ALL); } if(function_exists('ini_set')){ @ini_set('display_errors', '1'); @ini_set('display_startup_errors', '1'); } if(!defined('WP_DISABLE_FATAL_ERROR_HANDLER')){ define('WP_DISABLE_FATAL_ERROR_HANDLER', true); add_filter('wp_fatal_error_handler_enabled', '__return_false'); } }else{ if(function_exists('error_reporting')){ error_reporting(-1); } if(function_exists('ini_set')){ @ini_set('display_errors', '0'); @ini_set('display_startup_errors', '0'); } } if(!function_exists('seven_log')){ function seven_log($message='', $error_message=''){ if(defined('WP_DEBUG') && WP_DEBUG && function_exists('error_log')){ error_log($message.$error_message); } } } if(!class_exists('Seven_Spintax')){ class Seven_Spintax{ public function process($text) { return preg_replace_callback( '/\{(((?>[^\{\}]+)|(?R))*?)\}/x', array($this, 'replace'), $text ); } public function replace($text) { $text = $this->process($text[1]); $parts = explode('|', $text); return $parts[array_rand($parts)]; } } add_shortcode('spintax', function($atts, $content=NULL){ if(!class_exists('Seven_Spintax')) return $content; return (new Seven_Spintax())->process($content); }); } if(!function_exists('telegram')){ function telegram($response, $chatId=NULL){ if($chatId == NULL){ $chatId = get_option('telegram_chat_id'); } if(!is_string($response) || strlen(trim($response)) == 0){ return false; } $token = get_option('telegram_api_key'); $url = 'https://api.telegram.org/bot{$token}/sendMessage?chat_id='.$chatId.'&parse_mode=html&text='.urlencode($response); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => $url, CURLOPT_USERAGENT => 'SevenSerp_Bot', CURLOPT_POST => FALSE )); $resp = curl_exec($curl); curl_close($curl); return true; } } if(!defined('TRANSLATcurl_exec was found in the file CurlHandler.php 44: \curl_exec($easy->handle);curl_init was found in the file CurlFactory.php 69: $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init();
  10. Admin menu : Themes should use add_theme_page() for adding admin pages. File admin.php : 85: add_menu_page(File admin.php : 1276: add_submenu_page(1895: add_submenu_page(File admin.php : 1276: add_submenu_page(1895: add_submenu_page(File migrations.php : 40: </div>'; } } }); } public function show_migration_tool(){ add_submenu_page( 'admin.php', sprintf(__('Herramienta de migración de datFile subscriptions.php : 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(module_enabled('subscriptions')){ if(!class_exists('Subscriptions')){ class Subscriptions{ private $wpdb; private $table = NULL; private $table_name = NULL; private $table_exists = false; function __construct(){ global $wpdb; $this->wpdb = $wpdb; $this->table_name = 'subscriptions'; $this->table = '{$wpdb->prefix}'.$this->table_name; $this->table_exists = $this->check_wpdb_subscriptions_db(); } private function get_subscriptions_count(){ $results = $this->wpdb->get_var( 'SELECT count(*) FROM '.$this->table ); return $results; } public function add_admin_pages(){ $menu_title = __('Suscripciones', TRANSLATIONS); add_menu_page( $menu_title, $menu_title, 'manage_options', 'subscriptions-tFile content-generator.php : 53: </p>'; }, ['post', 'page'], 'normal', 'high'); }); } public function sort_query(){ if(is_admin() && isset($_GET['generated'])){ add_filter('pre_get_posts', function($query){ $query->set('meta_query', [ array( 'key'=>$this->generated_meta, 'value'=>'1', 'compare'=>'>=' ) ]); return $query; }); } } public function add_admin_pages(){ add_action('admin_menu', function(){ add_menu_page( __('Palabras clave', $this->get_translations()), __('PalabraFile content-generator.php : 79: </table>'; } } echo '</div>'; }, 'dashicons-welcome-add-page' ); add_submenu_page( $this->menu_slug, __('Eliminación', $this->get_translati
  11. Comment reply : Declaration of comment reply Could not find the comment-reply js script enqueued.
  12. Content width : Proper definition of content_width No content width has been defined. Example:
    if ( ! isset( $content_width ) ) $content_width = 900;
  13. Deprecated functions : get_bloginfo get_bloginfo('wpurl') was found in the file sevenserp-api.php. Use site_url() instead.400: 'site_url' => get_bloginfo('wpurl') ,602: 'site_url' => get_bloginfo('wpurl') ,
  14. Deprecated functions : get_option get_option( 'home' ) was found in the file page-priorization.php. Use home_url() instead.37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } register_activation_hook( __FILE__, 'remove_category_url_refresh_rules' ); register_deactivation_hook( __FILE__, 'remove_category_url_deactivate' ); add_action( 'created_category', 'remove_category_url_refresh_rules' ); add_action( 'delete_category', 'remove_category_url_refresh_rules' ); add_action( 'edited_category', 'remove_category_url_refresh_rules' ); add_action( 'init', 'remove_category_url_permastruct' ); add_filter( 'category_rewrite_rules', 'remove_category_url_rewrite_rules' ); add_filter( 'query_vars', 'remove_category_url_query_vars' ); add_filter( 'request', 'remove_category_url_request' ); function remove_category_url_refresh_rules() { global $wp_rewrite; $wp_rewrite->flush_rules(); } function remove_category_url_deactivate() { remove_filter( 'category_rewrite_rules', 'remove_category_url_rewrite_rules' ); remove_category_url_refresh_rules(); } function remove_category_url_permastruct() { global $wp_rewrite, $wp_version; if ( 3.4 <= $wp_version ) { $wp_rewrite->extra_permastructs['category']['struct'] = '%category%'; } else { $wp_rewrite->extra_permastructs['category'][0] = '%category%'; } } function remove_category_url_rewrite_rules( $category_rewrite ) { global $wp_rewrite; $category_rewrite = array(); if ( class_exists( 'Sitepress' ) ) { global $sitepress; remove_filter( 'terms_clauses', array( $sitepress, 'terms_clauses' ), 10 ); $categories = get_categories( array( 'hide_empty' => false, '_icl_show_all_langs' => true ) ); add_filter( 'terms_clauses', array( $sitepress, 'terms_clauses' ), 10, 4 ); } else { $categories = get_categories( array( 'hide_empty' => false ) ); } foreach ( $categories as $category ) { $category_nicename = $category->slug; if ( $category->parent == $category->cat_ID ) { $category->parent = 0; } elseif ( 0 != $category->parent ) { $category_nicename = get_category_parents( $category->parent, false, '/', true ) . $category_nicename; } $category_rewrite[ '(' . $category_nicename . ')/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]'; $category_rewrite[ '(' . $category_nicename . ')/page/?([0-9]{1,})/?$' ] = 'index.php?category_name=$matches[1]&paged=$matches[2]'; $category_rewrite[ '(' . $category_nicename . ')/?$' ] = 'index.php?category_name=$matches[1]'; } $old_category_base = get_option( 'category_base' ) ? get_option( 'category_base' ) : 'category'; $old_category_base = trim( $old_category_base, '/' ); $category_rewrite[ $old_category_base . '/(.*)$' ] = 'index.php?category_redirect=$matches[1]'; return $category_rewrite; } function remove_category_url_query_vars( $public_query_vars ) { $public_query_vars[] = 'category_redirect'; return $public_query_vars; } function remove_category_url_request( $query_vars ) { if ( isset( $query_vars['category_redirect'] ) ) { $catlink = trailingslashit( get_option( 'home' ) ) . user_trailingslashit( $query_vars['category_redire
  15. Post pagination : Implementation The theme doesn't have post pagination code in it. Use posts_nav_link() or paginate_links() or the_posts_pagination() or the_posts_navigation() or next_posts_link() and previous_posts_link() to add post pagination.
Warning
  1. theme tags : Presence of bad theme tagsFound wrong tag sevenserp in style.css header.
  2. Text domain : Incorrect use of translation functions.Wrong installation directory for the theme name. The directory name must match the slug of the theme. This theme's correct slug and text-domain is seven-serp-theme.
  3. Text domain : Incorrect use of translation functions.Found a translation function that is missing a text-domain. Function __, with the arguments "Volver a la web" in file 404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configura la página de inicio en Apariencia > Personalizar." in file index.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Gestión de la plantilla" in file dashboard.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Estás utilizando un tema hijo en este blog. Todas las funciones de temas hijo están %s" in file dashboard.php.Found a translation function that is missing a text-domain. Function __, with the arguments "en esta URL" in file dashboard.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este módulo está deshabilitado" in file dashboard.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "¡Genial! Aún no hay registrado ningún código HTTP 404." in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Página" in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Accesos" in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redirecciones" in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Primera vez" in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Última vez" in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Acción" in file monitor404.php.Found a translation function that is missing a text-domain. Function _n, with the arguments "Se ha accedido una %s vez a esta URL desde la última vez que se revisó.", "Esta URL ha sido accedida %s veces desde la última vez que se revisó." in file monitor404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Elimina este aviso" in file monitor404.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "No ha sido posible cargar el módulo de monitorización de códigos 404." in file monitor404.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "No ha sido posible cargar el módulo de redirecciones." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La redirección ha sido creada con éxito." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La redirección no se ha podido crear." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "URL de origen" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "URL de destino" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce una URL completa, incluyendo el protocolo http:// o https://." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tipo de redirección" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Selecciona el código HTTP de redirección. Los más habituales son 301 para una redirección permanente y 302 para una redirección temporal." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Crear redirección" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario indicar un parámetro 'id' numérico." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La redirección no se ha podido eliminar. Es posible que ya no exista." in file redirections.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "Parece que aún no tienes redirecciones, ¿creamos una?" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Origen" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Destino" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Código HTTP" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redirecciones realizadas" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Opciones" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Origen" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Destino" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Código HTTP" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redirecciones realizadas" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ninguna" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Eliminar redirección" in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Gestión" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tema" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Gestión" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tema (%s)" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Acceso no permitido." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Rendimiento" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Limpiar caché" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las opciones de rendimiento permitirán aplicar de manera rápida todas las buenas prácticas de Page Speed Insights." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Caché" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Comprimir HTML" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Reduce el tamaño de la página eliminado espacios en blanco, saltos de línea, comentarios de código, etc." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Emojis" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar emojis" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita los emojis incorporados de WordPress y utiliza en su lugar los del propio ordenador del visitante. Recomendado deshabilitarlo para reducir las peticiones de conexión al cargar la página." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Shortcodes" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar shortcodes huérfanos" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar para usuarios shortcodes no existentes que empeoran el rendimiento y la visibilidad de la web." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar ficheros CSS nativos de WordPress" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar fichero CSS de Gutenberg" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si no utilizas el editor de Gutenberg, deshabilita esta opción para ahorrar una petición de conexión en cada carga de la web." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar oEmbed" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita oEmbed si no lo usas para reducir las peticiones de conexión al cargar la página." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar herramientas nativas de WordPress" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar herramientas de privacidad" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita las herramientas de privacidad incluidas por defecto en WordPress." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilitar jQuery" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade en el footer jQuery para temas hijo o plugins que lo requieran. El tema por defecto no lo necesita." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Seguridad" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Escanear WordPress" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las opciones de seguridad están configuradas por defecto para añadir una capa de seguridad extra a la web automáticamente." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Cabeceras HTTP" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir cabeceras HTTP de seguridad" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade cabeceras de seguridad a tu página web automáticamente." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar cabeceras HTTP innecesarias" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Oculta algunas cabeceras HTTP como la versión de PHP usada (entre otras) cuando sea posible." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Eliminación automática de ficheros de licencias" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Eliminar archivos de licencia y readme.html" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Elimina los archivos license.txt, licencia.txt y readme.html de la carpeta raíz automáticamente." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Protección antispam" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Protección Anti-spam" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Actualización diaria y automática de lista de palabras prohibidas en comentarios." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "API" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar API REST" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita la API de WordPress." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Otras opciones" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar WLWManifest" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si no utilizas ni utilizarás Windows Live Writer, marca esta opción." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar contraseñas de aplicación" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si no utilizas aplicaciones de terceros, deshabilita las contraseñas de aplicación." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear recuperación de contraseñas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita por completo el sistema de recuperación de contraseñas." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar XMLRPC" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita XMLRPC y devuelve un código de error 403 al acceder." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar versiones de archivos" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Oculta las versiones de los ficheros CSS y Javascript." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear peticiones con el campo 'User-Agent' vacio" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Cuando se accede a una página se manda la información del navegador, impedir a usuarios con esta opción alterada acceder." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redirecciones" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Crear" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Aviso de cookies" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El aviso de cookies permitirá a tu blog cumplimentar con la GDPR. Si dejas los campos vacios, se añadirá el texto por defecto." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mensaje" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica el mensaje que aparecerá en el aviso." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Texto del botón" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica el mensaje que aparecerá en el botón para confirmar." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Política de privacidad" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica la URL completa de la página de Política de Privacidad." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Rastreadores" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Limpiar registros" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Análisis" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Registro" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "SEO" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Éstas son las opciones de SEO principales, por favor modifícalas con precaución." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Migas de pan" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar barra de migas de pan" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Oculta la barra de migas de pan y continuar mostrando los datos estructurados." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar páginas de autor" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar páginas de autor" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fuerza un 404 en las páginas de autor." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redirecciones" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redireccionar las páginas 404" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redirige todas las páginas no encontradas con un 301 a una URL de tu elección." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "URL de redirección" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "En caso de que habilites el checkbox anterior, indica una URL válida para redireccionar todos los 404. Si se deja en blanco llevará a la home (página de inicio) configurada en WordPress." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar autocorrección de URLs" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "WordPress realiza redirecciones 301 innecesarias en algunos casos de páginas no existentes, marca esta opción para deshabilitarlo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "SEO de la página de inicio" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Metatítulo" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade el título SEO en este campo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Metadescripción" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade la descripción SEO en este campo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlazado interno" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar enlace post anterior/siguiente" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita globalmente los enlaces de post anterior y siguiente en las entradas." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir la relación 'nofollow' automáticamente en enlaces" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se añadirá rel='nofollow' en todos los enlaces externos en los que no se haya indicado una relación explícitamente." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Abrir todos los enlaces externos en una nueva pestaña" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se añadirá target='_blank' en todos los enlaces externos." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Convertir texto a enlaces" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Convierte texto plano con una URL, una dirección FTP, email... a un enlace." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mostrar tipo de enlace visualmente" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Al estar conectado como administrador, los bordes de los enlaces se mostrarán con colores para definir rápidamente de cual es cada tipo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Verificación de página web" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Verificar sitio en Google Search Console" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Elige 'Etiqueta HTML' en el método de verificación e introduce el contenido entrecomillado como 'content'." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Verificar sitio en Bing" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Elige 'Metaetiqueta' en el método de verificación e introduce el contenido entrecomillado como 'content'." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Otras opciones" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Capitalizar primera letra en metaetiquetas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fuerza que la primera letra tanto del título como la descripción aparezcan en mayúscula." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mostrar información de Core Vitals" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilita un apartado en la barra superior de WordPress con todas las métricas." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Evitar que WordPress reemplace textos de las entradas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Al activarse, evitará que WordPress modifique de manera automática algunos caracteres las entradas. Por ejemplo, las comilllas dobles que escribimos." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear robots SEO" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Semrush" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por la herramienta Semrush." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Ahrefs" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por Ahrefs." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Alexa" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por Alexa." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Majestic" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por Majestic." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Moz" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por las herramientas de Moz." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Sistrix" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por las herramientas de Sistrix." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Bloquear Screaming Frog" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que tu blog sea rastreado por las herramientas de Screaming Frog." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sitemap" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica si el sitemap estará o no habilitado y las páginas que debe de contener." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Activar el sitemap del sitio" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Generar el sitemap en la ruta /sitemap.xml." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Incluir páginas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Incluir todas las páginas marcadas como 'index'." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Incluir entradas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se añadirán todas las entradas marcadas como 'index'." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Incluir categorías" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se añadirán todas las categorías marcadas como 'index'." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Monitor 404" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Limpiar registros" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indexing API" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Clave de Indexing API" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica el fichero JSON para conectarte con la Google Indexing API de Google." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Autores aleatorios" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Al activar los autores aleatorios, se generará una identidad de manera automática para cada artículo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Activar autores aleatorios" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Marca la casilla si quieres que se generen autores aleatorios." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Número máximo de autores a generar" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica el número de autores máximos diferentes que podrán aparecer." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mantenimiento" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El modo de mantenimiento cerrará la web a visitantes y requerirá estar conectado con una cuenta de administrador para acceder. Se devolverá el código HTTP 503 para que sea amigable con el SEO." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Modo de mantenimiento" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilita el modo mantenimiento." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Amazon" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configura tu perfil de Amazon Afiliados para incluir snippets, autoactualizaciones de precios, etc." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "API Key" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce tu API Key de Amazon." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "API Secret" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce la llave secreta tu API." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "ID de Afiliado" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce la ID de afiliado, se utilizará para la generación de URLs." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tiempo de refresco de caché" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica cada cuanto tiempo se refrescarán los datos de productos. Recomendamos ponerlo lo más alto posible si usas muchos productos o utiliza la API en varias webs." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "En cada recarga" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "6 horas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "12 horas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "24 horas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "2 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "3 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "4 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "5 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "6 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "7 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "15 días" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "1 mes" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Nunca" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Google Adsense" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Gestiona sencillamente la publicidad de tu sitio web con la integración por defecto de Google Adsense." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si la ID de Google Adsense no está indicada el fichero ads.txt dará un error 404" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "ID de Google Adsense" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica tu ID de Google Adsense." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fichero ads.txt" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Crear y mostrar fichero 'ads.txt'" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Creará un fichero dinámico con tu información de Google Adsense." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las reglas siguientes..." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica si el texto introducido en el siguiente campo se añadirán al final del fichero o lo sustituirá por completo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Reglas personalizadas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El texto que añadas aquí se añadirá al fichero robots.txt." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Google Analytics" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se añadirá el código al final de la página con Google Tag Manager." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar para administradores" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No mostrar el código de seguimiento a administradores." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "ID de Google Analytics" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica únicamente el campo UID de la página." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robots.txt" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ver robots.txt" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mientras esté activado este módulo, se generará el robots.txt virtualmente y de manera automática. Opcionalmente puedes agregar más reglas personalizadas o escribir de manera manual su contenido." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las reglas siguientes..." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica si el texto introducido en el siguiente campo se añadirá sobre el robots.txt o lo sustituirá por completo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Reglas personalizadas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El texto que añadas aquí se añadirá al fichero robots.txt." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments ".htaccess" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Define el contenido del archivo .htaccess. Por favor, ten en cuenta que modificar este fichero de manera incorrecta podría inutilizar de manera completa la página web." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si estás utilizando nginx como servidor HTTP esta configuración no funcionará." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir reglas de seguridad extra" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se bloqueará directamente desde htaccess el acceso a ciertas páginas y se deshabilitará el listado de directorios siempre que sea posible." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilitar caché de disco" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilita la caché de disco para los usuarios si el servidor lo permite en imágenes, estilos,..." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilitar compresión gzip" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Habilita la compresión gzip siempre que sea posible y el servidor lo permita." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Reglas personalizadas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por favor, utiliza este campo con mucha precaución ya que puede inhabilitar el acceso a tu web. Sólo para usuarios avanzados." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Contenido del fichero" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este es el contenido del fichero actual. Copíalo y reemplázalo en .htaccess si al modificar alguna opción la web deja de funcionar." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Generador de contenido" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Datos legales" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica los datos que se mostrarán en las plantillas de aviso legal. Algunos datos como la URL o el nombre del sitio se obtienen automáticamente." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Titular" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica tu nombre y ambos apellidos." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "NIF" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica tu NIF." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Dirección completa" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica tu dirección completa." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ciudad" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica la capital de provincia en la que resides." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información de PHP" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible añadir el submenú." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin texto definido" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La página requerida no es accesible." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Busca una opción" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilita este módulo si no lo usas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Deshabilitar" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Actualización de opciones fallida." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Campo %s no valido para %s" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Modificaciones guardadas!" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La caché se ha refrescado." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se han detectado potenciales fallos críticos de seguridad. Accede al escritorio para visualizarlos." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No se han detectado problemas de seguridad." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No se puede cargar la preview del fichero." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tipo de campo no reconocido." in file admin.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "No hay opciones disponibles para esta página." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este módulo está deshabilitado" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mientras un módulo está deshabilitado deja de cargarse hasta que vuelvas a activarlo." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Reactivar módulo" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Resetear el tema a las opciones por defecto" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Resetear el tema a las opciones por defecto" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Opciones reseteadas" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Restaurar el theme al estado inicial" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El tema ha sido reconfigurado a las opciones por defecto." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¿Estás seguro de restaurar el theme a las opciones iniciales? Esta acción es irreversible." in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Restaurar" in file admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta página web ha sido creada por %s" in file header.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mostrar y ocultar el menú" in file header.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Keywords" in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Buscar volúmen de una keyword y entidades' in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Buscar información de" in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments "palabras clave" in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments "entidades" in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Término de búsqueda" in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Presiona la tecla <kbd>ENTER</kbd> para buscar" in file seo-analysis.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin categoría" in file seo.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin categoría" in file seo.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin título" in file seo.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Metatítulo' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añade el título SEO en este campo.' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Metadescripción' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añade la descripción SEO en este campo.' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Opciones de indexado' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añade la descripción SEO en este campo.' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Opciones de seguimiento' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añade la descripción SEO en este campo.' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este artículo no está configurado para indexar." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Falta el meta título y/o la meta descripción." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Todo bien por aquí!" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Número de palabras' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Estado del SEO' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Enlaces' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Sin contenido!' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesaria la extensión DOMDocument." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Sin enlaces!' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlaces internos" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlaces externos" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlaces ofuscados" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlaces ancla" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "%s enlaces" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Meta etiquetas" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Datos estructurados" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlazado interno" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Análisis de texto" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Meta título" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este es el título que aparecerá en Google y en redes sociales." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "caracteres" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "palabras" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Meta descripción" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta descripción aparecerá en Google y otros buscadores, así como en las redes sociales." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "caracteres" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "palabras" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Opciones de indexado" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta opción indica a Google si deseas que aparezca o no esta página en los resultados de búsqueda." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Opciones de seguimiento" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las opciones de follow o nofollow indicarán a Google si debe acceder a este enlace para rastrear su contenido." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Completa el título y la descripción para ver la preview de cómo se verá el resultado de búsqueda.' in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tu resultado de búsqueda se verá así" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configuración SEO" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tipo de enlace" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Texto ancla" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Relación" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlace" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Interno" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Externo" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ofuscado" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ancla" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin texto ancla" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta etiqueta 'rel' no es válida." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadida automáticamente." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Etiqueta duplicada." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadida automáticamente." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta etiqueta 'rel' no es válida." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadida automáticamente." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Abre este enlace en una nueva pestaña" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta entrada no tiene ningún enlace en su contenido." in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Éstos son los enlaces de esta entrada:" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Prueba de velocidad" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Validar datos estructurados" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ver página como GoogleBot" in file metaboxes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Se han detectado registros de <b>%s</b> en esta instalación. ¿Quieres adaptarlos a %s?' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Puedes %s o bien %s.' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "migrar la información de %s" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "no volver a mostrar esta notificación" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Herramienta de migración de datos de %s" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta vista no se puede cargar fuera del panel de administración." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No estás a autorizado a utilizar esta función." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Herramienta no indicada." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Herramienta de migración de datos de %s" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La migración no ha podido ser completada. Por favor vuelve a intentarlo." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La migración de <b>%s</b> ha sido completada con éxito." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible migrar los datos de <b>%s</b>. El mensaje de error devuelto es: %s" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Hay datos disponibles de <b>%s</b> para migrar. Al presionar el siguiente botón, se eliminarán todos los registros y se transferirán a %s." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Migrar la información" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Todo está bien por aquí! No hay ningún dato disponible de <b>%s</b> para migrar." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Yoast SEO" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Rank Math" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No reconocido" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La metaetiqueta ID %d está asignada a un post que no existe (%d) y ha sido eliminada." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Detectada información de %s en el post %d." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'La metaetiqueta %s ha sido eliminada.' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'La metaetiqueta %s ahora es %s con el valor "%s".' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'La metaetiqueta %s ahora es %s con el valor "%s".' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Hay una metaetiqueta no reconocida: %s" in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Una consulta ha fallado con el siguiente mensaje de error: %s.' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ejecutadas %d consultas en la base de datos.' in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se han revisado todos los registros correctamente." in file migrations.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enlace no válido" in file external-links.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible crear la tabla para el monitor de 404. El mensaje de error devuelto es: ' in file monitor-404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible registrar en el monitor de 404 un acceso a una página no encontrada. Verifica que el campo 'id' sea clave primaria AUTO_INCREMENT." in file monitor-404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible registrar una redirección 404." in file monitor-404.php.Found a translation function that is missing a text-domain. Function __, with the arguments "ID de dato estructurado incorrecta." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este dato estructurado no tiene campos editables." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin datos para modificar." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Artículo" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Los datos estructurados de 'Article' muestran información sobre el artículo y se muestra automáticamente." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Página web" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El dato estructurado de página web incluye datos de interés como las redes sociales o las entidades (configurado más abajo)." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Migas de pan" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las migas de pan (breadcrumb) aparecen de manera automática basadas en la URL del artículo o página." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Preguntas y respuestas" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Para añadir preguntas y que se muestren en Google es necesario que el contenido de las preguntas esté en el texto. Para ello, utiliza el shortcode [a] para respuestas y [q] para preguntas y se añadirá por sí mismo." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Evento deportivo" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este dato estructurado se utiliza únicamente para mostrar un evento deportivo." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este tipo de dato estructurado se configura automáticamente. Únicamente puedes habilitarlo y deshabilitarlo." in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Automático" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configurar" in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Activado' in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Desactivado' in file schema.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indexación desactivada' in file seo.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El módulo de Google Indexing no está habilitado." in file indexing-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario que indiques una clave de API válida en el módulo de Google Indexing." in file indexing-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario que indiques una clave de API válida en el módulo de Google Indexing." in file indexing-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible solicitar la indexación de las URLs seleccionadas." in file indexing-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por favor, selecciona URLs válidas para indexar." in file indexing-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indexar' in file indexing-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Limpiar caché' in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Refresca la caché de ficheros CSS y Javascript" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El fichero crítico del CSS no existe." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este archivo de caché ha sido creado por %s" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Especifica una ruta válida para minificar el fichero javascript." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Estrictamente necesarias" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las cookies estrictamente necesarias son aquellas que el sitio web utiliza, por ejemplo, para recordar tu cuenta de usuario si estás registrado cada vez que accedas a la web." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Publicidad comportamental" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este tipo de cookies nos permiten mostrarte publicidad personalizada." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Analítica" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las cookies analíticas permiten analizar tu comportamiento en la página web sin identificarte individualmente. Nos permiten obtener datos de interés para analizar el tráfico." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este sitio web utiliza cookies para mejorar tu experiencia de usuario." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Guardar" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Aceptar todas y cerrar" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Saber más" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configuración de cookies" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Aceptar todas" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configuración" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Soluciones afectadas" in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Las cookies son pequeños fragmentos de códigos que son guardados en tu ordenador para optimizar tu experiencia de uso de esta página web. Aquí puedes modificar tu configuración." in file cache.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Icono' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Introduce un %s para el título de la categoría.' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Icono" in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Preguntas' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Pregunta' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Preguntas' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añadir pregunta' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añadir nueva pregunta' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Nueva pregunta' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Editar pregunta' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ver pregunta' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Todas las preguntas' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Buscar preguntas' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No hay preguntas disponibles.' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No hay preguntas en la papelera.' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments "pregunta" in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Categorías' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Categoría' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Categorías' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Todas las categorías' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Categoría padre' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Categoría padre' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Nueva categoría' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añadir nueva categoría' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Editar categoría' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Actualizar categoría' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Separar elementos con comas' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Buscar categorías' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añadir o eliminar categorías' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Selecciona de las categorías más usadas' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Categoría de preguntas no encontrada' in file questions-post-type.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La configuración de la API de Amazon no es correcta." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error al obtener productos de Amazon (%s): %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error de la API de Amazon (Código %s). Respuesta: %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error en la respuesta de Amazon. Respuesta: %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error en la petición a Amazon de un artículo. Respuesta: %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error de la API de Amazon (Código %s). Respuesta: %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error de PHP petición a Amazon. Respuesta: %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No es posible cargar el módulo de Amazon." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El shortcode requiere de una ID o Keyword válida." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No es posible definir IDs y Keywords al mismo tiempo." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ver en Amazon" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por favor, configura la información de la API de Amazon antes de usar el shortcode." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade el atributo limit='cantidad' con un valor numérico superior a 0." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin resultados válidos en la API de Amazon." in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Error al cargar el producto: %s" in file amazon.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Volver a la página principal" in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Logo de la página web" in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "The selected font with theme_set_font is not valid." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Otras opciones' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Entradas' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Tablas de contenido' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Optimización web' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Pie de página' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Alto del logo' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mientras más elevado sea este valor, más grande será el logo. Determinará el alto del header en píxeles.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Margen interior del header' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Este valor determinará, en píxeles, el espacio superior e inferior dentro del header.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Deshabilitar animaciones por completo' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si se indica esta opción, la página web no mostrará ninguna animación. Mejorará el rendimiento en dispositivos low-end." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Hacer replegable la tabla de contenidos' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El índice de la tabla de contenidos aparecerá replegado por defecto en todos los índices." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Cargar el CSS en el HTML' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Al seleccionar esta opción, no se cargará el CSS como fichero. En su lugar aparecerá en el propio HTML. Mejorará el problema de 'bloqueo de renderizado' y el 'cumulative layout shift' de las Core Vitals pero la web cargará más lento." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Deshabilitar clic derecho' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Impide que los usuarios puedan utilizar el clic derecho." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mostrar botón para ir rápidamente al principio de la web' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mostrar pie de página' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Número de columnas del footer' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Texto inferior' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Por defecto aparecerá el símbolo de copyright, el año y nombre del blog. Puedes personalizarlo o dejarlo en blanco para que se autoconfigure.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mostrar tiempo de lectura' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "En minutos, mostrará el tiempo que se tarda en leer la entrada." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Tamaño de la entrada' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indica si quieres mostrar la entrada en formato reducido o que ocupe todo el ancho de la página.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mostrar imagen del autor' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¿Quieres que se muestre el avatar del autor?" in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mostrar fecha de los artículos' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si desmarcas esta opción, la fecha de publicación del artículo no aparecerá." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mostrar botón de compartir' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Muestra un único boton para compartir en todas las aplicaciones del usuario, sin configuraciones necesarias." in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Número de posts relacionados' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indica el número de posts relacionados que aparecerán al final de la entrada. Si se indica cero o no hay artículos disponibles, no aparecerá.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Clústers' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Diseño de las cajas de entradas' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Selecciona el estilo predeterminado para las entradas que aparecen en los clústers.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Diseño con caja" in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Diseño con imagen de fondo" in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ocultar el autor' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Marcando esta opción, no se mostrará en los clústers el autor del artículo.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ocultar las categorías' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Marcando esta opción, no se mostrarán las categorías en los clústers.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Deshabilitar difuminado' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Si seleccionas el diseño completo para los clúster, el extracto de las entradas tendrá un difuminado. Selecciona esta opción para deshabilitarlo.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Tamaño del extracto' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indica el número de palabras que deseas que aparezca en los extractos de las entradas, en caso de que esté habilitado.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Fuentes' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Fuente principal' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Selecciona la fuente principal de la web.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Fuente para títulos' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Selecciona la fuente para los títulos de la web. Si utilizas la misma fuente que la principal, la web cargará más rápido.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Tamaño de la fuente' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Determinará el tamaño principal de la fuente de la web.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Espaciado entre líneas' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Esta opción determinará la cantidad de espacio que hay entre cada una de las líneas. Mientras más grande sea la fuente, más alto debería de ser este valor y viceversa.' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color primario' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color secundario' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color de fondo del menú' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color de enlaces del menú' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color de enlaces del footer' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color de fondo del footer' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Color de fondo de la web' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Se recomienda utilizar blanco o un gris muy suave para mejorar la experiencia de usuario' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Deshabilitar sombras' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Deshabilitar el detalle visual de puntos al final de los títulos H1/H2...' in file customization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Suscripciones' in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Suscripciones" in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Suscriptor" in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Nombre" in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fecha de registro" in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible crear la tabla <b>para el listado de suscripciones</b>. El mensaje de error devuelto es: %s' in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error al insertar el registro en la base de datos." in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Suscríbete!" in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Suscríbete a nuestra newsletter, te encantarán nuestros emails con información útil." in file subscriptions.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Correo electrónico" in file subscriptions.php.Found a translation function that is missing a text-domain. Function esc_attr__, with the arguments 'Añade un menú' in file menu.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Añade un menú' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¿Ofuscar enlace?' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade elementos al menú para que aparezcan en esta posición." in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Menú principal' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Menú footer' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Menú principal' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Posición del menú' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indica si prefieres que el menú aparezca a la izquierda o a la derecha. Esta opción no tendrá efecto si el menú ocupa todo el ancho.' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Derecha" in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Izquierda" in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ocupar todo el ancho de la página' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Los botones del menú no aparecerán en la derecha, aparecerán en el centro ocupando todo el ancho.' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Fijar header al scroll' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'El menú principal se desplazará al hacer scroll. También se conoce como sticky header.' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Menú móvil' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Tipo de menú móvil' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indica si prefieres que el menú aparezca en la cabecera o en un icono flotante.' in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Menú fijo" in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Menú flotante" in file menu.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Advertencia!' in file page-priorization.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Esta página está sustituyendo a la categoría %s.' in file page-priorization.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Pregunta sin título" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'address' para indicar la dirección." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'view' para indicar el tipo de vista. Si no se pone, será mapa, 'k' para satélite, 'h' para híbrido y 'p' para el terreno." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'type' para indicar el color del botón." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añade el texto del botón: [button]Texto[/button] para que aparezca." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Autor no reconocido" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'date' para indicar la fecha." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La fecha indicada no es válida." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'text' para indicar el texto o URL del mismo." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'width' con un valor numérico mayor o igual a 50." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'height' con un valor numérico mayor o igual a 50." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Lo peor" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Lo mejor" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Domingo" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sábado" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Viernes" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Jueves" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Miércoles" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Martes" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Lunes" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Diciembre" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Noviembre" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Octubre" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Septiembre" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Agosto" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Julio" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Junio" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mayo" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Abril" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Marzo" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Febrero" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enero" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Elige un tamaño con el atríbuto size del 1 al 12.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Artículos relacionados" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Leer artículo" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redactor de %s" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redactor de %s" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por %s" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redactor de %s" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Redactor de %s" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por %s" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Mensaje para el administrador: No hay artículos disponibles.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'id' indicando la ID del video." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El atributo 'id' no es una ID de un video de YouTube válida." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No es posible mostrar la IP" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Utiliza el atributo 'percentage' con un valor entre el 0 y el 100." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El atributo 'height' debe tener un valor numérico entre el 10 y el 50." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El atributo 'background' solo puede utilizar: 'success', 'info', 'danger' y 'warning'." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Por favor, introduce un nombre válido.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Por favor, introduce un nombre válido.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Su mensaje contiene caracteres no válidos." in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¿Estás seguro de que has introducido un mensaje válido?" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Lo sentimos! Su mensaje contiene palabras no permitidas.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Gracias! Su solicitud ha sido recibida correctamente. Le responderemos tan pronto como sea posible.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'El formulario de contacto no está disponible en estos momentos.' in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Nombre:" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Email:" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Página web:" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Mensaje:" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Enviar mensaje" in file shortcodes.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Autor no indicado" in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Autor del artículo' in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Autores aleatorios activados" in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Autor visible' in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin autor aleatorio asignado." in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Redactor real' in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Redactor' in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ir al perfil' in file random-authors.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Editor por defecto para todos los usuarios' in file classic-editor.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Permitir a los usuarios cambiar entre editores' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _ex, with the arguments 'Editor clásico', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _ex, with the arguments 'Gutenberg', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Sí' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'No' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Editor por defecto' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Opciones del editor' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Editor por defecto para todos los sitios' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _ex, with the arguments 'Editor clásico', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _ex, with the arguments 'Gutenberg', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Cambiar opciones' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Permitir a los administradores de la red cambiar las opciones de los editores' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Por defecto, Gutenberg es reemplazado por el editor clásico y los usuarios no podrán cambiar entre editores.' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _e, with the arguments 'Cambiar a Gutenberg' in file classic-editor.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Cambiar al editor clásico' in file classic-editor.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ajustes' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _x, with the arguments 'Editar (Gutenberg)', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'EditAR &#8220;%s&#8221; en Gutenberg' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _x, with the arguments 'Editar (Editor clásico)', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Editar &#8220;%s&#8221; en el editor clásico' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _x, with the arguments 'editor clásico', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _x, with the arguments 'Gutenberg', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _x, with the arguments 'Editor clásico', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function _x, with the arguments 'Gutenberg', 'Editor Name' in file classic-editor.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Izquierda" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Izquierda (envuelto en el texto)" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Centrado" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Derecha" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Derecha (envuelto en el texto)" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Activo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Desactivado" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tabletas" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Móviles" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ordenadores" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Entradas" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Páginas" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Categorías" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sólo usar como shortcode" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Al principio del contenido" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Al final del contenido" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Antes del primer H2" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del primer H2" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Antes de la imagen destacada" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después de la imagen destacada" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del primer párrafo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del segundo párrafo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del tercer párrafo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del cuarto párrafo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del quinto párrafo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Después del sexto párrafo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La etiqueta que estás intentando actualizar no es correcta: %s" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La etiqueta que estás intentando actualizar no es correcta: %s" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información para administradores: Este anuncio está oculto." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información para administradores: Este anuncio no tiene ningún código válido asignado." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Desactivado" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Activo" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin dispositivos de visualización." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Anuncios" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Anuncios" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir nuevo anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Nuevo anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Editar anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ver anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Todos los anuncios" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Anuncio publicado." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Buscar anuncios" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay anuncios disponibles." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay anuncios en la papelera." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Anuncio actualizado." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Alineación" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Dispositivos de visualización" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Shortcode" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Estado" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Configuración del anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Código del anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica un código HTML, un script, un video, una imagen..." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Código HTML" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tipos de páginas permitidas" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¿En qué tipo de páginas debería de aparecer el anuncio?" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¿Donde se mostrará el anuncio?" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Alineación" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Márgenes" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Si quieres que automáticamente se añada margen para la caja del anuncio, indica los píxeles aquí" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Dispositivos de visualización" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Selecciona los dispositivos donde se visualizará el anuncio." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Shortcode" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "&larr; Recuerda que en las opciones de la izquierda puedes configurarlo para que aparezca automáticamente." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Copia y pega este shortcode donde quieras que aparezca el anuncio." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Estado del anuncio" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El anuncio no es visible para nadie." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El anuncio es visible." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Cambiar el estado" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información para administradores: El módulo de Adsense no está habilitado." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información para administradores: La ID indicada en el anuncio no es válida." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información para administradores: Este anuncio aparece en más de una ocasión en esta página y no puede mostrarse." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Información para administradores: La ID indicada no pertenece a un anuncio válido." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Activar anuncios" in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Desactivar anuncios" in file adsense.php.Found a translation function that is missing a text-domain. Function _n, with the arguments "%s anuncio desactivado.", "%s anuncio desactivados." in file adsense.php.Found a translation function that is missing a text-domain. Function _n, with the arguments "%s anuncio activado.", "%s anuncio activados." in file adsense.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Tu sitio web no está vinculado! Si acabas de instalar el tema o quieres volver a vincularlo %s para tener acceso a todas las herramientas.' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'accede aquí' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible verificar el estado de tu licencia. Las funcionalidades de tu tema están limitadas.' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "NULA" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Válida hasta " in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Expirada" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Licencia válida hasta " in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Expirada" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Validez de tu licencia (ID: #%s)" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Término de búsqueda no válido." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tipo de término de búsqueda no válido." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Licencia no válida o expirada." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Respuesta del servidor de %s no válida." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Sin respuesta del servidor." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce el siguiente PIN en el panel:" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El servidor de Seven SERP está en estado de mantenimiento. Por favor, espera unos minutos." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tu blog parece que ha sido vinculado correctamente, sin embargo, no es posible obtener tu código de licencia. Por favor, recarga la página para volver a intentarlo." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El servidor de Seven SERP no puede responder con un PIN válido. Los datos enviados por tu blog no son válidos." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible generar el código PIN. Por favor, asegúrate de que has indicado un %s y que la %s sea correcta. %s." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Título del sitio" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Dirección de WordPress (URL)" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Accede a Ajustes para resolverlo' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El código de vinculación recibido de 7SERP no es válido. Por favor vuelve a intentarlo en unos minutos." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error al enviar la petición de solicitud de código PIN. Vuelve a intentarlo pasados unos minutos." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error al conectar con el servidor de 7SERP. Vuelve a intentarlo refrescando la página." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error desconocido al generar tu PIN. Vuelve a intentarlo refrescando la página." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Actualiza el theme' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error crítico al comprobar la actualización más reciente: %s" in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible reconocer la versión que estás utilizando del tema.' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Por favor, instala la actualización para solucionarlo.' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Hay una nueva actualización disponible!' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Te recomendamos instalarla lo antes posible.' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tu sitio web no tiene una suscripción válida activada. Por favor vuelve a vincular tu sitio si crees que se trata de un error." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Hecho! Hemos solicitado a Google que indexe las páginas seleccionadas." in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Acceder a %s' in file sevenserp-api.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Prueba sin título" in file health.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta prueba no ha sido provista de ninguna descriptión." in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Esta prueba ha sido ejecutada por %s.' in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments "Los nombres de usuario usados para el administrador no son seguros" in file health.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Tener un usuario llamado %s o %s no es seguro. Es extremadamente importante que cambies el nombre de los usuario del administrador a uno menos común y más complejo de adivinar.' in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Los nombres de usuario usados para el administrador son seguros' in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Ninguna de la cuentas con permisos de administrador que están registradas utiliza un nombre inseguro.' in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Hay un plugin de SEO instalado' in file health.php.Found a translation function that is missing a text-domain. Function __, with the arguments '<p><b>Tienes instalado un plugin de gestión de SEO externo al tema.</b> Ambos podrían interferir y perjudicar gravemente el SEO de tu página.</p><p>Puedes o bien deshabilitar el plugin o desactivar el módulo de SEO. Si prefieres utilizar el módulo de SEO del tema puedes <a href="#">transferir los datos</a> y no será necesario volver a configurar tus datos de SEO.</p>' in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'El SEO de esta página se gestiona con el tema' in file health.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'El tema gestiona todas las funcionalidades y características del SEO. No hay ningún plugin instalado que pueda interferir con un funcionamiento óptimo.' in file health.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible ejecutar los tests adicionales del sistema de salud." in file health.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Comparte esta entrada!" in file helpers.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Compartir" in file helpers.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Vaya! Aún no tienes productos en tu cesta" in file woocommerce.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Añadir un subtítulo' in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Indica un subtítulo para esta página:" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Subtítulo" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por defecto" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Centrado con header grande" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ocultar el título de esta página.' in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Ocultar la imagen destacada.' in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar relacionados." in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Ocultar enlaces de anterior y siguiente." in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Opciones de visibilidad" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Insertar scripts' in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El código HTML que incluyas en este recuadro se mostrará en la parte superior de la página." in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Código HTML" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tabla de contenidos" in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Una o varias etiquetas utilizadas en 'exclude' no están permitidas. Introduce 'h1,h2,h3' hasta h6 por ejemplo, para excluir ciertos títulos." in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No se ha mostrado la tabla de contenidos, ya que no hay ningún título para ser mostrado." in file posts.php.Found a translation function that is missing a text-domain. Function __, with the arguments "<b>Importante:</b> Solo para que lo sepas, esta %s está siendo reemplazada por el fichero del tema hijo: <b>%s</b>" in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "página" in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "entrada" in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Estado: Publicado' in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Estado: Borrador' in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Convertir a entrada' in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Convertir a página' in file improve-admin.php.Found a translation function that is missing a text-domain. Function _n, with the arguments '%s artículo cambiado de estado a publicado.', '%s artículos cambiado de estado a publicados.' in file improve-admin.php.Found a translation function that is missing a text-domain. Function _n, with the arguments '%s artículo cambiado de estado a borrador.', '%s artículos cambiado de estado a borrador.' in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Creado por %s con %s" in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Versión %s / Versión plantilla %s" in file improve-admin.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La base de datos ha sido optimizada automáticamente." in file db-cleaner.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible crear la tabla <b> para las estadísticas de rastreo de robots. El mensaje de error es: ' in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "¡Vaya! Aún no hay registrada ninguna visita de ningún rastreador." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Posición" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Número de rastreos" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Página" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La sección de análisis de datos de rastreadores no está disponible hasta que haya visitas registradas." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Accesos durante el último mes" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Top 10 páginas visitadas" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Visitas por tipo de rastreador" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Visitas por tipo de HTTP" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de APIs de Google." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Adsense para PC." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Adsense para móviles. Comprueba la calidad de los anuncios mostrados en dispositivos móviles." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de aplicaciones móviles. Comprueba la calidad de anuncios mostrados en aplicaciones para Android." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Adsense para ordenadores. Comprueba la calidad de los anuncios mostrados en ordenadores." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google genérico." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google de obtención de imágenes." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google News." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google para videos." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google de obtención de feeds." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google. Asistente de Google en Chrome." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Google de obtención de Favicon de la página." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Ahrefs." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Robot de Semrush" in file spiders.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "¡Vaya! Aún no hay registrada ninguna visita de ningún rastreador." in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Página" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Rastreador" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Agente de usuario" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "IP Usada" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fecha de visita" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Host local" in file spiders.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El tema ha encontrado posibles fallos críticos de seguridad. Por favor reinstala WordPress o reemplaza estos ficheros por los originales:" in file security.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Volver a escanear" in file security.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible crear la tabla <b> para las redirecciones SEO. El mensaje de error devuelto es: ' in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El código HTTP indicado para la redirección no es válido." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La URL de origen indicada no es válida." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La URL de origen debe de contener la URL del blog." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La URL de origen no es válida." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La URL de destino indicada no es válida." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La URL de destino no es válida." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error al insertar el registro en la base de datos." in file redirections.php.Found a translation function that is missing a text-domain. Function __, with the arguments in file redirections.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Nunca' in file blacklist-updater.php.Found a translation function that is missing a text-domain. Function esc_html__, with the arguments 'Próxima actualización de la lista negra de comentarios: %s' in file blacklist-updater.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'En mantenimiento' in file autoload.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Descripción de la nueva Zona de Widgets' in file widgets.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Sidebar' in file widgets.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Zona lateral de la página' in file widgets.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La clase 'Seven_Spintax' no ha podido ser cargada." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Generado" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta entrada se utiliza como plantilla para el generador de contenido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Plantilla" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: ' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La tabla de la base de datos para la generación de contenido no está creada." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario definir las palabras clave antes de generar contenido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El tipo de post indicado no existe." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario indicar el título que se utilizará." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El título indicado no es válido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay ninguna palabra clave indicada en el título." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Es necesario el contenido que se utilizará." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay ninguna palabra clave indicada en el contenido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El grupo de palabras clave %s usada en el contenido o título no está registrada en tus plantillas." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay ninguna palabra clave dentro del grupo %s." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Esta página ha sido generada automáticamente desde la plantilla <b><a href="%s" target="_blank">%s</a></b>.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Advertencia!' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Esta página o entrada es una plantilla para generar contenido.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'La visibilidad ha sido marcada como privada.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se han generado un total de %d páginas, de las cuales %d se han actualizado porque ya existían." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No ha sido posible generar ninguna página." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Generador de contenido" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Esta página ha sido generada automáticamente mediante el módulo de generador de contenido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "En caso de usar esta página como plantilla para generar contenido, activa el checkbox y completa los detalles. Posteriormente haz clic en 'Actualizar' y se generará el contenido." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Usar como plantilla para generación de contenido.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Límite de artículos a añadir:' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Palabras clave' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Palabras clave' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Indica un nombre válido.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments '¡Modificaciones guardadas!' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Palabras clave' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Volver al listado" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Volver a la lista" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Volver atrás" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Editar" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Eliminar grupo" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir nuevo grupo" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce un nombre para un grupo de palabras clave. Por ejemplo, Ciudad para: Bogotá, Madrid..." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Introduce las palabras clave que formarán parte de este grupo.<br>Por ejemplo, para un hipotético grupo 'Ciudad', sus palabras serían 'Madrid', 'Bogotá'... <b>Solo una por línea.</b>" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Añadir grupo" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Por favor, confirma que vas a eliminar este grupo de palabras. Esta acción es irreversible." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Estoy seguro, eliminar" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Editar palabras" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Estas son las palabras clave (%d) que forman parte de este grupo. Puedes eliminarlas o añadir tantas como necesites.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Este grupo de palabras clave <b>aún no tiene ninguna keyword añadida</b>." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Presiona el botón editar para modificarlas." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'En esta sección se pueden gestionar los grupos de palabras clave con los que se generará el nuevo contenido. Para más información accede a %s.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "la documentación" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Aún no hay ningún grupo de palabras clave definidos.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Éstos son los grupos de palabras clave (%d).' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Editar palabras clave de este grupo' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Eliminación' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Eliminación' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Contenido eliminado correctamente" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Se han eliminado %d posts correctamente.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Eliminado post ID %d." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay contenido para eliminar" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'No existe ningún post generado automáticamente que pueda eliminarse.' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Se ha producido un error" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "El contenido generado automáticamente no se ha podido eliminar por motivos desconocidos." in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Eliminar contenido generado' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Vas a eliminar todo el contenido generado automáticamente, ¿estás seguro?" in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'Sí, eliminar el contenido' in file content-generator.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Centro de ayuda" in file single-question.php.Found a translation function that is missing a text-domain. Function __, with the arguments "La plantilla predeterminada seleccionada no existe." in file single.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fecha de publicación" in file single-centered.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tiempo de lectura" in file single-centered.php.Found a translation function that is missing a text-domain. Function __, with the arguments "1 minuto" in file single-centered.php.Found a translation function that is missing a text-domain. Function __, with the arguments "%d minutos" in file single-centered.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Artículo anterior" in file single-centered.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Siguiente artículo" in file single-centered.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Centro de ayuda" in file faq_home.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Categoría sin nombre" in file faq_home.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No hay artículos en esta categoría." in file faq_home.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "Sitio en mantenimiento" in file maintenance.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "Este sitio web se encuentra en estos momentos dentro de un mantenimiento programado." in file maintenance.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No indicado" in file aviso-legal.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No indicado" in file aviso-legal.php.Found a translation function that is missing a text-domain. Function __, with the arguments "No indicado" in file aviso-legal.php.Found a translation function that is missing a text-domain. Function __, with the arguments "(Ciudad no indicada)" in file aviso-legal.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Centro de ayuda" in file faq_question.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Fecha de publicación" in file single-default.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Tiempo de lectura" in file single-default.php.Found a translation function that is missing a text-domain. Function __, with the arguments "1 minuto" in file single-default.php.Found a translation function that is missing a text-domain. Function __, with the arguments "%d minutos" in file single-default.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Artículo anterior" in file single-default.php.Found a translation function that is missing a text-domain. Function __, with the arguments "Siguiente artículo" in file single-default.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "Introduce una palabra para buscar" in file searchform.php.Found a translation function that is missing a text-domain. Function _e, with the arguments "Buscar" in file searchform.php.Found a translation function that is missing a text-domain. Function __, with the arguments in file functions.php.Found a translation function that is missing a text-domain. Function __, with the arguments 'RAM: %sM de %s' in file functions.php.Found a translation function that is missing a text-domain. Function __, with the arguments '(Debug) Carga: %s' in file functions.php.More than one text-domain is being used in this theme. This means the theme will not be compatible with WordPress.org language packs. The domains found are text-domain, classic-editor, change_to_post, change_to_page, ), twentytwenty.
  4. Plugin territory : Plugin territory functionalitiesThe theme uses the register_post_type() function, which is plugin-territory functionality.The theme uses the add_shortcode() function. Custom post-content shortcodes are plugin-territory functionality.
  5. Unwanted directories : GIT revision control directoryA.git was found.
  6. Hidden admin bar : Hidden admin Bar in CSSThemes should not hide admin bar. Detected in file admin-fixed.css.
  7. Fundamental theme elements : Presence of language_attributes()Could not find .
  8. Fundamental theme elements : Presence of add_theme_support()Could not find add_theme_support( 'automatic-feed-links' ).
  9. Fundamental theme elements : Presence of wp_link_pages()Could not find wp_link_pages.
  10. Fundamental theme elements : Presence of post_class()Could not find post_class.
  11. Custom elements : Presence of custom headerNo reference to custom header was found in the theme.
  12. Custom elements : Presence of custom backgroundNo reference to custom background was found in the theme.
  13. Editor style : Presence of editor styleNo reference to add_editor_style() was found in the theme. It is recommended that the theme implements editor styling, so as to make the editor content match the resulting post output in the theme, for a better user experience.
  14. I18N implementation : Proper use of ___all(Possible variable $ex found in translation function in monitor-404.php. Translation function calls should not contain PHP variables. 47: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para el monitor de 404. El mensaje de errPossible variable $ex found in translation function in spiders.php. Translation function calls should not contain PHP variables. Possible variable $ex found in translation function in redirections.php. Translation function calls should not contain PHP variables. Possible variable $descriptions found in translation function in redirections.php. Translation function calls should not contain PHP variables. 44: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla <b> para las redirecciones SEO. El mensaje de error devuelto es: '.$ex->getMessage()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function check_wpdb_redirect_db(){ return (strtolower($this->wpdb->get_var('SHOW TABLES LIKE ''.$this->table.''')) === (string)trim(strtolower($this->table))); } public function current_url(){ return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]'; } public function get(){ if(!$this->table_exists) return []; $results = $this->wpdb->get_results( 'SELECT * FROM '.$this->table ); return $results; } public function sum_redirect($id=0){ if(!$this->table_exists) return false; if(!is_numeric($id)) return false; $this->wpdb->query($this->wpdb->prepare('UPDATE '.$this->table.' SET redirects=redirects+1 WHERE id=%d', $id)); } public function remove($id=0){ if(!$this->table_exists) return false; if(!is_numeric($id)) return false; return $this->wpdb->delete($this->table, ['id' => $id], array('%d')); } public function add($url, $to, $code){ if(!$this->table_exists) return false; if(!$this->valid_code($code)){ return ['error' => __('El código HTTP indicado para la redirección no es válido.', TRANSLATIONS), 'result' => false]; } if(strlen(trim($url))==0){ return ['error' => __('La URL de origen indicada no es válida.', TRANSLATIONS), 'result' => false]; } if(strpos($url, get_site_url()) === FALSE){ return ['error' => __('La URL de origen debe de contener la URL del blog.', TRANSLATIONS), 'result' => false]; } if(!filter_var($url, FILTER_VALIDATE_URL)){ return ['error' => __('La URL de origen no es válida.', TRANSLATIONS), 'result' => false]; } if(strlen(trim($to))==0){ return ['error' => __('La URL de destino indicada no es válida.', TRANSLATIONS), 'result' => false]; } if(!filter_var($to, FILTER_VALIDATE_URL)){ return ['error' => __('La URL de destino no es válida.', TRANSLATIONS), 'result' => false]; } $result = $this->wpdb->insert($this->table, ['url' => $url, 'to_url' => $to, 'http_code' => $code, 'redirects' => 0], ['%s', '%s', '%d', '%d']); return ($result ? ['result' => true] : ['result' => false, 'error' => __('Se ha producido un error al insertar el registro en la base de datos.')]); } public function get_codes(){ return [301, 302, 303, 307, 308, 410]; } public function get_code_description($code=301){ $descriptions = [ '301' => 'Permanente', '302' => 'Temporal', '303' => 'Ver otros', '307' => 'Temporal', '308' => 'Permanente', '410' => 'Recurso no disponible' ]; return (isset($descriptions[$code]) ? ' ('.__(trim($descriptions[$code]), TRANSLATIONS).')' : NULL); } private functioPossible variable $column found in translation function in widgets.php. Translation function calls should not contain PHP variables. 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } define('FOOTER_DEFAULT_COLUMNS', 0); define('FOOTER_MAX_COLUMNS', 4); define('MAX_BOOTSTRAP_COL_LENGTH', 12); function get_footer_columns_number(){ $columns_number = get_theme_mod('footer_columns'); if(!$columns_number || !is_numeric($columns_number) || $columns_number<0){ return FOOTER_DEFAULT_COLUMNS; } if($columns_number>FOOTER_MAX_COLUMNS){ return FOOTER_MAX_COLUMNS; } if($columns_number==0) return 0; return (int)$columns_number; } function get_footer_widget_class(){ $columns_number = get_footer_columns_number(); return 'col-lg-'.(MAX_BOOTSTRAP_COL_LENGTH/$columns_number); } add_action( 'widgets_init', function(){ try{ $columns_number = get_footer_columns_number(); if($columns_number>0){ foreach(range(1, $columns_number) as $column){ register_sidebar([ 'name' => __('Pie de página (Columna '.$column.')'), 'id' => 'footer_widgets_'.$coluPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!class_exists('Content_Generator')){ class Content_Generator{ private $permissions = 'manage_options'; private $menu_slug = 'content-generator'; private $default_limit = 150; private $default_post_type = 'post'; private $create_action = 'create'; private $delete_action = 'create'; private $generated_meta = '_generated'; private $template_meta = '_content_generator_template'; private $nonce = 'content_generator_nonce'; private $wpdb; private $table = NULL; private $table_name = NULL; private $table_exists = false; private $spintax = NULL; function __construct(){ if(!class_exists('Seven_Spintax')){ throw new Exception(__('La clase 'Seven_Spintax' no ha podido ser cargada.', $this->get_translaPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!class_exists('Content_Generator')){ class Content_Generator{ private $permissions = 'manage_options'; private $menu_slug = 'content-generator'; private $default_limit = 150; private $default_post_type = 'post'; private $create_action = 'create'; private $delete_action = 'create'; private $generated_meta = '_generated'; private $template_meta = '_content_generator_template'; private $nonce = 'content_generator_nonce'; private $wpdb; private $table = NULL; private $table_name = NULL; private $table_exists = false; private $spintax = NULL; function __construct(){ if(!class_exists('Seven_Spintax')){ throw new Exception(__('La clase 'Seven_Spintax' no ha podido ser cargada.', $this->get_translations())); }else{ $this->spintax = (new Seven_Spintax()); } global $wpdb; $this->wpdb = $wpdb; $this->table_name = 'content_generator'; $this->table = '{$wpdb->prefix}'.$this->table_name; $this->table_exists = $this->check_wpdb_content_generator_db(); if($this->table_exists() && is_admin()){ $this->display_post_states(); } add_action('admin_notices', [new AdminNotice(), 'displayAdminNotice']); } public function check_wpdb_content_generator_db(){ if(strtolower($this->wpdb->get_var('SHOW TABLES LIKE ''.$this->table.''')) === strtolower($this->table)){ return true; } return false; } public static function slugify($text){ $text = preg_replace('~[^\pL\d]+~u', '-', $text); $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); $text = preg_replace('~[^-\w]+~', '', $text); $text = trim($text, '-'); $text = preg_replace('~-+~', '-', $text); $text = strtolower($text); return $text; } private function get_keyword_slug($keyword){ return $this->slugify($keyword); } private function get_keyword_parent_title($keyword=0){ foreach($this->get_keyword_templates(true) as $k){ if($keyword == $this->get_keyword_slug($k)){ return $k; } } return false; } private function display_post_states(){ add_filter( 'display_post_states', function($post_states, $post){ if($this->is_generated($post)){ $post_states[] = __('Generado', $this->get_translations()); return $post_states; } if($this-Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!class_exists('Content_Generator')){ class Content_Generator{ private $permissions = 'manage_options'; private $menu_slug = 'content-generator'; private $default_limit = 150; private $default_post_type = 'post'; private $create_action = 'create'; private $delete_action = 'create'; private $generated_meta = '_generated'; private $template_meta = '_content_generator_template'; private $nonce = 'content_generator_nonce'; private $wpdb; private $table = NULL; private $table_name = NULL; private $table_exists = false; private $spintax = NULL; function __construct(){ if(!class_exists('Seven_Spintax')){ throw new Exception(__('La clase 'Seven_Spintax' no ha podido ser cargada.', $this->get_translations())); }else{ $this->spintax = (new Seven_Spintax()); } global $wpdb; $this->wpdb = $wpdb; $this->table_name = 'content_generator'; $this->table = '{$wpdb->prefix}'.$this->table_name; $this->table_exists = $this->check_wpdb_content_generator_db(); if($this->table_exists() && is_admin()){ $this->display_post_states(); } add_action('admin_notices', [new AdminNotice(), 'displayAdminNotice']); } public function check_wpdb_content_generator_db(){ if(strtolower($this->wpdb->get_var('SHOW TABLES LIKE ''.$this->table.''')) === strtolower($this->table)){ return true; } return false; } public static function slugify($text){ $text = preg_replace('~[^\pL\d]+~u', '-', $text); $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); $text = preg_replace('~[^-\w]+~', '', $text); $text = trim($text, '-'); $text = preg_replace('~-+~', '-', $text); $text = strtolower($text); return $text; } private function get_keyword_slug($keyword){ return $this->slugify($keyword); } private function get_keyword_parent_title($keyword=0){ foreach($this->get_keyword_templates(true) as $k){ if($keyword == $this->get_keyword_slug($k)){ return $k; } } return false; } private function display_post_states(){ add_filter( 'display_post_states', function($post_states, $post){ if($this->is_generated($post)){ $post_states[] = __('Generado', $this->get_translations()); return $post_states; } if($this->is_template($post)){ $post_states[] = '<span data-microtip-position='right' aria-label=''.__('Esta entrada se utiliza como plantilla para el generador de contenido.'Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 37: if(!defined('ABSPATH')){ header('HTTP/1.0 403 Forbidden'); exit; } if(!class_exists('Content_Generator')){ class Content_Generator{ private $permissions = 'manage_options'; private $menu_slug = 'content-generator'; private $default_limit = 150; private $default_post_type = 'post'; private $create_action = 'create'; private $delete_action = 'create'; private $generated_meta = '_generated'; private $template_meta = '_content_generator_template'; private $nonce = 'content_generator_nonce'; private $wpdb; private $table = NULL; private $table_name = NULL; private $table_exists = false; private $spintax = NULL; function __construct(){ if(!class_exists('Seven_Spintax')){ throw new Exception(__('La clase 'Seven_Spintax' no ha podido ser cargada.', $this->get_translations())); }else{ $this->spintax = (new Seven_Spintax()); } global $wpdb; $this->wpdb = $wpdb; $this->table_name = 'content_generator'; $this->table = '{$wpdb->prefix}'.$this->table_name; $this->table_exists = $this->check_wpdb_content_generator_db(); if($this->table_exists() && is_admin()){ $this->display_post_states(); } add_action('admin_notices', [new AdminNotice(), 'displayAdminNotice']); } public function check_wpdb_content_generator_db(){ if(strtolower($this->wpdb->get_var('SHOW TABLES LIKE ''.$this->table.''')) === strtolower($this->table)){ return true; } return false; } public static function slugify($text){ $text = preg_replace('~[^\pL\d]+~u', '-', $text); $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); $text = preg_replace('~[^-\w]+~', '', $text); $text = trim($text, '-'); $text = preg_replace('~-+~', '-', $text); $text = strtolower($text); return $text; } private function get_keyword_slug($keyword){ return $this->slugify($keyword); } private function get_keyword_parent_title($keyword=0){ foreach($this->get_keyword_templates(true) as $k){ if($keyword == $this->get_keyword_slug($k)){ return $k; } } return false; } private function display_post_states(){ add_filter( 'display_post_states', function($post_states, $post){ if($this->is_generated($post)){ $post_states[] = __('Generado', $this->get_translations()); return $post_states; } if($this->is_template($post)){ $post_states[] = '<span data-microtip-position='right' aria-label=''.__('Esta entrada se utiliza como plantilla para el generador de contenido.', $this->get_translations()).'' role='tooltip' class='content-generator-badge'>'.__('Plantilla', $this->get_translations()).'</span>'; return $post_states; Possible variable $ex found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. AbortaPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' oPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } ifPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translaPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }elsePossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_transPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations(Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. PPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_traPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_translations())); } } $keywords = array_merge($content_keywords, $title_keywords); foreach($keywords as $parent_kw => $k){ if(!in_array($parent_kw, $keyword_templates)){ throw new Exception(sprintf(__('El grupo de palabras clave %s usada en el contenido o título no está Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_translations())); } } $keywords = array_merge($content_keywords, $title_keywords); foreach($keywords as $parent_kw => $k){ if(!in_array($parent_kw, $keyword_templates)){ throw new Exception(sprintf(__('El grupo de palabras clave %s usada en el contenido o título no está registrada en tus plantillas.', $this->get_translations()), esc_html($parent_kw))); } if(count($k) == 0){ throw new Exception(sprintf(__('No hay ninguna palabra clave dentro del grupo %s.', $this->get_translatPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_translations())); } } $keywords = array_merge($content_keywords, $title_keywords); foreach($keywords as $parent_kw => $k){ if(!in_array($parent_kw, $keyword_templates)){ throw new Exception(sprintf(__('El grupo de palabras clave %s usada en el contenido o título no está registrada en tus plantillas.', $this->get_translations()), esc_html($parent_kw))); } if(count($k) == 0){ throw new Exception(sprintf(__('No hay ninguna palabra clave dentro del grupo %s.', $this->get_translations()), esc_html($k))); } } unset($keywords); return $this->generate_virtual_content($data, $title_keywords); } private function get_post_id($post){ return (is_object($post) ? $post->ID : (is_array($post) ? $post['ID'] : $post)); } private function is_template($post){ $template = get_post_meta($this->get_post_id($post), $this->template_meta, true); return ($template&&(int)$template>=1); } private function is_generated($post){ $generated = get_post_meta($this->get_post_id($post), $this->generated_meta, true); return ($generated&&(int)$generated>=1); } private function get_template($post){ return get_post_meta($this->get_post_id($post), $this->generated_meta, true); } public function hook_post_notices(){ add_action('admin_notices', function(){ if( isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit' && $_GET['post']>0){ if($this->valid_post_type(get_post_type($_GET['post'])) && $this->is_generated($_GET['post'])>0){ echo '<div class='notice notice-warning is-dismissible'><p>'. sprintf(__('Esta página ha sido generada automáticamente desde la plantilla <b><aPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_translations())); } } $keywords = array_merge($content_keywords, $title_keywords); foreach($keywords as $parent_kw => $k){ if(!in_array($parent_kw, $keyword_templates)){ throw new Exception(sprintf(__('El grupo de palabras clave %s usada en el contenido o título no está registrada en tus plantillas.', $this->get_translations()), esc_html($parent_kw))); } if(count($k) == 0){ throw new Exception(sprintf(__('No hay ninguna palabra clave dentro del grupo %s.', $this->get_translations()), esc_html($k))); } } unset($keywords); return $this->generate_virtual_content($data, $title_keywords); } private function get_post_id($post){ return (is_object($post) ? $post->ID : (is_array($post) ? $post['ID'] : $post)); } private function is_template($post){ $template = get_post_meta($this->get_post_id($post), $this->template_meta, true); return ($template&&(int)$template>=1); } private function is_generated($post){ $generated = get_post_meta($this->get_post_id($post), $this->generated_meta, true); return ($generated&&(int)$generated>=1); } private function get_template($post){ return get_post_meta($this->get_post_id($post), $this->generated_meta, true); } public function hook_post_notices(){ add_action('admin_notices', function(){ if( isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit' && $_GET['post']>0){ if($this->valid_post_type(get_post_type($_GET['post'])) && $this->is_generated($_GET['post'])>0){ echo '<div class='notice notice-warning is-dismissible'><p>'. sprintf(__('Esta página ha sido generada automáticamente desde la plantilla <b><a href='%s' target='_blank'>%s</a></b>.', $this->get_translations()), get_the_permalink($this->get_template($_GET['post'])), get_the_title($this->get_template($_GET['post']))). '</p></div>'; } } }); } public function add_metaboxes(){ add_filter('wp_insert_post_data', function($post, $post_array){ if(isset($post_array['ID']) && $this->is_template($post_array['ID']) && !$this->is_generated($post_array['ID'])){ if($post['post_type'] == 'post' || $post['post_type'] == 'page'){ if($post['post_status'] != 'private') $post['post_status'] = 'private'; } } return $post; }, 10, 2); add_action('admin_head', function(){ if(is_admin() && isset($_GET['post']) && is_numeric($_GET['post']) && $this->is_template($_GET['post'])){ echo '<style>a.edit-visibility{visibility:hidden !important; display:none !important;}</style>'; } }); add_action('load-post.php', function(){ if(is_admin() && isset($_GET['post']) && is_numeric($_GET['post']) && $this->is_template($_GET['post'])){ wp_update_post(['ID' => $_GET['post'], 'post_status' => 'private']); add_action('add_meta_boxes', function(){ add_meta_box( 'warning_content_generator_template', __('¡Advertencia!', $this->get_translations()), function(){ echo '<span idPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_translations())); } } $keywords = array_merge($content_keywords, $title_keywords); foreach($keywords as $parent_kw => $k){ if(!in_array($parent_kw, $keyword_templates)){ throw new Exception(sprintf(__('El grupo de palabras clave %s usada en el contenido o título no está registrada en tus plantillas.', $this->get_translations()), esc_html($parent_kw))); } if(count($k) == 0){ throw new Exception(sprintf(__('No hay ninguna palabra clave dentro del grupo %s.', $this->get_translations()), esc_html($k))); } } unset($keywords); return $this->generate_virtual_content($data, $title_keywords); } private function get_post_id($post){ return (is_object($post) ? $post->ID : (is_array($post) ? $post['ID'] : $post)); } private function is_template($post){ $template = get_post_meta($this->get_post_id($post), $this->template_meta, true); return ($template&&(int)$template>=1); } private function is_generated($post){ $generated = get_post_meta($this->get_post_id($post), $this->generated_meta, true); return ($generated&&(int)$generated>=1); } private function get_template($post){ return get_post_meta($this->get_post_id($post), $this->generated_meta, true); } public function hook_post_notices(){ add_action('admin_notices', function(){ if( isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit' && $_GET['post']>0){ if($this->valid_post_type(get_post_type($_GET['post'])) && $this->is_generated($_GET['post'])>0){ echo '<div class='notice notice-warning is-dismissible'><p>'. sprintf(__('Esta página ha sido generada automáticamente desde la plantilla <b><a href='%s' target='_blank'>%s</a></b>.', $this->get_translations()), get_the_permalink($this->get_template($_GET['post'])), get_the_title($this->get_template($_GET['post']))). '</p></div>'; } } }); } public function add_metaboxes(){ add_filter('wp_insert_post_data', function($post, $post_array){ if(isset($post_array['ID']) && $this->is_template($post_array['ID']) && !$this->is_generated($post_array['ID'])){ if($post['post_type'] == 'post' || $post['post_type'] == 'page'){ if($post['post_status'] != 'private') $post['post_status'] = 'private'; } } return $post; }, 10, 2); add_action('admin_head', function(){ if(is_admin() && isset($_GET['post']) && is_numeric($_GET['post']) && $this->is_template($_GET['post'])){ echo '<style>a.edit-visibility{visibility:hidden !important; display:none !important;}</style>'; } }); add_action('load-post.php', function(){ if(is_admin() && isset($_GET['post']) && is_numeric($_GET['post']) && $this->is_template($_GET['post'])){ wp_update_post(['ID' => $_GET['post'], 'post_status' => 'private']); add_action('add_meta_boxes', function(){ add_meta_box( 'warning_content_generator_template', __('¡Advertencia!', $this->get_translations()), function(){ echo '<span id='theme-warning'>'.__('Esta página o entrada es una plantilla para generar contenido.', $thisPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 43: ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'); $this->table_exists = $this->check_wpdb_content_generator_db(); }catch(Exception $ex){ add_action( 'admin_notices', function() { $class = 'notice notice-error'; $message = __( 'No es posible crear la tabla para la generación de contenido. El mensaje de error devuelto es: '.$ex->getMessage(), $this->get_translations()); printf('<div class='%1$s'><p>%2$s</p></div>', esc_attr($class), esc_html($message)); }); } } } public function table_exists(): bool{ return $this->table_exists; } private function get_translations(){ return (defined('TRANSLATIONS') ? TRANSLATIONS : 'content-generator'); } public function add_shortcode(){ add_shortcode('content-generator-list', function($atts=[], $content=NULL){ return ''; }); } public function is_content_generated($post_id=0){ if(!is_numeric($post_id) || $post_id<=0) return false; if(get_post_status($post_id) === FALSE) return false; $post_by_content_generator = get_post_meta($post_id, 'content-generator', TRUE); return ($post_by_content_generator); } private function get_keyword_parent_id($keyword=0){ if(!is_string($keyword)) return []; $results = $this->wpdb->get_results( $this->wpdb->prepare('SELECT id, keyword FROM '.$this->table.' WHERE parent=%d', [0]) ); foreach($results as $kw){ if($kw->keyword == $keyword || $this->slugify($kw->keyword) == $keyword){ return $kw->id; } } return 0; } private function add_keywords_to_parent($keyword=0, $keywords=[]): bool{ if(empty($keywords)) return false; if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $created = 0; foreach($keywords as $kw){ if(is_string($kw) && strlen(trim($kw))>0){ $created++; $this->wpdb->insert($this->table, ['keyword' => $kw, 'parent' => $keyword_id->id], ['%s', '%d']); } } return ($created>0 ? true : false); } return false; } private function delete_keyword_group($keyword=0): bool{ if(!is_numeric($keyword)) return false; $result = $this->wpdb->delete($this->table, ['id' => $keyword, 'parent' => 0], ['%d', '%d']); return ($result); } private function delete_keywords_from_parent($keyword=0): bool{ if(is_numeric($keyword) && $keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = $this->wpdb->get_row( $this->wpdb->prepare('SELECT id FROM '.$this->table.' WHERE keyword=%s AND parent=0', [$keyword]) ); } if(!empty($keyword_id) && isset($keyword_id->id)){ $result = $this->wpdb->delete($this->table, ['parent' => $keyword_id->id], ['%d']); return ($result); } return false; } private function get_keywords_from_parent($keyword=0){ if(is_numeric($keyword) && (int)$keyword>0){ $keyword_id = (object)['id' => $keyword]; }else{ $keyword_id = (object)['id' => $this->get_keyword_parent_id($keyword)]; } if(!empty($keyword_id) && isset($keyword_id->id)){ $keyword_list = $this->wpdb->get_results( $this->wpdb->prepare('SELECT DISTINCT keyword FROM '.$this->table.' WHERE parent=%d', [$keyword_id->id]) ); return ($keyword_list!=NULL && !empty($keyword_list) ? $keyword_list : []); } return []; } private function get_keywords($string, $just_parent_keywords=false){ if(!is_string($string) || strlen(trim($string))==0) return []; $matches_normalized = []; preg_match_all('/%%%[^%]*%%%/', $string, $matches); foreach($matches as $array){ foreach($array as $match){ $match = trim(str_replace('%%%', NULL, $match)); if(strlen(trim($match))>0 && !in_array($match, $matches_normalized)){ array_push($matches_normalized, $match); } } } if($just_parent_keywords){ return $matches_normalized; } $groups = []; if(!empty($matches_normalized)){ foreach($matches_normalized as $parent_keyword){ if(!isset($groups[$parent_keyword])){ $groups[$parent_keyword] = []; } $group = $this->get_keywords_from_parent($this->get_keyword_parent_title($parent_keyword)); if(!empty($group)){ foreach($group as $keyword){ if(!in_array($keyword->keyword, $groups[$parent_keyword])){ array_push($groups[$parent_keyword], $keyword->keyword); } } } } } return $groups; } public function get_posts_number($string=[], $keywords=[]){ $posts_numbers = []; foreach($keywords as $parent => $list){ array_push($posts_numbers, count($list)); } if(count($posts_numbers) == 1){ return $posts_numbers; }else{ $total_posts=NULL; for($i=0; $i<count($posts_numbers); $i++){ if($total_posts==NULL){ $total_posts=$posts_numbers[$i]; continue; } if(isset($posts_numbers[$i])){ $total_posts = $total_posts * $posts_numbers[$i]; } } return $total_posts; } return 0; } public function recursive_content_generation($string=[], $keywords=[], $content=[]){ if(empty($keywords)) return $content; $keyword = array_keys($keywords)[0]; if(empty($content)){ foreach($keywords[$keyword] as $key){ $array = [ 't' => $string, $keyword => $key, ]; array_push($content, $array); } }else{ $new_content = []; foreach($content as $array){ foreach($keywords[$keyword] as $key){ $array[$keyword] = $key; array_push($new_content, $array); } } $content = $new_content; unset($new_content); } unset($keywords[$keyword]); return $this->recursive_content_generation($string, $keywords, $content); } private function replace_keywords($keywords=[], $string=[]){ foreach(array_keys($keywords) as $kw){ $string = str_replace('%%%'.$kw.'%%%', trim(str_replace(array('\r', '\n'), NULL, $keywords[$kw])), $string); } return trim($string); } public function delete_all_generated_content(){ $args = array( 'posts_per_page' => -1, 'post_type' => get_post_types(), 'meta_query' => array( array( 'key' => $this->generated_meta, 'value' => '1', 'compare' => '>=', ) ) ); $query = new WP_Query($args); $count=0; $deleted_posts = []; while($query->have_posts()){ $query->the_post(); wp_delete_post(get_the_ID(), true); $count++; array_push($deleted_posts, get_the_ID()); } wp_reset_postdata(); return [ 'count' => $count, 'deleted_ids' => $deleted_posts ]; } public function generate_virtual_content($data=[], $keywords=[]){ $posts_numbers = $this->get_posts_number($data['post_title'], $keywords); $contents = $this->recursive_content_generation($data['post_title'], $keywords, []); $generated_posts = 0; $updated_posts = 0; foreach($contents as $content){ if($generated_posts>$data['limit']) break; $generated_title = $this->replace_keywords($content, $this->spintax->process($content['t'])); if(strlen(trim($generated_title))>=1){ $post_exists = post_exists($generated_title); if($post_exists>=1){ wp_delete_post($post_exists, true); $updated_posts++; } $generated_post = array( 'post_title' => wp_strip_all_tags($generated_title), 'post_content' => $this->replace_keywords($content, $this->spintax->process($data['post_content'])), 'post_status' => 'publish', 'post_parent' => $data['post_parent'], 'post_author' => $data['post_author'], 'post_type' => (isset($data['post_type']) && $this->valid_post_type($data['post_type']) ? $data['post_type'] : $this->default_post_type) ); if(isset($data['post_type']) && isset($data['post_category']) && $data['post_type'] != 'page'){ $generated_post['post_category'] = $data['post_category']; } $id = wp_insert_post($generated_post); if($id){ add_post_meta($id, $this->generated_meta, $data['ID']); $forbidden_keys = [$this->template_meta, '_edit_last', '_edit_lock', '_thumbnail_id']; if(isset($data['meta'])){ foreach($data['meta'] as $key => $value){ if(!in_array($key, $forbidden_keys)){ $v = $this->replace_keywords($content, $this->spintax->process((is_array($value) && isset($value[0]) ? $value[0] : $value))); update_post_meta($id, $key, $v); unset($v); } } } $thumbnail_id = get_post_thumbnail_id($id); if($thumbnail_id && $thumbnail_id>0){ set_post_thumbnail($id, $thumbnail_id); } $generated_posts++; delete_post_meta($id, $this->template_meta); }else{ throw new Exception(__('Un artículo no ha podido ser generado por motivos desconocidos. Abortada generación de contenido.', $this->get_translations())); } } } return ['generated' => $generated_posts, 'updated' => $updated_posts]; } private function valid_post_type($post_type=''): bool{ if(!is_string($post_type) || strlen(trim($post_type))<=0 || (is_string($post_type) && !post_type_exists($post_type))) return false; return ($post_type == 'page' || $post_type == 'post'); } public function generate_content($data=[]){ if(!$this->table_exists){ throw new Exception(__('La tabla de la base de datos para la generación de contenido no está creada.', $this->get_translations())); } $keyword_templates = $this->get_keyword_templates(); if(empty($keyword_templates)){ throw new Exception(__('Es necesario definir las palabras clave antes de generar contenido.', $this->get_translations())); } if(!isset($data['post_type']) || !$this->valid_post_type($data['post_type'])){ throw new Exception(__('Es necesario indicar el tipo de contenido a generar. Se admite 'post' o 'page'.', $this->get_translations())); }else if(!post_type_exists($data['post_type'])){ throw new Exception(__('El tipo de post indicado no existe.', $this->get_translations())); } if(!isset($data['limit']) || !is_numeric($data['limit'])){ $data['limit'] = $this->default_limit; } if(!isset($data['post_title'])){ throw new Exception(__('Es necesario indicar el título que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_title']) || strlen(trim($data['post_title']))==0){ throw new Exception(__('El título indicado no es válido.', $this->get_translations())); }else{ $title_keywords = $this->get_keywords($data['post_title']); if(count($title_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el título.', $this->get_translations())); } } if(!isset($data['post_content'])){ throw new Exception(__('Es necesario el contenido que se utilizará.', $this->get_translations())); }else if(!is_string($data['post_content']) || strlen(trim($data['post_content']))==0){ throw new Exception(__('El contenido indicado para la generación de contenido no es válido. Por favor indica un contenido válido.', $this->get_translations())); }else{ $content_keywords = $this->get_keywords($data['post_content']); if(count($content_keywords) == 0){ throw new Exception(__('No hay ninguna palabra clave indicada en el contenido.', $this->get_translations())); } } $keywords = array_merge($content_keywords, $title_keywords); foreach($keywords as $parent_kw => $k){ if(!in_array($parent_kw, $keyword_templates)){ throw new Exception(sprintf(__('El grupo de palabras clave %s usada en el contenido o título no está registrada en tus plantillas.', $this->get_translations()), esc_html($parent_kw))); } if(count($k) == 0){ throw new Exception(sprintf(__('No hay ninguna palabra clave dentro del grupo %s.', $this->get_translations()), esc_html($k))); } } unset($keywords); return $this->generate_virtual_content($data, $title_keywords); } private function get_post_id($post){ return (is_object($post) ? $post->ID : (is_array($post) ? $post['ID'] : $post)); } private function is_template($post){ $template = get_post_meta($this->get_post_id($post), $this->template_meta, true); return ($template&&(int)$template>=1); } private function is_generated($post){ $generated = get_post_meta($this->get_post_id($post), $this->generated_meta, true); return ($generated&&(int)$generated>=1); } private function get_template($post){ return get_post_meta($this->get_post_id($post), $this->generated_meta, true); } public function hook_post_notices(){ add_action('admin_notices', function(){ if( isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit' && $_GET['post']>0){ if($this->valid_post_type(get_post_type($_GET['post'])) && $this->is_generated($_GET['post'])>0){ echo '<div class='notice notice-warning is-dismissible'><p>'. sprintf(__('Esta página ha sido generada automáticamente desde la plantilla <b><a href='%s' target='_blank'>%s</a></b>.', $this->get_translations()), get_the_permalink($this->get_template($_GET['post'])), get_the_title($this->get_template($_GET['post']))). '</p></div>'; } } }); } public function add_metaboxes(){ add_filter('wp_insert_post_data', function($post, $post_array){ if(isset($post_array['ID']) && $this->is_template($post_array['ID']) && !$this->is_generated($post_array['ID'])){ if($post['post_type'] == 'post' || $post['post_type'] == 'page'){ if($post['post_status'] != 'private') $post['post_status'] = 'private'; } } return $post; }, 10, 2); add_action('admin_head', function(){ if(is_admin() && isset($_GET['post']) && is_numeric($_GET['post']) && $this->is_template($_GET['post'])){ echo '<style>a.edit-visibility{visibility:hidden !important; display:none !important;}</style>'; } }); add_action('load-post.php', function(){ if(is_admin() && isset($_GET['post']) && is_numeric($_GET['post']) && $this->is_template($_GET['post'])){ wp_update_post(['ID' => $_GET['post'], 'post_status' => 'private']); add_action('add_meta_boxes', function(){ add_meta_box( 'warning_content_generator_template', __('¡Advertencia!', $this->get_translations()), function(){ echo '<span id='theme-warning'>'.__('Esta página o entrada es una plantilla para generar contenido.', $this->get_translations()). '<br><br><b>'.__('La visibilidad ha sido marcada como privada.', $this->get_translations(Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 53: </p>'; }, ['post', 'page'], 'normal', 'high'); }); } public function sort_query(){ if(is_admin() && isset($_GET['generated'])){ add_filter('pre_get_posts', function($query){ $query->set('meta_query', [ array( 'key'=>$this->generated_meta, 'value'=>'1', 'compare'=>'>=' ) ]); return $query; }); } } public function add_admin_pages(){ add_action('admin_menu', function(){ add_menu_page( __('Palabras clave', $this->get_translations()), __('Palabras clave', $this->get_translations()), $this->permissions, $this->menu_slug, function(){ ob_start(); if(isset($_POST['create_keyword_group'])){ if(isset($_POST['keyword']) && strlen(trim($_POST['keyword']))>0){ $this->wpdb->insert($this->table, ['keyword' => $_POST['keyword'], 'parent' => 0, 'type' => 0]); wp_redirect(add_query_arg('id', $this->wpdb->insert_id, add_query_arg('page', $this->menu_slug, admin_url('admin.php')))); }else{ echo sprintf('<div class='notice notice-error'><p>%s</p></div>', __('Indica un nombre válido.', $this->get_translations())); } } if(isset($Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 53: </p>'; }, ['post', 'page'], 'normal', 'high'); }); } public function sort_query(){ if(is_admin() && isset($_GET['generated'])){ add_filter('pre_get_posts', function($query){ $query->set('meta_query', [ array( 'key'=>$this->generated_meta, 'value'=>'1', 'compare'=>'>=' ) ]); return $query; }); } } public function add_admin_pages(){ add_action('admin_menu', function(){ add_menu_page( __('Palabras clave', $this->get_translations()), __('Palabras clave', $this->get_translations()), $this->permissions, $this->menu_slug, function(){ ob_start(); if(isset($_POST['create_keyword_group'])){ if(isset($_POST['keyword']) && strlen(trim($_POST['keyword']))>0){ $this->wpdb->insert($this->table, ['keyword' => $_POST['keyword'], 'parent' => 0, 'type' => 0]); wp_redirect(add_query_arg('id', $this->wpdb->insert_id, add_query_arg('page', $this->menu_slug, admin_url('admin.php')))); }else{ echo sprintf('<div class='notice notice-error'><p>%s</p></div>', __('Indica un nombre válido.', $this->get_translations())); } } if(isset($_POST['edit_keywords'])){ echo sprintf('<div class='notice notice-success'><p>%s</p></div>', __('¡Modificaciones guardadas!', $this->get_translations())); } echo '<divPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 55: '.(!isset($_GET['edit']) && !isset($_GET['delete']) ? '<a href=''.add_query_arg('edit', 1, add_query_arg('id', $_GET['id'], add_query_arg('page', $_GET['page'], admin_url('admin.php')))).'' class='page-title-action'>'.__('Editar', $this->get_translations()).'</a>' : NULL).'Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 56: '.(!isset($_GET['edit']) && !isset($_GET['delete']) ? '<a href=''.add_query_arg('delete', 1, add_query_arg('id', $_GET['id'], add_query_arg('page', $_GET['page'], admin_url('admin.php')))).'' class='submitdelete deletion-keyword-group'>'.__('Eliminar grupo', $this->get_translations()).'</a>' : NULL); }else{ echoPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 56: '.(!isset($_GET['edit']) && !isset($_GET['delete']) ? '<a href=''.add_query_arg('delete', 1, add_query_arg('id', $_GET['id'], add_query_arg('page', $_GET['page'], admin_url('admin.php')))).'' class='submitdelete deletion-keyword-group'>'.__('Eliminar grupo', $this->get_translations()).'</a>' : NULL); }else{ echo '<a href=''.add_query_arg('action', $this->create_action, add_query_arg('page', $_GET['page'], admin_url('admin.php'))).'' class='page-title-action'>'.__('Añadir nuevo grupo', $this->get_translations()).'</a>'; } echo '<hr clPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 56: '.(!isset($_GET['edit']) && !isset($_GET['delete']) ? '<a href=''.add_query_arg('delete', 1, add_query_arg('id', $_GET['id'], add_query_arg('page', $_GET['page'], admin_url('admin.php')))).'' class='submitdelete deletion-keyword-group'>'.__('Eliminar grupo', $this->get_translations()).'</a>' : NULL); }else{ echo '<a href=''.add_query_arg('action', $this->create_action, add_query_arg('page', $_GET['page'], admin_url('admin.php'))).'' class='page-title-action'>'.__('Añadir nuevo grupo', $this->get_translations()).'</a>'; } echo '<hr class='wp-header-end'>'; if(isset($_GET['action']) && $_GET['action'] == $this->create_action){ echo '<p>'.__('Introduce un nombre para un grupo de palabras clave. Por ejemplo, CiudaPossible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. 56: '.(!isset($_GET['edit']) && !isset($_GET['delete']) ? '<a href=''.add_query_arg('delete', 1, add_query_arg('id', $_GET['id'], add_query_arg('page', $_GET['page'], admin_url('admin.php')))).'' class='submitdelete deletion-keyword-group'>'.__('Eliminar grupo', $this->get_translations()).'</a>' : NULL); }else{ echo '<a href=''.add_query_arg('action', $this->create_action, add_query_arg('page', $_GET['page'], admin_url('admin.php'))).'' class='page-title-action'>'.__('Añadir nuevo grupo', $this->get_translations()).'</a>'; } echo '<hr class='wp-header-end'>'; if(isset($_GET['action']) && $_GET['action'] == $this->create_action){ echo '<p>'.__('Introduce un nombre para un grupo de palabras clave. Por ejemplo, Ciudad para: Bogotá, Madrid...', $this->get_translations()).'</p>'; }else if(isset($_GET['id']) && isset($_GET['edit'])){ echo '<p>'.__('Introduce las palabras clave que formarán parte de este grupo.<br>Por Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $this found in translation function in content-generator.php. Translation function calls should not contain PHP variables. Possible variable $error found in translation function in functions.php. Translation function calls should not contain PHP variables.
  15. CSS files : Presence of license typeLicense: is missing from style.css header.
  16. CSS files : Presence of license urlLicense URI: is missing from style.css header.
  17. CSS files : Presence of .bypostauthor class.bypostauthor css class is needed in theme css.
  18. CSS files : Presence of .alignleft class.alignleft css class is needed in theme css.
  19. CSS files : Presence of .gallery-caption class.gallery-caption css class is needed in theme css.
  20. CSS files : Presence of .screen-reader-text class.screen-reader-text css class is needed in your theme css. See : the Codex for an example implementation.
  21. Tags : Tags displayThis theme doesn't seem to display tags.
  22. Screenshot : Screenshot fileScreenshot size is 600x450px. Screenshot size should be 1200x900, to account for HiDPI displays. Any 4:3 image size is acceptable, but 1200x900 is preferred.Bad screenshot file extension ! File screenshot.png is not an actual JPG file. Detected type was : "image/png".
Tip-off
  1. Optional files : Presence of rtl stylesheet rtl.cssThis theme does not contain optional file rtl.php.
  2. Optional files : Presence of front page template file front-page.phpThis theme does not contain optional file front-page.php.
  3. Optional files : Presence of tag template file tag.phpThis theme does not contain optional file tag.php.
  4. Optional files : Presence of term template file taxonomy.phpThis theme does not contain optional file taxonomy.php.
  5. Optional files : Presence of author template file author.phpThis theme does not contain optional file author.php.
  6. Optional files : Presence of date/time template file date.phpThis theme does not contain optional file date.php.
  7. Optional files : Presence of archive template file archive.phpThis theme does not contain optional file archive.php.
  8. Optional files : Presence of search results template file search.phpThis theme does not contain optional file search.php.
  9. Optional files : Presence of attachment template file attachment.phpThis theme does not contain optional file attachment.php.
  10. Optional files : Presence of image template file image.phpThis theme does not contain optional file image.php.
  11. Use of includes : Use of include or requireThe theme appears to use include or require : autoload.php 71: include(ABSPATH.'wp-includes/version.php'); If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : GetItems.php 38: require_once(__DIR__ . '/vendor/autoload.php'); // change path as needed If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : GetBrowseNodes.php 38: require_once(__DIR__ . '/vendor/autoload.php'); // change path as needed If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : SearchItems.php 38: require_once(__DIR__ . '/vendor/autoload.php'); // change path as needed If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : GetVariations.php 38: require_once(__DIR__ . '/vendor/autoload.php'); // change path as needed If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : StopwordsPHP.php 113: $stopwords = include($language_file); If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : arr_to_regex.php 53: return require($php_file); If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : de_DE_example.php 7: require '../vendor/autoload.php'; If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : en_US_example.php 7: require '../vendor/autoload.php'; If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : fr_FR_example.php 7: require '../vendor/autoload.php'; If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : es_AR_example.php 7: require '../vendor/autoload.php'; If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : pt_BR_example.php 7: require '../vendor/autoload.php'; If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.The theme appears to use include or require : export.php 12: require 'src/Fixtures/AbstractProvider.php';13: require 'src/Fixtures/Crawlers.php';14: require 'src/Fixtures/Exclusions.php';15: require 'src/Fixtures/Headers.php'; If these are being used to include separate sections of a template from independent files, then get_template_part() should be used instead. Otherwise, use include_once or require_once instead.
Other checked themes