├── README.md ├── .gitignore ├── assets └── components │ └── seopro │ ├── img │ ├── tips.png │ ├── info0.png │ ├── info1.png │ ├── thumb-up.png │ ├── google-logo.jpg │ └── thumb-down.png │ ├── js │ └── mgr │ │ ├── resource.js │ │ └── seopro.js │ ├── connector.php │ └── css │ ├── mgr23.css │ └── mgr.css ├── _packages ├── seopro-1.0.0-pl.transport.zip ├── seopro-1.0.2-pl.transport.zip ├── seopro-1.1.0-pl.transport.zip ├── seopro-1.2.0-pl.transport.zip ├── seopro-1.2.1-pl.transport.zip ├── seopro-1.2.2-pl.transport.zip ├── seopro-1.3.0-pl.transport.zip └── seopro-1.3.1-pl.transport.zip ├── core └── components │ └── seopro │ ├── model │ ├── seopro │ │ ├── seokeywords.class.php │ │ ├── metadata.mysql.php │ │ ├── mysql │ │ │ ├── seokeywords.class.php │ │ │ └── seokeywords.map.inc.php │ │ └── seopro.class.php │ └── schema │ │ └── seopro.mysql.schema.xml │ ├── lexicon │ ├── it │ │ └── default.inc.php │ ├── fr │ │ └── default.inc.php │ ├── ru │ │ └── default.inc.php │ ├── pl │ │ └── default.inc.php │ ├── de │ │ └── default.inc.php │ ├── nl │ │ └── default.inc.php │ └── en │ │ └── default.inc.php │ ├── docs │ ├── readme.txt │ ├── changelog.txt │ └── license.txt │ ├── processors │ └── mgr │ │ └── resource │ │ └── parse.class.php │ └── elements │ └── plugins │ └── seopro.plugin.php └── _build ├── gpm_resolvers └── gpm.resolve.tables.php ├── resolvers ├── setupoptions.resolver.php ├── description.resolver.php ├── stercextra.resolver.php └── tables.resolver.php ├── setup.options.php └── config.json /README.md: -------------------------------------------------------------------------------- 1 | SEOPro is now part of SEO Suite: https://github.com/sterc/seosuite 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _build/build.config.php 2 | config.core.php 3 | .idea 4 | .settings 5 | nbproject 6 | .project -------------------------------------------------------------------------------- /assets/components/seopro/img/tips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/assets/components/seopro/img/tips.png -------------------------------------------------------------------------------- /_packages/seopro-1.0.0-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.0.0-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.0.2-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.0.2-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.1.0-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.1.0-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.2.0-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.2.0-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.2.1-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.2.1-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.2.2-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.2.2-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.3.0-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.3.0-pl.transport.zip -------------------------------------------------------------------------------- /_packages/seopro-1.3.1-pl.transport.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/_packages/seopro-1.3.1-pl.transport.zip -------------------------------------------------------------------------------- /assets/components/seopro/img/info0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/assets/components/seopro/img/info0.png -------------------------------------------------------------------------------- /assets/components/seopro/img/info1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/assets/components/seopro/img/info1.png -------------------------------------------------------------------------------- /assets/components/seopro/img/thumb-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/assets/components/seopro/img/thumb-up.png -------------------------------------------------------------------------------- /assets/components/seopro/img/google-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/assets/components/seopro/img/google-logo.jpg -------------------------------------------------------------------------------- /assets/components/seopro/img/thumb-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sterc/SEOPro/HEAD/assets/components/seopro/img/thumb-down.png -------------------------------------------------------------------------------- /core/components/seopro/model/seopro/seokeywords.class.php: -------------------------------------------------------------------------------- 1 | 5 | array ( 6 | 0 => 'seoKeywords', 7 | ), 8 | ); -------------------------------------------------------------------------------- /core/components/seopro/model/seopro/mysql/seokeywords.class.php: -------------------------------------------------------------------------------- 1 | Please enter a description'; 12 | $_lang['seopro.branding_text']='This site is optimized with the Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 13 | -------------------------------------------------------------------------------- /core/components/seopro/model/schema/seopro.mysql.schema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /core/components/seopro/lexicon/fr/default.inc.php: -------------------------------------------------------------------------------- 1 | Remplissez la description avant de prévisualiser'; 11 | $_lang['seopro.branding_text']='This site is optimized with the Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 12 | 13 | $_lang['setting_seopro.delimiter'] = 'Séparateur dans Google/Yandex preview.'; 14 | $_lang['setting_seopro.delimiter_desc'] = 'Séparateur de titre et de nom de site'; 15 | -------------------------------------------------------------------------------- /_build/gpm_resolvers/gpm.resolve.tables.php: -------------------------------------------------------------------------------- 1 | xpdo) { 16 | $modx =& $object->xpdo; 17 | switch ($options[xPDOTransport::PACKAGE_ACTION]) { 18 | case xPDOTransport::ACTION_INSTALL: 19 | case xPDOTransport::ACTION_UPGRADE: 20 | $modelPath = $modx->getOption('seopro.core_path', null, $modx->getOption('core_path') . 'components/seopro/') . 'model/'; 21 | 22 | $modx->addPackage('seopro', $modelPath, null); 23 | 24 | 25 | 26 | $manager = $modx->getManager(); 27 | 28 | $manager->createObjectContainer('seoKeywords'); 29 | 30 | 31 | break; 32 | } 33 | } 34 | 35 | return true; -------------------------------------------------------------------------------- /core/components/seopro/docs/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------- 2 | SEO Pro 3 | -------------------- 4 | Version: 1.3.1-pl 5 | Author: Sterc 6 | -------------------- 7 | 8 | SEO Pro is a MODX Extra developed by Sterc. This Extra offers you guidance in the process of optimising your website for search engines. It enables you to enter focus keywords per page. Based on that input, SEO Pro provides you feedback on the SEO quality of your pagetitle, longtitle, description and alias by checking if the keywords are present. 9 | 10 | Workflow: 11 | 1. Pick a page on your MODX website which you would like to optimise for search engines and click it. 12 | 2. Look for the field called 'Focus keywords'. Enter the keywords you would like to optimise your page for. 13 | 3. Take a look at the input fields with a 'Keywords' label. Make s ure keywords are present here and you don't exceed the given length. 14 | 4. Save it. 15 | 16 | Issues can be added on github.com/sterc/seopro 17 | -------------------------------------------------------------------------------- /core/components/seopro/lexicon/ru/default.inc.php: -------------------------------------------------------------------------------- 1 | Для предварительного просмотра заполните поле Описание'; 11 | $_lang['seopro.branding_text']='This site is optimized with the Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 12 | 13 | $_lang['setting_seopro.delimiter'] = 'Разделитель в сниппете Google/Yandex'; 14 | $_lang['setting_seopro.delimiter_desc'] = 'Разделитель между Заголовком и Названием сайта'; 15 | $_lang['setting_seopro.title_format'] ='Format used for the meta title.'; 16 | $_lang['setting_seopro.title_format_desc'] ='Here you can specify the format used for the meta title used 17 | in Google/Yandex preview. The rendered output is also available on frontend with [[+seoPro.title]].'; 18 | -------------------------------------------------------------------------------- /core/components/seopro/processors/mgr/resource/parse.class.php: -------------------------------------------------------------------------------- 1 | getProperty('html'); 16 | $resourceId = $this->getProperty('id'); 17 | $resource = $this->modx->newObject('modResource'); 18 | $resource->set('pagetitle', $this->getProperty('pagetitle')); 19 | $resource->set('longtitle', $this->getProperty('longtitle')); 20 | if ($resource) { 21 | $this->modx->resource = $resource; 22 | $maxIterations = (int)$this->modx->getOption('parser_max_iterations', null, 10); 23 | if (!$this->modx->parser) { 24 | $this->modx->getParser(); 25 | } 26 | $this->modx->parser->processElementTags('', $html, true, false, '[[', ']]', array(), $maxIterations); 27 | $this->modx->parser->processElementTags('', $html, true, true, '[[', ']]', array(), $maxIterations); 28 | } 29 | 30 | return $this->outputArray(array('id' => $resourceId, 'output' => $html), 0); 31 | } 32 | 33 | } 34 | return 'seoProParseResourceProcessor'; 35 | -------------------------------------------------------------------------------- /_build/resolvers/setupoptions.resolver.php: -------------------------------------------------------------------------------- 1 | xpdo->getObject( 21 | 'modSystemSetting', 22 | array('key' => strtolower($package) . '.' . $key) 23 | ); 24 | 25 | if ($settingObject) { 26 | $settingObject->set('value', $options[$key]); 27 | $settingObject->save(); 28 | } else { 29 | $error = '[' . $package . '] ' . strtolower($package) . '.' . $key . ' setting could not be found,'; 30 | $error .= ' so the setting could not be changed.'; 31 | 32 | $object->xpdo->log( 33 | xPDO::LOG_LEVEL_ERROR, 34 | $error 35 | ); 36 | } 37 | } 38 | } 39 | 40 | $success = true; 41 | break; 42 | case xPDOTransport::ACTION_UNINSTALL: 43 | $success = true; 44 | break; 45 | } 46 | 47 | return $success; 48 | -------------------------------------------------------------------------------- /assets/components/seopro/connector.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * seoPro is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU General Public License as published by the Free Software 9 | * Foundation; either version 2 of the License, or (at your option) any later 10 | * version. 11 | * 12 | * seoPro is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 14 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * seoPro; if not, write to the Free Software Foundation, Inc., 59 Temple 18 | * Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * @package seopro 21 | */ 22 | /** 23 | * seoPro Connector 24 | * 25 | * @package seopro 26 | */ 27 | require_once dirname(dirname(dirname(dirname(__FILE__)))).'/config.core.php'; 28 | require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php'; 29 | require_once MODX_CONNECTORS_PATH.'index.php'; 30 | 31 | $corePath = $modx->getOption('seopro.core_path',null,$modx->getOption('core_path').'components/seopro/'); 32 | require_once $corePath.'model/seopro/seopro.class.php'; 33 | $modx->seopro = new seoPro($modx); 34 | 35 | $modx->lexicon->load('seopro:default'); 36 | 37 | /* handle request */ 38 | $path = $modx->getOption('processorsPath',$modx->seopro->config,$corePath.'processors/'); 39 | $modx->request->handleRequest(array( 40 | 'processors_path' => $path, 41 | 'location' => '', 42 | )); -------------------------------------------------------------------------------- /core/components/seopro/model/seopro/mysql/seokeywords.map.inc.php: -------------------------------------------------------------------------------- 1 | 'seopro', 7 | 'version' => NULL, 8 | 'table' => 'seopro_keywords', 9 | 'extends' => 'xPDOSimpleObject', 10 | 'tableMeta' => array( 11 | 'engine' => 'InnoDB', 12 | ), 13 | 'fields' => array( 14 | 'resource' => 0, 15 | 'keywords' => '', 16 | ), 17 | 'fieldMeta' => array( 18 | 'resource' => array( 19 | 'dbtype' => 'integer', 20 | 'precision' => '10', 21 | 'phptype' => 'int', 22 | 'null' => false, 23 | 'default' => 0, 24 | 'index' => 'index', 25 | ), 26 | 'keywords' => array( 27 | 'dbtype' => 'text', 28 | 'phptype' => 'string', 29 | 'null' => true, 30 | 'default' => '', 31 | ), 32 | ), 33 | 'indexes' => array( 34 | 'resource' => array( 35 | 'alias' => 'resource', 36 | 'primary' => false, 37 | 'unique' => false, 38 | 'type' => 'BTREE', 39 | 'columns' => array( 40 | 'resource' => array( 41 | 'length' => '', 42 | 'collation' => 'A', 43 | 'null' => false, 44 | ), 45 | ), 46 | ), 47 | ), 48 | 'aggregates' => array( 49 | 'Resource' => array( 50 | 'class' => 'modResource', 51 | 'local' => 'resource', 52 | 'foreign' => 'id', 53 | 'cardinality' => 'one', 54 | 'owner' => 'foreign', 55 | ), 56 | ), 57 | ); 58 | -------------------------------------------------------------------------------- /core/components/seopro/lexicon/pl/default.inc.php: -------------------------------------------------------------------------------- 1 | Wprowadź opis aby zobaczyć podgląd'; 11 | $_lang['seopro.branding_text']='This site is optimized with the Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 12 | 13 | $_lang['setting_seopro.delimiter'] = 'Separator'; 14 | $_lang['setting_seopro.delimiter_desc'] = 'Separator pomiędzy title i sitename'; 15 | $_lang['setting_seopro.fields'] = 'Pola na których będzie operować SEO Pro'; 16 | $_lang['setting_seopro.fields_desc'] = 'Modyfikuj ustawienie tylko jeśli wiesz co robisz. Domyślna wartość:pagetitle,longtitle,description,alias,menutitle. Nie działa dla pola content.'; 17 | $_lang['setting_seopro.version'] ='Numer wersji'; 18 | $_lang['setting_seopro.version_desc']= 'Bieżąca '.$_lang['setting_seopro.version']; 19 | $_lang['setting_seopro.allowbranding'] ='Pozwól na branding Sterc w kodzie strony'; 20 | $_lang['setting_seopro.allowbranding_desc']= 'Zezwól na link do naszej strony ukryty w komentarzu HTML'; 21 | $_lang['setting_seopro.usesitename'] ='Pokaż sitename w [[+seoPro.title]] oraz w podglądzie Google?'; 22 | $_lang['setting_seopro.usesitename_desc']= 'Wartość NO oznacza usunięcie sitename z [[+seoPro.title]] i podglądu Google'; 23 | $_lang['setting_seopro.title_format'] ='Format used for the meta title.'; 24 | $_lang['setting_seopro.title_format_desc'] ='Here you can specify the format used for the meta title used 25 | in Google/Yandex preview. The rendered output is also available on frontend with [[+seoPro.title]].'; 26 | -------------------------------------------------------------------------------- /_build/setup.options.php: -------------------------------------------------------------------------------- 1 | 'user_name', 13 | 'value' => '', 14 | 'name' => 'Name' 15 | ), 16 | array( 17 | 'key' => 'user_email', 18 | 'value' => '', 19 | 'name' => 'Email address' 20 | ), 21 | ); 22 | switch ($options[xPDOTransport::PACKAGE_ACTION]) { 23 | case xPDOTransport::ACTION_INSTALL: 24 | case xPDOTransport::ACTION_UPGRADE: 25 | foreach ($settings as $key => $setting) { 26 | $settingObject = $modx->getObject( 27 | 'modSystemSetting', 28 | array('key' => strtolower($package) . '.' . $setting['key']) 29 | ); 30 | if ($settingObject) { 31 | $settings[$key]['value'] = $settingObject->get('value'); 32 | } 33 | } 34 | break; 35 | case xPDOTransport::ACTION_UNINSTALL: 36 | break; 37 | } 38 | 39 | /* Hide default setuptoptions text */ 40 | $output[] = ' 41 | 44 | 45 | 49 | 50 |

Get free priority updates

51 |

Enter your name and email address below to receive priority updates about our extras. 52 | Be the first to know about updates and new features. 53 | It is NOT required to enter your name and email to use this extra.

'; 54 | 55 | foreach ($settings as $setting) { 56 | $str = ''; 57 | $str .= ''; 59 | 60 | $output[] = $str; 61 | } 62 | 63 | return implode('

', $output); 64 | -------------------------------------------------------------------------------- /_build/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "seoPro", 3 | "lowCaseName": "seopro", 4 | "description": "MODX SEO Pro is a MODX package that helps you when performing Search Engine Optimization (SEO) in MODX.", 5 | "author": "Sterc", 6 | "version": "1.3.1-pl", 7 | "package":{ 8 | "elements": { 9 | "plugins": [{ 10 | "name": "seoPro", 11 | "description": "SEO optimizing plugin for MODx Revolution.", 12 | "file": "seopro.plugin.php", 13 | "events": [ 14 | "OnMODXInit", 15 | "OnDocFormRender", 16 | "OnDocFormSave", 17 | "OnResourceDuplicate", 18 | "OnLoadWebDocument" 19 | ] 20 | }], 21 | "snippets": [], 22 | "chunks": [], 23 | "templates": [], 24 | "tvs": [] 25 | }, 26 | "systemSettings": [{ 27 | "key": "delimiter", 28 | "value": "|", 29 | "area": "general" 30 | },{ 31 | "key": "fields", 32 | "value": "pagetitle:70,longtitle:70,description:320,alias:2023,menutitle:2023", 33 | "area": "general" 34 | },{ 35 | "key": "usesitename", 36 | "type": "combo-boolean", 37 | "value": "1", 38 | "area": "general" 39 | },{ 40 | "key": "title_format", 41 | "area": "general" 42 | },{ 43 | "key": "disabledtemplates", 44 | "value": "", 45 | "area": "general" 46 | },{ 47 | "key": "max_keywords_title", 48 | "value": "4", 49 | "area": "general" 50 | },{ 51 | "key": "max_keywords_description", 52 | "value": "8", 53 | "area": "general" 54 | },{ 55 | "key": "searchengine", 56 | "value": "google", 57 | "area": "general" 58 | },{ 59 | "key": "user_name", 60 | "type": "textfield", 61 | "area": "general", 62 | "value": "" 63 | }, { 64 | "key": "user_email", 65 | "type": "textfield", 66 | "area": "general", 67 | "value": "" 68 | }] 69 | }, 70 | "database": { 71 | "tables": ["seoKeywords"] 72 | }, 73 | "build":{ 74 | "resolver": { 75 | "after": [ 76 | "setupoptions.resolver.php", 77 | "description.resolver.php", 78 | "tables.resolver.php", 79 | "stercextra.resolver.php" 80 | ] 81 | }, 82 | "setupOptions":{ 83 | "source": "setup.options.php" 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /core/components/seopro/docs/changelog.txt: -------------------------------------------------------------------------------- 1 | Changelog for SEO Pro. 2 | 3 | SEO Pro 1.3.1 pl 4 | ============== 5 | - Added an index for resource-field. 6 | 7 | SEO Pro 1.3.0 pl 8 | ============== 9 | - Change type of modResource.description to be "text" instead of "varchar". (#74) 10 | - Small code improvements. 11 | - Fix error on PHP 7.2 not correctly saving keywords. (#73) 12 | 13 | SEO Pro 1.2.2 pl 14 | ============== 15 | - Add count back to pagetitle & longtitle 16 | 17 | SEO Pro 1.2.1 pl 18 | ============== 19 | - Set correct preview url for multi-context environments 20 | 21 | SEO Pro 1.2.0 pl 22 | ============== 23 | - Remove the SEO Pro branding HTML comment 24 | - Add system setting for specifying the title format 25 | - Update counters to set correct value based on title format setting 26 | 27 | SEO Pro 1.1.0 pl 28 | ============== 29 | - Removed template request parameter for OnLoadWebDocument system event 30 | - Fixed resource/create processor error when creating resource without $data['keywords'] set (PR#56) 31 | - Add build config for GPM 32 | - Add lexicon for branding text 33 | - Fix character count in pagetitle/longtitle to include site_name according to system setting 'usesitename' (#48 and #57) 34 | - Allow plugin to fire on new resource, when template is default_template (#58) 35 | - Refactor assigning and checking of template resource/request variable (#58 and #59) 36 | - Add system settings for max amount keywords for title/description (#51) 37 | - Add keyword counter to Keywords labels on title/description (#51) 38 | - Add support for Yandex (via system settings) 39 | - Add tooltip to focus keywords field (#52) 40 | 41 | seoPro 1.0.4 pl 42 | ============== 43 | - Saving keywords on save #29 44 | - FIX #39 alias error on homepage (friendly urls) @bartholomej 45 | - Added seopro.disabledtemplates option @Jako 46 | 47 | seoPro 1.0.3 pl 48 | ============== 49 | - Fixed keyword count to work also with Cyrillic 50 | - Fixed empty NOT NULL field resource to NULL 51 | - Added styles for MODX 2.3, thanks to christianseel 52 | 53 | seoPro 1.0.2 pl 54 | ============== 55 | - Added system setting for to enabled/disabled sitename in preview and seoPro.title placeholder 56 | 57 | 58 | seoPro 1.0.0 pl 59 | ============== 60 | - Initial Public Release 61 | - Added several lexicons 62 | -- Special thanks to 63 | --- DE: Christian Seel 64 | --- FR: Romain Tripault 65 | --- IT: Alberto Rossi 66 | --- RU: Ilya Ershov 67 | - Added system setting for divider 68 | - Added system setting for field where seoPro should trigger on. 69 | -------------------------------------------------------------------------------- /core/components/seopro/model/seopro/seopro.class.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * seoPro is free software; you can redistribute it and/or modify it under the 8 | * terms of the GNU General Public License as published by the Free Software 9 | * Foundation; either version 2 of the License, or (at your option) any later 10 | * version. 11 | * 12 | * seoPro is distributed in the hope that it will be useful, but WITHOUT ANY 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 14 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along with 17 | * seoPro; if not, write to the Free Software Foundation, Inc., 59 Temple 18 | * Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * @package seopro 21 | */ 22 | /** 23 | * The base class for seoPro. 24 | * 25 | * @package seopro 26 | */ 27 | class seoPro { 28 | /** @var \modX $modx */ 29 | public $modx; 30 | /** @var array $config */ 31 | public $config = array(); 32 | /** @var array $chunks */ 33 | public $chunks = array(); 34 | 35 | function __construct(modX &$modx,array $config = array()) { 36 | $this->modx =& $modx; 37 | 38 | $corePath = $this->modx->getOption('seopro.core_path',$config,$this->modx->getOption('core_path').'components/seopro/'); 39 | $assetsUrl = $this->modx->getOption('seopro.assets_url',$config,$this->modx->getOption('assets_url').'components/seopro/'); 40 | $connectorUrl = $assetsUrl.'connector.php'; 41 | 42 | $this->config = array_merge(array( 43 | 'assetsUrl' => $assetsUrl, 44 | 'cssUrl' => $assetsUrl.'css/', 45 | 'jsUrl' => $assetsUrl.'js/', 46 | 'imagesUrl' => $assetsUrl.'images/', 47 | 48 | 'connectorUrl' => $connectorUrl, 49 | 50 | 'corePath' => $corePath, 51 | 'modelPath' => $corePath.'model/', 52 | 'chunksPath' => $corePath.'elements/chunks/', 53 | 'chunkSuffix' => '.chunk.tpl', 54 | 'snippetsPath' => $corePath.'elements/snippets/', 55 | 'processorsPath' => $corePath.'processors/', 56 | 'templatesPath' => $corePath.'templates/', 57 | ),$config); 58 | 59 | $this->modx->addPackage('seopro',$this->config['modelPath']); 60 | $this->modx->lexicon->load('seopro:default'); 61 | } 62 | } -------------------------------------------------------------------------------- /_build/resolvers/description.resolver.php: -------------------------------------------------------------------------------- 1 | xpdo) { 14 | $modx =& $transport->xpdo; 15 | $version = $modx->getVersionData(); 16 | $version = (int)($version['version'] . $version['major_version']); 17 | 18 | if ($version < 27) { 19 | $table = $modx->getTableName('modResource'); 20 | switch ($options[xPDOTransport::PACKAGE_ACTION]) { 21 | case xPDOTransport::ACTION_INSTALL: 22 | case xPDOTransport::ACTION_UPGRADE: 23 | $c = $modx->prepare("SHOW COLUMNS IN {$table} WHERE Field = 'description';"); 24 | if ($c->execute() && $data = $c->fetch(PDO::FETCH_ASSOC)) { 25 | if (stripos($data['Type'], 'varchar') === 0) { 26 | $c = $modx->prepare("ALTER TABLE {$table} CHANGE `description` `description` TEXT;"); 27 | $c->execute(); 28 | } 29 | } 30 | break; 31 | 32 | case xPDOTransport::ACTION_UNINSTALL: 33 | $c = $modx->prepare("SHOW COLUMNS IN {$table} WHERE Field = 'description';"); 34 | if ($c->execute() && $data = $c->fetch(PDO::FETCH_ASSOC)) { 35 | if ($data['Type'] == 'text') { 36 | $length = 255; 37 | $schema = MODX_CORE_PATH . 'model/schema/modx.mysql.schema.xml'; 38 | if (is_file($schema)) { 39 | if ($schema = new SimpleXMLElement($schema, 0, true)) { 40 | foreach ($schema->object as $obj) { 41 | if ((string)$obj['class'] == 'modResource') { 42 | foreach ($obj->field as $field) { 43 | if ((string)$field['key'] == 'description') { 44 | $length = (string)$field['precision']; 45 | } 46 | } 47 | } 48 | } 49 | } 50 | unset($schema); 51 | } 52 | $modx->prepare("ALTER TABLE {$table} CHANGE `description` `description` VARCHAR({$length});") 53 | ->execute(); 54 | } 55 | } 56 | break; 57 | } 58 | } 59 | } 60 | 61 | return true; -------------------------------------------------------------------------------- /core/components/seopro/lexicon/de/default.inc.php: -------------------------------------------------------------------------------- 1 | Bitte geben Sie eine Beschreibung ein.'; 11 | $_lang['seopro.branding_text']='This site is optimized with the Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 12 | 13 | $_lang['setting_seopro.delimiter'] = 'Trennzeichen in Google-Vorschau'; 14 | $_lang['setting_seopro.delimiter_desc'] = 'Trennzeichen zwischen Titel und Seitenname'; 15 | $_lang['setting_seopro.fields'] = 'SEO Pro Felder'; 16 | $_lang['setting_seopro.fields_desc'] = 'Ändern Sie diese Einstellung nur, wenn Sie genau wissen, was Sie tun. Standard-Felder: pagetitle:70,longtitle:70,description:155,alias:2023,menutitle:2023. SEO Pro funktioniert nicht für das Content-Feld.'; 17 | $_lang['setting_seopro.version'] ='Versionsnummer'; 18 | $_lang['setting_seopro.version_desc']= 'Aktuelle '.$_lang['setting_seopro.version']; 19 | $_lang['setting_seopro.allowbranding'] ='Sterc Branding im Head erlauben'; 20 | $_lang['setting_seopro.allowbranding_desc']= 'Give us some love...'; 21 | $_lang['setting_seopro.usesitename'] ='site_name im Titel verwenden?'; 22 | $_lang['setting_seopro.usesitename_desc']= 'Wenn Sie NEIN auswählen wird der site_name und das Trennzeichen aus der Vorschau und dem SEO Pro Platzhalter ([[+seoPro.title]]) entfernt.'; 23 | $_lang['setting_seopro.disabledtemplates'] ='Deaktivierte Templates'; 24 | $_lang['setting_seopro.disabledtemplates_desc']= 'Komma getrennte Liste der deaktivierten Template-IDs'; 25 | $_lang['setting_seopro.max_keywords_title'] ='Maximale Anzahl von Fokus-Keywords im Titel erlaubt.'; 26 | $_lang['setting_seopro.max_keywords_title_desc'] ='Use this setting to control the maximum amount of focus keywords that are allowed in the title to get a thumbs-up. 27 | It is advised to use no more than 4 keywords in your title.'; 28 | $_lang['setting_seopro.max_keywords_description'] ='Maximale Anzahl von Fokus-Keywords im description erlaubt.'; 29 | $_lang['setting_seopro.max_keywords_description_desc'] ='Use this setting to control the maximum amount of focus keywords that are allowed in the description to get a thumbs-up. 30 | It is advised to use no more than 8 keywords in your description.'; 31 | $_lang['setting_seopro.searchengine'] ='Suchmaschine für die Vorschau verwendet.'; 32 | $_lang['setting_seopro.searchengine_desc'] ='Mögliche Werte: google, yandex.'; 33 | $_lang['setting_seopro.title_format'] ='Format used for the meta title.'; 34 | $_lang['setting_seopro.title_format_desc'] ='Here you can specify the format used for the meta title used 35 | in Google/Yandex preview. The rendered output is also available on frontend with [[+seoPro.title]].'; -------------------------------------------------------------------------------- /core/components/seopro/lexicon/nl/default.inc.php: -------------------------------------------------------------------------------- 1 | Vul een omschrijving in'; 11 | $_lang['seopro.branding_text']='Deze website is geoptimaliseerd met de Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 12 | 13 | $_lang['setting_seopro.delimiter'] = 'Scheidingsteken in Google/Yandex preview.'; 14 | $_lang['setting_seopro.delimiter_desc'] = 'Scheidingsteken tussen titel en sitenaam'; 15 | $_lang['setting_seopro.fields'] = 'Velden waarop SEO Pro zal werken '; 16 | $_lang['setting_seopro.fields_desc'] = 'Verander deze gegevens alleen als je weet wat je doet. Standaard waarde:pagetitle,longtitle,description,alias,menutitle. SEO Pro werkt niet op het content veld'; 17 | $_lang['setting_seopro.version'] ='Versie nummer'; 18 | $_lang['setting_seopro.version_desc']= 'Huidige '.$_lang['setting_seopro.version']; 19 | $_lang['setting_seopro.allowbranding'] ='Toestaan van Sterc branding in de <head>'; 20 | $_lang['setting_seopro.allowbranding_desc']= 'Give us some love...'; 21 | $_lang['setting_seopro.usesitename'] ='Site naam tonen in Google/Yandex Preview en in de SEO Pro title placeholder [[+seoPro.title]]?'; 22 | $_lang['setting_seopro.usesitename_desc']= 'Als deze op \'nee\' staat wordt het scheidingsteken en de sitenaam niet getoond.'; 23 | $_lang['setting_seopro.disabledtemplates'] ='Niet-gebruikte templates'; 24 | $_lang['setting_seopro.disabledtemplates_desc']= 'Komma gescheiden lijst met template ID\'s waar SEO Pro niet getoond wordt.'; 25 | $_lang['setting_seopro.max_keywords_title'] ='Maximaal aantal focus keywords toegestaan in titel.'; 26 | $_lang['setting_seopro.max_keywords_title_desc'] ='Vul hier het maximaal aantal toegestane focus keywords voor de titel om een thumbs-up te krijgen. 27 | We adviseren om niet meer dan 4 keywords in de titel te gebruiken.'; 28 | $_lang['setting_seopro.max_keywords_description'] ='Maximaal aantal focus keywords toegestaan in omschrijving.'; 29 | $_lang['setting_seopro.max_keywords_description_desc'] ='Vul hier het maximaal aantal toegestane focus keywords voor de omschrijving om een thumbs-up te krijgen. 30 | We adviseren om niet meer dan 8 keywords in de omschrijving te gebruiken.'; 31 | $_lang['setting_seopro.searchengine'] ='Welke zoekmachine gebruiken in de preview'; 32 | $_lang['setting_seopro.searchengine_desc'] ='Mogelijke waarden: google, yandex.'; 33 | $_lang['setting_seopro.title_format'] ='Format used for the meta title.'; 34 | $_lang['setting_seopro.title_format_desc'] ='Here you can specify the format used for the meta title used 35 | in Google/Yandex preview. The rendered output is also available on frontend with [[+seoPro.title]].'; 36 | -------------------------------------------------------------------------------- /core/components/seopro/lexicon/en/default.inc.php: -------------------------------------------------------------------------------- 1 | Please enter a description'; 11 | $_lang['seopro.branding_text']='This site is optimized with the Sterc seoPro plugin - https://github.com/Sterc/SEOPro.'; 12 | 13 | $_lang['setting_seopro.delimiter'] = 'Delimiter in Google/Yandex Preview.'; 14 | $_lang['setting_seopro.delimiter_desc'] = 'Delimiter between Title and Sitename'; 15 | $_lang['setting_seopro.fields'] = 'Fields where SEO Pro will work on'; 16 | $_lang['setting_seopro.fields_desc'] = 'Only change these if you know what you\'re doing. Default value:pagetitle,longtitle,description,alias,menutitle. Will not work on the content field'; 17 | $_lang['setting_seopro.version'] ='Version number'; 18 | $_lang['setting_seopro.version_desc']= 'Current '.$_lang['setting_seopro.version']; 19 | $_lang['setting_seopro.allowbranding'] ='Allow Sterc branding in the <head>'; 20 | $_lang['setting_seopro.allowbranding_desc']= 'Show us some love ;x'; 21 | $_lang['setting_seopro.usesitename'] ='Display sitename in the Google/Yandex Preview and add it to the SEO Pro title placeholder [[+seoPro.title]]?'; 22 | $_lang['setting_seopro.usesitename_desc']= 'If this value is \'no\' the delimiter and sitename setting will be removed from the Google Preview AND SEO Pro title placeholder'; 23 | $_lang['setting_seopro.disabledtemplates'] ='Disabled Templates'; 24 | $_lang['setting_seopro.disabledtemplates_desc']= 'Comma separated list of disabled template IDs'; 25 | $_lang['setting_seopro.max_keywords_title'] ='Max amount of focus keywords allowed in title.'; 26 | $_lang['setting_seopro.max_keywords_title_desc'] ='Use this setting to control the maximum amount of focus keywords that are allowed in the title to get a thumbs-up. 27 | It is advised to use no more than 4 keywords in your title.'; 28 | $_lang['setting_seopro.max_keywords_description'] ='Max amount of focus keywords allowed in description.'; 29 | $_lang['setting_seopro.max_keywords_description_desc'] ='Use this setting to control the maximum amount of focus keywords that are allowed in the description to get a thumbs-up. 30 | It is advised to use no more than 8 keywords in your description.'; 31 | $_lang['setting_seopro.searchengine'] ='Search engine used for the preview.'; 32 | $_lang['setting_seopro.searchengine_desc'] ='Possible values: google, yandex. Defaults to google.'; 33 | $_lang['setting_seopro.title_format'] ='Format used for the meta title.'; 34 | $_lang['setting_seopro.title_format_desc'] ='Here you can specify the format for the meta title used 35 | in Google/Yandex preview. The rendered output is also available on frontend with [[+seoPro.title]].'; 36 | -------------------------------------------------------------------------------- /assets/components/seopro/css/mgr23.css: -------------------------------------------------------------------------------- 1 | .seopro-panel{ 2 | background-color: #fff; 3 | border: #e4e4e4 1px solid; 4 | border-radius: 2px; 5 | padding: 2px 3px; 6 | } 7 | .seopro-counter{ 8 | position: absolute; 9 | z-index: 2; 10 | top: -22px; 11 | right: 0; 12 | text-align: right; 13 | font-size: 12px; 14 | line-height: 20px; 15 | display: block; 16 | } 17 | .seopro-counter-wrap{ 18 | background: #FBFBFB; 19 | border: 1px #e4e4e4 solid; 20 | border-bottom: none; 21 | text-align: center; 22 | border-radius: 8px 8px 0 0; 23 | padding: 4px 11px 0 14px; 24 | line-height: 18px; 25 | float: left; 26 | margin-left: 5px; 27 | display: block; 28 | } 29 | 30 | #modx-resource-pagetitle, #modx-resource-longtitle, #modx-resource-description, #modx-resource-alias, #modx-resource-menutitle { 31 | border-top-right-radius: 0; 32 | } 33 | 34 | .x-form-focus + .seopro-counter .seopro-counter-wrap{ 35 | background-color: #FBFBFB; 36 | border-color: #2d86b7; 37 | border-bottom-color: #FBFBFB; 38 | } 39 | 40 | .x-form-invalid + .seopro-counter .seopro-counter-wrap{ 41 | border-color: #be0000 !important; 42 | } 43 | 44 | .x-form-item.x-tab-item{ 45 | position: relative; 46 | } 47 | #seopro-google-logo{ 48 | text-align: center; 49 | } 50 | #seopro-google-logo img{ 51 | width: 70%; 52 | } 53 | .x-form-label-top .x-form-item { 54 | margin-top: 3px; 55 | } 56 | #seopro-google-title { 57 | color: #1A0DAB; 58 | font-size: 18px; 59 | white-space: nowrap; 60 | width: 520px; 61 | font-family: Arial, Helvetica, sans-serif; 62 | text-overflow: ellipsis; 63 | overflow: hidden; 64 | background-repeat: no-repeat; 65 | background-size: 0; 66 | } 67 | #seopro-google-title.yandex { 68 | color: #00c; 69 | padding-left: 20px; 70 | background-position: 0 4px; 71 | background-size: auto; 72 | } 73 | 74 | #seopro-google-url{ 75 | color: #006621; 76 | margin-bottom: 1px; 77 | } 78 | #seopro-google-url.yandex { 79 | color: #070; 80 | padding-left: 20px; 81 | } 82 | 83 | #seopro-google-description{ 84 | font-size: 13px; 85 | color: #545454; 86 | line-height: 1.4; 87 | word-wrap: break-word; 88 | font-family: arial, sans-serif; 89 | } 90 | #seopro-google-description.yandex { 91 | padding-left: 20px; 92 | } 93 | 94 | .seopro-counter .green{ 95 | color: #919191 !important; 96 | } 97 | .seopro-counter .red{ 98 | color: #707070 !important; 99 | } 100 | .seopro-counter-keywords.green{ 101 | background: url(../img/thumb-up.png) no-repeat 10px 3px #FBFBFB; 102 | } 103 | .seopro-counter-keywords.red{ 104 | background: url(../img/thumb-down.png) no-repeat 10px 4px #FBFBFB; 105 | } 106 | #seopro-resource-alias .seopro-counter-chars, #seopro-resource-menutitle .seopro-counter-chars{ 107 | display: none; 108 | } 109 | .seopro-counter-keywords{ 110 | padding-left: 30px; 111 | } 112 | .x-btn-seopro button{ 113 | /* background-image: url(../img/tips.png); 114 | background-position: 0px 0px !important;*/ 115 | color:#ccc !important; 116 | text-shadow:0 1px -1px #111 !important; 117 | } 118 | .x-btn-seopro button:hover{ 119 | color: #f2f2f2 !important; 120 | } 121 | .x-btn-seopro{ 122 | background:-webkit-gradient( linear,left bottom,left top,color-stop(0.32,#555),color-stop(0.69,#666),color-stop(0,#555) ); 123 | border:1px solid #1E1E1E; 124 | margin-left: 10px; 125 | } 126 | .seopro-counter-chars.red { 127 | color: #D80000 !important; 128 | } 129 | 130 | .seopro-counter .current { 131 | text-align: right; 132 | margin-right: 1px; 133 | display: inline-block; 134 | width: 21px; 135 | } 136 | 137 | .seopro-counter .allowed { 138 | width: 21px; 139 | display: inline-block; 140 | text-align: left; 141 | } 142 | -------------------------------------------------------------------------------- /assets/components/seopro/css/mgr.css: -------------------------------------------------------------------------------- 1 | .seopro-panel{ 2 | background-color: #FBFBFB; 3 | border: #CCC 1px solid; 4 | border-radius: 2px; 5 | padding: 2px 3px; 6 | } 7 | .seopro-counter{ 8 | position: absolute; 9 | z-index: 2; 10 | top: -21px; 11 | right: 0; 12 | text-align: right; 13 | font-size: 12px; 14 | line-height: 20px; 15 | } 16 | .seopro-counter-wrap{ 17 | background: #FBFBFB; 18 | border: 1px #CDCDCD solid; 19 | border-bottom: none; 20 | text-align: center; 21 | border-radius: 8px 8px 0 0; 22 | padding: 4px 14px 0; 23 | line-height: 17px; 24 | float: left; 25 | margin-left: 5px; 26 | } 27 | 28 | .x-form-focus + .seopro-counter .seopro-counter-wrap{ 29 | background-color: white; 30 | border-color:#658F1A; 31 | border-bottom-color: white; 32 | } 33 | .x-form-item.x-tab-item{ 34 | position: relative; 35 | } 36 | #seopro-google-logo{ 37 | text-align: center; 38 | } 39 | #seopro-google-logo img{ 40 | width: 70%; 41 | } 42 | .x-form-label-top .x-form-item { 43 | margin-top: 3px; 44 | } 45 | #seopro-google-title{ 46 | color: #12C; 47 | font-size: medium; 48 | } 49 | 50 | #seopro-google-url{ 51 | color: #093; 52 | margin-bottom: 1px; 53 | } 54 | 55 | #seopro-google-description{ 56 | color: #222; 57 | line-height: 1.24; 58 | } 59 | .green{ 60 | color: #658F1A; 61 | } 62 | .seopro-counter .red{ 63 | color: #707070 !important; 64 | } 65 | .seopro-counter-keywords.green{ 66 | background: url(../img/thumb-up.png) no-repeat 10px 3px #FBFBFB; 67 | } 68 | .seopro-counter-keywords.red{ 69 | background: url(../img/thumb-down.png) no-repeat 10px 4px #FBFBFB; 70 | } 71 | #seopro-resource-alias .seopro-counter-chars, #seopro-resource-menutitle .seopro-counter-chars{ 72 | display: none; 73 | } 74 | .seopro-counter-keywords{ 75 | padding-left: 30px; 76 | } 77 | .x-btn-seopro button{ 78 | /* background-image: url(../img/tips.png); 79 | background-position: 0px 0px !important;*/ 80 | color:#ccc !important; 81 | text-shadow:0 1px -1px #111 !important; 82 | } 83 | .x-btn-seopro button:hover{ 84 | color: #f2f2f2 !important; 85 | } 86 | .x-btn-seopro{ 87 | /* margin-left: 10px; 88 | */ background:-webkit-gradient( linear,left bottom,left top,color-stop(0.32,#555),color-stop(0.69,#666),color-stop(0,#555) ); 89 | border:1px solid #1E1E1E; 90 | margin-left: 10px; 91 | } 92 | /*.x-btn-blue{ 93 | background:#4f93cf; 94 | background:-moz-linear-gradient(center bottom,#4f93cf 0%,#9ccbea 100%) repeat scroll 0 0 transparent; 95 | background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#9ccbea),color-stop(100%,#4f93cf)); 96 | background:-webkit-linear-gradient(center bottom,#4f93cf 0%,#9ccbea 100%); 97 | background:-o-linear-gradient(center bottom,#4f93cf 0%,#9ccbea 100%); 98 | background:-ms-linear-gradient(center bottom,#4f93cf 0%,#9ccbea 100%); 99 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#9ccbea,endColorstr=#4f93cf,GradientType=0); 100 | background:linear-gradient(center bottom,#4f93cf 0%,#9ccbea 100%); 101 | text-shadow:0 1px 0 #9ccbea; 102 | border:1px solid #3b77ab; 103 | color:#14296f !important; 104 | }*/ 105 | 106 | 107 | .x-btn-blue:hover{ 108 | /* background:#4f93cf; 109 | background:-moz-linear-gradient(center bottom,#4f93cf 0%,#bcd7e9 100%) repeat scroll 0 0 transparent; 110 | background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#bcd7e9),color-stop(100%,#4f93cf)); 111 | background:-webkit-linear-gradient(center bottom,#4f93cf 0%,#bcd7e9 100%); 112 | background:-o-linear-gradient(center bottom,#4f93cf 0%,#bcd7e9 100%); 113 | background:-ms-linear-gradient(center bottom,#4f93cf 0%,#bcd7e9 100%); 114 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#bcd7e9,endColorstr=#4f93cf,GradientType=0); 115 | background:linear-gradient(center bottom,#4f93cf 0%,#bcd7e9 100%);*/ 116 | } -------------------------------------------------------------------------------- /_build/resolvers/stercextra.resolver.php: -------------------------------------------------------------------------------- 1 | xpdo; 7 | $c = $modx->newQuery('transport.modTransportPackage'); 8 | $c->where( 9 | array( 10 | 'workspace' => 1, 11 | "(SELECT 12 | `signature` 13 | FROM {$modx->getTableName('modTransportPackage')} AS `latestPackage` 14 | WHERE `latestPackage`.`package_name` = `modTransportPackage`.`package_name` 15 | ORDER BY 16 | `latestPackage`.`version_major` DESC, 17 | `latestPackage`.`version_minor` DESC, 18 | `latestPackage`.`version_patch` DESC, 19 | IF(`release` = '' OR `release` = 'ga' OR `release` = 'pl','z',`release`) DESC, 20 | `latestPackage`.`release_index` DESC 21 | LIMIT 1,1) = `modTransportPackage`.`signature`", 22 | ) 23 | ); 24 | $c->where( 25 | array( 26 | array( 27 | 'modTransportPackage.package_name' => strtolower($package) 28 | ), 29 | 'installed:IS NOT' => null 30 | ) 31 | ); 32 | $c->limit(1); 33 | 34 | /** @var modTransportPackage $oldPackage */ 35 | $oldPackage = $modx->getObject('transport.modTransportPackage', $c); 36 | 37 | $oldVersion = ''; 38 | if ($oldPackage) { 39 | $oldVersion = $oldPackage->get('version_major') . '.' . $oldPackage->get('version_minor'); 40 | $oldVersion .= '.' . $oldPackage->get('version_patch'); 41 | $oldVersion .= '-' . $oldPackage->get('release'); 42 | } 43 | 44 | $version = ''; 45 | if ($options['topic']) { 46 | $topic = trim($options['topic'], '/'); 47 | $topic = explode('/', $topic); 48 | $signature = end($topic); 49 | $version = str_replace(strtolower($package) . '-', '', $signature); 50 | } 51 | 52 | $userNameObj = $modx->getObject( 53 | 'modSystemSetting', 54 | array('key' => strtolower($package) . '.user_name') 55 | ); 56 | $userName = ($userNameObj) ? $userNameObj->get('value') : ''; 57 | 58 | $userEmailObj = $modx->getObject( 59 | 'modSystemSetting', 60 | array('key' => strtolower($package) . '.user_email') 61 | ); 62 | $userEmail = ($userEmailObj) ? $userEmailObj->get('value') : ''; 63 | 64 | $modxVersionObj = $modx->getObject('modSystemSetting', array('key' => 'settings_version')); 65 | $modxVersion = ($modxVersionObj) ? $modxVersionObj->get('value') : ''; 66 | $managerLang = $modx->getOption('manager_language'); 67 | 68 | $action = ''; 69 | switch ($options[xPDOTransport::PACKAGE_ACTION]) { 70 | case xPDOTransport::ACTION_INSTALL: 71 | $action = 'install'; 72 | break; 73 | case xPDOTransport::ACTION_UPGRADE: 74 | $action = 'upgrade'; 75 | break; 76 | case xPDOTransport::ACTION_UNINSTALL: 77 | $action = 'uninstall'; 78 | 79 | $version = $oldVersion; 80 | $setupOptionsPath = explode('/', $options['setup-options']); 81 | $signature = $setupOptionsPath[0]; 82 | $oldVersion = str_replace(strtolower($package) . '-', '', $signature); 83 | 84 | break; 85 | } 86 | 87 | $params = array( 88 | 'name' => $options['namespace'], 89 | 'url' => $_SERVER['SERVER_NAME'], 90 | 'user_name' => $userName, 91 | 'user_email' => $userEmail, 92 | 'php_version' => phpversion(), 93 | 'modx_version' => $modxVersion, 94 | 'manager_lang' => $managerLang, 95 | 'installation_type' => $action, 96 | 'package_version_from' => $oldVersion, 97 | 'package_version' => $version, 98 | 'date' => time() 99 | ); 100 | 101 | /** 102 | * Curl POST. 103 | */ 104 | $curl = curl_init(); 105 | curl_setopt($curl, CURLOPT_URL, $url); 106 | curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: STERC-A64XHC7PNY8G61L79E')); 107 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 108 | curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 120); 109 | curl_setopt($curl, CURLOPT_POST, true); 110 | curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params)); 111 | curl_setopt($curl, CURLOPT_TIMEOUT, 120); 112 | 113 | $response = curl_exec($curl); 114 | $responseInfo = curl_getinfo($curl); 115 | $curlError = curl_error($curl); 116 | curl_close($curl); 117 | 118 | return true; 119 | -------------------------------------------------------------------------------- /_build/resolvers/tables.resolver.php: -------------------------------------------------------------------------------- 1 | getTableName($table); 18 | $tableName = str_replace('`', '', $tableName); 19 | $dbname = $modx->getOption('dbname'); 20 | 21 | $dbtype = $modx->prepare("ALTER TABLE `" . $tableName . "` ENGINE = InnoDB"); 22 | if ($dbtype->execute()) { 23 | $modx->log(modX::LOG_LEVEL_INFO, ' -- Set table `' . $tableName . '` to InnoDB for index-compatibility.'); 24 | } else { 25 | $modx->log(modX::LOG_LEVEL_INFO, ' -- Unable to set table `' . $tableName . '` to InnoDB.'); 26 | } 27 | 28 | $c = $modx->prepare("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = :dbName AND table_name = :tableName"); 29 | $c->bindParam(':dbName', $dbname); 30 | $c->bindParam(':tableName', $tableName); 31 | $c->execute(); 32 | 33 | $unusedColumns = $c->fetchAll(PDO::FETCH_COLUMN, 0); 34 | $unusedColumns = array_flip($unusedColumns); 35 | 36 | $meta = $modx->getFieldMeta($table); 37 | $columns = array_keys($meta); 38 | 39 | $m = $modx->getManager(); 40 | 41 | foreach ($columns as $column) { 42 | if (isset($unusedColumns[$column])) { 43 | $m->alterField($table, $column); 44 | $modx->log(modX::LOG_LEVEL_INFO, ' -- altered column: ' . $column); 45 | unset($unusedColumns[$column]); 46 | } else { 47 | $m->addField($table, $column); 48 | $modx->log(modX::LOG_LEVEL_INFO, ' -- added column: ' . $column); 49 | } 50 | } 51 | 52 | foreach ($unusedColumns as $column => $v) { 53 | $m->removeField($table, $column); 54 | $modx->log(modX::LOG_LEVEL_INFO, ' -- removed column: ' . $column); 55 | } 56 | } 57 | } 58 | 59 | if (!function_exists('updateTableIndexes')) { 60 | /** 61 | * @param modX $modx 62 | * @param string $table 63 | */ 64 | function updateTableIndexes($modx, $table) 65 | { 66 | $tableName = $modx->getTableName($table); 67 | $tableName = str_replace('`', '', $tableName); 68 | $dbname = $modx->getOption('dbname'); 69 | 70 | $c = $modx->prepare("SELECT DISTINCT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema = :dbName AND table_name = :tableName AND INDEX_NAME != 'PRIMARY'"); 71 | $c->bindParam(':dbName', $dbname); 72 | $c->bindParam(':tableName', $tableName); 73 | $c->execute(); 74 | 75 | $oldIndexes = $c->fetchAll(PDO::FETCH_COLUMN, 0); 76 | 77 | $m = $modx->getManager(); 78 | 79 | foreach ($oldIndexes as $oldIndex) { 80 | $m->removeIndex($table, $oldIndex); 81 | $modx->log(modX::LOG_LEVEL_INFO, ' -- removed index: ' . $oldIndex); 82 | } 83 | 84 | $meta = $modx->getIndexMeta($table); 85 | $indexes = array_keys($meta); 86 | 87 | foreach ($indexes as $index) { 88 | if ($index == 'PRIMARY') continue; 89 | $m->addIndex($table, $index); 90 | $modx->log(modX::LOG_LEVEL_INFO, ' -- added index: ' . $index); 91 | } 92 | } 93 | } 94 | 95 | if (!function_exists('alterTable')) { 96 | /** 97 | * @param modX $modx 98 | * @param string $table 99 | */ 100 | function alterTable($modx, $table) 101 | { 102 | $modx->log(modX::LOG_LEVEL_INFO, ' - Updating columns'); 103 | updateTableColumns($modx, $table); 104 | 105 | $modx->log(modX::LOG_LEVEL_INFO, ' - Updating indexes'); 106 | updateTableIndexes($modx, $table); 107 | } 108 | } 109 | 110 | if ($object->xpdo) { 111 | switch ($options[xPDOTransport::PACKAGE_ACTION]) { 112 | case xPDOTransport::ACTION_INSTALL: 113 | /** @var modX $modx */ 114 | $modx =& $object->xpdo; 115 | 116 | $tables = array( 117 | 'seoKeywords' 118 | ); 119 | $modelPath = $modx->getOption('seopro.core_path', null, $modx->getOption('core_path').'components/seopro/').'model/'; 120 | $modx->addPackage('seopro', $modelPath); 121 | foreach ($tables as $table) { 122 | $modx->log(modX::LOG_LEVEL_INFO, 'Altering table: ' . $table); 123 | alterTable($modx, $table); 124 | } 125 | 126 | break; 127 | } 128 | } 129 | return true; -------------------------------------------------------------------------------- /core/components/seopro/elements/plugins/seopro.plugin.php: -------------------------------------------------------------------------------- 1 | getService('seopro', 'seoPro', $modx->getOption('seopro.core_path', null, $modx->getOption('core_path') . 'components/seopro/') . 'model/seopro/', $scriptProperties); 8 | if (!($seoPro instanceof seoPro)) { 9 | return ''; 10 | } 11 | 12 | $disabledTemplates = explode(',', $modx->getOption('seopro.disabledtemplates', null, '0')); 13 | 14 | switch ($modx->event->name) { 15 | case 'OnMODXInit': 16 | $version = $modx->getVersionData(); 17 | $version = (int)($version['version'] . $version['major_version']); 18 | if ($version < 27) { 19 | $modx->loadClass('modResource'); 20 | $modx->map['modResource']['fieldMeta']['description'] = array( 21 | 'dbtype' => 'text', 22 | 'phptype' => 'string', 23 | 'index' => 'fulltext', 24 | 'indexgrp' => 'content_ft_idx', 25 | ); 26 | } 27 | break; 28 | 29 | case 'OnDocFormRender': 30 | $template = (string)$resource->get('template'); 31 | $override = false; 32 | if (isset($_REQUEST['template'])) { 33 | $template = (string)$_REQUEST['template']; 34 | $override = true; 35 | } 36 | if (($override && $template === '0') || (!empty($template) && in_array($template, $disabledTemplates))) { 37 | break; 38 | } 39 | 40 | $currClassKey = $resource->get('class_key'); 41 | $strFields = $modx->getOption('seopro.fields', null, 'pagetitle:70,longtitle:70,description:320,alias:2023,menutitle:2023'); 42 | $arrFields = array(); 43 | if (is_array(explode(',', $strFields))) { 44 | foreach (explode(',', $strFields) as $field) { 45 | list($fieldName, $fieldCount) = explode(':', $field); 46 | $arrFields[$fieldName] = $fieldCount; 47 | } 48 | } else { 49 | return ''; 50 | } 51 | 52 | $keywords = ''; 53 | $modx->controller->addLexiconTopic('seopro:default'); 54 | $ctxKey = !empty($resource) ? $resource->get('context_key') : $modx->getOption('default_context'); 55 | $ctx = $modx->getContext($ctxKey); 56 | if ($ctx) { 57 | $url = $ctx->getOption('site_url', '', $modx->getOption('site_url')); 58 | } else { 59 | $url = $modx->getOption('site_url'); 60 | } 61 | if ($mode == 'upd') { 62 | if ($ctx) { 63 | if ($resource->get('id') != $ctx->getOption('site_start', '', $modx->getOption('site_start'))) { 64 | $url .= $resource->get('uri'); 65 | } 66 | } else { 67 | $url = $modx->makeUrl($resource->get('id'), '', '', 'full'); 68 | } 69 | $url = str_replace( 70 | $resource->get('alias'), 71 | '' . $resource->get('alias') . '', 72 | $url 73 | ); 74 | $seoKeywords = $modx->getObject('seoKeywords', array('resource' => $resource->get('id'))); 75 | if ($seoKeywords) { 76 | $keywords = $seoKeywords->get('keywords'); 77 | } 78 | } 79 | 80 | if ($_REQUEST['id'] == $modx->getOption('site_start')) { 81 | unset($arrFields['alias']); 82 | unset($arrFields['menutitle']); 83 | } 84 | 85 | 86 | $config = $seoPro->config; 87 | unset($config['resource']); 88 | $modx->regClientStartupHTMLBlock(''); 97 | 98 | /* include CSS and JS*/ 99 | $version = $modx->getVersionData(); 100 | if($version['version'] == 2 && $version['major_version'] == 2){ 101 | $modx->regClientCSS($seoPro->config['assetsUrl'] . 'css/mgr.css'); 102 | }else{ 103 | $modx->regClientCSS($seoPro->config['assetsUrl'] . 'css/mgr23.css'); 104 | } 105 | $modx->regClientStartupScript($seoPro->config['assetsUrl'] . 'js/mgr/seopro.js??v=' . $modx->getOption('seopro.version', null, 'v1.0.0')); 106 | $modx->regClientStartupScript($seoPro->config['assetsUrl'] . 'js/mgr/resource.js?v=' . $modx->getOption('seopro.version', null, 'v1.0.0')); 107 | 108 | break; 109 | 110 | case 'OnDocFormSave': 111 | $template = (string)$resource->get('template'); 112 | $override = false; 113 | if (isset($_REQUEST['template'])) { 114 | $template = (string)$_REQUEST['template']; 115 | $override = true; 116 | } 117 | if (($override && $template === '0') || (!empty($template) && in_array($template, $disabledTemplates))) { 118 | break; 119 | } 120 | $seoKeywords = $modx->getObject('seoKeywords', array('resource' => $resource->get('id'))); 121 | if (!$seoKeywords && isset($resource)) { 122 | $seoKeywords = $modx->newObject('seoKeywords', array('resource' => $resource->get('id'))); 123 | } 124 | if($seoKeywords){ 125 | if (isset($_POST['keywords'])){ 126 | $seoKeywords->set('keywords', trim($_POST['keywords'], ',')); 127 | } else { 128 | $seoKeywords->set('keywords', ''); 129 | } 130 | $seoKeywords->save(); 131 | } 132 | break; 133 | 134 | case 'onResourceDuplicate': 135 | $template = (string)$resource->get('template'); 136 | $override = false; 137 | if (isset($_REQUEST['template'])) { 138 | $template = (string)$_REQUEST['template']; 139 | $override = true; 140 | } 141 | if (($override && $template === '0') || (!empty($template) && in_array($template, $disabledTemplates))) { 142 | break; 143 | } 144 | 145 | $seoKeywords = $modx->getObject('seoKeywords', array('resource' => $resource->get('id'))); 146 | if (!$seoKeywords) { 147 | $seoKeywords = $modx->newObject('seoKeywords', array('resource' => $resource->get('id'))); 148 | } 149 | $newSeoKeywords = $modx->newObject('seoKeywords'); 150 | $newSeoKeywords->fromArray($seoKeywords->toArray()); 151 | $newSeoKeywords->set('resource', $newResource->get('id')); 152 | $newSeoKeywords->save(); 153 | break; 154 | 155 | case 'OnLoadWebDocument': 156 | if ($modx->context->get('key') == "mgr") { 157 | break; 158 | } 159 | $template = ($modx->resource->get('template')) ? (string)$modx->resource->get('template') : ''; 160 | if (in_array($template, $disabledTemplates)) { 161 | break; 162 | } 163 | $seoKeywords = $modx->getObject('seoKeywords', array('resource' => $modx->resource->get('id'))); 164 | if ($seoKeywords) { 165 | $keyWords = $seoKeywords->get('keywords'); 166 | $modx->setPlaceholder('seoPro.keywords', $keyWords); 167 | } 168 | // Render the meta title, based on system settings 169 | $titleFormat = $modx->getOption('seopro.title_format'); 170 | if (empty($titleFormat)) { 171 | $siteDelimiter = $modx->getOption('seopro.delimiter', null, '/'); 172 | $siteUseSitename = (boolean)$modx->getOption('seopro.usesitename', null, true); 173 | $siteID = $modx->resource->get('id'); 174 | $siteName = $modx->getOption('site_name'); 175 | $longtitle = $modx->resource->get('longtitle'); 176 | $pagetitle = $modx->resource->get('pagetitle'); 177 | $seoProTitle = array(); 178 | if ($siteID == $modx->getOption('site_start')) { 179 | $seoProTitle['pagetitle'] = !empty($longtitle) ? $longtitle : $siteName; 180 | } else { 181 | $seoProTitle['pagetitle'] = !empty($longtitle) ? $longtitle : $pagetitle; 182 | if ($siteUseSitename) { 183 | $seoProTitle['delimiter'] = $siteDelimiter; 184 | $seoProTitle['sitename'] = $siteName; 185 | } 186 | } 187 | $title = implode(' ', $seoProTitle); 188 | } else { 189 | $title = $modx->getOption('seopro.title_format'); 190 | } 191 | $modx->setPlaceholder('seoPro.title', $title); 192 | break; 193 | } -------------------------------------------------------------------------------- /assets/components/seopro/js/mgr/seopro.js: -------------------------------------------------------------------------------- 1 | var seoPro = function(config) { 2 | config = config || {}; 3 | seoPro.superclass.constructor.call(this, config); 4 | }; 5 | Ext.extend(seoPro, Ext.Component, { 6 | page: {}, window: {}, grid: {}, tree: {}, panel: {}, combo: {}, config: {}, view: {}, 7 | initialize: function() { 8 | seoPro.config.loaded = true; 9 | seoPro.config.delimiter = MODx.isEmpty(MODx.config['seopro.delimiter']) ? '|' : MODx.config['seopro.delimiter']; 10 | seoPro.config.siteNameShow = !MODx.isEmpty(MODx.config['seopro.usesitename']); 11 | seoPro.config.searchEngine = MODx.isEmpty(MODx.config['seopro.searchengine']) ? 'google' : MODx.config['seopro.searchengine']; 12 | seoPro.config.titleFormat = MODx.isEmpty(MODx.config['seopro.title_format']) ? '' : MODx.config['seopro.title_format']; 13 | seoPro.addKeywords(); 14 | seoPro.addPanel(); 15 | 16 | Ext.each(seoPro.config.fields.split(','), function(field) { 17 | seoPro.addCounter(field); 18 | if (field !== 'alias' && field !== 'menutitle') { 19 | seoPro.changePrevBox(field); 20 | } 21 | }); 22 | Ext.getCmp('modx-panel-resource').on('success', function() { 23 | if(Ext.get('seopro-replace-alias')) { 24 | Ext.get('seopro-replace-alias').dom.innerHTML = this.record.alias; 25 | } 26 | }); 27 | }, 28 | addCounter: function(field) { 29 | var Field = Ext.getCmp('modx-resource-' + field); 30 | /* 31 | if (!Field && field === 'description') { 32 | field = 'introtext'; 33 | Field = Ext.getCmp('modx-resource-' + field); 34 | seoPro.config.chars[field] = "155"; 35 | }*/ 36 | if (Field) { 37 | seoPro.config.values[field] = Field.getValue(); 38 | Field.maxLength = Number(seoPro.config.chars[field]); 39 | Field.reset(); 40 | Field.on('keyup', function() { 41 | seoPro.config.values[field] = Field.getValue(); 42 | seoPro.count(field); 43 | seoPro.changePrevBox(field); 44 | }); 45 | Field.on('blur', function() { 46 | seoPro.config.values[field] = Field.getValue(); 47 | seoPro.changePrevBox(field); 48 | }); 49 | 50 | Ext.get('x-form-el-modx-resource-' + field).createChild({ 51 | tag: 'div', 52 | id: 'seopro-resource-' + field, 53 | class: 'seopro-counter', 54 | html: '' + _('seopro.keywords') + ':  0\ 55 | ' + _('seopro.characters') + ': 1/' + seoPro.config.chars[field] + '' 56 | }); 57 | seoPro.count(field); 58 | } 59 | }, 60 | addKeywords: function() { 61 | var fp = Ext.getCmp('modx-resource-main-left'); 62 | var field = new Ext.form.TextField({ 63 | xtype: 'textfield', 64 | name: 'keywords', 65 | id: 'seopro-keywords', 66 | fieldLabel: _('seopro.focuskeywords'), 67 | description: '[[+seoPro.keywords]]', 68 | value: seoPro.config.record, 69 | enableKeyEvents: true, 70 | anchor: '100%', 71 | listeners: { 72 | 'keyup': function() { 73 | MODx.fireResourceFormChange(); 74 | Ext.each(seoPro.config.fields.split(','), function(field) { 75 | var Field = Ext.getCmp('modx-resource-' + field); 76 | if (Field) { 77 | seoPro.count(field); 78 | } 79 | }); 80 | } 81 | } 82 | }); 83 | var fieldDesc = new Ext.form.Label({ 84 | forId: 'pagetitle', 85 | text: _('seopro.focuskeywords_desc'), 86 | cls: 'desc-under' 87 | }); 88 | fp.add(field); 89 | fp.add(fieldDesc); 90 | fp.doLayout(); 91 | }, 92 | addPanel: function() { 93 | var fp = Ext.getCmp('modx-resource-main-left'); 94 | fp.add({ 95 | xtype: 'panel', 96 | anchor: '100%', 97 | border: false, 98 | fieldLabel: (seoPro.config.searchEngine == 'yandex' ? _('seopro.prevbox_yandex') : _('seopro.prevbox')), 99 | layout: 'form', 100 | items: [{ 101 | columnWidth: .67, 102 | xtype: 'panel', 103 | baseCls: 'seopro-panel', 104 | cls: seoPro.config.searchEngine, 105 | bodyStyle: 'padding: 10px;', 106 | border: false, 107 | autoHeight: true, 108 | items: [{ 109 | xtype: 'box', 110 | id: 'seopro-google-title', 111 | style: 'background-color: #fbfbfb; background-image: url(https://www.google.com/s2/favicons?domain='+MODx.config.site_url+');', 112 | cls: seoPro.config.searchEngine, 113 | html: '', 114 | border: false 115 | }, { 116 | xtype: 'box', 117 | id: 'seopro-google-url', 118 | bodyStyle: 'background-color: #fbfbfb;', 119 | cls: seoPro.config.searchEngine, 120 | html: seoPro.config.url, 121 | border: false 122 | }, { 123 | xtype: 'box', 124 | id: 'seopro-google-description', 125 | bodyStyle: 'background-color: #fbfbfb;', 126 | cls: seoPro.config.searchEngine, 127 | html: '', 128 | border: false 129 | }] 130 | }] 131 | }); 132 | fp.doLayout(); 133 | 134 | }, 135 | count: function(field, overrideCount) { 136 | var Value = Ext.get('modx-resource-' + field).getValue(); 137 | var maxchars = Ext.get('seopro-counter-chars-' + field + '-allowed').dom.innerHTML; 138 | var charCount; 139 | if (overrideCount) { 140 | charCount = overrideCount; 141 | } else { 142 | charCount = Value.length; 143 | // console.log(Ext.get('seopro-google-title').length); 144 | // console.log(Ext.get('seopro-google-title').dom.innerHTML); 145 | if (seoPro.config.siteNameShow && (field === 'pagetitle' || field === 'longtitle')) { 146 | var extra = ' ' + seoPro.config.delimiter + ' ' + MODx.config.site_name; 147 | charCount = charCount + extra.length; 148 | } 149 | } 150 | var keywordCount = 0; 151 | Ext.each(Ext.get('seopro-keywords').getValue().split(','), function(keyword) { 152 | keyword = keyword.replace(/^\s+/, '').toLowerCase(); 153 | 154 | if (keyword) { 155 | var counter = Value.toLowerCase().match(new RegExp("(^|[ \s\n\r\t\.,'\(\"\+;!?:\-])" + keyword + "($|[ \s\n\r\t.,'\)\"\+!?:;\-])", 'gim')); 156 | // var counter = Value.toLowerCase().match(new RegExp('\\b' + keyword + '\\b', 'g')); 157 | if (counter) { 158 | keywordCount = keywordCount + counter.length; 159 | } 160 | } 161 | }); 162 | Ext.get('seopro-counter-chars-' + field + '-current').dom.innerHTML = charCount; 163 | Ext.get('seopro-counter-keywords-' + field + '-current').dom.innerHTML = keywordCount; 164 | 165 | var maxKeywords = MODx.isEmpty(MODx.config['seopro.max_keywords_title']) ? '4' : MODx.config['seopro.max_keywords_title']; 166 | if (field === 'description') { 167 | // use different limit for the description 168 | maxKeywords = MODx.isEmpty(MODx.config['seopro.max_keywords_description']) ? '8' : MODx.config['seopro.max_keywords_description']; 169 | } 170 | maxKeywords = parseInt(maxKeywords); 171 | 172 | if (keywordCount > 0 && keywordCount <= maxKeywords) { 173 | Ext.get('seopro-counter-keywords-' + field).removeClass('red').addClass('green'); 174 | } else { 175 | Ext.get('seopro-counter-keywords-' + field).removeClass('green').addClass('red'); 176 | } 177 | 178 | if (charCount > maxchars || charCount === 0) { 179 | Ext.get('seopro-counter-chars-' + field).removeClass('green').addClass('red'); 180 | } else { 181 | Ext.get('seopro-counter-chars-' + field).removeClass('red').addClass('green'); 182 | } 183 | }, 184 | changePrevBox: function(field) { 185 | switch (field) { 186 | case 'pagetitle': 187 | case 'longtitle': 188 | var title; 189 | var resourceId = MODx.request.id; 190 | var pagetitle = Ext.get('modx-resource-pagetitle').getValue(); 191 | var longtitle = Ext.get('modx-resource-longtitle').getValue(); 192 | if (seoPro.config.titleFormat && resourceId) { 193 | MODx.Ajax.request({ 194 | url: seoPro.config.connectorUrl 195 | ,params: { 196 | action: 'mgr/resource/parse', 197 | id: resourceId, 198 | pagetitle: pagetitle, 199 | longtitle: longtitle, 200 | html: seoPro.config.titleFormat, 201 | } 202 | ,listeners: { 203 | 'success':{fn:function(r) { 204 | title = r.results.output; 205 | Ext.get('seopro-google-title').dom.innerHTML = title; 206 | var count = title.length; 207 | seoPro.count(field, count); 208 | },scope:this} 209 | } 210 | }); 211 | } else { 212 | title = seoPro.config.values['pagetitle']; 213 | if (!MODx.isEmpty(seoPro.config.values['longtitle'])) { 214 | title = seoPro.config.values['longtitle']; 215 | } 216 | if (seoPro.config.siteNameShow) { 217 | title += ' ' + seoPro.config.delimiter + ' ' + MODx.config.site_name; 218 | } 219 | Ext.get('seopro-google-title').dom.innerHTML = title; 220 | } 221 | break; 222 | case 'description': 223 | case 'introtext': 224 | var description; 225 | if (MODx.isEmpty(seoPro.config.values['description'])) { 226 | var introCheck = Ext.getCmp('modx-resource-description'); 227 | if (!MODx.isEmpty(seoPro.config.values['introtext']) && !introCheck) { 228 | description = seoPro.config.values['introtext']; 229 | } else { 230 | description = _('seopro.emptymetadescription'); 231 | } 232 | } else { 233 | description = seoPro.config.values['description']; 234 | } 235 | Ext.get('seopro-google-description').dom.innerHTML = description; 236 | break; 237 | case 'alias': 238 | Ext.get('seopro-replace-alias').dom.innerHTML = seoPro.config.values['alias']; 239 | break; 240 | } 241 | } 242 | }); 243 | Ext.reg('seopro', seoPro); 244 | 245 | seoPro = new seoPro(); 246 | 247 | Ext.onReady(function() { 248 | if (!seoPro.config.loaded) { 249 | seoPro.initialize(); 250 | } 251 | }); 252 | -------------------------------------------------------------------------------- /core/components/seopro/docs/license.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | -------------------------- 4 | 5 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 6 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies 9 | of this license document, but changing it is not allowed. 10 | 11 | Preamble 12 | -------- 13 | 14 | The licenses for most software are designed to take away your 15 | freedom to share and change it. By contrast, the GNU General Public 16 | License is intended to guarantee your freedom to share and change free 17 | software--to make sure the software is free for all its users. This 18 | General Public License applies to most of the Free Software 19 | Foundation's software and to any other program whose authors commit to 20 | using it. (Some other Free Software Foundation software is covered by 21 | the GNU Library General Public License instead.) You can apply it to 22 | your programs, too. 23 | 24 | When we speak of free software, we are referring to freedom, not 25 | price. Our General Public Licenses are designed to make sure that you 26 | have the freedom to distribute copies of free software (and charge for 27 | this service if you wish), that you receive source code or can get it 28 | if you want it, that you can change the software or use pieces of it 29 | in new free programs; and that you know you can do these things. 30 | 31 | To protect your rights, we need to make restrictions that forbid 32 | anyone to deny you these rights or to ask you to surrender the rights. 33 | These restrictions translate to certain responsibilities for you if you 34 | distribute copies of the software, or if you modify it. 35 | 36 | For example, if you distribute copies of such a program, whether 37 | gratis or for a fee, you must give the recipients all the rights that 38 | you have. You must make sure that they, too, receive or can get the 39 | source code. And you must show them these terms so they know their 40 | rights. 41 | 42 | We protect your rights with two steps: (1) copyright the software, and 43 | (2) offer you this license which gives you legal permission to copy, 44 | distribute and/or modify the software. 45 | 46 | Also, for each author's protection and ours, we want to make certain 47 | that everyone understands that there is no warranty for this free 48 | software. If the software is modified by someone else and passed on, we 49 | want its recipients to know that what they have is not the original, so 50 | that any problems introduced by others will not reflect on the original 51 | authors' reputations. 52 | 53 | Finally, any free program is threatened constantly by software 54 | patents. We wish to avoid the danger that redistributors of a free 55 | program will individually obtain patent licenses, in effect making the 56 | program proprietary. To prevent this, we have made it clear that any 57 | patent must be licensed for everyone's free use or not licensed at all. 58 | 59 | The precise terms and conditions for copying, distribution and 60 | modification follow. 61 | 62 | 63 | GNU GENERAL PUBLIC LICENSE 64 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 65 | --------------------------------------------------------------- 66 | 67 | 0. This License applies to any program or other work which contains 68 | a notice placed by the copyright holder saying it may be distributed 69 | under the terms of this General Public License. The "Program", below, 70 | refers to any such program or work, and a "work based on the Program" 71 | means either the Program or any derivative work under copyright law: 72 | that is to say, a work containing the Program or a portion of it, 73 | either verbatim or with modifications and/or translated into another 74 | language. (Hereinafter, translation is included without limitation in 75 | the term "modification".) Each licensee is addressed as "you". 76 | 77 | Activities other than copying, distribution and modification are not 78 | covered by this License; they are outside its scope. The act of 79 | running the Program is not restricted, and the output from the Program 80 | is covered only if its contents constitute a work based on the 81 | Program (independent of having been made by running the Program). 82 | Whether that is true depends on what the Program does. 83 | 84 | 1. You may copy and distribute verbatim copies of the Program's 85 | source code as you receive it, in any medium, provided that you 86 | conspicuously and appropriately publish on each copy an appropriate 87 | copyright notice and disclaimer of warranty; keep intact all the 88 | notices that refer to this License and to the absence of any warranty; 89 | and give any other recipients of the Program a copy of this License 90 | along with the Program. 91 | 92 | You may charge a fee for the physical act of transferring a copy, and 93 | you may at your option offer warranty protection in exchange for a fee. 94 | 95 | 2. You may modify your copy or copies of the Program or any portion 96 | of it, thus forming a work based on the Program, and copy and 97 | distribute such modifications or work under the terms of Section 1 98 | above, provided that you also meet all of these conditions: 99 | 100 | a) You must cause the modified files to carry prominent notices 101 | stating that you changed the files and the date of any change. 102 | 103 | b) You must cause any work that you distribute or publish, that in 104 | whole or in part contains or is derived from the Program or any 105 | part thereof, to be licensed as a whole at no charge to all third 106 | parties under the terms of this License. 107 | 108 | c) If the modified program normally reads commands interactively 109 | when run, you must cause it, when started running for such 110 | interactive use in the most ordinary way, to print or display an 111 | announcement including an appropriate copyright notice and a 112 | notice that there is no warranty (or else, saying that you provide 113 | a warranty) and that users may redistribute the program under 114 | these conditions, and telling the user how to view a copy of this 115 | License. (Exception: if the Program itself is interactive but 116 | does not normally print such an announcement, your work based on 117 | the Program is not required to print an announcement.) 118 | 119 | These requirements apply to the modified work as a whole. If 120 | identifiable sections of that work are not derived from the Program, 121 | and can be reasonably considered independent and separate works in 122 | themselves, then this License, and its terms, do not apply to those 123 | sections when you distribute them as separate works. But when you 124 | distribute the same sections as part of a whole which is a work based 125 | on the Program, the distribution of the whole must be on the terms of 126 | this License, whose permissions for other licensees extend to the 127 | entire whole, and thus to each and every part regardless of who wrote it. 128 | 129 | Thus, it is not the intent of this section to claim rights or contest 130 | your rights to work written entirely by you; rather, the intent is to 131 | exercise the right to control the distribution of derivative or 132 | collective works based on the Program. 133 | 134 | In addition, mere aggregation of another work not based on the Program 135 | with the Program (or with a work based on the Program) on a volume of 136 | a storage or distribution medium does not bring the other work under 137 | the scope of this License. 138 | 139 | 3. You may copy and distribute the Program (or a work based on it, 140 | under Section 2) in object code or executable form under the terms of 141 | Sections 1 and 2 above provided that you also do one of the following: 142 | 143 | a) Accompany it with the complete corresponding machine-readable 144 | source code, which must be distributed under the terms of Sections 145 | 1 and 2 above on a medium customarily used for software interchange; or, 146 | 147 | b) Accompany it with a written offer, valid for at least three 148 | years, to give any third party, for a charge no more than your 149 | cost of physically performing source distribution, a complete 150 | machine-readable copy of the corresponding source code, to be 151 | distributed under the terms of Sections 1 and 2 above on a medium 152 | customarily used for software interchange; or, 153 | 154 | c) Accompany it with the information you received as to the offer 155 | to distribute corresponding source code. (This alternative is 156 | allowed only for noncommercial distribution and only if you 157 | received the program in object code or executable form with such 158 | an offer, in accord with Subsection b above.) 159 | 160 | The source code for a work means the preferred form of the work for 161 | making modifications to it. For an executable work, complete source 162 | code means all the source code for all modules it contains, plus any 163 | associated interface definition files, plus the scripts used to 164 | control compilation and installation of the executable. However, as a 165 | special exception, the source code distributed need not include 166 | anything that is normally distributed (in either source or binary 167 | form) with the major components (compiler, kernel, and so on) of the 168 | operating system on which the executable runs, unless that component 169 | itself accompanies the executable. 170 | 171 | If distribution of executable or object code is made by offering 172 | access to copy from a designated place, then offering equivalent 173 | access to copy the source code from the same place counts as 174 | distribution of the source code, even though third parties are not 175 | compelled to copy the source along with the object code. 176 | 177 | 4. You may not copy, modify, sublicense, or distribute the Program 178 | except as expressly provided under this License. Any attempt 179 | otherwise to copy, modify, sublicense or distribute the Program is 180 | void, and will automatically terminate your rights under this License. 181 | However, parties who have received copies, or rights, from you under 182 | this License will not have their licenses terminated so long as such 183 | parties remain in full compliance. 184 | 185 | 5. You are not required to accept this License, since you have not 186 | signed it. However, nothing else grants you permission to modify or 187 | distribute the Program or its derivative works. These actions are 188 | prohibited by law if you do not accept this License. Therefore, by 189 | modifying or distributing the Program (or any work based on the 190 | Program), you indicate your acceptance of this License to do so, and 191 | all its terms and conditions for copying, distributing or modifying 192 | the Program or works based on it. 193 | 194 | 6. Each time you redistribute the Program (or any work based on the 195 | Program), the recipient automatically receives a license from the 196 | original licensor to copy, distribute or modify the Program subject to 197 | these terms and conditions. You may not impose any further 198 | restrictions on the recipients' exercise of the rights granted herein. 199 | You are not responsible for enforcing compliance by third parties to 200 | this License. 201 | 202 | 7. If, as a consequence of a court judgment or allegation of patent 203 | infringement or for any other reason (not limited to patent issues), 204 | conditions are imposed on you (whether by court order, agreement or 205 | otherwise) that contradict the conditions of this License, they do not 206 | excuse you from the conditions of this License. If you cannot 207 | distribute so as to satisfy simultaneously your obligations under this 208 | License and any other pertinent obligations, then as a consequence you 209 | may not distribute the Program at all. For example, if a patent 210 | license would not permit royalty-free redistribution of the Program by 211 | all those who receive copies directly or indirectly through you, then 212 | the only way you could satisfy both it and this License would be to 213 | refrain entirely from distribution of the Program. 214 | 215 | If any portion of this section is held invalid or unenforceable under 216 | any particular circumstance, the balance of the section is intended to 217 | apply and the section as a whole is intended to apply in other 218 | circumstances. 219 | 220 | It is not the purpose of this section to induce you to infringe any 221 | patents or other property right claims or to contest validity of any 222 | such claims; this section has the sole purpose of protecting the 223 | integrity of the free software distribution system, which is 224 | implemented by public license practices. Many people have made 225 | generous contributions to the wide range of software distributed 226 | through that system in reliance on consistent application of that 227 | system; it is up to the author/donor to decide if he or she is willing 228 | to distribute software through any other system and a licensee cannot 229 | impose that choice. 230 | 231 | This section is intended to make thoroughly clear what is believed to 232 | be a consequence of the rest of this License. 233 | 234 | 8. If the distribution and/or use of the Program is restricted in 235 | certain countries either by patents or by copyrighted interfaces, the 236 | original copyright holder who places the Program under this License 237 | may add an explicit geographical distribution limitation excluding 238 | those countries, so that distribution is permitted only in or among 239 | countries not thus excluded. In such case, this License incorporates 240 | the limitation as if written in the body of this License. 241 | 242 | 9. The Free Software Foundation may publish revised and/or new versions 243 | of the General Public License from time to time. Such new versions will 244 | be similar in spirit to the present version, but may differ in detail to 245 | address new problems or concerns. 246 | 247 | Each version is given a distinguishing version number. If the Program 248 | specifies a version number of this License which applies to it and "any 249 | later version", you have the option of following the terms and conditions 250 | either of that version or of any later version published by the Free 251 | Software Foundation. If the Program does not specify a version number of 252 | this License, you may choose any version ever published by the Free Software 253 | Foundation. 254 | 255 | 10. If you wish to incorporate parts of the Program into other free 256 | programs whose distribution conditions are different, write to the author 257 | to ask for permission. For software which is copyrighted by the Free 258 | Software Foundation, write to the Free Software Foundation; we sometimes 259 | make exceptions for this. Our decision will be guided by the two goals 260 | of preserving the free status of all derivatives of our free software and 261 | of promoting the sharing and reuse of software generally. 262 | 263 | NO WARRANTY 264 | ----------- 265 | 266 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 267 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 268 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 269 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 270 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 271 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 272 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 273 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 274 | REPAIR OR CORRECTION. 275 | 276 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 277 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 278 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 279 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 280 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 281 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 282 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 283 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 284 | POSSIBILITY OF SUCH DAMAGES. 285 | 286 | --------------------------- 287 | END OF TERMS AND CONDITIONS --------------------------------------------------------------------------------