From 6daadd0f18bd70d85db8b788a0b8409a546965a8 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Wed, 19 Jul 2017 12:17:19 +0300 Subject: [PATCH 001/338] fix version in top menu --- manager/frames/1.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager/frames/1.php b/manager/frames/1.php index c8ce43d857..c756a64bc2 100644 --- a/manager/frames/1.php +++ b/manager/frames/1.php @@ -1,7 +1,7 @@ INCLUDE_ORDERING_ERROR

Please use the MODX Content Manager instead of accessing this file directly."); + die("INCLUDE_ORDERING_ERROR

Please use the EVO Content Manager instead of accessing this file directly."); } header("X-XSS-Protection: 0"); @@ -291,7 +291,7 @@ config['settings_version'] != $modx->getVersionData('version') ? 'style="color:#ffff8a;"' : ''; - $version = stristr($modx->config['settings_version'], 'd') === FALSE ? 'MODX Evolution' : 'MODX EVO Custom'; + $version = 'Evolution'; ?> ' . $version . ' %s', $site_name, $modx->getVersionData('full_appname'), $style, $modx->config['settings_version']); From c2348530388915c16c116a0abff48ade1635dca0 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Wed, 19 Jul 2017 12:47:31 +0300 Subject: [PATCH 002/338] - DocLister 2.3.5 fix paginate --- assets/snippets/DocLister/core/controller/onetable.php | 2 +- assets/snippets/DocLister/core/controller/shopkeeper.php | 2 +- assets/snippets/DocLister/core/controller/site_content.php | 2 +- install/assets/snippets/DocLister.tpl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/snippets/DocLister/core/controller/onetable.php b/assets/snippets/DocLister/core/controller/onetable.php index e25e0b1900..4cf95974a2 100644 --- a/assets/snippets/DocLister/core/controller/onetable.php +++ b/assets/snippets/DocLister/core/controller/onetable.php @@ -288,7 +288,7 @@ protected function getChildrenList() $where = ''; } $fields = $this->getCFGDef('selectFields', '*'); - $group = $this->getGroupSQL($this->getCFGDef('groupBy', "`{$this->getPK()}`")); + $group = $this->getGroupSQL($this->getCFGDef('groupBy', '')); if ($sanitarInIDs != "''" || $this->getCFGDef('ignoreEmpty', '0')) { $sql = $this->dbQuery("SELECT {$fields} FROM " . $this->table . " " . $where . " " . $group . " " . diff --git a/assets/snippets/DocLister/core/controller/shopkeeper.php b/assets/snippets/DocLister/core/controller/shopkeeper.php index 5b1d984426..23eb6a092c 100644 --- a/assets/snippets/DocLister/core/controller/shopkeeper.php +++ b/assets/snippets/DocLister/core/controller/shopkeeper.php @@ -203,7 +203,7 @@ public function getChildrenCount() if (trim($where) == 'WHERE') { $where = ''; } - $group = $this->getGroupSQL($this->getCFGDef('groupBy', '')); + $group = $this->getGroupSQL($this->getCFGDef('groupBy', 'c.id')); $sort = $this->SortOrderSQL("c.createdon"); list($from) = $this->injectSortByTV($from, $sort); diff --git a/assets/snippets/DocLister/core/controller/site_content.php b/assets/snippets/DocLister/core/controller/site_content.php index e90a288a22..623c919e2f 100644 --- a/assets/snippets/DocLister/core/controller/site_content.php +++ b/assets/snippets/DocLister/core/controller/site_content.php @@ -348,7 +348,7 @@ public function getChildrenCount() if (trim($where) == 'WHERE') { $where = ''; } - $group = $this->getGroupSQL($this->getCFGDef('groupBy', '')); + $group = $this->getGroupSQL($this->getCFGDef('groupBy', 'c.id')); $sort = $this->SortOrderSQL("if(c.pub_date=0,c.createdon,c.pub_date)"); list($from) = $this->injectSortByTV($from, $sort); diff --git a/install/assets/snippets/DocLister.tpl b/install/assets/snippets/DocLister.tpl index e8725c07cb..b7bf7d650b 100644 --- a/install/assets/snippets/DocLister.tpl +++ b/install/assets/snippets/DocLister.tpl @@ -5,7 +5,7 @@ * Snippet to display the information of the tables by the description rules. The main goal - replacing Ditto and CatalogView * * @category snippet - * @version 2.3.3 + * @version 2.3.5 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL) * @internal @properties * @internal @modx_category Content From f1ec7e9c2485c4db15010b515d7eaf5a822ab521 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Wed, 19 Jul 2017 12:52:49 +0300 Subject: [PATCH 003/338] 1.3.1 --- assets/docs/changelog.txt | 4 ++++ manager/includes/version.inc.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/docs/changelog.txt b/assets/docs/changelog.txt index 68242bcf83..5445fdf739 100644 --- a/assets/docs/changelog.txt +++ b/assets/docs/changelog.txt @@ -1,6 +1,10 @@ This file shows the changes in recent releases of MODX. The most current release is usually the development release, and is only shown to give an idea of what's currently in the pipeline. +Evolution CMS 1.3.1(Jul 10, 2017) +* [GitHub:#c2348530] - [F] DocLister 2.3.5 fix paginate (dmi3yy) +* [GitHub:#6daadd0f] - [F] version in top menu (dmi3yy) + Evolution CMS 1.3.0(Jul 10, 2017) * [GitHub:#3dda520a] - [R] update sortables list delete mootools sortables (64j) * [GitHub:#9cafe6db] - [F] fix toggle menu (64j) diff --git a/manager/includes/version.inc.php b/manager/includes/version.inc.php index 228a66c7a7..af5f95b8eb 100755 --- a/manager/includes/version.inc.php +++ b/manager/includes/version.inc.php @@ -1,5 +1,5 @@ Date: Wed, 19 Jul 2017 21:57:33 +0300 Subject: [PATCH 004/338] =?UTF-8?q?=D0=98=D0=B7=D0=B2=D0=B8=D0=BD=D1=8F?= =?UTF-8?q?=D1=8E=D1=81=D1=8C=20=D0=B7=D0=B0=20=D1=82=D0=B2=D0=BE=D1=80?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Это не нужно --- install/config.inc.tpl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/install/config.inc.tpl b/install/config.inc.tpl index a70d528ef4..a2549ec2de 100644 --- a/install/config.inc.tpl +++ b/install/config.inc.tpl @@ -100,19 +100,7 @@ if(!function_exists('startCMSSession')) { removeInvalidCmsSessionFromStorage($_GET, $session_name); removeInvalidCmsSessionFromStorage($_POST, $session_name); } - function is_session_started(){ - if (php_sapi_name() !== 'cli') { - if (version_compare(phpversion(), '5.4.0', '>=')) { - return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE; - } else { - return session_id() === '' ? FALSE : TRUE; - } - } - return FALSE; - } function startCMSSession(){ - - if ( is_session_started() !== FALSE ) return; global $site_sessionname, $https_port; From ffa6303466b2bdb8805cca45797ac30a40ab0bb7 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Wed, 19 Jul 2017 21:58:12 +0300 Subject: [PATCH 005/338] fix #68 (for hide widget better use $widgets['welcome']['hide'] = 1;) --- manager/actions/welcome.static.php | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/manager/actions/welcome.static.php b/manager/actions/welcome.static.php index 4e26eef3ae..8010e10453 100644 --- a/manager/actions/welcome.static.php +++ b/manager/actions/welcome.static.php @@ -315,7 +315,8 @@ -' + ', + 'hide'=>'0' ); $widgets['onlineinfo'] = array( 'menuindex' => '20', @@ -323,7 +324,8 @@ 'cols' => 'col-sm-6', 'icon' => 'fa-user', 'title' => '[%onlineusers_title%]', - 'body' => '
[+OnlineInfo+]
' + 'body' => '
[+OnlineInfo+]
', + 'hide'=>'0' ); $widgets['recentinfo'] = array( 'menuindex' => '30', @@ -331,7 +333,8 @@ 'cols' => 'col-sm-12', 'icon' => 'fa-pencil-square-o', 'title' => '[%activity_title%]', - 'body' => '
[+RecentInfo+]
' + 'body' => '
[+RecentInfo+]
', + 'hide'=>'0' ); $widgets['news'] = array( 'menuindex' => '40', @@ -339,7 +342,8 @@ 'cols' => 'col-sm-6', 'icon' => 'fa-rss', 'title' => '[%modx_news_title%]', - 'body' => '
[+modx_news_content+]
' + 'body' => '
[+modx_news_content+]
', + 'hide'=>'0' ); $widgets['security'] = array( 'menuindex' => '50', @@ -347,15 +351,18 @@ 'cols' => 'col-sm-6', 'icon' => 'fa-exclamation-triangle', 'title' => '[%security_notices_title%]', - 'body' => '
[+modx_security_notices_content+]
' + 'body' => '
[+modx_security_notices_content+]
', + 'hide'=>'0' ); // invoke OnManagerWelcomeHome event $sitewidgets = $modx->invokeEvent("OnManagerWelcomeHome", array('widgets' => $widgets)); if(is_array($sitewidgets)) { + $newwidgets = array(); foreach($sitewidgets as $widget){ - $widgets = array_merge($widgets, unserialize($widget)); + $newwidgets = array_merge($newwidgets, unserialize($widget)); } + $widgets = $newwidgets; } usort($widgets, function ($a, $b) { @@ -365,7 +372,9 @@ $tpl = getTplWidget(); $output = ''; foreach($widgets as $widget) { - $output .= $modx->parseText($tpl, $widget); + if ($widget['hide'] != '1'){ + $output .= $modx->parseText($tpl, $widget); + } } $ph['widgets'] = $output; @@ -606,4 +615,4 @@ function hideConfigCheckWarning(key) { '; return $script; -} +} \ No newline at end of file From d29faf9aefe0297357dfa452a36d66024a3451b7 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Wed, 19 Jul 2017 22:34:19 +0300 Subject: [PATCH 006/338] update refactor sortableList --- .../actions/mutate_menuindex_sort.dynamic.php | 123 +++++++----------- .../mutate_plugin_priority.dynamic.php | 106 ++++++--------- .../mutate_template_tv_rank.dynamic.php | 121 +++++++---------- manager/actions/mutate_tv_rank.dynamic.php | 118 +++++++---------- manager/media/style/default/css/custom.css | 4 + manager/media/style/default/css/fonts.css | 2 +- manager/media/style/default/css/page.css | 6 +- manager/media/style/default/style.css | 4 +- 8 files changed, 195 insertions(+), 289 deletions(-) diff --git a/manager/actions/mutate_menuindex_sort.dynamic.php b/manager/actions/mutate_menuindex_sort.dynamic.php index 019ef032a0..4cba33dd34 100644 --- a/manager/actions/mutate_menuindex_sort.dynamic.php +++ b/manager/actions/mutate_menuindex_sort.dynamic.php @@ -24,7 +24,7 @@ } if(isset($_POST['listSubmitted'])) { - $updateMsg .= '
' . $_lang['sort_updated'] . '
'; + $updateMsg .= '
' . $_lang['sort_updated'] . '
'; if(strlen($items) > 0) { $items = explode(';', $items); foreach($items as $key => $value) { @@ -37,64 +37,33 @@ } } -$limit = 0; $disabled = 'true'; $pagetitle = ''; +$ressourcelist = ''; if($id !== NULL) { $rs = $modx->db->select('pagetitle', $modx->getFullTableName('site_content'), "id='{$id}'"); $pagetitle = $modx->db->getValue($rs); - $rs = $modx->db->select('id, pagetitle, parent, menuindex, published, hidemenu, deleted', $modx->getFullTableName('site_content'), "parent='{$id}'", 'menuindex ASC'); - $resource = $modx->db->makeArray($rs); - $limit = count($resource); - if($limit < 1) { - $updateMsg = $_lang['sort_nochildren']; - } else { - $disabled = 0; - foreach($resource as $item) { - // Add classes to determine whether it's published, deleted, not in the menu - // or has children. - // Use class names which match the classes in the document tree + $rs = $modx->db->select('id, pagetitle, parent, menuindex, published, hidemenu, deleted, isfolder', $modx->getFullTableName('site_content'), "parent='{$id}'", 'menuindex ASC'); + if($modx->db->getRecordCount($rs)) { + $ressourcelist .= '
    '; + while($row = $modx->db->getRow($rs)) { $classes = ''; - $classes .= ($item['hidemenu']) ? ' notInMenuNode ' : ' inMenuNode'; - $classes .= ($item['published']) ? ' publishedNode ' : ' unpublishedNode '; - $classes = ($item['deleted']) ? ' deletedNode ' : $classes; - $hasChildren = (count($modx->getChildIds($item['id'], 1)) > 0) ? ' ' : ' '; - $ressourcelist .= '
  • ' . $hasChildren . $item['pagetitle'] . ' (' . $item['id'] . ')
  • '; + $classes .= ($row['hidemenu']) ? ' notInMenuNode ' : ' inMenuNode'; + $classes .= ($row['published']) ? ' publishedNode ' : ' unpublishedNode '; + $classes = ($row['deleted']) ? ' deletedNode ' : $classes; + $icon = $row['isfolder'] ? ' ' : ' '; + $ressourcelist .= '
  • ' . $icon . $row['pagetitle'] . ' (' . $row['id'] . ')
  • '; } + $ressourcelist .= '
'; + } else { + $updateMsg = '

' . $_lang['sort_nochildren'] . '

'; } } $pagetitle = $id == 0 ? $site_name : $pagetitle; ?> - -

@@ -172,47 +142,51 @@ function resetSortOrder() {
() -

-

- - -

- - -
    + +

    +

    + + +

    + + -
- -
- - -
+
+
+ + +
+ -

+

+ +

-
-

+

- + - + -
- - - - -
-
+
+
+ + + + +
+ -

+

+ +

- -

-

- - -

- - - - -
- - -
+ + +

+

+ + +

+ + + +
+
+ + +
+ -

+

+ +

- -

-

- - -

- - - - -
- - -
+ + +

+

+ + +

+ + + +
+
+ + +
+ + +
+ .help'); - h1help.onclick = function() { - document.querySelector('.element-edit-message').classList.toggle('show') + // invoke OnChunkFormPrerender event + $evtOut = $modx->invokeEvent('OnChunkFormPrerender', array( + 'id' => $id, + )); + if(is_array($evtOut)) { + echo implode('', $evtOut); } - }); - + ?> + + + - - + + - // invoke OnChunkFormPrerender event - $evtOut = $modx->invokeEvent('OnChunkFormPrerender', array( - 'id' => $id, - )); - if(is_array($evtOut)) { - echo implode('', $evtOut); - } + - ?> - - - - -

- -

- - - -
-
-
- -
- - -
-

- -
-
- -
-
- - hasPermission('save_role')): ?> - - +
+
+
+ +
+ + +
+

+ +
+
+ +
+
+ + hasPermission('save_role')): ?> + + +
+ +
- -
-
-
- -
- +
+ +
+ +
-
-
- -
- +
+ +
+ +
-
-
- -
- +
+ +
+ +
-
- - +
+ +
+
-
- -
- -
- invokeEvent('OnChunkFormRender', array( - 'id' => $id, - )); - if(is_array($evtOut)) { - echo implode('', $evtOut); - } - ?> -
- - + // invoke OnChunkFormRender event + $evtOut = $modx->invokeEvent('OnChunkFormRender', array( + 'id' => $id, + )); + if(is_array($evtOut)) { + echo implode('', $evtOut); + } + ?> +
+ + diff --git a/manager/processors/save_htmlsnippet.processor.php b/manager/processors/save_htmlsnippet.processor.php index ec5b881b4b..bfbe0f25b8 100755 --- a/manager/processors/save_htmlsnippet.processor.php +++ b/manager/processors/save_htmlsnippet.processor.php @@ -1,6 +1,8 @@ INCLUDE_ORDERING_ERROR

Please use the MODX Content Manager instead of accessing this file directly."); -if (!$modx->hasPermission('save_chunk')) { +if(IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

Please use the MODX Content Manager instead of accessing this file directly."); +} +if(!$modx->hasPermission('save_chunk')) { $modx->webAlertAndQuit($_lang["error_no_privileges"]); } @@ -8,35 +10,36 @@ $snippet = $modx->db->escape($_POST['post']); $name = $modx->db->escape(trim($_POST['name'])); $description = $modx->db->escape($_POST['description']); -$locked = $_POST['locked']=='on' ? 1 : 0 ; +$locked = $_POST['locked'] == 'on' ? 1 : 0; //Kyle Jaebker - added category support -if (empty($_POST['newcategory']) && $_POST['categoryid'] > 0) { - $categoryid = intval($_POST['categoryid']); -} elseif (empty($_POST['newcategory']) && $_POST['categoryid'] <= 0) { - $categoryid = 0; +if(empty($_POST['newcategory']) && $_POST['categoryid'] > 0) { + $categoryid = intval($_POST['categoryid']); +} elseif(empty($_POST['newcategory']) && $_POST['categoryid'] <= 0) { + $categoryid = 0; } else { - include_once(MODX_MANAGER_PATH.'includes/categories.inc.php'); - $categoryid = checkCategory($_POST['newcategory']); - if (!$categoryid) { - $categoryid = newCategory($_POST['newcategory']); - } + include_once(MODX_MANAGER_PATH . 'includes/categories.inc.php'); + $categoryid = checkCategory($_POST['newcategory']); + if(!$categoryid) { + $categoryid = newCategory($_POST['newcategory']); + } } -if($name=="") $name = "Untitled chunk"; +if($name == "" || $name == 'null') { + $name = "Untitled chunk"; +} $editor_type = $_POST['which_editor'] != 'none' ? 1 : 2; $editor_name = $_POST['which_editor'] != 'none' ? $_POST['which_editor'] : 'none'; -switch ($_POST['mode']) { - case '77': +switch($_POST['mode']) { + case '77': // invoke OnBeforeChunkFormSave event - $modx->invokeEvent("OnBeforeChunkFormSave", - array( - "mode" => "new", - "id" => $id - )); + $modx->invokeEvent("OnBeforeChunkFormSave", array( + "mode" => "new", + "id" => $id + )); // disallow duplicate names for new chunks $rs = $modx->db->select('COUNT(*)', $modx->getFullTableName('site_htmlsnippets'), "name='{$name}'"); @@ -47,47 +50,44 @@ } //do stuff to save the new doc - $newid = $modx->db->insert( - array( - 'name' => $name, - 'description' => $description, - 'snippet' => $snippet, - 'locked' => $locked, - 'category' => $categoryid, - 'editor_type' => $editor_type, - 'editor_name' => $editor_name - ), $modx->getFullTableName('site_htmlsnippets')); - - // invoke OnChunkFormSave event - $modx->invokeEvent("OnChunkFormSave", - array( - "mode" => "new", - "id" => $newid - )); + $newid = $modx->db->insert(array( + 'name' => $name, + 'description' => $description, + 'snippet' => $snippet, + 'locked' => $locked, + 'category' => $categoryid, + 'editor_type' => $editor_type, + 'editor_name' => $editor_name + ), $modx->getFullTableName('site_htmlsnippets')); + + // invoke OnChunkFormSave event + $modx->invokeEvent("OnChunkFormSave", array( + "mode" => "new", + "id" => $newid + )); // Set the item name for logger $_SESSION['itemname'] = $name; - // empty cache - $modx->clearCache('full'); - - // finished emptying cache - redirect - if($_POST['stay']!='') { - $a = ($_POST['stay']=='2') ? "78&id=$newid":"77"; - $header="Location: index.php?a=".$a."&r=2&stay=".$_POST['stay']; - header($header); - } else { - $header="Location: index.php?a=76&r=2"; - header($header); - } - break; - case '78': + // empty cache + $modx->clearCache('full'); + + // finished emptying cache - redirect + if($_POST['stay'] != '') { + $a = ($_POST['stay'] == '2') ? "78&id=$newid" : "77"; + $header = "Location: index.php?a=" . $a . "&r=2&stay=" . $_POST['stay']; + header($header); + } else { + $header = "Location: index.php?a=76&r=2"; + header($header); + } + break; + case '78': // invoke OnBeforeChunkFormSave event - $modx->invokeEvent("OnBeforeChunkFormSave", - array( - "mode" => "upd", - "id" => $id - )); + $modx->invokeEvent("OnBeforeChunkFormSave", array( + "mode" => "upd", + "id" => $id + )); // disallow duplicate names for chunks $rs = $modx->db->select('COUNT(*)', $modx->getFullTableName('site_htmlsnippets'), "name='{$name}' AND id!='{$id}'"); @@ -97,42 +97,39 @@ } //do stuff to save the edited doc - $modx->db->update( - array( - 'name' => $name, - 'description' => $description, - 'snippet' => $snippet, - 'locked' => $locked, - 'category' => $categoryid, - 'editor_type' => $editor_type, - 'editor_name' => $editor_name - ), $modx->getFullTableName('site_htmlsnippets'), "id='{$id}'"); - - // invoke OnChunkFormSave event - $modx->invokeEvent("OnChunkFormSave", - array( - "mode" => "upd", - "id" => $id - )); + $modx->db->update(array( + 'name' => $name, + 'description' => $description, + 'snippet' => $snippet, + 'locked' => $locked, + 'category' => $categoryid, + 'editor_type' => $editor_type, + 'editor_name' => $editor_name + ), $modx->getFullTableName('site_htmlsnippets'), "id='{$id}'"); + + // invoke OnChunkFormSave event + $modx->invokeEvent("OnChunkFormSave", array( + "mode" => "upd", + "id" => $id + )); // Set the item name for logger $_SESSION['itemname'] = $name; - // empty cache - $modx->clearCache('full'); - - // finished emptying cache - redirect - if($_POST['stay']!='') { - $a = ($_POST['stay']=='2') ? "78&id=$id":"77"; - $header="Location: index.php?a=".$a."&r=2&stay=".$_POST['stay']; - header($header); - } else { - $modx->unlockElement(3, $id); - $header="Location: index.php?a=76&r=2"; - header($header); - } - break; - default: - $modx->webAlertAndQuit("No operation set in request."); + // empty cache + $modx->clearCache('full'); + + // finished emptying cache - redirect + if($_POST['stay'] != '') { + $a = ($_POST['stay'] == '2') ? "78&id=$id" : "77"; + $header = "Location: index.php?a=" . $a . "&r=2&stay=" . $_POST['stay']; + header($header); + } else { + $modx->unlockElement(3, $id); + $header = "Location: index.php?a=76&r=2"; + header($header); + } + break; + default: + $modx->webAlertAndQuit("No operation set in request."); } -?> \ No newline at end of file diff --git a/manager/processors/save_snippet.processor.php b/manager/processors/save_snippet.processor.php index 4357ac4424..6b058b62f5 100755 --- a/manager/processors/save_snippet.processor.php +++ b/manager/processors/save_snippet.processor.php @@ -1,6 +1,8 @@ INCLUDE_ORDERING_ERROR

Please use the MODX Content Manager instead of accessing this file directly."); -if (!$modx->hasPermission('save_snippet')) { +if(IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

Please use the MODX Content Manager instead of accessing this file directly."); +} +if(!$modx->hasPermission('save_snippet')) { $modx->webAlertAndQuit($_lang["error_no_privileges"]); } @@ -8,60 +10,68 @@ $snippet = trim($_POST['post']); $name = $modx->db->escape(trim($_POST['name'])); $description = $modx->db->escape($_POST['description']); -$locked = $_POST['locked']=='on' ? 1 : 0 ; +$locked = $_POST['locked'] == 'on' ? 1 : 0; + // strip out PHP tags from snippets -if ( strncmp($snippet, "' ) $snippet = substr($snippet, 0, -2); + +if(substr($snippet, -2) == '?>') { + $snippet = substr($snippet, 0, -2); +} + $snippet = $modx->db->escape($snippet); $properties = $modx->db->escape($_POST['properties']); $moduleguid = $modx->db->escape($_POST['moduleguid']); -$parse_docblock = $_POST['parse_docblock']=="1" ? '1' : '0'; +$parse_docblock = $_POST['parse_docblock'] == "1" ? '1' : '0'; //Kyle Jaebker - added category support -if (empty($_POST['newcategory']) && $_POST['categoryid'] > 0) { - $categoryid = intval($_POST['categoryid']); -} elseif (empty($_POST['newcategory']) && $_POST['categoryid'] <= 0) { - $categoryid = 0; +if(empty($_POST['newcategory']) && $_POST['categoryid'] > 0) { + $categoryid = intval($_POST['categoryid']); +} elseif(empty($_POST['newcategory']) && $_POST['categoryid'] <= 0) { + $categoryid = 0; } else { - include_once(MODX_MANAGER_PATH.'includes/categories.inc.php'); - $categoryid = checkCategory($_POST['newcategory']); - if (!$categoryid) { - $categoryid = newCategory($_POST['newcategory']); - } + include_once(MODX_MANAGER_PATH . 'includes/categories.inc.php'); + $categoryid = checkCategory($_POST['newcategory']); + if(!$categoryid) { + $categoryid = newCategory($_POST['newcategory']); + } } -if($name=="") $name = "Untitled snippet"; +if($name == "") { + $name = "Untitled snippet"; +} if($parse_docblock) { - $parsed = $modx->parseDocBlockFromString($snippet, true); - $name = isset($parsed['name']) ? $parsed['name'] : $name; - $properties = isset($parsed['properties']) ? $parsed['properties'] : $properties; - $moduleguid = isset($parsed['guid']) ? $parsed['guid'] : $moduleguid; - - $description = isset($parsed['description']) ? $parsed['description'] : $description; - $version = isset($parsed['version']) ? ''.$parsed['version'].' ' : ''; - if($version) { - $description = $version . trim(preg_replace('/(.+?)+(<\/b>)/i', '', $description)); - } - if(isset($parsed['modx_category'])) { - include_once(MODX_MANAGER_PATH.'includes/categories.inc.php'); - $categoryid = getCategory($parsed['modx_category']); - } + $parsed = $modx->parseDocBlockFromString($snippet, true); + $name = isset($parsed['name']) ? $parsed['name'] : $name; + $properties = isset($parsed['properties']) ? $parsed['properties'] : $properties; + $moduleguid = isset($parsed['guid']) ? $parsed['guid'] : $moduleguid; + + $description = isset($parsed['description']) ? $parsed['description'] : $description; + $version = isset($parsed['version']) ? '' . $parsed['version'] . ' ' : ''; + if($version) { + $description = $version . trim(preg_replace('/(.+?)+(<\/b>)/i', '', $description)); + } + if(isset($parsed['modx_category'])) { + include_once(MODX_MANAGER_PATH . 'includes/categories.inc.php'); + $categoryid = getCategory($parsed['modx_category']); + } } -switch ($_POST['mode']) { - case '23': // Save new snippet +switch($_POST['mode']) { + case '23': // Save new snippet // invoke OnBeforeSnipFormSave event - $modx->invokeEvent("OnBeforeSnipFormSave", - array( - "mode" => "new", - "id" => $id - )); + $modx->invokeEvent("OnBeforeSnipFormSave", array( + "mode" => "new", + "id" => $id + )); // disallow duplicate names for new snippets $rs = $modx->db->select('COUNT(id)', $modx->getFullTableName('site_snippets'), "name='{$name}'"); @@ -72,92 +82,89 @@ } //do stuff to save the new doc - $newid = $modx->db->insert( - array( - 'name' => $name, - 'description' => $description, - 'snippet' => $snippet, - 'moduleguid' => $moduleguid, - 'locked' => $locked, - 'properties' => $properties, - 'category' => $categoryid, - ), $modx->getFullTableName('site_snippets')); - - // invoke OnSnipFormSave event - $modx->invokeEvent("OnSnipFormSave", - array( - "mode" => "new", - "id" => $newid - )); + $newid = $modx->db->insert(array( + 'name' => $name, + 'description' => $description, + 'snippet' => $snippet, + 'moduleguid' => $moduleguid, + 'locked' => $locked, + 'properties' => $properties, + 'category' => $categoryid, + ), $modx->getFullTableName('site_snippets')); + + // invoke OnSnipFormSave event + $modx->invokeEvent("OnSnipFormSave", array( + "mode" => "new", + "id" => $newid + )); // Set the item name for logger $_SESSION['itemname'] = $name; - // empty cache - $modx->clearCache('full'); - - // finished emptying cache - redirect - if($_POST['stay']!='') { - $a = ($_POST['stay']=='2') ? "22&id=$newid":"23"; - $header="Location: index.php?a=".$a."&r=2&stay=".$_POST['stay']; - header($header); - } else { - $header="Location: index.php?a=76&r=2"; - header($header); - } - break; - case '22': // Save existing snippet + // empty cache + $modx->clearCache('full'); + + // finished emptying cache - redirect + if($_POST['stay'] != '') { + $a = ($_POST['stay'] == '2') ? "22&id=$newid" : "23"; + $header = "Location: index.php?a=" . $a . "&r=2&stay=" . $_POST['stay']; + header($header); + } else { + $header = "Location: index.php?a=76&r=2"; + header($header); + } + break; + case '22': // Save existing snippet // invoke OnBeforeSnipFormSave event - $modx->invokeEvent("OnBeforeSnipFormSave", - array( - "mode" => "upd", - "id" => $id - )); + $modx->invokeEvent("OnBeforeSnipFormSave", array( + "mode" => "upd", + "id" => $id + )); // disallow duplicate names for snippets $rs = $modx->db->select('COUNT(*)', $modx->getFullTableName('site_snippets'), "name='{$name}' AND id!='{$id}'"); - if ($modx->db->getValue($rs) > 0) { + if($modx->db->getValue($rs) > 0) { $modx->manager->saveFormValues(22); $modx->webAlertAndQuit(sprintf($_lang['duplicate_name_found_general'], $_lang['snippet'], $name), "index.php?a=22&id={$id}"); } //do stuff to save the edited doc - $modx->db->update( - array( - 'name' => $name, - 'description' => $description, - 'snippet' => $snippet, - 'moduleguid' => $moduleguid, - 'locked' => $locked, - 'properties' => $properties, - 'category' => $categoryid, - ), $modx->getFullTableName('site_snippets'), "id='{$id}'"); - - // invoke OnSnipFormSave event - $modx->invokeEvent("OnSnipFormSave", - array( - "mode" => "upd", - "id" => $id - )); + $modx->db->update(array( + 'name' => $name, + 'description' => $description, + 'snippet' => $snippet, + 'moduleguid' => $moduleguid, + 'locked' => $locked, + 'properties' => $properties, + 'category' => $categoryid, + ), $modx->getFullTableName('site_snippets'), "id='{$id}'"); + + // invoke OnSnipFormSave event + $modx->invokeEvent("OnSnipFormSave", array( + "mode" => "upd", + "id" => $id + )); // Set the item name for logger $_SESSION['itemname'] = $name; - // empty cache - $modx->clearCache('full'); - - if($_POST['runsnippet']) run_snippet($snippet); - // finished emptying cache - redirect - if($_POST['stay']!='') { - $a = ($_POST['stay']=='2') ? "22&id=$id":"23"; - $header="Location: index.php?a=".$a."&r=2&stay=".$_POST['stay']; - header($header); - } else { - $modx->unlockElement(4, $id); - $header="Location: index.php?a=76&r=2"; - header($header); - } - break; - default: + // empty cache + $modx->clearCache('full'); + + if($_POST['runsnippet']) { + run_snippet($snippet); + } + // finished emptying cache - redirect + if($_POST['stay'] != '') { + $a = ($_POST['stay'] == '2') ? "22&id=$id" : "23"; + $header = "Location: index.php?a=" . $a . "&r=2&stay=" . $_POST['stay']; + header($header); + } else { + $modx->unlockElement(4, $id); + $header = "Location: index.php?a=76&r=2"; + header($header); + } + break; + default: $modx->webAlertAndQuit("No operation set in request."); } From d4c67e6a217b391934659c53235582906623d938 Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Thu, 20 Jul 2017 00:19:36 +0300 Subject: [PATCH 013/338] =?UTF-8?q?=D0=94=D0=BB=D1=8F=20FormLister=20?= =?UTF-8?q?=D1=83=D0=B6=D0=B5=20=D0=BD=D1=83=D0=B6=D0=BD=D0=B0=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20PHP=20>=3D=205.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88d1036b7d..bc69b073e5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ EVO is an open source Content Management System and Application Framework. Initi EVO provides a fast, lightweight and powerful framework on which to deploy and secure your website and web applications. For example, it gives you a true system for registered web users and groups that is separate from administration users. You can grant some web users access to one page and others access to another page. For content management, you can easily duplicate documents, folders (and all their children!), chunks and snippets. Most significant, though, is EVO's ability to empower you to quickly and easily create and maintain a rich and dynamic website like never before. -Evolution CMS requires **PHP version 5.4 and higher**. +Evolution CMS requires **PHP version 5.6 and higher**. ### Screenshots @@ -31,4 +31,4 @@ Extras: https://extras.evolution-cms.com Documentation: -https://evolution-docs.com \ No newline at end of file +https://evolution-docs.com From ee27d0875b36016c3da20eff8d9a8f29161c08bf Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 20 Jul 2017 00:32:56 +0300 Subject: [PATCH 014/338] remove unused files DLUsers --- assets/snippets/DLUsers/lang/russian-UTF8.php | 14 - assets/snippets/DLUsers/plugin.DLLogout.php | 10 - assets/snippets/DLUsers/snippet.DLUsers.php | 14 - assets/snippets/DLUsers/src/Actions.php | 578 ------------------ assets/snippets/DLUsers/tpl/authForm.html | 9 - assets/snippets/DLUsers/tpl/tplProfile.html | 3 - 6 files changed, 628 deletions(-) delete mode 100755 assets/snippets/DLUsers/lang/russian-UTF8.php delete mode 100755 assets/snippets/DLUsers/plugin.DLLogout.php delete mode 100755 assets/snippets/DLUsers/snippet.DLUsers.php delete mode 100755 assets/snippets/DLUsers/src/Actions.php delete mode 100755 assets/snippets/DLUsers/tpl/authForm.html delete mode 100755 assets/snippets/DLUsers/tpl/tplProfile.html diff --git a/assets/snippets/DLUsers/lang/russian-UTF8.php b/assets/snippets/DLUsers/lang/russian-UTF8.php deleted file mode 100755 index 658e6c9e64..0000000000 --- a/assets/snippets/DLUsers/lang/russian-UTF8.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - 'incorrect_mail' => 'Указан (если вообще указан) не корректный email', - 'no_user' => 'Пользователь не обнаружен или заблокирован', - 'incorrect_password' => 'Не удалось авторизоваться. Пароль указан не верно или в плагине отказали в авторизации' - ) -); - -return $_lang; diff --git a/assets/snippets/DLUsers/plugin.DLLogout.php b/assets/snippets/DLUsers/plugin.DLLogout.php deleted file mode 100755 index 7be5bb9bae..0000000000 --- a/assets/snippets/DLUsers/plugin.DLLogout.php +++ /dev/null @@ -1,10 +0,0 @@ -event->name == 'OnWebPagePrerender' && $modx->getLoginUserID('web')) { - $snippetName = (isset($snippetName) && is_string($snippetName)) ? $snippetName : 'DLUsers'; - $modx->runSnippet($snippetName, array( - 'action' => 'logout' - )); -} diff --git a/assets/snippets/DLUsers/snippet.DLUsers.php b/assets/snippets/DLUsers/snippet.DLUsers.php deleted file mode 100755 index c56b1f329c..0000000000 --- a/assets/snippets/DLUsers/snippet.DLUsers.php +++ /dev/null @@ -1,14 +0,0 @@ -event->params) ? $modx->event->params : array(); -$action = APIHelpers::getkey($params, 'action', ''); -$lang = APIHelpers::getkey($params, 'lang', $modx->getConfig('manager_language')); -$userClass = APIHelpers::getkey($params, 'userClass', 'modUsers'); -$DLUsers = \DLUsers\Actions::getInstance($modx, $lang, $userClass); -$out = ''; -if ( ! empty($action) && method_exists($DLUsers, $action)) { - $out = call_user_func_array(array($DLUsers, $action), array($params)); -} - -return $out; diff --git a/assets/snippets/DLUsers/src/Actions.php b/assets/snippets/DLUsers/src/Actions.php deleted file mode 100755 index c67a2c3e43..0000000000 --- a/assets/snippets/DLUsers/src/Actions.php +++ /dev/null @@ -1,578 +0,0 @@ -modx = $modx; - $this->userObj = new $userClass($this->modx, $debug); - $this->url = new DLCollection($this->modx); - - $site_url = $this->modx->getConfig('site_url'); - $site_start = $this->modx->getConfig('site_start', 1); - $error_page = $this->modx->getConfig('error_page', $site_start); - $unauthorized_page = $this->modx->getConfig('unauthorized_page', $error_page); - - $this->config = compact('site_url', 'site_start', 'error_page', 'unauthorized_page'); - } - - /** - * prevent the instance from being cloned - * - * @return void - */ - private function __clone() - { - - } - - /** - * prevent from being unserialized - * - * @return void - */ - private function __wakeup() - { - - } - - /** - * Сброс авторизации и обновление страницы - */ - public function logout($params) - { - $LogoutName = APIHelpers::getkey($params, 'LogoutName', 'logout'); - if (is_scalar($LogoutName) && !empty($LogoutName) && isset($_GET[$LogoutName])) { - $userID = $this->UserID('web'); - if ($userID) { - $this->userObj->edit($userID); - $params = array(); - if ($this->userObj->getID()) { - $params = array( - "userid" => $this->userObj->getID(), - "username" => $this->userObj->get('username') - ); - $this->modx->invokeEvent("OnBeforeWebLogout", $params); - } - $this->userObj->logOut(); - if ($this->userObj->getID()) { - $this->modx->invokeEvent("OnWebLogout", $params); - } - - $go = APIHelpers::getkey($params, 'url', ''); - if (empty($go)) { - $go = str_replace( - array("?" . $LogoutName, "&" . $LogoutName), - array("", ""), - $_SERVER['REQUEST_URI'] - ); - } - - $start = $this->makeUrl($this->config['site_start']); - if ($start == $go) { - $go = $this->config['site_url']; - } else { - $go = $this->config['site_url'] . ltrim($go, '/'); - } - $this->moveTo(array('url' => $go)); - } else { - //Если юзер не авторизован, то показываем ему 404 ошибку - $this->modx->sendErrorPage(); - } - } - - return true; - } - - /** - * Генерация ссылки под кнопку выход - * @return string - */ - public function logoutUrl($params) - { - $LogoutName = APIHelpers::getkey($params, 'LogoutName', 'logout'); - $request = parse_url($_SERVER['REQUEST_URI']); - - //Во избежании XSS мы не сохраняем весь REQUEST_URI, а берем только path - $query = '?' . $LogoutName; - - return $request['path'] . $query; - } - - /** - * Авторизация из блока - * если указан параметр authId, то данные из формы перекидываются в метод AuthPage - * В противном случае вся работа происходит внутри самого блока - */ - public function AuthBlock($params) - { - $POST = array('backUrl' => $_SERVER['REQUEST_URI']); - - $error = $errorCode = ''; - - $pwdField = APIHelpers::getkey($params, 'pwdField', 'password'); - $emailField = APIHelpers::getkey($params, 'emailField', 'email'); - $rememberField = APIHelpers::getkey($params, 'rememberField', 'remember'); - - if ($this->UserID('web')) { - $tpl = APIHelpers::getkey($params, 'tplProfile', ''); - if (empty($tpl)) { - $tpl = $this->getTemplate('tplProfile'); - } - $dataTPL = $this->userObj->toArray(); - $dataTPL['url.logout'] = $this->logoutUrl($params); - $homeID = APIHelpers::getkey($params, 'homeID'); - if (!empty($homeID)) { - $dataTPL['url.profile'] = $this->makeUrl($homeID); - } - } else { - $tpl = APIHelpers::getkey($params, 'tplForm', ''); - if (empty($tpl)) { - $tpl = $this->getTemplate('authForm'); - } - $POST = $this->Auth($pwdField, $emailField, $rememberField, $POST['backUrl'], __METHOD__, $error, - $errorCode, $params); - $dataTPL = array( - 'backUrl' => APIHelpers::getkey($POST, 'backUrl', ''), - 'emailValue' => APIHelpers::getkey($POST, 'email', ''), - 'emailField' => $emailField, - 'pwdField' => $pwdField, - 'method' => strtolower(__METHOD__), - 'error' => $error, - 'errorCode' => $errorCode - ); - $authId = APIHelpers::getkey($params, 'authId'); - if (!empty($authId)) { - $dataTPL['authPage'] = $this->makeUrl($authId); - $dataTPL['method'] = strtolower(__CLASS__ . '::' . 'authpage'); - } - } - - return DLTemplate::getInstance($this->modx)->parseChunk($tpl, $dataTPL); - } - - /** - * Авторизация на сайте со страницы авторизации - * [!Auth? &login=`password` &pwdField=`password` &homeID=`72`!] - */ - public function AuthPage($params) - { - $homeID = APIHelpers::getkey($params, 'homeID'); - $this->isAuthGoHome(array('id' => $homeID)); - - $error = $errorCode = ''; - $POST = array('backUrl' => ''); - - $pwdField = APIHelpers::getkey($params, 'pwdField', 'password'); - $emailField = APIHelpers::getkey($params, 'emailField', 'email'); - $rememberField = APIHelpers::getkey($params, 'rememberField', 'remember'); - - $tpl = APIHelpers::getkey($params, 'tpl', ''); - if (empty($tpl)) { - $tpl = $this->getTemplate('authForm'); - } - - $request = parse_url($_SERVER['REQUEST_URI']); - if ($request === false) { - $request = array(); - } - if (!empty($_SERVER['HTTP_REFERER'])) { - /** - * Thank you for super protection against hacking in protect.inc.php:-) - */ - $refer = htmlspecialchars_decode($_SERVER['HTTP_REFERER'], ENT_QUOTES); - } else { - $refer = $this->getBackUrl($request); - } - - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - $backUrl = APIHelpers::getkey($_POST, 'backUrl', $POST['backUrl']); - if (!is_scalar($backUrl)) { - $backUrl = $refer; - } else { - $backUrl = urldecode($backUrl); - } - } else { - $backUrl = $refer; - } - $backUrl = parse_url($backUrl); - if ($backUrl === false) { - $backUrl = array(); - } - if (!empty($backUrl['path']) && $request['path'] != $backUrl['path']) { - $POST['backUrl'] = $backUrl['path']; - } else { - $POST['backUrl'] = $this->getBackUrl($backUrl); - } - if (!empty($POST['backUrl'])) { - $idURL = $this->moveTo(array( - 'url' => '/' . ltrim($POST['backUrl'], '/'), - 'validate' => true - )); - } else { - $idURL = 0; - } - if (empty($idURL)) { - if (empty($homeID)) { - $homeID = $this->config['site_start']; - } - $POST['backUrl'] = $this->makeUrl($homeID); - } - $POST = $this->Auth($pwdField, $emailField, $rememberField, $POST['backUrl'], __METHOD__, $error, $errorCode, - $params); - - return DLTemplate::getInstance($this->modx)->parseChunk($tpl, array( - 'backUrl' => APIHelpers::getkey($POST, 'backUrl', ''), - 'emailValue' => APIHelpers::getkey($POST, 'email', ''), - 'emailField' => $emailField, - 'pwdField' => $pwdField, - 'method' => strtolower(__METHOD__), - 'error' => $error, - 'errorCode' => $errorCode - )); - } - - /** - * @param array $request - * @return string - */ - protected function getBackUrl(array $request = array()) - { - $selfHost = rtrim(str_replace("http://", "", $this->config['site_url']), '/'); - if (empty($request['host']) || $request['host'] == $selfHost) { - $query = !empty($request['query']) ? '?' . $request['query'] : ''; - $out = !empty($request['path']) ? $request['path'] . $query : ''; - } else { - $out = ''; - } - - return $out; - } - - /** - * @param $pwdField - * @param $emailField - * @param $rememberField - * @param $backUrl - * @param $method - * @param $error - * @param $errorCode - * @param array $params - * @return array - */ - protected function Auth( - $pwdField, - $emailField, - $rememberField, - $backUrl, - $method, - &$error, - &$errorCode, - $params = array() - ) { - $POST = array( - 'backUrl' => urlencode($backUrl) - ); - $userObj = &$this->userObj; - if ($_SERVER['REQUEST_METHOD'] == 'POST' && APIHelpers::getkey($_POST, 'method', '') == strtolower($method)) { - $POST = array_merge($POST, array( - 'password' => APIHelpers::getkey($_POST, $pwdField, ''), - 'email' => APIHelpers::getkey($_POST, $emailField, ''), - 'remember' => (bool)((int)APIHelpers::getkey($_POST, $rememberField, 0)) - )); - if (!empty($POST['email']) && is_scalar($POST['email']) && !$userObj->emailValidate($POST['email'], - false) - ) { - $userObj->edit($POST['email']); - - $this->modx->invokeEvent("OnBeforeWebLogin", array( - "username" => $POST['email'], - "userpassword" => $POST['password'], - "rememberme" => $POST['remember'], - 'userObj' => $userObj - )); - if ($userObj->getID() && !$userObj->checkBlock($userObj->getID())) { - $pluginFlag = $this->modx->invokeEvent("OnWebAuthentication", array( - "userid" => $userObj->getID(), - "username" => $userObj->get('username'), - "userpassword" => $POST['password'], - "savedpassword" => $userObj->get('password'), - "rememberme" => $POST['remember'], - )); - if ( - ($pluginFlag === true || $userObj->testAuth($userObj->getID(), $POST['password'], 0)) - && - $userObj->authUser($userObj->getID(), $POST['remember']) - ) { - $userObj->set('logincount', (int)$userObj->get('logincount') + 1); - $userObj->set('lastlogin', time()); - $userObj->set('failedlogincount', 0); - $userObj->save(false, false); - - $this->modx->invokeEvent("OnWebLogin", array( - "userid" => $userObj->getID(), - "username" => $userObj->get('username'), - "userpassword" => $POST['password'], - "rememberme" => $POST['remember'], - )); - $this->moveTo(array('url' => urldecode($POST['backUrl']))); - } else { - $userObj->set('failedlogincount', (int)$userObj->get('failedlogincount') + 1); - $userObj->save(false, false); - - $error = 'error.incorrect_password'; - } - } else { - $error = 'error.no_user'; - } - } else { - $error = 'error.incorrect_mail'; - $POST['email'] = ''; - } - } - if (!empty($error)) { - $errorCode = $error; - $error = APIHelpers::getkey($params, $error, ''); - $error = static::getLangMsg($error, $error); - } - - return $POST; - } - - /** - * Информация о пользователе - * [!DLUsers? &action=`UserInfo` &field=`fullname` &id=`2`!] - */ - public function UserInfo($params) - { - $out = ''; - $userID = APIHelpers::getkey($params, 'id', 0); - if (empty($userID)) { - $userID = $this->UserID('web'); - } - $field = APIHelpers::getkey($params, 'field', 'username'); - if ($userID > 0) { - $this->userObj->edit($userID); - switch (true) { - case ($field == $this->userObj->fieldPKName()): - $out = $this->userObj->getID(); - break; - case ($this->userObj->issetField($field)): - $out = $this->userObj->get($field); - break; - } - } - - return $out; - } - - /** - * ID пользователя - */ - public function UserID($type = 'web') - { - return $this->modx->getLoginUserID($type); - } - - /** - * Если не авторизован - то отправить на страницу - */ - public function isGuestGoHome($params) - { - if (!$this->UserID('web')) { - /** - * @see : http://modx.im/blog/triks/105.html - */ - $this->modx->invokeEvent('OnPageUnauthorized'); - $id = APIHelpers::getkey($params, 'id', $this->config['unauthorized_page']); - $this->moveTo(compact('id')); - } - - return; - } - - /** - * Если авторизован - то открыть личный кабинет - */ - public function isAuthGoHome($params) - { - $userID = $this->UserID('web'); - if ($userID > 0) { - $id = APIHelpers::getkey($params, 'homeID'); - if (empty($id)) { - $id = $this->modx->getConfig('login_home', $this->config['site_start']); - } - $this->moveTo(compact('id')); - } - - return; - } - - /** - * Редирект - */ - public function moveTo($params) - { - $id = (int)APIHelpers::getkey($params, 'id', 0); - $uri = APIHelpers::getkey($params, 'url', ''); - if ((empty($uri) && !empty($id)) || !is_string($uri)) { - $uri = $this->makeUrl($id); - } - $code = (int)APIHelpers::getkey($params, 'code', 0); - $addUrl = APIHelpers::getkey($params, 'addUrl', ''); - if (is_scalar($addUrl) && $addUrl != '') { - $uri .= "?" . $addUrl; - } - if (APIHelpers::getkey($params, 'validate', false)) { - if (isset($this->modx->snippetCache['getPageID'])) { - $out = $this->modx->runSnippet('getPageID', compact('uri')); - if (empty($out)) { - $uri = ''; - } - } else { - $uri = APIhelpers::sanitarTag($uri); - } - } else { - header("Location: " . $uri, true, ($code > 0 ? $code : 307)); - } - - return $uri; - } - - /** - * Создание ссылки на страницу - * - * @param int $id ID документа - * @return string - */ - protected function makeUrl($id = null) - { - $id = (int)$id; - if ($id <= 0) { - $id = $this->modx->documentObject['id']; - } - if ($this->url->containsKey($id)) { - $url = $this->url->get($id); - } else { - $url = $this->modx->makeUrl($id); - $this->url->set($id, $url); - } - - return $url; - } - - /** - * @param $name - * @return string - */ - protected function getTemplate($name) - { - $out = ''; - $file = dirname(dirname(__FILE__)) . '/tpl/' . $name . '.html'; - if (FS::getInstance()->checkFile($file)) { - $out = '@CODE: ' . file_get_contents($file); - } - - return $out; - } - - /** - * @param $lang - * @return bool - */ - protected static function loadLang($lang) - { - $file = dirname(dirname(__FILE__)) . '/lang/' . $lang . '.php'; - if (!FS::getInstance()->checkFile($file)) { - $file = false; - } - if (!empty($lang) && !isset(static::$langDic[$lang]) && !empty($file)) { - static::$langDic[$lang] = include_once($file); - if (is_array(static::$langDic[$lang])) { - static::$langDic[$lang] = APIHelpers::renameKeyArr(static::$langDic[$lang], $lang); - } else { - static::$langDic[$lang] = array(); - } - } - - return !(empty($lang) || empty(static::$langDic[$lang])); - } - - /** - * @param $key - * @param $default - * @return string - */ - protected static function getLangMsg($key, $default) - { - $out = $default; - $lng = static::$lang; - $dic = static::$langDic; - if (isset($dic[$lng], $dic[$lng][$lng . '.' . $key])) { - $out = $dic[$lng][$lng . '.' . $key]; - } - if (class_exists('evoBabel', false) && isset(self::$instance->modx->snippetCache['lang'])) { - $msg = self::$instance->modx->runSnippet('lang', array('a' => 'DLUsers.' . $key)); - if (!empty($msg)) { - $out = $msg; - } - } - - return $out; - } -} diff --git a/assets/snippets/DLUsers/tpl/authForm.html b/assets/snippets/DLUsers/tpl/authForm.html deleted file mode 100755 index bc4ac5e802..0000000000 --- a/assets/snippets/DLUsers/tpl/authForm.html +++ /dev/null @@ -1,9 +0,0 @@ -[+error:isnotempty=` -
[+error+]
`+] -
- - - Email:
- Password:
- -
\ No newline at end of file diff --git a/assets/snippets/DLUsers/tpl/tplProfile.html b/assets/snippets/DLUsers/tpl/tplProfile.html deleted file mode 100755 index 543bf5c2db..0000000000 --- a/assets/snippets/DLUsers/tpl/tplProfile.html +++ /dev/null @@ -1,3 +0,0 @@ -[+fullname+] -[+url.profile:isnotempty=`Личный кабинет`+] -Выход \ No newline at end of file From 900854ba0dae528437989ce2d18b74b442e3c7bd Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 20 Jul 2017 00:34:19 +0300 Subject: [PATCH 015/338] fix issues #66 format code --- manager/includes/accesscontrol.inc.php | 150 ++++----- manager/processors/login.processor.php | 407 +++++++++++++------------ 2 files changed, 286 insertions(+), 271 deletions(-) diff --git a/manager/includes/accesscontrol.inc.php b/manager/includes/accesscontrol.inc.php index 9e95ea5b1e..6f239b41c9 100644 --- a/manager/includes/accesscontrol.inc.php +++ b/manager/includes/accesscontrol.inc.php @@ -1,35 +1,36 @@ INCLUDE_ORDERING_ERROR


Please use the MODX Content Manager instead of accessing this file directly."); +if(IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

Please use the MODX Content Manager instead of accessing this file directly."); +} if(!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { header('HTTP/1.0 404 Not Found'); exit; } -if (isset($_SESSION['mgrValidated']) && $_SESSION['usertype']!='manager'){ -// if (isset($_COOKIE[session_name()])) { -// setcookie(session_name(), '', 0, MODX_BASE_URL); -// } +if(isset($_SESSION['mgrValidated']) && $_SESSION['usertype'] != 'manager') { + // if (isset($_COOKIE[session_name()])) { + // setcookie(session_name(), '', 0, MODX_BASE_URL); + // } @session_destroy(); // start session -// startCMSSession(); + // startCMSSession(); } // andrazk 20070416 - if installer is running, destroy active sessions -if (file_exists(MODX_BASE_PATH . 'assets/cache/installProc.inc.php')) { +if(file_exists(MODX_BASE_PATH . 'assets/cache/installProc.inc.php')) { include_once(MODX_BASE_PATH . 'assets/cache/installProc.inc.php'); - if (isset($installStartTime)) { - if ((time() - $installStartTime) > 5 * 60) { // if install flag older than 5 minutes, discard + if(isset($installStartTime)) { + if((time() - $installStartTime) > 5 * 60) { // if install flag older than 5 minutes, discard unset($installStartTime); @ chmod(MODX_BASE_PATH . 'assets/cache/installProc.inc.php', 0755); unlink(MODX_BASE_PATH . 'assets/cache/installProc.inc.php'); - } - else { - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - if (isset($_COOKIE[session_name()])) { + } else { + if($_SERVER['REQUEST_METHOD'] != 'POST') { + if(isset($_COOKIE[session_name()])) { session_unset(); @session_destroy(); -// setcookie(session_name(), '', 0, MODX_BASE_URL); + // setcookie(session_name(), '', 0, MODX_BASE_URL); } $installGoingOn = 1; } @@ -38,83 +39,86 @@ } // andrazk 20070416 - if session started before install and was not destroyed yet -if (isset($lastInstallTime)) { - if (isset($_SESSION['mgrValidated'])) { - if (isset($_SESSION['modx.session.created.time'])) { - if ($_SESSION['modx.session.created.time'] < $lastInstallTime) { - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - if (isset($_COOKIE[session_name()])) { +if(isset($lastInstallTime)) { + if(isset($_SESSION['mgrValidated'])) { + if(isset($_SESSION['modx.session.created.time'])) { + if($_SESSION['modx.session.created.time'] < $lastInstallTime) { + if($_SERVER['REQUEST_METHOD'] != 'POST') { + if(isset($_COOKIE[session_name()])) { session_unset(); @session_destroy(); -// setcookie(session_name(), '', 0, MODX_BASE_URL); + // setcookie(session_name(), '', 0, MODX_BASE_URL); } header('HTTP/1.0 307 Redirect'); - header('Location: '.MODX_MANAGER_URL.'index.php?installGoingOn=2'); + header('Location: ' . MODX_MANAGER_URL . 'index.php?installGoingOn=2'); } } } } } -if(!isset($_SESSION['mgrValidated'])){ +if(!isset($_SESSION['mgrValidated'])) { if(isset($manager_language)) { // establish fallback to English default include_once "lang/english.inc.php"; // include localized overrides - include_once "lang/".$manager_language.".inc.php"; - } - else { + include_once "lang/" . $manager_language . ".inc.php"; + } else { include_once "lang/english.inc.php"; } - $modx->setPlaceholder('modx_charset',$modx_manager_charset); - $modx->setPlaceholder('theme',$manager_theme); + $modx->setPlaceholder('modx_charset', $modx_manager_charset); + $modx->setPlaceholder('theme', $manager_theme); // invoke OnManagerLoginFormPrerender event $evtOut = $modx->invokeEvent('OnManagerLoginFormPrerender'); - $html = is_array($evtOut) ? implode('',$evtOut) : ''; - $modx->setPlaceholder('OnManagerLoginFormPrerender',$html); + $html = is_array($evtOut) ? implode('', $evtOut) : ''; + $modx->setPlaceholder('OnManagerLoginFormPrerender', $html); - $modx->setPlaceholder('site_name',$site_name); - $modx->setPlaceholder('manager_path',MGR_DIR); - $modx->setPlaceholder('logo_slogan',$_lang["logo_slogan"]); - $modx->setPlaceholder('login_message',$_lang["login_message"]); - $modx->setPlaceholder('manager_theme_url',MODX_MANAGER_URL . 'media/style/' . $modx->config['manager_theme'] . '/'); - $modx->setPlaceholder('year',date('Y')); + $modx->setPlaceholder('site_name', $site_name); + $modx->setPlaceholder('manager_path', MGR_DIR); + $modx->setPlaceholder('logo_slogan', $_lang["logo_slogan"]); + $modx->setPlaceholder('login_message', $_lang["login_message"]); + $modx->setPlaceholder('manager_theme_url', MODX_MANAGER_URL . 'media/style/' . $modx->config['manager_theme'] . '/'); + $modx->setPlaceholder('year', date('Y')); // andrazk 20070416 - notify user of install/update - if (isset($_GET['installGoingOn'])) { + if(isset($_GET['installGoingOn'])) { $installGoingOn = $_GET['installGoingOn']; } - if (isset($installGoingOn)) { - switch ($installGoingOn) { - case 1 : $modx->setPlaceholder('login_message',"

".$_lang["login_cancelled_install_in_progress"]."

".$_lang["login_message"]."

"); break; - case 2 : $modx->setPlaceholder('login_message',"

".$_lang["login_cancelled_site_was_updated"]."

".$_lang["login_message"]."

"); break; + if(isset($installGoingOn)) { + switch($installGoingOn) { + case 1 : + $modx->setPlaceholder('login_message', "

" . $_lang["login_cancelled_install_in_progress"] . "

" . $_lang["login_message"] . "

"); + break; + case 2 : + $modx->setPlaceholder('login_message', "

" . $_lang["login_cancelled_site_was_updated"] . "

" . $_lang["login_message"] . "

"); + break; } } - if($use_captcha==1) { - $modx->setPlaceholder('login_captcha_message',$_lang["login_captcha_message"]); - $modx->setPlaceholder('captcha_image',''.$_lang['); - $modx->setPlaceholder('captcha_input',' '); + if($modx->config['use_captcha'] == 1) { + $modx->setPlaceholder('login_captcha_message', $_lang["login_captcha_message"]); + $modx->setPlaceholder('captcha_image', '' . $_lang['); + $modx->setPlaceholder('captcha_input', ' '); } // login info - $uid = isset($_COOKIE['modx_remember_manager']) ? preg_replace('/[^a-zA-Z0-9\-_@\.]*/', '', $_COOKIE['modx_remember_manager']) :''; - $modx->setPlaceholder('uid',$uid); - $modx->setPlaceholder('username',$_lang["username"]); - $modx->setPlaceholder('password',$_lang["password"]); + $uid = isset($_COOKIE['modx_remember_manager']) ? preg_replace('/[^a-zA-Z0-9\-_@\.]*/', '', $_COOKIE['modx_remember_manager']) : ''; + $modx->setPlaceholder('uid', $uid); + $modx->setPlaceholder('username', $_lang["username"]); + $modx->setPlaceholder('password', $_lang["password"]); // remember me - $html = isset($_COOKIE['modx_remember_manager']) ? 'checked="checked"' :''; - $modx->setPlaceholder('remember_me',$html); - $modx->setPlaceholder('remember_username',$_lang["remember_username"]); - $modx->setPlaceholder('login_button',$_lang["login_button"]); + $html = isset($_COOKIE['modx_remember_manager']) ? 'checked="checked"' : ''; + $modx->setPlaceholder('remember_me', $html); + $modx->setPlaceholder('remember_username', $_lang["remember_username"]); + $modx->setPlaceholder('login_button', $_lang["login_button"]); // invoke OnManagerLoginFormRender event $evtOut = $modx->invokeEvent('OnManagerLoginFormRender'); - $html = is_array($evtOut) ? '
'.implode('',$evtOut).'
' : ''; - $modx->setPlaceholder('OnManagerLoginFormRender',$html); + $html = is_array($evtOut) ? '
' . implode('', $evtOut) . '
' : ''; + $modx->setPlaceholder('OnManagerLoginFormRender', $html); // load template $target = $modx->getConfig('manager_login_tpl'); @@ -122,20 +126,21 @@ $target = $modx->mergeSettingsContent($target); $login_tpl = null; - if(substr($target,0,1)==='@') { - if(substr($target,0,6)==='@CHUNK') { - $target = trim(substr($target,7)); + if(substr($target, 0, 1) === '@') { + if(substr($target, 0, 6) === '@CHUNK') { + $target = trim(substr($target, 7)); $login_tpl = $modx->getChunk($target); - } - elseif(substr($target,0,5)==='@FILE') { - $target = trim(substr($target,6)); + } elseif(substr($target, 0, 5) === '@FILE') { + $target = trim(substr($target, 6)); $login_tpl = file_get_contents($target); } } else { $theme_path = MODX_MANAGER_PATH . 'media/style/' . $modx->config['manager_theme'] . '/'; - if(is_file($theme_path . 'style.php')) include($theme_path . 'style.php'); + if(is_file($theme_path . 'style.php')) { + include($theme_path . 'style.php'); + } $chunk = $modx->getChunk($target); - if($chunk!==false && !empty($chunk)) { + if($chunk !== false && !empty($chunk)) { $login_tpl = $chunk; } elseif(is_file(MODX_BASE_PATH . $target)) { $target = MODX_BASE_PATH . $target; @@ -159,7 +164,7 @@ // merge placeholders $login_tpl = $modx->mergePlaceholderContent($login_tpl); - $regx = strpos($login_tpl,'[[+')!==false ? '~\[\[\+(.*?)\]\]~' : '~\[\+(.*?)\+\]~'; // little tweak for newer parsers + $regx = strpos($login_tpl, '[[+') !== false ? '~\[\[\+(.*?)\]\]~' : '~\[\+(.*?)\+\]~'; // little tweak for newer parsers $login_tpl = preg_replace($regx, '', $login_tpl); //cleanup echo $login_tpl; @@ -169,23 +174,18 @@ } else { // Update table active_user_sessions $modx->updateValidatedUserSession(); - + // Update last action in table active_users $itemid = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : ''; $lasthittime = time(); $action = isset($_REQUEST['a']) ? (int) $_REQUEST['a'] : 1; if($action !== 1) { - if (!intval($itemid)) $itemid= null; - $sql = sprintf("REPLACE INTO %s (sid, internalKey, username, lasthit, action, id) VALUES ('%s', %d, '%s', %d, '%s', %s)" - , $modx->getFullTableName('active_users') // Table - , session_id() - , $modx->getLoginUserID() - , $_SESSION['mgrShortname'] - , $lasthittime - , (string)$action - , $itemid == null ? var_export(null, true) : $itemid - ); + if(!intval($itemid)) { + $itemid = null; + } + $sql = sprintf("REPLACE INTO %s (sid, internalKey, username, lasthit, action, id) VALUES ('%s', %d, '%s', %d, '%s', %s)", $modx->getFullTableName('active_users') // Table + , session_id(), $modx->getLoginUserID(), $_SESSION['mgrShortname'], $lasthittime, (string) $action, $itemid == null ? var_export(null, true) : $itemid); $modx->db->query($sql); } } \ No newline at end of file diff --git a/manager/processors/login.processor.php b/manager/processors/login.processor.php index aa1106ea18..95b1550ee5 100755 --- a/manager/processors/login.processor.php +++ b/manager/processors/login.processor.php @@ -1,17 +1,18 @@ db->escape($modx->htmlspecialchars($_REQUEST['username'], ENT_NOQUOTES)); +$username = $modx->db->escape($modx->htmlspecialchars($_REQUEST['username'], ENT_NOQUOTES)); $givenPassword = $modx->htmlspecialchars($_REQUEST['password'], ENT_NOQUOTES); -$captcha_code = $_REQUEST['captcha_code']; -$rememberme = $_REQUEST['rememberme']; +$captcha_code = $_REQUEST['captcha_code']; +$rememberme = $_REQUEST['rememberme']; $failed_allowed = $modx->config['failed_login_attempts']; // invoke OnBeforeManagerLogin event -$modx->invokeEvent('OnBeforeManagerLogin', - array( - 'username' => $username, - 'userpassword' => $givenPassword, - 'rememberme' => $rememberme - )); +$modx->invokeEvent('OnBeforeManagerLogin', array( + 'username' => $username, + 'userpassword' => $givenPassword, + 'rememberme' => $rememberme + )); $fields = 'mu.*, ua.*'; -$from = '[+prefix+]manager_users AS mu, [+prefix+]user_attributes AS ua'; -$where = "BINARY mu.username='{$username}' and ua.internalKey=mu.id"; -$rs = $modx->db->select($fields, $from,$where); +$from = '[+prefix+]manager_users AS mu, [+prefix+]user_attributes AS ua'; +$where = "BINARY mu.username='{$username}' and ua.internalKey=mu.id"; +$rs = $modx->db->select($fields, $from, $where); $limit = $modx->db->getRecordCount($rs); -if($limit==0 || $limit>1) { - jsAlert($_lang['login_processor_unknown_user']); - return; +if($limit == 0 || $limit > 1) { + jsAlert($_lang['login_processor_unknown_user']); + return; } $row = $modx->db->getRow($rs); -$internalKey = $row['internalKey']; -$dbasePassword = $row['password']; -$failedlogins = $row['failedlogincount']; -$blocked = $row['blocked']; -$blockeduntildate = $row['blockeduntil']; -$blockedafterdate = $row['blockedafter']; -$registeredsessionid = $row['sessionid']; -$role = $row['role']; -$lastlogin = $row['lastlogin']; -$nrlogins = $row['logincount']; -$fullname = $row['fullname']; -$email = $row['email']; +$internalKey = $row['internalKey']; +$dbasePassword = $row['password']; +$failedlogins = $row['failedlogincount']; +$blocked = $row['blocked']; +$blockeduntildate = $row['blockeduntil']; +$blockedafterdate = $row['blockedafter']; +$registeredsessionid = $row['sessionid']; +$role = $row['role']; +$lastlogin = $row['lastlogin']; +$nrlogins = $row['logincount']; +$fullname = $row['fullname']; +$email = $row['email']; // get the user settings from the database $rs = $modx->db->select('setting_name, setting_value', '[+prefix+]user_settings', "user='{$internalKey}' AND setting_value!=''"); -while ($row = $modx->db->getRow($rs)) { - extract($row); - ${$setting_name} = $setting_value; +while($row = $modx->db->getRow($rs)) { + extract($row); + ${$setting_name} = $setting_value; } // blocked due to number of login errors. -if($failedlogins>=$failed_allowed && $blockeduntildate>time()) { - @session_destroy(); - session_unset(); - if ($cip = getenv("HTTP_CLIENT_IP")) - $ip = $cip; - elseif ($cip = getenv("HTTP_X_FORWARDED_FOR")) - $ip = $cip; - elseif ($cip = getenv("REMOTE_ADDR")) - $ip = $cip; - else $ip = "UNKNOWN"; - $log = new logHandler; - $log->initAndWriteLog("Login Fail (Temporary Block)", $internalKey, $username, "119", $internalKey, "IP: ".$ip); - jsAlert($_lang['login_processor_many_failed_logins']); - return; +if($failedlogins >= $failed_allowed && $blockeduntildate > time()) { + @session_destroy(); + session_unset(); + if($cip = getenv("HTTP_CLIENT_IP")) { + $ip = $cip; + } elseif($cip = getenv("HTTP_X_FORWARDED_FOR")) { + $ip = $cip; + } elseif($cip = getenv("REMOTE_ADDR")) { + $ip = $cip; + } else { + $ip = "UNKNOWN"; + } + $log = new logHandler; + $log->initAndWriteLog("Login Fail (Temporary Block)", $internalKey, $username, "119", $internalKey, "IP: " . $ip); + jsAlert($_lang['login_processor_many_failed_logins']); + return; } // blocked due to number of login errors, but get to try again -if($failedlogins>=$failed_allowed && $blockeduntildate= $failed_allowed && $blockeduntildate < time()) { $fields = array(); $fields['failedlogincount'] = '0'; - $fields['blockeduntil'] = time()-1; - $modx->db->update($fields,'[+prefix+]user_attributes',"internalKey='{$internalKey}'"); + $fields['blockeduntil'] = time() - 1; + $modx->db->update($fields, '[+prefix+]user_attributes', "internalKey='{$internalKey}'"); } // this user has been blocked by an admin, so no way he's loggin in! -if($blocked=='1') { - @session_destroy(); - session_unset(); - jsAlert($_lang['login_processor_blocked1']); - return; +if($blocked == '1') { + @session_destroy(); + session_unset(); + jsAlert($_lang['login_processor_blocked1']); + return; } // blockuntil: this user has a block until date -if($blockeduntildate>time()) { - @session_destroy(); - session_unset(); - jsAlert($_lang['login_processor_blocked2']); - return; +if($blockeduntildate > time()) { + @session_destroy(); + session_unset(); + jsAlert($_lang['login_processor_blocked2']); + return; } // blockafter: this user has a block after date -if($blockedafterdate>0 && $blockedafterdate 0 && $blockedafterdate < time()) { + @session_destroy(); + session_unset(); + jsAlert($_lang['login_processor_blocked3']); + return; } // allowed ip -if ($allowed_ip) { - if(($hostname = gethostbyaddr($_SERVER['REMOTE_ADDR'])) && ($hostname != $_SERVER['REMOTE_ADDR'])) { - if(gethostbyname($hostname) != $_SERVER['REMOTE_ADDR']) { - jsAlert($_lang['login_processor_remotehost_ip']); - return; - } - } - if(!in_array($_SERVER['REMOTE_ADDR'], array_filter(array_map('trim', explode(',', $allowed_ip))))) { - jsAlert($_lang['login_processor_remote_ip']); - return; - } +if($allowed_ip) { + if(($hostname = gethostbyaddr($_SERVER['REMOTE_ADDR'])) && ($hostname != $_SERVER['REMOTE_ADDR'])) { + if(gethostbyname($hostname) != $_SERVER['REMOTE_ADDR']) { + jsAlert($_lang['login_processor_remotehost_ip']); + return; + } + } + if(!in_array($_SERVER['REMOTE_ADDR'], array_filter(array_map('trim', explode(',', $allowed_ip))))) { + jsAlert($_lang['login_processor_remote_ip']); + return; + } } // allowed days -if ($allowed_days) { - $date = getdate(); - $day = $date['wday']+1; - if (strpos($allowed_days, $day)===false) { - jsAlert($_lang['login_processor_date']); - return; - } +if($allowed_days) { + $date = getdate(); + $day = $date['wday'] + 1; + if(strpos($allowed_days, $day) === false) { + jsAlert($_lang['login_processor_date']); + return; + } } // invoke OnManagerAuthentication event -$rt = $modx->invokeEvent('OnManagerAuthentication', - array( - 'userid' => $internalKey, - 'username' => $username, - 'userpassword' => $givenPassword, - 'savedpassword' => $dbasePassword, - 'rememberme' => $rememberme - )); +$rt = $modx->invokeEvent('OnManagerAuthentication', array( + 'userid' => $internalKey, + 'username' => $username, + 'userpassword' => $givenPassword, + 'savedpassword' => $dbasePassword, + 'rememberme' => $rememberme + )); // check if plugin authenticated the user $matchPassword = false; -if (!isset($rt) || !$rt || (is_array($rt) && !in_array(true,$rt))) -{ +if(!isset($rt) || !$rt || (is_array($rt) && !in_array(true, $rt))) { // check user password - local authentication $hashType = $modx->manager->getHashType($dbasePassword); - if($hashType=='phpass') $matchPassword = login($username,$_REQUEST['password'],$dbasePassword); - elseif($hashType=='md5') $matchPassword = loginMD5($internalKey,$givenPassword,$dbasePassword,$username); - elseif($hashType=='v1') $matchPassword = loginV1($internalKey,$givenPassword,$dbasePassword,$username); - else $matchPassword = false; -} else if($rt === true || (is_array($rt) && in_array(true,$rt))) { + if($hashType == 'phpass') { + $matchPassword = login($username, $_REQUEST['password'], $dbasePassword); + } elseif($hashType == 'md5') { + $matchPassword = loginMD5($internalKey, $givenPassword, $dbasePassword, $username); + } elseif($hashType == 'v1') { + $matchPassword = loginV1($internalKey, $givenPassword, $dbasePassword, $username); + } else { + $matchPassword = false; + } +} else if($rt === true || (is_array($rt) && in_array(true, $rt))) { $matchPassword = true; } if(!$matchPassword) { jsAlert($_lang['login_processor_wrong_password']); - incrementFailedLoginCount($internalKey,$failedlogins,$failed_allowed,$blocked_minutes); + incrementFailedLoginCount($internalKey, $failedlogins, $failed_allowed, $blocked_minutes); return; } -if($use_captcha==1) { - if (!isset ($_SESSION['veriword'])) { - jsAlert($_lang['login_processor_captcha_config']); +if($modx->config['use_captcha'] == 1) { + if(!isset ($_SESSION['veriword'])) { + jsAlert($_lang['login_processor_captcha_config']); + return; + } elseif($_SESSION['veriword'] != $captcha_code) { + jsAlert($_lang['login_processor_bad_code']); + incrementFailedLoginCount($internalKey, $failedlogins, $failed_allowed, $blocked_minutes); return; } - elseif ($_SESSION['veriword'] != $captcha_code) { - jsAlert($_lang['login_processor_bad_code']); - incrementFailedLoginCount($internalKey,$failedlogins,$failed_allowed,$blocked_minutes); - return; - } } $modx->cleanupExpiredLocks(); @@ -211,159 +217,168 @@ $_SESSION['usertype'] = 'manager'; // user is a backend user // get permissions -$_SESSION['mgrShortname']=$username; -$_SESSION['mgrFullname']=$fullname; -$_SESSION['mgrEmail']=$email; -$_SESSION['mgrValidated']=1; -$_SESSION['mgrInternalKey']=$internalKey; -$_SESSION['mgrFailedlogins']=$failedlogins; -$_SESSION['mgrLastlogin']=$lastlogin; -$_SESSION['mgrLogincount']=$nrlogins; // login count -$_SESSION['mgrRole']=$role; +$_SESSION['mgrShortname'] = $username; +$_SESSION['mgrFullname'] = $fullname; +$_SESSION['mgrEmail'] = $email; +$_SESSION['mgrValidated'] = 1; +$_SESSION['mgrInternalKey'] = $internalKey; +$_SESSION['mgrFailedlogins'] = $failedlogins; +$_SESSION['mgrLastlogin'] = $lastlogin; +$_SESSION['mgrLogincount'] = $nrlogins; // login count +$_SESSION['mgrRole'] = $role; $rs = $modx->db->select('*', $modx->getFullTableName('user_roles'), "id='{$role}'"); $_SESSION['mgrPermissions'] = $modx->db->getRow($rs); // successful login so reset fail count and update key values -$modx->db->update( - 'failedlogincount=0, ' - . 'logincount=logincount+1, ' - . 'lastlogin=thislogin, ' - . 'thislogin=' . time() . ', ' - . "sessionid='{$currentsessionid}'", '[+prefix+]user_attributes', "internalKey='{$internalKey}'" -); +$modx->db->update('failedlogincount=0, ' . 'logincount=logincount+1, ' . 'lastlogin=thislogin, ' . 'thislogin=' . time() . ', ' . "sessionid='{$currentsessionid}'", '[+prefix+]user_attributes', "internalKey='{$internalKey}'"); // get user's document groups -$i=0; -$rs = $modx->db->select( - 'uga.documentgroup', - $modx->getFullTableName('member_groups').' ug - INNER JOIN ' . $modx->getFullTableName('membergroup_access').' uga ON uga.membergroup=ug.user_group', - "ug.member='{$internalKey}'" - ); +$i = 0; +$rs = $modx->db->select('uga.documentgroup', $modx->getFullTableName('member_groups') . ' ug + INNER JOIN ' . $modx->getFullTableName('membergroup_access') . ' uga ON uga.membergroup=ug.user_group', "ug.member='{$internalKey}'"); $_SESSION['mgrDocgroups'] = $modx->db->getColumn('documentgroup', $rs); if($rememberme == '1') { - $_SESSION['modx.mgr.session.cookie.lifetime']= intval($modx->config['session.cookie.lifetime']); - + $_SESSION['modx.mgr.session.cookie.lifetime'] = intval($modx->config['session.cookie.lifetime']); + // Set a cookie separate from the session cookie with the username in it. // Are we using secure connection? If so, make sure the cookie is secure global $https_port; - - $secure = ( (isset ($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') || $_SERVER['SERVER_PORT'] == $https_port); - if ( version_compare(PHP_VERSION, '5.2', '<') ) { - setcookie('modx_remember_manager', $_SESSION['mgrShortname'], time()+60*60*24*365, MODX_BASE_URL, '; HttpOnly' , $secure ); + + $secure = ((isset ($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') || $_SERVER['SERVER_PORT'] == $https_port); + if(version_compare(PHP_VERSION, '5.2', '<')) { + setcookie('modx_remember_manager', $_SESSION['mgrShortname'], time() + 60 * 60 * 24 * 365, MODX_BASE_URL, '; HttpOnly', $secure); } else { - setcookie('modx_remember_manager', $_SESSION['mgrShortname'], time()+60*60*24*365, MODX_BASE_URL, NULL, $secure, true); + setcookie('modx_remember_manager', $_SESSION['mgrShortname'], time() + 60 * 60 * 24 * 365, MODX_BASE_URL, NULL, $secure, true); } } else { - $_SESSION['modx.mgr.session.cookie.lifetime']= 0; - + $_SESSION['modx.mgr.session.cookie.lifetime'] = 0; + // Remove the Remember Me cookie - setcookie ('modx_remember_manager', '', time() - 3600, MODX_BASE_URL); + setcookie('modx_remember_manager', '', time() - 3600, MODX_BASE_URL); } // Check if user already has an active session, if not check if user pressed logout end of last session $rs = $modx->db->select('lasthit', $modx->getFullTableName('active_user_sessions'), "internalKey='{$internalKey}'"); $activeSession = $modx->db->getValue($rs); if(!$activeSession) { - $rs = $modx->db->select('lasthit', $modx->getFullTableName('active_users'), "internalKey='{$internalKey}' AND action != 8"); - if ($lastHit = $modx->db->getValue($rs)) $_SESSION['show_logout_reminder'] = array('type'=>'logout_reminder', 'lastHit'=>$lastHit); + $rs = $modx->db->select('lasthit', $modx->getFullTableName('active_users'), "internalKey='{$internalKey}' AND action != 8"); + if($lastHit = $modx->db->getValue($rs)) { + $_SESSION['show_logout_reminder'] = array( + 'type' => 'logout_reminder', + 'lastHit' => $lastHit + ); + } } $log = new logHandler; $log->initAndWriteLog('Logged in', $modx->getLoginUserID(), $_SESSION['mgrShortname'], '58', '-', 'MODX'); // invoke OnManagerLogin event -$modx->invokeEvent('OnManagerLogin', - array( - 'userid' => $internalKey, - 'username' => $username, - 'userpassword' => $givenPassword, - 'rememberme' => $rememberme - )); +$modx->invokeEvent('OnManagerLogin', array( + 'userid' => $internalKey, + 'username' => $username, + 'userpassword' => $givenPassword, + 'rememberme' => $rememberme + )); // check if we should redirect user to a web page $rs = $modx->db->select('setting_value', '[+prefix+]user_settings', "user='{$internalKey}' AND setting_name='manager_login_startup'"); $id = intval($modx->db->getValue($rs)); -if($id>0) { - $header = 'Location: '.$modx->makeUrl($id,'','','full'); - if($_POST['ajax']==1) echo $header; - else header($header); -} -else { - $header = 'Location: '.MODX_MANAGER_URL; - if($_POST['ajax']==1) echo $header; - else header($header); +if($id > 0) { + $header = 'Location: ' . $modx->makeUrl($id, '', '', 'full'); + if($_POST['ajax'] == 1) { + echo $header; + } else { + header($header); + } +} else { + $header = 'Location: ' . MODX_MANAGER_URL; + if($_POST['ajax'] == 1) { + echo $header; + } else { + header($header); + } } // show javascript alert -function jsAlert($msg){ +function jsAlert($msg) { global $modx; - if($_POST['ajax']!=1) echo ""; - else echo $msg."\n"; + if($_POST['ajax'] != 1) { + echo ""; + } else { + echo $msg . "\n"; + } } -function login($username,$givenPassword,$dbasePassword) { +function login($username, $givenPassword, $dbasePassword) { global $modx; return $modx->phpass->CheckPassword($givenPassword, $dbasePassword); } -function loginV1($internalKey,$givenPassword,$dbasePassword,$username) { +function loginV1($internalKey, $givenPassword, $dbasePassword, $username) { global $modx; - + $user_algo = $modx->manager->getV1UserHashAlgorithm($internalKey); - - if(!isset($modx->config['pwd_hash_algo']) || empty($modx->config['pwd_hash_algo'])) + + if(!isset($modx->config['pwd_hash_algo']) || empty($modx->config['pwd_hash_algo'])) { $modx->config['pwd_hash_algo'] = 'UNCRYPT'; - + } + if($user_algo !== $modx->config['pwd_hash_algo']) { $bk_pwd_hash_algo = $modx->config['pwd_hash_algo']; $modx->config['pwd_hash_algo'] = $user_algo; } - + if($dbasePassword != $modx->manager->genV1Hash($givenPassword, $internalKey)) { return false; } - - updateNewHash($username,$givenPassword); - + + updateNewHash($username, $givenPassword); + return true; } -function loginMD5($internalKey,$givenPassword,$dbasePassword,$username) { +function loginMD5($internalKey, $givenPassword, $dbasePassword, $username) { global $modx; - - if($dbasePassword != md5($givenPassword)) return false; - updateNewHash($username,$givenPassword); + + if($dbasePassword != md5($givenPassword)) { + return false; + } + updateNewHash($username, $givenPassword); return true; } -function updateNewHash($username,$password) { +function updateNewHash($username, $password) { global $modx; - + $field = array(); $field['password'] = $modx->phpass->HashPassword($password); $modx->db->update($field, '[+prefix+]manager_users', "username='{$username}'"); } -function incrementFailedLoginCount($internalKey,$failedlogins,$failed_allowed,$blocked_minutes) { +function incrementFailedLoginCount($internalKey, $failedlogins, $failed_allowed, $blocked_minutes) { global $modx; - - $failedlogins += 1; - $fields = array('failedlogincount' => $failedlogins); - if($failedlogins>=$failed_allowed) //block user for too many fail attempts - $fields['blockeduntil'] = time()+($blocked_minutes*60); + $failedlogins += 1; + + $fields = array('failedlogincount' => $failedlogins); + if($failedlogins >= $failed_allowed) //block user for too many fail attempts + { + $fields['blockeduntil'] = time() + ($blocked_minutes * 60); + } - $modx->db->update($fields, '[+prefix+]user_attributes', "internalKey='{$internalKey}'"); + $modx->db->update($fields, '[+prefix+]user_attributes', "internalKey='{$internalKey}'"); - if($failedlogins<$failed_allowed) { + if($failedlogins < $failed_allowed) { //sleep to help prevent brute force attacks - $sleep = (int)$failedlogins/2; - if($sleep>5) $sleep = 5; - sleep($sleep); - } + $sleep = (int) $failedlogins / 2; + if($sleep > 5) { + $sleep = 5; + } + sleep($sleep); + } @session_destroy(); session_unset(); - return; + return; } From 2c71ff6a6b5b778ecb4f26fcd1dc11c7843d243a Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Thu, 20 Jul 2017 00:42:29 +0300 Subject: [PATCH 016/338] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=88=D0=B8=D0=BB=D1=8C=D0=B4=D0=B8=D0=BA=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D0=B8=20PHP=20=D0=BF=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D0=BE=D0=BB=D0=BE=D0=B2=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bc69b073e5..2852878796 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Evolution CMS +![PHP version](https://img.shields.io/badge/PHP->=v5.6-green.svg?php=5.6) +---- **What is EVO** EVO is an open source Content Management System and Application Framework. Initially inspired by Etomite 0.6, then it been MODX Evolution 0.7 - 1.0.8 is an ongoing project written by Raymond Irving and a core team of contributors MODX, and now its Evolution CMS maintained by Dmytro Lukianenko and a core team of contributors at the EVO Project. EVO is distributed under the GPL license and is now run by a professional team of developers from all over the world. Visit the Forums for more information. From aa00f6c8ac8d8b46adb61a8ef3d55f4193be00b2 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 20 Jul 2017 02:38:19 +0300 Subject: [PATCH 017/338] fix issues #71 --- manager/frames/1.php | 3 +- manager/media/style/default/ajax.php | 86 ++++++++++++++++---------- manager/media/style/default/js/modx.js | 30 +++++---- 3 files changed, 71 insertions(+), 48 deletions(-) diff --git a/manager/frames/1.php b/manager/frames/1.php index c756a64bc2..40044fedb8 100644 --- a/manager/frames/1.php +++ b/manager/frames/1.php @@ -168,7 +168,8 @@ edit_snippet: hasPermission('edit_snippet') ? 1 : 0 ?>, edit_template: hasPermission('edit_template') ? 1 : 0 ?>, new_document: hasPermission('new_document') ? 1 : 0 ?>, - publish_document: hasPermission('publish_document') ? 1 : 0 ?> + publish_document: hasPermission('publish_document') ? 1 : 0 ?>, + dragndropdocintree: hasPermission('new_document') && $modx->hasPermission('edit_document') && $modx->hasPermission('save_document') ? 1 : 0) ?> }, plugins: { diff --git a/manager/media/style/default/ajax.php b/manager/media/style/default/ajax.php index 4b7ede1c10..9168fd949f 100644 --- a/manager/media/style/default/ajax.php +++ b/manager/media/style/default/ajax.php @@ -20,6 +20,7 @@ $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : ''; $frame = isset($_REQUEST['f']) ? $_REQUEST['f'] : ''; +$role = isset($_SESSION['mgrRole']) ? $_SESSION['mgrRole'] : ''; // set limit sql query $limit = !empty($modx->config['number_of_results']) ? $modx->config['number_of_results'] : 100; @@ -46,7 +47,6 @@ $items = ''; $sql = ''; $a = ''; - $role = $_SESSION['mgrRole']; $filter = !empty($_REQUEST['filter']) ? addcslashes(trim($_REQUEST['filter']), '%*_') : ''; $sqlLike = $filter ? 'WHERE t1.name LIKE "' . $modx->db->escape($filter) . '%"' : ''; $sqlLimit = $sqlLike ? '' : 'LIMIT ' . $limit; @@ -457,48 +457,66 @@ } case 'movedocument' : { - $id = !empty($_REQUEST['id']) ? (int) $_REQUEST['id'] : ''; - $parent = isset($_REQUEST['parent']) ? (int) $_REQUEST['parent'] : 0; - $menuindex = isset($_REQUEST['menuindex']) ? $_REQUEST['menuindex'] : 0; - - // set parent - if($id && $parent >= 0) { - // находим старого родителя - $parentOld = $modx->db->getValue($modx->db->select('parent', $modx->getFullTableName('site_content'), 'id=' . $id)); - - // устанавливаем нового родителя - $modx->db->update(array( - 'parent' => $parent - ), $modx->getFullTableName('site_content'), 'id=' . $id); - // устанавливаем родителю isfolder = 1 - $modx->db->update(array( - 'isfolder' => 1 - ), $modx->getFullTableName('site_content'), 'id=' . $parent); - - if($parent != $parentOld) { - // проверяем остались ли дочерние ресурсы у родителя и меняем значение isfolder - if($modx->db->getRecordCount($modx->db->select('id', $modx->getFullTableName('site_content'), 'parent=' . $parentOld))) { - $modx->db->update(array( - 'isfolder' => 1 - ), $modx->getFullTableName('site_content'), 'id=' . $parentOld); + $json = array(); + + if($modx->hasPermission('new_document') && $modx->hasPermission('edit_document') && $modx->hasPermission('save_document')) { + $id = !empty($_REQUEST['id']) ? (int) $_REQUEST['id'] : ''; + $parent = isset($_REQUEST['parent']) ? (int) $_REQUEST['parent'] : 0; + $menuindex = isset($_REQUEST['menuindex']) ? $_REQUEST['menuindex'] : 0; + + // set parent + if($id && $parent >= 0) { + // находим старого родителя + $parentOld = $modx->db->getValue($modx->db->select('parent', $modx->getFullTableName('site_content'), 'id=' . $id)); + + if($parent == 0 && $parent != $parentOld && (!$modx->config['udperms_allowroot'] && $role != 1)) { + $json['errors'] = $_lang["error_no_privileges"]; } else { + // устанавливаем нового родителя $modx->db->update(array( - 'isfolder' => 0 - ), $modx->getFullTableName('site_content'), 'id=' . $parentOld); + 'parent' => $parent + ), $modx->getFullTableName('site_content'), 'id=' . $id); + // устанавливаем родителю isfolder = 1 + $modx->db->update(array( + 'isfolder' => 1 + ), $modx->getFullTableName('site_content'), 'id=' . $parent); + + if($parent != $parentOld) { + // проверяем остались ли дочерние ресурсы у родителя и меняем значение isfolder + if($modx->db->getRecordCount($modx->db->select('id', $modx->getFullTableName('site_content'), 'parent=' . $parentOld))) { + $modx->db->update(array( + 'isfolder' => 1 + ), $modx->getFullTableName('site_content'), 'id=' . $parentOld); + } else { + $modx->db->update(array( + 'isfolder' => 0 + ), $modx->getFullTableName('site_content'), 'id=' . $parentOld); + } + } } } - } - // set menuindex - if(!empty($menuindex)) { - $menuindex = explode(',', $menuindex); - foreach($menuindex as $key => $value) { - $modx->db->query('UPDATE ' . $modx->getFullTableName('site_content') . ' SET menuindex=' . $key . ' WHERE id =' . $value); + // set menuindex + if(!empty($menuindex)) { + $menuindex = explode(',', $menuindex); + foreach($menuindex as $key => $value) { + $modx->db->query('UPDATE ' . $modx->getFullTableName('site_content') . ' SET menuindex=' . $key . ' WHERE id =' . $value); + } + } else { + // TODO: max(*) menuindex + } + + if(!$json['errors']) { + $json['success'] = $_lang["actioncomplete"]; } + } else { - // TODO: max(*) menuindex + $json['errors'] = $_lang["error_no_privileges"]; } + header('content-type: application/json'); + echo json_encode($json); + break; } } diff --git a/manager/media/style/default/js/modx.js b/manager/media/style/default/js/modx.js index 4936904dad..93429aa3b7 100644 --- a/manager/media/style/default/js/modx.js +++ b/manager/media/style/default/js/modx.js @@ -600,14 +600,16 @@ this.restoreTree() }, draggable: function() { - var els = d.querySelectorAll('#treeRoot a:not(.empty)'); - for(var i = 0; i < els.length; i++) { - els[i].onmousedown = this.onmousedown; - els[i].ondragstart = this.ondragstart; - els[i].ondragenter = this.ondragenter; - els[i].ondragover = this.ondragover; - els[i].ondragleave = this.ondragleave; - els[i].ondrop = this.ondrop; + if(modx.permission.dragndropdocintree) { + var els = d.querySelectorAll('#treeRoot a:not(.empty)'); + for(var i = 0; i < els.length; i++) { + els[i].onmousedown = this.onmousedown; + els[i].ondragstart = this.ondragstart; + els[i].ondragenter = this.ondragenter; + els[i].ondragover = this.ondragover; + els[i].ondragleave = this.ondragleave; + els[i].ondrop = this.ondrop; + } } }, onmousedown: function(e) { @@ -684,7 +686,6 @@ id = modx.tree.itemToChange.substr(4), parent = 0, menuindex = [], - index = 0, level = 0, indent = el.firstChild.querySelector('.indent'), i = 0; @@ -736,9 +737,10 @@ id: id, parent: parent, menuindex: menuindex - }, function() { - modx.tree.restoreTree() - }); + }, function(r) { + if(r.errors) alert(r.errors); + modx.tree.restoreTree(); + }, 'json'); var b = w.main.frameElement.contentWindow.location.search.substr(1); if(parseInt(modx.main.getQueryVariable('a', b)) === 27 && parseInt(modx.main.getQueryVariable('id', b)) === parseInt(id)) { var index = menuindex.indexOf(id), @@ -1421,10 +1423,11 @@ }; x.send() }, - post: function(a, b, c) { + post: function(a, b, c, t) { var x = this.XHR(), f = ''; if(typeof b === 'function') { + t = c; c = b; } else if(typeof b === 'object') { var e = [], @@ -1440,6 +1443,7 @@ x.open('POST', a, true); x.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); x.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest'); + if(t) x.responseType = t; x.onload = function() { if(this.readyState === 4 && c !== u) { return c(this.response) From c469b0ed840dfd48eddecbcb5593d35e47c88ceb Mon Sep 17 00:00:00 2001 From: Dmytro Lukianenko Date: Thu, 20 Jul 2017 02:56:55 +0300 Subject: [PATCH 018/338] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2852878796..e2debaf7e4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Evolution CMS -![PHP version](https://img.shields.io/badge/PHP->=v5.6-green.svg?php=5.6) +![PHP version](https://img.shields.io/badge/PHP->=v5.6-green.svg?php=5.6) [![GitHub release](https://img.shields.io/github/release/evolution-cms/evolution.svg)](https://github.com/evolution-cms/evolution/) ---- **What is EVO** From 3ac1ef3fad157f3e8d200e5beffbb012f2a3363b Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 20 Jul 2017 04:08:09 +0300 Subject: [PATCH 019/338] fix issues #73 update login form --- manager/includes/accesscontrol.inc.php | 3 +- manager/media/style/default/login.tpl | 125 ++++++++++--------------- 2 files changed, 54 insertions(+), 74 deletions(-) diff --git a/manager/includes/accesscontrol.inc.php b/manager/includes/accesscontrol.inc.php index 6f239b41c9..653500619d 100644 --- a/manager/includes/accesscontrol.inc.php +++ b/manager/includes/accesscontrol.inc.php @@ -81,6 +81,7 @@ $modx->setPlaceholder('login_message', $_lang["login_message"]); $modx->setPlaceholder('manager_theme_url', MODX_MANAGER_URL . 'media/style/' . $modx->config['manager_theme'] . '/'); $modx->setPlaceholder('year', date('Y')); + $modx->setPlaceholder('manager_theme_style', (isset($_COOKIE['MODX_themeColor']) ? $_COOKIE['MODX_themeColor'] : '')); // andrazk 20070416 - notify user of install/update if(isset($_GET['installGoingOn'])) { @@ -188,4 +189,4 @@ , session_id(), $modx->getLoginUserID(), $_SESSION['mgrShortname'], $lasthittime, (string) $action, $itemid == null ? var_export(null, true) : $itemid); $modx->db->query($sql); } -} \ No newline at end of file +} diff --git a/manager/media/style/default/login.tpl b/manager/media/style/default/login.tpl index 8a06d39aa0..220c3db9ee 100644 --- a/manager/media/style/default/login.tpl +++ b/manager/media/style/default/login.tpl @@ -6,85 +6,63 @@ - - -
-
- [+OnManagerLoginFormPrerender+] -
-
+ +
+
+ + [+OnManagerLoginFormPrerender+] + - - - - -

[+login_captcha_message+]

-

[+captcha_image+]

- [+captcha_input+] -
-
-
+ +
+
+

+
© 2005-2017 by the EVO. EVO™ is licensed under the GPL.
+
-

-
© 2005-2017 by the EVO. EVO™ is licensed under the GPL.
- +
- + + \ No newline at end of file From f83719a043dec2408c7a6655117b71a9bf44cd88 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 20 Jul 2017 10:32:11 +0300 Subject: [PATCH 020/338] fix for multiTV need branch name Evolution --- manager/includes/version.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/version.inc.php b/manager/includes/version.inc.php index ee46b38bb9..dc5269c6c1 100755 --- a/manager/includes/version.inc.php +++ b/manager/includes/version.inc.php @@ -1,5 +1,5 @@ Date: Thu, 20 Jul 2017 10:35:47 +0300 Subject: [PATCH 021/338] 1.3.3 --- assets/docs/changelog.txt | 20 +++++++++++++++++--- manager/includes/version.inc.php | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/assets/docs/changelog.txt b/assets/docs/changelog.txt index 06d476c159..e899d01909 100644 --- a/assets/docs/changelog.txt +++ b/assets/docs/changelog.txt @@ -1,17 +1,31 @@ This file shows the changes in recent releases of MODX. The most current release is usually the development release, and is only shown to give an idea of what's currently in the pipeline. -Evolution CMS 1.3.2 (Jul 10, 2017) +Evolution CMS 1.3.3 (Jul 20, 2017) +* [GitHub:#f83719a0] - [F] fix for multiTV<10.0.12 (need branch name Evolution) (dmi3yy) +* [GitHub:#3ac1ef3f] - [F] fix issues #73 update login form (64j) +* [GitHub:#c469b0ed] - [I] Update README.md add version informer (Dmytro Lukianenko) +* [GitHub:#aa00f6c8] - [F] fix issues #71 (64j) +* [GitHub:#2c71ff6a] - [F] update Readme add php informer (Anton Kolesnikov) +* [GitHub:#900854ba] - [F] fix issues #66 format code (64j) +* [GitHub:#ee27d087] - [C] remove unused files DLUsers (dmi3yy) +* [GitHub:#d4c67e6a] - [I] FormLister need PHP >= 5.6 (Anton Kolesnikov) +* [GitHub:#8e4594f8] - [F] fix issues #72 forma code (64j) + + +Evolution CMS 1.3.2 (Jul 19, 2017) * [GitHub:#a8fc2fdf] - [F] updater plugin (dmi3yy) * [GitHub:#ad14254c] - [F] fix #75 (Pathologic) * [GitHub:#d29faf9a] - [R] refactor sortableList (64j) * [GitHub:#ffa63034] - [F] fix #68 (for hide widget better use $widgets['welcome']['hide'] = 1;) (dmi3yy) -Evolution CMS 1.3.1 (Jul 10, 2017) + +Evolution CMS 1.3.1 (Jul 19, 2017) * [GitHub:#c2348530] - [F] DocLister 2.3.5 fix paginate (dmi3yy) * [GitHub:#6daadd0f] - [F] version in top menu (dmi3yy) -Evolution CMS 1.3.0 (Jul 10, 2017) + +Evolution CMS 1.3.0 (Jul 19, 2017) * [GitHub:#3dda520a] - [R] update sortables list delete mootools sortables (64j) * [GitHub:#9cafe6db] - [F] fix toggle menu (64j) * [GitHub:#6c316c18] - [I] Update DocLister add DLmenu (dmi3yy) diff --git a/manager/includes/version.inc.php b/manager/includes/version.inc.php index dc5269c6c1..1f8bf98260 100755 --- a/manager/includes/version.inc.php +++ b/manager/includes/version.inc.php @@ -1,5 +1,5 @@ Date: Thu, 20 Jul 2017 10:46:16 +0300 Subject: [PATCH 022/338] [I] add installer link in Readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index e2debaf7e4..e457061041 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,11 @@ EVO provides a fast, lightweight and powerful framework on which to deploy and s Evolution CMS requires **PHP version 5.6 and higher**. + +### Install +for easy and fast install you can use [Evo Installer](https://github.com/evolution-cms/installer) + + ### Screenshots ![screenshot_1](https://cloud.githubusercontent.com/assets/523389/20504423/97db8bf8-b047-11e6-9eef-550c1c7d34f2.jpg) From 2fe1694c741c4b6cc5fac6db2b9850d4f2ca7a48 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 20 Jul 2017 11:35:16 +0300 Subject: [PATCH 023/338] fix readme --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e457061041..35bd14c3cc 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ # Evolution CMS -![PHP version](https://img.shields.io/badge/PHP->=v5.6-green.svg?php=5.6) [![GitHub release](https://img.shields.io/github/release/evolution-cms/evolution.svg)](https://github.com/evolution-cms/evolution/) ----- -**What is EVO** +![PHP version](https://img.shields.io/badge/PHP->=v5.4-green.svg?php=5.4) [![GitHub release](https://img.shields.io/github/release/evolution-cms/evolution.svg)](https://github.com/evolution-cms/evolution/) + +Evolution CMS requires **PHP >= 5.4**, but snippet FormLister need **PHP >=5.6** + + +## What is EVO EVO is an open source Content Management System and Application Framework. Initially inspired by Etomite 0.6, then it been MODX Evolution 0.7 - 1.0.8 is an ongoing project written by Raymond Irving and a core team of contributors MODX, and now its Evolution CMS maintained by Dmytro Lukianenko and a core team of contributors at the EVO Project. EVO is distributed under the GPL license and is now run by a professional team of developers from all over the world. Visit the Forums for more information. EVO provides a fast, lightweight and powerful framework on which to deploy and secure your website and web applications. For example, it gives you a true system for registered web users and groups that is separate from administration users. You can grant some web users access to one page and others access to another page. For content management, you can easily duplicate documents, folders (and all their children!), chunks and snippets. Most significant, though, is EVO's ability to empower you to quickly and easily create and maintain a rich and dynamic website like never before. -Evolution CMS requires **PHP version 5.6 and higher**. ### Install From 12007dec9f1936c08b735a908e0395bbdd56ef4d Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 20 Jul 2017 16:11:55 +0200 Subject: [PATCH 024/338] [F] #87 missing OnManagerTopPrerender https://github.com/evolution-cms/evolution/issues/87 --- manager/frames/1.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/manager/frames/1.php b/manager/frames/1.php index c756a64bc2..37f4be9ae9 100644 --- a/manager/frames/1.php +++ b/manager/frames/1.php @@ -191,7 +191,14 @@ ?> - +invokeEvent('OnManagerTopPrerender', $_REQUEST); +if(is_array($evtOut)) { + echo implode("\n", $evtOut); +} +?> +
From bd649a9f8908b1c8956c5628c03c323779e97ca3 Mon Sep 17 00:00:00 2001 From: Pathologic Date: Fri, 21 Jul 2017 02:30:53 +0300 Subject: [PATCH 025/338] fix #93 --- .../tab1_site_settings.inc.php | 46 +++++++++---------- .../tab2_furl_settings.inc.php | 22 ++++----- .../tab3_user_settings.inc.php | 14 +++--- .../tab4_manager_settings.inc.php | 40 ++++++++-------- .../tab5_security_settings.inc.php | 28 +++++------ .../tab6_filemanager_settings.inc.php | 16 +++---- .../tab7_filebrowser_settings.inc.php | 32 ++++++------- 7 files changed, 99 insertions(+), 99 deletions(-) diff --git a/manager/actions/mutate_settings/tab1_site_settings.inc.php b/manager/actions/mutate_settings/tab1_site_settings.inc.php index e9153d3cbf..7b12b8f789 100644 --- a/manager/actions/mutate_settings/tab1_site_settings.inc.php +++ b/manager/actions/mutate_settings/tab1_site_settings.inc.php @@ -11,50 +11,50 @@ - + - + - + - + - + - + - + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/manager/actions/mutate_settings/tab2_furl_settings.inc.php b/manager/actions/mutate_settings/tab2_furl_settings.inc.php index 5a8ac2cf10..2269244e37 100644 --- a/manager/actions/mutate_settings/tab2_furl_settings.inc.php +++ b/manager/actions/mutate_settings/tab2_furl_settings.inc.php @@ -4,7 +4,7 @@

[(site_status)]

htmlspecialchars($_lang['sitename_title']) ?>htmlspecialchars($_lang['sitename_title']) ?>
[(site_name)]

[(emailsender)]

[(site_start)]

[(error_page)]

[(unauthorized_page)]

[(site_unavailable_page)]
+
[(site_unavailable_message)]


[(default_template)]
db->select( @@ -121,7 +121,7 @@

[(auto_template_logic)]


@@ -130,7 +130,7 @@

[(enable_filter)]

[(publish_default)]

@@ -159,7 +159,7 @@

[(cache_default)]

@@ -167,7 +167,7 @@

[(search_default)]

@@ -175,7 +175,7 @@

[(auto_menuindex)]

@@ -200,7 +200,7 @@

[(docid_incrmnt_method)]

[(cache_type)]


[(minifyphp_incache)]

@@ -232,7 +232,7 @@

[(server_offset_time)]

[(server_protocol)]

@@ -256,13 +256,13 @@

[(rss_url_news)]

[(track_visitors)]

@@ -270,7 +270,7 @@

[(top_howmany)]
- + - + > - +> @@ -43,7 +43,7 @@ > - +> @@ -54,7 +54,7 @@ > - +> - +> - + > - +> - +> - +> - + - From 9b2b89f4aea6370d21fd83ab883edaaff65f148d Mon Sep 17 00:00:00 2001 From: Pathologic Date: Tue, 1 Aug 2017 12:55:03 +0300 Subject: [PATCH 130/338] update DLMenu --- .../DocLister/core/controller/site_content_menu.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/assets/snippets/DocLister/core/controller/site_content_menu.php b/assets/snippets/DocLister/core/controller/site_content_menu.php index f0be9aa0b7..f7b80b0c88 100644 --- a/assets/snippets/DocLister/core/controller/site_content_menu.php +++ b/assets/snippets/DocLister/core/controller/site_content_menu.php @@ -42,7 +42,11 @@ public function getDocs($tvlist = '') $maxDepth = $this->getCFGDef('maxDepth', 10); //TODO кэширование if ($this->getCFGDef('hideSubMenus', 0) && empty($this->getCFGDef('openIds'))) { - $maxDepth = $this->setActiveBranch($this->getHereId()); + $maxDepth = min($maxDepth, $this->setActiveBranch($this->getHereId())); + if (empty(array_intersect($this->IDs, $this->activeBranch))) { + $maxDepth = 1; + $this->config->setConfig(array('hideSubMenus' => 0)); + }; } else { $this->setActiveBranch($this->getHereId()); } @@ -243,6 +247,7 @@ public function _render($tpl = '') unset($docs[$currentLevel]); $currentLevel--; } + unset($data); $out = ''; $joinMenus = $this->getCFGDef('joinMenus', 0) && !$this->getCFGDef('showParents', 0); From c5ec13edcca2d8857006aa2b736423aeff97afbf Mon Sep 17 00:00:00 2001 From: Nicola Date: Tue, 1 Aug 2017 13:44:23 +0200 Subject: [PATCH 131/338] revert https://github.com/Nicola1971/evolution/commit/0a6889f553e1ea59406a29638fc311b59f22f37a --- manager/media/style/default/css/fonts.css | 1 + 1 file changed, 1 insertion(+) diff --git a/manager/media/style/default/css/fonts.css b/manager/media/style/default/css/fonts.css index 2dbf369c9c..082df7380f 100644 --- a/manager/media/style/default/css/fonts.css +++ b/manager/media/style/default/css/fonts.css @@ -97,4 +97,5 @@ h1 small { margin-left: 0.5em; line-height: 1em } #previewIframe { width: 100%; height: 400px; } .messageRead { color: #333; } .messageUnread { color: #3CB371; font-weight: 500; } +.element-edit-message { display: none } .element-edit-message p:last-child, .element-edit-message-tab p:last-child { margin-bottom: 0 } From d36bf3f92a7a3b5165f12921c782d6456c472eeb Mon Sep 17 00:00:00 2001 From: Nicola Date: Tue, 1 Aug 2017 13:46:21 +0200 Subject: [PATCH 132/338] https://github.com/evolution-cms/evolution/issues/135 reverted the css fix and changed class in the module reverted the css fix and changed class in the module --- manager/actions/category_mgr/skin/add.tpl.phtml | 2 +- manager/actions/category_mgr/skin/categorize.tpl.phtml | 2 +- manager/actions/category_mgr/skin/edit.tpl.phtml | 2 +- manager/actions/category_mgr/skin/sort.tpl.phtml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/manager/actions/category_mgr/skin/add.tpl.phtml b/manager/actions/category_mgr/skin/add.tpl.phtml index 7a857666e3..c414e37413 100644 --- a/manager/actions/category_mgr/skin/add.tpl.phtml +++ b/manager/actions/category_mgr/skin/add.tpl.phtml @@ -5,7 +5,7 @@
  • - ' . "\n", $modx->config['mgr_jquery_path']); ?> - - - - - - - - - - + + + ' . "\n", $modx->config['mgr_jquery_path']) ?> + + + + + + + + + + - class=""> + class=""> diff --git a/manager/media/style/default/style.css b/manager/media/style/default/style.css index 15f597cf5f..b089d34a47 100644 --- a/manager/media/style/default/style.css +++ b/manager/media/style/default/style.css @@ -139,10 +139,10 @@ form#mutate select.tv_url_select { padding: 5px 3px; } /* ppb: * Style mootools tooltips */ +.evo-tooltip, .custom-tip { position: fixed; z-index: 13000; width: 13rem; margin: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); -webkit-box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); } +.evo-tooltip { opacity: 0; content: attr(data-tooltip); } +.evo-tooltip.show { opacity: 1; visibility: visible; transform: translate3d(0, 0, 0); } [data-tooltip] { cursor: help } -[data-tooltip]::after, .custom-tip { position: absolute; z-index: 13000; width: 13rem; margin-left: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; border: 1px solid #ccc; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); } -[data-tooltip]::after { opacity: 0; content: attr(data-tooltip); } -[data-tooltip]:hover::after { opacity: 1; visibility: visible; transform: translate3d(0, 0, 0); } [data-tooltip].fa-question-circle { opacity: 0.15; } [data-tooltip].fa-question-circle:hover { opacity: 1; } th > [data-tooltip].fa-question-circle, td > [data-tooltip].fa-question-circle { float: right; } From b3ecfd0f204f6ebf948f01b0fc202a62edd6ba7f Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Wed, 2 Aug 2017 03:22:31 +0300 Subject: [PATCH 138/338] refactor bkmanager --- manager/actions/bkmanager.static.php | 182 +++++++++++++++------------ 1 file changed, 100 insertions(+), 82 deletions(-) diff --git a/manager/actions/bkmanager.static.php b/manager/actions/bkmanager.static.php index 50cbf4568b..cfb8685d2f 100644 --- a/manager/actions/bkmanager.static.php +++ b/manager/actions/bkmanager.static.php @@ -119,12 +119,12 @@ if (isset($_SESSION['result_msg']) && $_SESSION['result_msg'] != '') { switch ($_SESSION['result_msg']) { case 'import_ok': - $ph['result_msg_import'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; - $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; + $ph['result_msg_import'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; + $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; break; case 'snapshot_ok': $ph['result_msg_import'] = ''; - $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_snapshot_ok"] . '
    '; + $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_snapshot_ok"] . '
    '; break; } $_SESSION['result_msg'] = ''; @@ -165,12 +165,24 @@ function confirmRevert(filename) { var m = ''; m = m.replace('[+filename+]', filename); - var c = confirm(m); - if (c) { + if (confirm(m) === true) { document.restore2.filename.value = filename; document.restore2.save.click(); } } + + function showhide(a) + { + var f = document.getElementById('sqlfile'); + var t = document.getElementById('textarea'); + if (a == 'file') { + f.style.display = 'block'; + t.style.display = 'none'; + } else { + t.style.display = 'block'; + f.style.display = 'none'; + } + } @@ -181,7 +193,6 @@ function confirmRevert(filename) -
    $v) { $title[] = $k; } - $result = '
    '; + $result = ''; + $result .= ''; foreach ($last_result as $row) { $result_value = array(); if ($row) { @@ -334,7 +334,8 @@ function showhide(a) $result .= ''; } } - $result = '

    [(friendly_urls)]

    @@ -18,7 +18,7 @@

    [(xhtml_urls)]

    @@ -32,7 +32,7 @@

    [(friendly_url_prefix)]

    [(friendly_url_suffix)]

    [(make_folders)]

    @@ -69,7 +69,7 @@

    [(seostrict)]

    @@ -84,7 +84,7 @@

    [(aliaslistingfolder)]

    @@ -99,7 +99,7 @@

    [(friendly_alias_urls)]

    @@ -113,7 +113,7 @@

    [(use_alias_path)]

    @@ -127,7 +127,7 @@

    [(allow_duplicate_alias)]

    @@ -141,7 +141,7 @@

    [(automatic_alias)]

    diff --git a/manager/actions/mutate_settings/tab3_user_settings.inc.php b/manager/actions/mutate_settings/tab3_user_settings.inc.php index 83e5b93135..31320489eb 100644 --- a/manager/actions/mutate_settings/tab3_user_settings.inc.php +++ b/manager/actions/mutate_settings/tab3_user_settings.inc.php @@ -4,7 +4,7 @@ - + > - + - + - - - - '; + foreach ($last_result as $row) { + $result_value = array(); + if ($row) { + foreach ($row as $k => $v) { + $result_value[] = $v; + } + $result .= ''; + } + } + $result = '

    [(use_udperms)]

    @@ -18,7 +18,7 @@

    [(udperms_allowroot)]

    @@ -37,7 +37,7 @@

    [(email_method)]

    @@ -50,7 +50,7 @@
    +
    [(emailsubject)]

    +
    [(signupemail_message)]

    +
    [(websignupemail_message)]

    +
    [(webpwdreminder_message)]

    - + @@ -17,7 +17,7 @@ - + @@ -30,7 +30,7 @@ - + - + - + - + - + - + - + @@ -156,7 +156,7 @@ - + - + @@ -197,7 +197,7 @@ - + - + @@ -231,7 +231,7 @@ - + @@ -242,7 +242,7 @@ - + @@ -253,7 +253,7 @@ - + @@ -272,7 +272,7 @@ } ?> > - + > - + > - + @@ -324,7 +324,7 @@ > - + diff --git a/manager/actions/mutate_settings/tab5_security_settings.inc.php b/manager/actions/mutate_settings/tab5_security_settings.inc.php index 3d87f7e186..bebb006549 100644 --- a/manager/actions/mutate_settings/tab5_security_settings.inc.php +++ b/manager/actions/mutate_settings/tab5_security_settings.inc.php @@ -9,7 +9,7 @@

    [(manager_language)]

    [(modx_charset)]

    [(manager_theme)]

    [(warning_visibility)]


    [(tree_page_click)]

    @@ -86,7 +86,7 @@

    [(use_breadcrumbs)]

    @@ -102,7 +102,7 @@

    [(remember_last_tab)]

    @@ -117,7 +117,7 @@

    [(resource_tree_node_name)]

    [(session_timeout)]

    [(tree_show_protected)]

    @@ -186,7 +186,7 @@

    [(datepicker_offset)]

    [(datetime_format)]

    [(number_of_logs)]

    [(mail_check_timeperiod)]

    [(number_of_messages)]

    [(number_of_results)]

    [(use_editor)]

    @@ -288,7 +288,7 @@

    [(which_editor)]

    [(fe_editor_lang)]

    [(editor_css_path)]
    - + - + - + - + - + @@ -72,7 +72,7 @@ - + @@ -83,7 +83,7 @@ - + - + - + - + @@ -139,7 +139,7 @@ - + @@ -150,7 +150,7 @@ - + - + > - '; - foreach($last_result as $row) { - $result_value = array(); - if($row) { - foreach($row as $k => $v) { - $result_value[] = $v; - } - $result .= ''; - } - } - $style = ''; - $result = $style . '

    [(allow_eval)]


    @@ -24,7 +24,7 @@

    [(safe_functions_at_eval)]
    @@ -37,7 +37,7 @@

    [(check_files_onlogin)]

    @@ -47,7 +47,7 @@

    [(validate_referer)]

    @@ -61,7 +61,7 @@

    [(valid_hostnames)]

    [(rss_url_security)]

    [(error_reporting)]


    @@ -97,7 +97,7 @@

    [(send_errormail)]


    @@ -109,7 +109,7 @@

    [(enable_bindings)]

    @@ -128,7 +128,7 @@

    [(failed_login_attempts)]

    [(blocked_minutes)]

    [(pwd_hash_algo)]

    [(use_captcha)]

    +
    [(captcha_words)]

    - + - + @@ -31,7 +31,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -57,7 +57,7 @@ - + @@ -70,7 +70,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -96,7 +96,7 @@ - + diff --git a/manager/actions/mutate_settings/tab7_filebrowser_settings.inc.php b/manager/actions/mutate_settings/tab7_filebrowser_settings.inc.php index 01ab003ba6..2534a2de5d 100644 --- a/manager/actions/mutate_settings/tab7_filebrowser_settings.inc.php +++ b/manager/actions/mutate_settings/tab7_filebrowser_settings.inc.php @@ -4,7 +4,7 @@

    [(filemanager_path)]
    [(base_path)]
    @@ -18,7 +18,7 @@

    [(upload_files)]

    [(upload_images)]

    [(upload_media)]

    [(upload_flash)]

    [(upload_maxsize)]

    [(new_file_permissions)]

    [(new_folder_permissions)]
    - + > - + > - + > - + > - + @@ -84,7 +84,7 @@ > - + > - + > - + @@ -129,7 +129,7 @@ > - + @@ -142,7 +142,7 @@ > - + @@ -155,7 +155,7 @@ > - + @@ -168,7 +168,7 @@ > - + @@ -181,7 +181,7 @@ > - + @@ -194,7 +194,7 @@ > - + > - + > - + "; + } else { + echo ""; + } + ?> + + + + + + + + + + + + + +

    [(use_browser)]

    @@ -19,7 +19,7 @@

    [(which_browser)]

    [(rb_webuser)]

    @@ -57,7 +57,7 @@

    [(rb_base_dir)]
    [(base_path)]assets/
    @@ -71,7 +71,7 @@

    [(rb_base_url)]

    [(clean_uploaded_filename)]

    @@ -100,7 +100,7 @@

    [(strip_image_paths)]

    @@ -116,7 +116,7 @@

    [(maxImageWidth)]

    [(maxImageHeight)]

    [(thumbWidth)]

    [(thumbHeight)]

    [(thumbsDir)]

    [(jpegQuality)]

    [(denyZipDownload)]

    @@ -206,7 +206,7 @@

    [(denyExtensionRename)]

    @@ -218,7 +218,7 @@

    [(showHiddenFiles)]

    From 60a779401982751c6305febcd2bacb21d3782af0 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 21 Jul 2017 10:27:09 +0300 Subject: [PATCH 026/338] [F] fix #94 Hide rss widgets if rss_url_news and rss_url_security settings are empty --- manager/actions/welcome.static.php | 40 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/manager/actions/welcome.static.php b/manager/actions/welcome.static.php index e39f229748..24e0178616 100644 --- a/manager/actions/welcome.static.php +++ b/manager/actions/welcome.static.php @@ -336,24 +336,28 @@ 'body' => '
    [+RecentInfo+]
    ', 'hide'=>'0' ); -$widgets['news'] = array( - 'menuindex' => '40', - 'id' => 'news', - 'cols' => 'col-sm-6', - 'icon' => 'fa-rss', - 'title' => '[%modx_news_title%]', - 'body' => '
    [+modx_news_content+]
    ', - 'hide'=>'0' -); -$widgets['security'] = array( - 'menuindex' => '50', - 'id' => 'security', - 'cols' => 'col-sm-6', - 'icon' => 'fa-exclamation-triangle', - 'title' => '[%security_notices_title%]', - 'body' => '
    [+modx_security_notices_content+]
    ', - 'hide'=>'0' -); +if ($modx->config['rss_url_news']) { + $widgets['news'] = array( + 'menuindex' => '40', + 'id' => 'news', + 'cols' => 'col-sm-6', + 'icon' => 'fa-rss', + 'title' => '[%modx_news_title%]', + 'body' => '
    [+modx_news_content+]
    ', + 'hide'=>'0' + ); +} +if ($modx->config['rss_url_security']) { + $widgets['security'] = array( + 'menuindex' => '50', + 'id' => 'security', + 'cols' => 'col-sm-6', + 'icon' => 'fa-exclamation-triangle', + 'title' => '[%security_notices_title%]', + 'body' => '
    [+modx_security_notices_content+]
    ', + 'hide'=>'0' + ); +} // invoke OnManagerWelcomeHome event $sitewidgets = $modx->invokeEvent("OnManagerWelcomeHome", array('widgets' => $widgets)); From 8fd7d31f151a29d90ef797efaf65080a4c799ab4 Mon Sep 17 00:00:00 2001 From: Deesen Date: Fri, 21 Jul 2017 11:14:27 +0200 Subject: [PATCH 027/338] [F] Avoid "Fatal error: Call to undefined function curl_init()" --- assets/plugins/updater/plugin.updater.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/assets/plugins/updater/plugin.updater.php b/assets/plugins/updater/plugin.updater.php index 218e3497a1..6e96f85e46 100644 --- a/assets/plugins/updater/plugin.updater.php +++ b/assets/plugins/updater/plugin.updater.php @@ -32,6 +32,7 @@ if (!extension_loaded('curl')){ $errorsMessage .= '-'.$_lang['error_curl'].'
    '; $errors += 1; + $curlNotReady = true; } if (!extension_loaded('zip')){ $errorsMessage .= '-'.$_lang['error_zip'].'
    '; @@ -46,6 +47,23 @@ $errors += 1; } + // Avoid "Fatal error: Call to undefined function curl_init()" + if(isset($curlNotReady)) { + $output = '
    + '.$errorsMessage.'
    '; + + $widgets['updater'] = array( + 'menuindex' =>'1', + 'id' => 'updater', + 'cols' => 'col-sm-12', + 'icon' => 'fa-exclamation-triangle', + 'title' => $_lang['system_update'], + 'body' => $output + ); + $e->output(serialize($widgets)); + return; + } + $output = ''; if(!file_exists(MODX_BASE_PATH . 'assets/cache/updater/check_'.date("d").'.json')){ $ch = curl_init(); From d834d0f0168abea6f4ae07ab9b3b1c8fd4fa5c00 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Fri, 21 Jul 2017 23:22:19 +0900 Subject: [PATCH 028/338] Change product name --- install/functions.php | 2 +- install/index.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/install/functions.php b/install/functions.php index 47fb063253..1f39dc99d3 100644 --- a/install/functions.php +++ b/install/functions.php @@ -52,7 +52,7 @@ function ph() $ph['pagetitle'] = $_lang['modx_install']; $ph['textdir'] = $modx_textdir ? ' id="rtl"':''; $ph['help_link'] = $installmode == 0 ? $_lang['help_link_new'] : $_lang['help_link_upd']; - $ph['version'] = $moduleName.' '.$moduleVersion; + $ph['version'] = $moduleVersion; $ph['release_date'] = ($modx_textdir ? '‏':'') . $modx_release_date; $ph['footer1'] = $_lang['modx_footer1']; $ph['footer2'] = $_lang['modx_footer2']; diff --git a/install/index.php b/install/index.php index 4f4f4cdf18..05725a4521 100644 --- a/install/index.php +++ b/install/index.php @@ -1,6 +1,6 @@ Date: Fri, 21 Jul 2017 17:34:58 +0300 Subject: [PATCH 029/338] remove redundant code - tags are cleaned in cleanUpMODXTags --- manager/includes/document.parser.class.inc.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index d6f4fcbadb..d704338844 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -714,14 +714,6 @@ function outputContent($noEvent= false) { $this->documentOutput = $this->cleanUpMODXTags($this->documentOutput); - // remove all unused placeholders - if (strpos($this->documentOutput, '[+')!==false) { - $matches= array (); - preg_match_all('~\[\+(.*?)\+\]~s', $this->documentOutput, $matches); - if ($matches[0]) - $this->documentOutput= str_replace($matches[0], '', $this->documentOutput); - } - $this->documentOutput= $this->rewriteUrls($this->documentOutput); // send out content-type and content-disposition headers From 7b60d2cc34e60c93080ae7793de8b219078e4d61 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sat, 22 Jul 2017 14:03:50 +0300 Subject: [PATCH 030/338] fix #71 fix permissions --- manager/actions/document_data.static.php | 17 +++--- manager/frames/1.php | 2 + manager/frames/nodes.functions.inc.php | 23 ++++---- manager/media/style/default/ajax.php | 63 ++++++++++++++-------- manager/media/style/default/css/custom.css | 1 + manager/media/style/default/css/fonts.css | 1 - manager/media/style/default/css/page.css | 6 +-- manager/media/style/default/css/tree.css | 4 +- manager/media/style/default/js/modx.js | 15 ++++-- manager/media/style/default/style.css | 4 +- 10 files changed, 79 insertions(+), 57 deletions(-) diff --git a/manager/actions/document_data.static.php b/manager/actions/document_data.static.php index 7173f44f66..1f0bffbd66 100644 --- a/manager/actions/document_data.static.php +++ b/manager/actions/document_data.static.php @@ -170,16 +170,9 @@ break; default: if($children['isfolder']) { - $isPrivate = ($children['privateweb'] || $children['privatemgr']) ? '1' : '0'; - $icon = $isPrivate ? $_style['tree_folder_secure'] : $_style['tree_folder_new']; + $icon = $_style['tree_folder_new']; } else { - if($children['privateweb'] || $children['privatemgr']) { - if(isset($icons[$children['contentType']])) { - $icon = $icons[$children['contentType']]; - } else { - $icon = $_style['tree_page_secure']; - } - } elseif(isset($icons[$children['contentType']])) { + if(isset($icons[$children['contentType']])) { $icon = $icons[$children['contentType']]; } else { $icon = $_style['tree_page']; @@ -187,15 +180,17 @@ } } + $private = ($children['privateweb'] || $children['privatemgr'] ? ' private' : ''); + // дописываем в заголовок класс для неопубликованных плюс по всем ссылкам обратный путь // для сохранения сортировки $class = ($children['deleted'] ? 'text-danger text-decoration-through' : (!$children['published'] ? ' font-italic text-muted' : ' publish')); //$class .= ($children['hidemenu'] ? ' text-muted' : ' text-primary'); //$class .= ($children['isfolder'] ? ' font-weight-bold' : ''); if($modx->hasPermission('edit_document')) { - $title = '' . $icon . '' . $children['pagetitle'] . ''; + $title = '' . $icon . '' . $children['pagetitle'] . ''; } else { - $title = '' . $icon . '' . $children['pagetitle'] . ''; + $title = '' . $icon . '' . $children['pagetitle'] . ''; } $icon_pub_unpub = (!$children['published']) ? '' : ''; diff --git a/manager/frames/1.php b/manager/frames/1.php index ae6cea6644..ce3d12aa95 100644 --- a/manager/frames/1.php +++ b/manager/frames/1.php @@ -103,6 +103,7 @@ MGR_DIR: "", MODX_SITE_URL: "", user: { + role: , username: "" }, config: { @@ -130,6 +131,7 @@ confirm_unpublish: "", empty_recycle_bin: "", empty_recycle_bin_empty: "", + error_no_privileges: "", expand_tree: "", inbox: "", loading_doc_tree: "", diff --git a/manager/frames/nodes.functions.inc.php b/manager/frames/nodes.functions.inc.php index 7a963dd11c..da25a7fd54 100644 --- a/manager/frames/nodes.functions.inc.php +++ b/manager/frames/nodes.functions.inc.php @@ -70,7 +70,7 @@ function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') { } $docgrp_cond = $docgrp ? "OR dg.document_group IN ({$docgrp})" : ''; $field = "DISTINCT sc.id, pagetitle, longtitle, menutitle, parent, isfolder, published, pub_date, unpub_date, richtext, searchable, cacheable, deleted, type, template, templatename, menuindex, donthit, hidemenu, alias, contentType, privateweb, privatemgr, - MAX(IF(1={$mgrRole} OR sc.privatemgr=0 {$docgrp_cond}, 1, 0)) AS hasAccess"; + MAX(IF(1={$mgrRole} OR sc.privatemgr=0 {$docgrp_cond}, 1, 0)) AS hasAccess, GROUP_CONCAT(document_group SEPARATOR ',') AS roles"; $from = "{$tblsc} AS sc LEFT JOIN {$tbldg} dg on dg.document = sc.id LEFT JOIN {$tblst} st on st.id = sc.template"; $where = "(parent={$parent}) {$access} GROUP BY sc.id"; $result = $modx->db->select($field, $from, $where, $orderby); @@ -193,13 +193,15 @@ function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') { 'spacer' => $spacer, 'subMenuState' => '', 'level' => $level, - 'isPrivate' => 0 + 'isPrivate' => 0, + 'roles' => ($row['roles'] ? $row['roles'] : '') ); $ph = $data; $ph['nodetitle_esc'] = addslashes($nodetitle); $ph['indent'] = $indent + 1; $ph['expandAll'] = $expandAll; + $ph['isPrivate'] = ($row['privateweb'] || $row['privatemgr']) ? 1 : 0; if(!$row['isfolder']) { $tpl = getTplSingleNode(); @@ -217,14 +219,7 @@ function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') { $icon = $_style['tree_page_info']; break; default: - if($row['privateweb'] || $row['privatemgr']) { - if(isset($iconsPrivate[$row['contentType']])) { - $icon = $iconsPrivate[$row['contentType']]; - } else { - $icon = $_style['tree_page_secure']; - } - $ph['isPrivate'] = 1; - } elseif(isset($icons[$row['contentType']])) { + if(isset($icons[$row['contentType']])) { $icon = $icons[$row['contentType']]; } else { $icon = $_style['tree_page']; @@ -257,9 +252,8 @@ function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') { } } else { - $ph['isPrivate'] = ($row['privateweb'] || $row['privatemgr']) ? '1' : '0'; - $ph['icon_folder_open'] = $ph['isPrivate'] ? $_style['tree_folderopen_secure'] : $_style['tree_folderopen_new']; - $ph['icon_folder_close'] = $ph['isPrivate'] ? $_style['tree_folder_secure'] : $_style['tree_folder_new']; + $ph['icon_folder_open'] = $_style['tree_folderopen_new']; + $ph['icon_folder_close'] = $_style['tree_folder_new']; if($_SESSION['tree_show_only_folders']) { $tpl = getTplFolderNodeNotChildren(); @@ -598,6 +592,7 @@ function getTplSingleNode() { data-isfolder="[+isfolder+]" data-href="[+url+]" data-private="[+isPrivate+]" + data-roles="[+roles+]" data-level="[+level+]" data-treepageclick="[+tree_page_click+]" [+contextmenu+] @@ -623,6 +618,7 @@ function getTplFolderNode() { data-isfolder="[+isfolder+]" data-href="[+url+]" data-private="[+isPrivate+]" + data-roles="[+roles+]" data-level="[+level+]" data-icon-expanded="[+tree_plusnode+]" data-icon-collapsed="[+tree_minusnode+]" @@ -660,6 +656,7 @@ function getTplFolderNodeNotChildren() { data-isfolder="[+isfolder+]" data-href="[+url+]" data-private="[+isPrivate+]" + data-roles="[+roles+]" data-level="[+level+]" data-icon-expanded="[+tree_plusnode+]" data-icon-collapsed="[+tree_minusnode+]" diff --git a/manager/media/style/default/ajax.php b/manager/media/style/default/ajax.php index 9168fd949f..80440801ba 100644 --- a/manager/media/style/default/ajax.php +++ b/manager/media/style/default/ajax.php @@ -20,7 +20,7 @@ $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : ''; $frame = isset($_REQUEST['f']) ? $_REQUEST['f'] : ''; -$role = isset($_SESSION['mgrRole']) ? $_SESSION['mgrRole'] : ''; +$role = isset($_SESSION['mgrRole']) ? $_SESSION['mgrRole'] : 0; // set limit sql query $limit = !empty($modx->config['number_of_results']) ? $modx->config['number_of_results'] : 100; @@ -466,23 +466,45 @@ // set parent if($id && $parent >= 0) { - // находим старого родителя + + // find older parent $parentOld = $modx->db->getValue($modx->db->select('parent', $modx->getFullTableName('site_content'), 'id=' . $id)); - if($parent == 0 && $parent != $parentOld && (!$modx->config['udperms_allowroot'] && $role != 1)) { + // check privileges user for move docs + if(!empty($modx->config['tree_show_protected']) && $role != 1) { + $sql = $modx->db->select('*', $modx->getFullTableName('document_groups'), 'document IN(' . $id . ',' . $parent . ',' . $parentOld . ')'); + if($modx->db->getRecordCount($sql)) { + $document_groups = array(); + while($row = $modx->db->getRow($sql)) { + $document_groups[$row['document']]['roles'][] = $row['document_group']; + } + foreach($document_groups as $key => $value) { + if(($key == $parent || $key == $parentOld || $key == $id) && !in_array($role, $value['roles'])) { + $json['errors'] = $_lang["error_no_privileges"]; + } + } + if($json['errors']) { + header('content-type: application/json'); + echo json_encode($json, JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE); + break; + } + } + } + + if($parent == 0 && $parent != $parentOld && !$modx->config['udperms_allowroot'] && $role != 1) { $json['errors'] = $_lang["error_no_privileges"]; } else { - // устанавливаем нового родителя + // set new parent $modx->db->update(array( 'parent' => $parent ), $modx->getFullTableName('site_content'), 'id=' . $id); - // устанавливаем родителю isfolder = 1 + // set parent isfolder = 1 $modx->db->update(array( 'isfolder' => 1 ), $modx->getFullTableName('site_content'), 'id=' . $parent); if($parent != $parentOld) { - // проверяем остались ли дочерние ресурсы у родителя и меняем значение isfolder + // check children docs and set parent isfolder if($modx->db->getRecordCount($modx->db->select('id', $modx->getFullTableName('site_content'), 'parent=' . $parentOld))) { $modx->db->update(array( 'isfolder' => 1 @@ -493,29 +515,28 @@ ), $modx->getFullTableName('site_content'), 'id=' . $parentOld); } } - } - } - // set menuindex - if(!empty($menuindex)) { - $menuindex = explode(',', $menuindex); - foreach($menuindex as $key => $value) { - $modx->db->query('UPDATE ' . $modx->getFullTableName('site_content') . ' SET menuindex=' . $key . ' WHERE id =' . $value); - } - } else { - // TODO: max(*) menuindex - } + // set menuindex + if(!empty($menuindex)) { + $menuindex = explode(',', $menuindex); + foreach($menuindex as $key => $value) { + $modx->db->query('UPDATE ' . $modx->getFullTableName('site_content') . ' SET menuindex=' . $key . ' WHERE id =' . $value); + } + } else { + // TODO: max(*) menuindex + } - if(!$json['errors']) { - $json['success'] = $_lang["actioncomplete"]; + if(!$json['errors']) { + $json['success'] = $_lang["actioncomplete"]; + } + } } - } else { $json['errors'] = $_lang["error_no_privileges"]; } header('content-type: application/json'); - echo json_encode($json); + echo json_encode($json, JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE); break; } diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index ba35b44e08..abba0a124c 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -124,6 +124,7 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .table.data .doc-item .fa { width: 1.2em; font-size: 0.9rem; text-align: center; margin-right: 0.25rem } .table.data .doc-item { text-decoration: none } .table.data .doc-item:hover span { text-decoration: underline } +.table.data .doc-item.private .fa::after { position: relative; float: left; margin: .5em -1em 0 0; content: "\f023"; font-size: 0.75em; color: #d9534f; } /* [ WIDGETS ] */ .widgets .card { margin-bottom: .75rem; border: none; border-radius: 0.15rem; background-color: #fff; box-shadow: 0 0 0.1rem 0 rgba(0, 0, 0, 0.1), 0 0.1rem 0.3rem rgba(0, 0, 0, 0.05) } .widgets .card-header { padding: .75rem 1rem; font-size: .675rem; color: #616a73; text-transform: uppercase; font-weight: 900; border: none; background-color: #f2f2f2; } diff --git a/manager/media/style/default/css/fonts.css b/manager/media/style/default/css/fonts.css index a8cd1a6cbd..a2371f1a33 100644 --- a/manager/media/style/default/css/fonts.css +++ b/manager/media/style/default/css/fonts.css @@ -83,7 +83,6 @@ a.text-gray-dark:focus, a.text-gray-dark:hover { color: #101112 !important } .invisible { visibility: hidden !important; } .clear { clear: both; } /* custom */ -.fa { } .fa > .fa-lock { position: relative; float: left; width: auto !important; margin-top: -1em; font-size: 0.7em !important; color: #FFC107 !important; -webkit-text-stroke: 1px rgba(0, 0, 0, 0.39); text-stroke: 1px rgba(0, 0, 0, 0.39); } .rotate180 { -webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -ms-transform: rotate(180deg); -o-transform: rotate(180deg); transform: rotate(180deg); } .disabledPlugin, .disabledPlugin a { color: #B68282; font-style: italic; } diff --git a/manager/media/style/default/css/page.css b/manager/media/style/default/css/page.css index 18c16e0d37..7bd92974e0 100644 --- a/manager/media/style/default/css/page.css +++ b/manager/media/style/default/css/page.css @@ -1,6 +1,6 @@ -@import 'fonts.css?v=1.3.1'; -@import "forms.css?v=1.3.1"; -@import "mainmenu.css?v=1.3.1"; +@import 'fonts.css?v=1.3.2'; +@import "forms.css?v=1.3.2"; +@import "mainmenu.css?v=1.3.2"; @import "contextmenu.css"; @import "tree.css"; @import "tabpane.css"; diff --git a/manager/media/style/default/css/tree.css b/manager/media/style/default/css/tree.css index 46b985a167..a5a13df59f 100644 --- a/manager/media/style/default/css/tree.css +++ b/manager/media/style/default/css/tree.css @@ -34,8 +34,8 @@ #treeRoot .toggle { float: left; margin: 1px 0.2em 1px -1.5em; width: 1.3em; height: 1.3em; line-height: 1.4em; text-align: center; vertical-align: top; cursor: pointer; border-radius: 50%; -webkit-transition-duration: 0.15s; transition-duration: 0.15s } #treeRoot .toggle:hover { background-color: rgba(255, 255, 255, 0.5); } #treeRoot .toggle .fa { margin: 0; width: auto; } -#treeRoot .fa:not(.fa-lock), #treeHolder .rootNode .fa:not(.fa-lock) { margin-right: 1px; width: 1em; font-size: 1.1em; text-align: center; color: #565656; -webkit-transition-duration: 0.15s; transition-duration: 0.15s } -#treeRoot .fa > .fa-lock, .fa > .fa-lock { color: #FFC107; -webkit-text-stroke: 1px rgba(0, 0, 0, 0.39); text-stroke: 1px rgba(0, 0, 0, 0.39); } +#treeRoot .fa, #treeHolder .rootNode .fa { margin-right: 1px; width: 1em; font-size: 1.1em; text-align: center; color: #565656; -webkit-transition-duration: 0.15s; transition-duration: 0.15s } +#treeRoot a[data-private="1"] .icon::after { position: relative; float: left; margin: .5em -1em 0 0; content: "\f023"; font-family: FontAwesome; font-size: 0.75em; color: #d9534f; } #treeRoot .fa-file, #treeRoot .fa-file-o, #treeRoot .fa-file-code, #treeRoot .fa-file-code-o { } #treeRoot .fa-folder, #treeRoot .fa-folder-open, #treeRoot .fa-folder-o, #treeRoot .fa-folder-open-o, #treeRoot .fa-exclamation-triangle { margin-top: 0.1em; text-align: left } #treeRoot .fa-link { margin-right: 0; font-size: 0.8em } diff --git a/manager/media/style/default/js/modx.js b/manager/media/style/default/js/modx.js index 93429aa3b7..e786681241 100644 --- a/manager/media/style/default/js/modx.js +++ b/manager/media/style/default/js/modx.js @@ -617,7 +617,8 @@ this.parentNode.removeAttribute('draggable'); return; } else { - this.parentNode.draggable = true + var roles = this.dataset.roles + (this.parentNode.parentNode.id !== 'treeRoot' ? this.parentNode.parentNode.previousSibling.dataset.roles : ''); + this.parentNode.draggable = (roles && modx.user.role !== 1 ? (roles.split(",").map(Number).indexOf(modx.user.role) > -1) : true); } modx.tree.itemToChange = this.parentNode.id; this.parentNode.ondragstart = modx.tree.ondragstart @@ -732,6 +733,12 @@ e.preventDefault(); }, ondragupdate: function(a, id, parent, menuindex) { + var roles = a.dataset.roles + (a.parentNode.parentNode.id !== 'treeRoot' ? a.parentNode.parentNode.previousSibling.dataset.roles : ''); + if(!(roles && modx.user.role !== 1 ? (roles.split(",").map(Number).indexOf(modx.user.role) > -1) : true)) { + alert(modx.lang.error_no_privileges); + modx.tree.restoreTree(); + return; + } modx.post(modx.MODX_SITE_URL + modx.MGR_DIR + '/media/style/' + modx.config.theme + '/ajax.php', { a: 'movedocument', id: id, @@ -1132,7 +1139,7 @@ } }, restoreTree: function() { - console.log('modx.tree.restoreTree()'); + //console.log('modx.tree.restoreTree()'); d.getElementById('treeloader').classList.add('visible'); this.setItemToChange(); this.rpcNode = d.getElementById('treeRoot'); @@ -1467,7 +1474,7 @@ setTimeout('modx.tree.restoreTree()', 50) }; w.mainMenu.startrefresh = function(a) { - console.log('mainMenu.startrefresh(' + a + ')'); + //console.log('mainMenu.startrefresh(' + a + ')'); if(a === 1) { modx.tree.restoreTree() } @@ -1502,7 +1509,7 @@ modx.tree.reloadElementsInTree() }; w.tree.resizeTree = function() { - console.log('tree.resizeTree() off') + //console.log('tree.resizeTree() off') }; w.onbeforeunload = function() { var a = w.main.frameElement.contentWindow; diff --git a/manager/media/style/default/style.css b/manager/media/style/default/style.css index 811a6d8f0a..da4b372266 100644 --- a/manager/media/style/default/style.css +++ b/manager/media/style/default/style.css @@ -1,7 +1,7 @@ @import "../common/bootstrap/css/bootstrap.min.css?v=4.0.0-alpha.5"; @import "../common/font-awesome/css/font-awesome.min.css?v=4.7.0"; -@import "css/fonts.css?v=1.3.1"; -@import "css/custom.css?v=1.3.1"; +@import "css/fonts.css?v=1.3.2"; +@import "css/custom.css?v=1.3.2"; @import "css/tabpane.css"; @import "css/contextmenu.css"; /* -------------------------[ Misc stuff ]--- */ From a3bac9d813a16361231519eddf3515fc1c07c8d1 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sat, 22 Jul 2017 14:20:41 +0300 Subject: [PATCH 031/338] fix #71 --- manager/media/style/default/js/modx.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/manager/media/style/default/js/modx.js b/manager/media/style/default/js/modx.js index e786681241..531ffa2a91 100644 --- a/manager/media/style/default/js/modx.js +++ b/manager/media/style/default/js/modx.js @@ -618,10 +618,18 @@ return; } else { var roles = this.dataset.roles + (this.parentNode.parentNode.id !== 'treeRoot' ? this.parentNode.parentNode.previousSibling.dataset.roles : ''); - this.parentNode.draggable = (roles && modx.user.role !== 1 ? (roles.split(",").map(Number).indexOf(modx.user.role) > -1) : true); + var draggable = (roles && modx.user.role !== 1 ? (roles.split(",").map(Number).indexOf(modx.user.role) > -1) : true); + if(draggable) { + this.parentNode.draggable = true; + modx.tree.itemToChange = this.parentNode.id; + this.parentNode.ondragstart = modx.tree.ondragstart + } else { + this.parentNode.draggable = false; + this.parentNode.ondragstart = function() { + return false + } + } } - modx.tree.itemToChange = this.parentNode.id; - this.parentNode.ondragstart = modx.tree.ondragstart }, ondragstart: function(e) { e.dataTransfer.effectAllowed = "all"; From a7243bb3efec284a5c6dd61a79ae29fcc6e7d5cb Mon Sep 17 00:00:00 2001 From: Pathologic Date: Sat, 22 Jul 2017 17:04:21 +0300 Subject: [PATCH 032/338] fix #92 --- assets/images/noimage.jpg | Bin 43101 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 assets/images/noimage.jpg diff --git a/assets/images/noimage.jpg b/assets/images/noimage.jpg deleted file mode 100755 index e0de171897caabb267ebadd14d064d9bab21a15e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43101 zcmbrm2S5|q*Ec)~paCodLzNmSNu)@zfRq>$N}Mpbfqa$M8pLGf^;b&EeJ}H zsvv?cU783|L}gdHph!^!0lzyzUH5tR|Ge+}d}oHqojZ4KJ>_@K9sM@&?N5k{s->$1 zArKIR00;DK2s#XHVrARJ#=2<}+osK%H=#JVI5^nZIWXI{Z{gy@@bmLwczFedB}D~y z?h@kV6_XL$B_)j~-~~iw_sHV*NaFA~xDv$X&6_z;96LBTcHjhg1#$n+^z9D_jbagE z5o1B1AtV~Xf<}C6fOdkeA|MvHzds0pWMSLHx*0s=2hZTgzYuuH`t2pOg#`g2xmdWs zleH^7^-kw*E?hZB|51)!fk_O>ve?RH7HPaoBK73qv*Y&<|yIm|G!R1Us#mrWoj2pI$&;$RJ7r4gwi;w?WLId|K@Lt|z- zz4~FguV4F2iq$jb+uRtFJ2*NA2jWm({6=-G5El}OkelXl3-RUV*ng{X_ z*m#DFsU(5U2_ftpAvTCDPmIQ<1F;byNi0V=yWGr39*HXho&`}w`;}fqSE4hbZ?ON> ze6i_P;h&K>NQ8< zH|IMMU8#-49iv65W;<;bRL6p^=im`qmu-XNF&I(-GJ>@t--81WSIwq_u*HUxk%mEB z-N8uiEDFSxgWp{5WLyw+_)*j69C>B`lpw^yZR3J^*CD+Q9E7lak;q6KG{t0Kh<6Aa zyeW~-?y-T2SfNA=F_@IqfHY*$<}V{)DTyQq+T7@5>7lZ1_~0lcH2={I+8I@6Tv#O( zdiLf##3_5vg%C%j8*)OX_w*rtf_hcYLI!G=QfgILS;Whgdie?Lkx*TAiU{4E8=N

    drdt?R9y-=ysl$NEk(_#BIa!&cFb>jnD4y${7(s>?l0cx0 zC3H`-mR}FGE?9ioGUNDAe;^06G@kTVFSPA&Bu7bxe{1jbt{A@>*PBKsoikl%Ph~lv zLTiW2-i%m1 zf7;5;0YNHd7iOTX0-RK{+{+&ayJuNq0_0`q8!fg%Mmn-oad)&~)^&)36(@!xg6c?y zVj(m2EQ$D~VCsC>`PHS* zZO0nfGC1vYI0!~;EMy`MmPmvcHVF9ym2o{nMsSaq;~x!E=hN?-j~$#jn`lNdi5w&V zHW6B`5e!1KoXpK?b1Quw+}xbsa5LBYSgVNzvW<3?2N#bpJbe<>1(O6eh!;g+{r&hc zdu~=Gt7G2xHNEY~#_l3?UWC)|}Gk@w|B3Zf^{4P-!n4 zgPcLjGDTz|zH2Qa#7cV17IQLATlg+38cb6{A_2+OO5jQaGaab@m@Vq`ZwX$s$Iq@| z?%LmxHLRraCg9?^6Nt!^$RKzaU}A6(t4@Z@@5i-h+#wQM26-jS?ZxuB+Y9u2B@tZ- zhNRxnL<|E*H+N5PGqhm$3M$VFrh^I|XFw2GP$W3PP{?#t);KREEQe@+%sw&JFho4o zL?^>jdnuEUxJgT?OpLi{FtHUc8(CzoS&sIq-5hvUkNPIH-h(aHc{C?WF0hrq5%koK$#b(Bj*(_YZ%3KV(Ow z265#Qm2@|`n}w0MLb9ka1g;KpsB)cDZiMU+c?o+4IxE2&`Ajb-)9W(sIR^3ERruIK zGim3+b-(v>nL3#5nmr;r>vocW-9o`?P+FocciC@^`!WGC`Qz$!x{hN|47cTu-Q0#D z1u>HL;~jtX=4KULYha^S5Z>YLY^8A0!nLkv_@CEcsS|nl8^jjfy}I@=@=O6FnsTw` z8zjO2FaxY72{6#~7q3rN)kJnf!96jg7K+p{Gng}U3EaQy+9&O!j&&sH3F05bCnn08 zJ;MK|k_y+67$K+T;N92^9(vVsW?Ft5w^4G=m6 zC2)`=4E0}LO{Ss1WR!A*D3XrLSqUb%ohE!xvIu^s=T7I;dB&MTC72@9<%{Ka58VJp zsN}DnA&>WsoLp+>18rO@@p?A*Lk*5JXJ9bM;NV-SD-XP@uZL)A&3~RzdcehQ(jt!B zP0*ooZ_=gdy6KVx#CIoZ963T!u2k8=t4vFYw_woubjdl-FYAdWF=rqHf}(m<*A92Q z7Eq)eA5Sk55=_ju`y?-&H9iU>#(YAC@SUGfp_2$G}(F^3g1T#OUSdxjYuU%3&rws!^xmy#4Ggv3}`b+)G(KVEt82YJ6}*7C!-++!w3v|r3_n;wNXVA}N57Eai1LhUH3-=*WpzBnic?rgZF;#kUIJ8H@-M z!OO>W;!W=0=LVPivqM|K(i%G^Xy`#Z`_}j;aRcY3rmMU|#B_~x6U@a9@0CbwNI=9T9+;-!_RG+XiRBR( z%Y2T#9K5RTBMY|-xFFK+9XqWt-C2EfS_&Huhq(%IiLrul3y9zNT|aqGvP#({tNE1! zE->@OT5^%N!es#}36-eZ+nE@jI~IPN5^+c_wvZ~BZ?aW8=6zf9=W*z(Qef5TBdJz5 z&n#r66gj^?R|q;wHRWZy!)l1osnmgt5Uhv0ynwlgW52O>zHRbpPDiGr$@LC)mVK1p zX@((Xar-0mFpMZl?8X$_h1nWYGIG#k{$^E>CT)J{eM!|ZqS3N;SqJ@vacNVX?)>=? zcA%cPASCfl5DLjElfnMi*ZGA<=dR$x*3Py~(y65@>vM6N?AM&yChwqASUd71OTb(vm&XoVAB_@Z z;O$&F1=(_{NxfMXW~MURcMc`RzHdjYBqi0Ix|zd6T&*9R80iHKHm-@bPW}ZJSJir? z@$*>kSpowG#k`!bX^Xa*-bq9w2ap$PS8JB6?4R6Nvuk^mk!%QbcY=BY@4%b@73p~6lzwO$l?3)l0!FGKFP~pdMJpw!?T=J+|`_)tvwvEq8Zoy z7=rlA{#Y6tSM@x0P0$(x9hQiD?m6}Tg7;|rmW;&9BLPDG-ynUs#S?AAgiVHb6^XVX z=v489aGYb6ZG0Bt1EmsAF?Wmb3fBsfF}(2M)oSP&;`UzuM_*;!u4Wt`*XYs|PEigR zsLNhf7a~I2c53cl{B3H*F?HWVWm?eH5XF=4&lNvgeO=|iB~iXzU~*)l+D>Xq^Sd`T zD~X07$o4z>FH4ExsrGu}1fh~f6Gren`7S2ou6^YoClzsWyXerZ>+f3-E73`HPS;3z z9II{pU^a83AM!0;lFkl;w%kft@n4hIpBx44Ilo+J=DCrHas-W5O)nbkzeo(WP&=EQ zbaSdpO27GCy3N-_Ljh)+hfvg*l(0Mxy?GZihD=RJ@zTwzYQ#N`{3Z7Tk#N4?Sa}d0%YvI}w|;bY(+~=H5@sUn-Q1KQylGg!xBQq-@#XZdY7v)o~|> z)Rpb2l}E4m&UhB}3nFic+zwy-_+`K1$#$JJ&9=#j4zy%;^NNb^o0`#+?SZ$)W~&^C zB-W0+1Q~Aelvq7mYN$+&kF#uSTd5!$XFjLPV+I=+VR_rDn)6_ddsZKPwQ`X~hK|?P zY4S3Z1Cr~qzpM!nS^hXbGIr2&ROR^fuZ%VM*5Sh5)uEpH^voImwE$_kplw?XSl<0L z?_xiqAaX0(;8cA9yR3+2o&3Qe<|K&92kJVoQZGxEO2+7-NK)<+U=8l9>#}HZM}2;KO>S5B z>Z6DHXBTF*MT#pm=t4EKlWz>Ppv}htRCv)WwPk1HnnCO22s=SOX3=Bek?**oqo&dP z(yP)8EX6!QLg~BFinZCP%qh5ErjS^kM9X6Yosb-gj)KMcd{Uk3H3|pILiCAS zp~e)A_Tlc;z$h+Yx>oC7On}LV|DaF|`myfWcz&$s{KTT=_OgVv&27UW(Bb-vU%XR0 zw+NkEF-WTGzeeUB-Zh+b^L>{>oC09%+OY%#H=(6OJcWCci^TB3~msSIGdfwk&Q>^{j+t9M^sVCXu_;_&{!;q*T- zn}*@7&%}+^u(iW&!-?hqvf>hu_9mB8ekVBsTO`Mz8ymG$9g$_* z%f?i8k9quW+t}={6WcshduFXz9fRB684wt_^$2fmjq75xXdtv*U?}POY+JJLQR>=` zw&8mdz*Yl&TXbVCu=YTtkW=Bp;^OMXIWTgK)tXu6$a_{_FDp3^9XQH%a|>jOIcC|1 z!by?^F-GbPKRS{w3<%#REjOq%$_V z?#sFQ9<^A~IP+*&E(o-X^0Ka4me-cKaiGg#VtVq+;)ssyy!Eng(JNRQZ;j7(r4o=_ z5|z3Hyf}*7k(01Z_d>xl8FQb*#7u8-cQZ@|;6Lg9q=;Fd08gaWd3G5&Go@fX;0R`= z479v*fT$`vvJh>s4Q_c+?f!fJ*QKCk#CFklBhNoI*=-hB*`9RYsq2EyosE_k1e8Q? z`#xL~D9sQ@>e=gIW4S^ADl{BT8trA!&Bl`UxtKZ&2KVSBGK}<~+T+FY0>fav>)`dy zdWH-1o?cj8iSJ%)TR9%l{TNa2G+JA?U$W-5q^I_jh^Dqo258;?WmoX$bAOx!M&&r* z&M>`GV+ZFK0;!SW{{Q;wCINx7>U?bZ-n*9KhJjiC$Ro_k(z?)Ksr9BBr93;HtwH5~^_Ig(1=EUi)#`B}lnsmo-^+Z7e@%V&Ion~8p)-CaQNJF7Z~&eLe^J^Zx27pQuJ`E6Y`D&c0P&)AIWk;eOe#-=O_xW5gu0 zpMoB!F0{r;1Ksfr(mLZz0&$xgromb?%N^LvZDxPnp@of_xlr$9fetWr-sQ3Cg*oeG zNKSwQ?ELfMDM!d zyZnhY^7@mm)D?rcM@iwV<=gSYNjIjuq_*6;?dun?!w`)vh=^wjnS(7=Kt(_P831d> z#7wWNjLTF+p2+cH%^mQfNAC}u-KoQQ=;N#gUr+OR*>ut{c)zL-f`lCxmiuoT?*w#a2exR5LoI;E`u-Tw9hueUSN z^cu3;8*6FG{k$>rr01$(R23N_{ zgT+s)7aeW5C3rAgzDHlJ-aq5J$3fFzerd%qGoH}m00JEBaBLzrlOQdVO~KpgNxZ1U z$x8M{fXFItQ+C^@34oKKz-#00-;Cr^%@NMXAY==K%UGUSSo2*BQ0hOcn0HM$aqpXj z;q0;6(-(AzSM~)R8vW`Cp!lCpPr?fMeM$_0HL*c}2e?I8b2fXS*pGu5&RTtxyMk<+ z5;&eq3PL4-vp%i?PSINMnJwuNqZ~2;5k__#1i8EWPerImt~lf#RT8_*T8>2d%Dq~> z1%{EVX$X*bZsv8M0b~xrrbf>ecDOEfM!*i2vS}};iB|BGOcujXZTM*5E+B{ZMtUAL zearyUbu~UX2!vWBf#=UkyxyW@7?Llc_-MPnw_oQDDTCgcN9*|o;>YZRI&wn7?X7Yo zL98OJbhMjle2%x(y@YC^b@^D9Q4Vfue{@#>0IM5rmvaT|b^$+*O;QZRzQ6ljzi-K9 z4Qw1;oHI}0RLqwIFq}Jc*FFN*??=r>o;O|2rZs?=6obtYOau=hN_n;T#l&Ag`K4Gh z9k0avtawZYxM#XuT&=q#6z%`85B2LhaeMiZ=%yTY0zud95Q-#G2@dgXx`EbCw4uGS z`yBCEg>(ycpQ{XVwvN%nMbD3qs=#y#?mO*eOi{Lgy+Z^M3gQX^kpkG=)Xzl)2-My6 zeK_B?V910rD1fD786*~b%2?7BW257gYsoUsjJ>#W8N+I-q*VNNrJh^Y-nT^sL5OVE zY|38Vd>1ebHrVAPlDNgUTyKqU4c7L)78qK8|AlN1Q6oQj0F+GHaWN6 z@@McXNI*To>~rqWjGMS#z6#Nj*hnN|IqnB z=FdE&V{hyL{kkGS%Nc~X4)1LfRZp?RbeBoe%_;|A2cFb>&nPR%Y*ZOZ4~DX?^AaHl zoQXkVD2R?lKm|>1bY4pAZo)mCkh~aMusy$4{&S;XPjA=e2-=Ta{*45{n zK;Sqbj`BQ6Rt(|+OoO9r5tb* zw8V@m(h>=SvXwX-o?LlH5_2y@#t<^11wqXBSs@TAg{VQ0J*Q%xd4gC_D?t|r55Y*W zru*Z&t(abqwv-a;E(+lt+Z|4f>=E`u$`}qah$CBfqj`vx0}F}eA-Lrtvr6wtnc9nm z+nXhu#fC^Gn+l*@+-d zD49&#a_0$_MLBL?19yhv;l11(;~gXScp26W${e&OZiz#JY>3nLmU`mEXAm!h49egL z0-+8ZD;LC0M4+znD7b(~rt#VtU>WChQJ;zh5 z#o>@|FY-CV1VPJ#jE&$i0AdAE&u|Re^`}#cltcu)jM#>Fadsf{1wq?q54~q(De10cQ5D&XUP&HiXbZZ zGLhXx3 zF>(5ns`W{a;+(NsXG=W{GN`;1c_)F(NC!cJxSvtQkU;C`Qi4&EC757f1Gx1*POER$ zKO7UVX>W%N;8<)BB-9P|1zFu5=QuOy{yyHSEn_wdg5wtQ%p3eT2Xoc%D(Dv%3JSJ_h(Js0 z$M7};hlHPC>(Z@>`op!NGlRIXxk82Z^JhTXZB8B5iDwlY7|=Z+;ie#%m;seu%ca86 ze+UHyMX&{-#89!__KhWCk|=gZhvmH*2XEEd=$e4%DvUqxF{?qnFn2M{cgV=NXJNu~ z+BS%jxK)750v0STw&2GQ7m+I@6V3ZdEMA6Nw8xwk)FBc#>8XUWZ3wHR zjybP{B;uJX|Gx7o!+Ri>Tl?R>g0|^=ahonWRq@_o)DWpmYqW^JgS)JU435WT$~;sA zs*=bGmK|wk#zo@3o_F~ANFFMAle2wr!yQqqcmJ;I@1?3Rkji{HB#QNV+46G9y#D}% zlBM!C;tw4nKD?~HmBp9fpY z+uYs=6E`>9)GAfstLdx~2QA}G%rd|pDtBy*08w8x=`ewo^NNBKb+ZZ(6^R{aApm`Amynw=hjc%!sJ0(OmF5JEP(%j+T!4^jN*ytYMz9X*+OvRpQ~YNQ?Np_P7_}6gCK>6&Yj- z=b^YDNr;t|wUnxS?s+R0(=u$2Y8Um-0OL5QNV@{IK4C(fCd$x)gA5I~YLQ}t;2bez zP!JaqXsc|57<>gav>DE$$u^<{+&!&ytik!`Hu zmfxFzHgCPTx8>_X@fCBC=$$K)m>(}ggkHiS6E0I8usfTBXI?nDh?v;xdF&j>>)%^I zyl_=NTDIhL0(@^F1!B7hRwVp2#`iBWxOadLF3=dj(3^O<#5VKnAsT|OF96~LTMy9K z-J3cuUPRRv{VNrC@AdZfwkw3mrKu87?Jor1ZxH-)Zc$O;n}4sT_~NXZ^sL3y&AkH2 zKd8~jNB|AUEHCVz)Iwj=a{NI~1CNxt*hNUa&D6fm_7j8ujRpYuy;-W7^&37j{buRW zEV$XYbosrRcr+W>)HpPB@LxzhHKE64IBdMa`oOzsSIRZ_f1v89)FgI_IwlF`ekb{`*~eY@_hT??IYb5sAi zb9=zUVlZr#PS3On6?g*b>`u*sY5BZQ)aP?kC!oH+so%3ze<6G5<;#~-K14_@)N=ks zXT?dl4;4i?D1w=SAPkKOD}ca>!H)nTJc1y$!jo`nRDRvO!m$PN$^#SPQ{&$(YxV9a zJT(z0(hgqkc!2$Zb=9R6TGC8F+M*B604ZHK8&5s+l4=;gF`2?c-=Ld*`&6At=___>RTv1ZeNVr%HsHFeJi}x2==GIOK-@PkrZSC&vJnhS z$wo$Kj4s+qg5si6mNp?lCYyJ9g3igr@OqFb7j?qI=q}h@N=%wOUIr82XTS$OJ_pmO z!*SC~C-`8-2OL0wr^}+Rls>SLVBVEn16d$t_3i@@6;N`mOVS{A`us)}%z7?bGiAWJ z1QvE-_cJfl%Ff@$^#exd1vZpGqcQM!T3#hsz>Q^OE;B6wtZICG|7mzOT(et!G}ZP# z`dgCDBw0ZaJ_EuIP=q_I~2|AP&znfllBx;zjfB;HAYc)wngQ z9SJMXD`(`pT3J~1J*WiYWLN>f2u!>cunaK@U1|LuS7oWRn%70%1>V)VRKpOg8?0QI za*(@d<9U`DmYE*uAiOA(W8Dcm~15oR;;xuR``Dr^RDr z3NO%&OvVZV3yAE4IB9*=d9?ThJOQj4ShKyKK2=myR9pXsszg(i8^OmXWFrg(t<#8A z(21mBcVR~O(M<}Mv-a%zp}ZbPv7U=Osm+f@7qOBZW6%OHHby$LXF#eLcXw^ag9-z= zpBsGkVb|;5eto-;wQ!TqVxYROBIX=Cj8n-yM#;&y&bRtJdRq6}%533ESHVi%-Id}y zE5-RMxAIp~HHM!rZL4#K3)>NZP+0B7 z2rf|ymz(wgfz$`Qq#io(;T0^KOH8Gk{raPZ9slDIe!)M1=)wdMi4Y5eg#82CU>;%Q zpx`Lem_T6=WbsDsu4b&3bO@RE;j8TMxv$&redP=sd8;!aEfLI=!rON3y06KYmyzZCs7p*1p>d0MTUuzhp2Sevf;28qt~8*e*O{A=%bns0DK%JduZBXHJ9`a)cBH0Jds$e60n%C zxO(LQxU_HIt`ffVrN#*gu#S~-6(#2)?O%Tu#jiE*ifI}3z-nT5&1){T8%$*S;tL~P z9jAfS=^?idXk5610>YkACb25IdDsuL_ zwF&6|?5p-ssMCWI3v_u{SbO_Qg7%3MHmWO&gJd&(b1Ds3P70$)wlMG;WH2|S2GlR& zW!Pxo1rZyjIbP7HA5*`w0M=MTsq4a74Y0`fpe3EvbOW``ycPLWTJBR?e5T+Epf#Hs zfUZn=j3oiaGExB&1O%uv;Op{Yls-syxq|iceB!aRDsQu}-m{EpRM4jZhScC3EO^5l z%97?=-|5v(Po=c>2??^X5gN@$yWP0-XwJJE%yPGPA*{k8ot8IUiq`oHsN}QE3g>5H z&}g5pHuV!K=pzdHWMeeY`{)$^&B^aRN4B?jy_Sw^9bM>W3g0V$P*l$X)IR*87B)X& zsq}igddQp>*!AkZ^145F{mvoX$cD?1eV3mu{1wF;SE)<*@;ct?X zQul1@K|+wolxSI(_1nh)W&o6yUkY%xHm!vM!FCDoZ;wuo&Rgs*G=GD3UGv=J>K!bQ z*eW0bDu4O<%Jpch7A*+k-pNfvF_{fb}8@bEhr&_*)({DXm`CY|i$$^R`S$V;0ED#P4H+ zSnPrb>C;QN88yv_Ih);2ed%jMO<&p3qOp_920O#U!y`<;yqQW){+hN981X)sUx4X4 z01)sS2DYoWb{8hn7}E$WR#<}_7>Jfa^!%1fBG;Z~gU-Df4g3;lJ+2VxH|rNqQP97T z9(wrpdl4thz@6s2Wnk7mc>70FZEbDsx(}8eRZxibj0P*wR~2cugTLW%2Rx%#bqm^! z(i>$*9>5Sz)@#V(Z4fF0QeW4Mri__{g+*V4M-n#n26fHz%?z;f3i=nDBddkP7X*Ow_Uj;JKt30A3~CEV(*E{i`QNY>Nc(;ciz4g>$r!ZT|j>-~Q0G#0EL z1^6my#~i_KqGm}KWy}~azOylCzj*MOWm$bndwZuVyheqtX&)Fp2MXRkxI@4Jq=m~1E4z_4p*bqB7IjgY z0Aqm|SnJHGJ#3%Q_y+l?XyeD!77y~dbj3_9tvc*iy?K`9?U@&#;1Z{C>*&1iRoDFYW(t$?-0d^f@{P8o<>yd5p&JEpyOS4B+W;?U4YAolLeFy6CHxZrVk>e=$3y>(#`UPc}e` z%v!4lt6?sEv-Ig~Ci)cGQI-Pm5S|+0YGn!0A(mmFf;khOfgx|yJwJ+yuJ)cBQ@b6% z&~woAIkR88-tS*lOE*wgZ5&|FP=Br|z3}1y?3ue0+yOuU?xnD$m;#Za+=Gdv?ZRAB zxE$7mRS1g?j2?OBYelx>Z;l5N@WFchV4@VW*AX{GhF4cZ9mo9B4RG1{jzzY1A`_x< ztrPhkfKfK@U{MAO83cJv4Ma6HHJpej3FrizX$u6{3(bpXi`$M{9dmRVV=DRc za;<2-2a9>kUiYo$!@d!Z>GG^3==H_WqwlpG1E)0M>d(PQprXtdwkH7z&Q5EkKdgKdF;(QZ-R|LP`tWZ-LXWRfEYnp2G75wgge<%4D=G`K}5URxflHxtm4<{yw6@^s|&DfZHZi3L^^at?c-_ z0`GqL1_{rP!M?8(4;)cM^LggKUR>`FDhf+WsJ>XcIs2Wk$kp>M)o_u(Psf2Om{Pk_ zxi|8Aq-d$uPgrj<0tl(CEG51%0SGA&Q;R+X#_zpm^Oxx)91vJmGT>My#!3R}v4t`7P-!!BE5$n6?&JsB6k$4X6e?{-p=& z>e8LBKFepV$Y({{f(v{K21HB-UYXSRaR!D?Zk)9dleN*4>v2;WNmGHTQ?;p6>$l!% z+N2>u3m8=WEykDz)StGjwhCd9wrlCLmg{H* z7#avgw|s;CZ10-L{nA#UZ?^-f#B%vDP#Yb)dU9nbH%jAs-0=X`zkQil(O6M{4chMh zv2G5wf7-j|RfNLBzd?hVkG9H__t$LjH)!-f(YWf=w0gGL|9tc6 zrRLSp7XM#Qki$H|Q~$F~s}3Tm&p#$u6_@QrqcMGChrNK;Qu#Y?p6iP$_s%XZK63NI zbhC{N7I-%LuxAsWR|$fsxw#6FAWlbbZwHeUR+cs)2{`;4^t%fEFIQT^#@M;8!Lj84 zclR?%7T_c4x79AdPQyVFIv7B^X<8!)QvxYbPyj#V36)kfuV-2e_yYz8zO*{+ZRPdc zYoD712Smcca!Zvak5>rayfLF~E3bWOZeSo{HsXV4+GI^%ML|RXtZpOs3H%ynCgiRRL#L}Yg9$IxMUSsDIEM+&E|(?iKUm z`6Fe8Y6k~^l~^Q%MJU5D@VxhK&5rWTb}-q>KiU{n<9J1h_r|asfSa-r7FDv_`n^tz zmv>!L25Vqz3}eQU67`#a3X78LSpo38LDvF3BA-KF4ih4yniV3+u;EmQw7t(&zAlW-_~?YuU6quuSh=f~@Lr9=B^PiR9Ehq1p@>nnv@SKx zQ%r^istts4Ecz-VuDSkT8rVMo@wt?~icatILKEs;3-_yD)b-86{0!={1b+t)s>?OO zdsj7Pa0v5lgBjUeJ8otjgkD#|skU&W(#YL~mdI%_mFa5n7>t@3sdcq@0x}tR(;-@X z{O#67DHYpUTDj!+(Sr$?@_q~L*@9wtbAKxWoF=bpLeC=A;3<%{i z1wRE0JIa$eSmq@S44bJEyxWR57=83&kI?jqk~f23d*?gByF5rdh)K?@n^nA+MukOT zH?yEG3!NmNYu^gX;x{N!Arcj(av9ykdX7HA0-S77$>*ydU!mcyZA-wBxae+~D6JZ^ z_ZQx&Ii1LbnIFVR0Z-?{EP?l#`nyX&OIXA+WL;=|4C_i*$Vzq7Z%PPPvY*)!MGqOSz>t&h2H@#aB42xT!t+RV*8 zu)PB`2YsM(*5_b=#tFgaF9l>ov&Oi~2DaB|;qqwnfY;LWVX2eTQt z?#`c^JhN|B=k`^Aea^dJ-vb2prl+${SPQO9!W%qzs&jb)Q+DCOY@~n`gRr(wXKnS~ zZm2iOW z9WZ0x3EtL(g&PmFK4ahee6X>@T)-R#tk@Yi5-o(mCo2gLzVOF8ujfFQi_GqW`{(z- z&S2qu<6Yt3m^@9#2GJpG41x;++d5@Bz)Jm~AQU*Ry(2P54xUY~hr871 zKk*$J9foF_r^jK}9)Q3GlXd~U4+8W}tiSDtW%)a4`J$iSei-PKe;&BK%xLXDE`T$D z#e}EL-4aYCbNZN_@W!Utvkw*zX1by!96+(mConqs{T~f-#$9UI=h>no7&Mn*VpF^njd# zJd>Q$l#_>usLgph2TI5ux$V_{)~KNv7#p|PU5#f?wJu$kXLUGYj z|LN(!<@^3V*LYjAIO)Yl|LJ-Vwyc*iH;!;=b(iP1)N4q(kvgSmAz5CdyK$fReC~g9 zBMmBWTh(=IeGh8YnC=%O=a-3Rh>m)pd-e*~9mYw|b{9 z#J;p)KKx(Ys9kW7#Cxh#4nH1FxZrr7?D-8kO&1nebLl*it1=#$vW)g06zM?Ebn`{g zCNCy4lmFM3_Gm}#vR#8Q&!R%S_#CxKs_17HoQIsX4^geEk<6qlTShr=@IRA3ipioT z!3iqJCh&7p6el5em`!p-;&Sy>PvB-Fzc-UA+hTv`aSA%n02Ob%jb~uyrbuL zJ-82FtAraL+{ZX{=-s#v(k&mfJr2gaief(a#|MjJ9I7VDpF14sb z{$HJKj}r_2&xfnDg?$A$@?&%Lj{P{O$pmI5{NTSl`cdSczq(^d5`(hlvL`OXr@5@d z-y`@rlz&Ye##GCvCUB*W_Jn_bnOTK=)Tw3pDXcg5#^Ea@E|*ii&i-*3Ggo`GAko>A zsy=y>{68NFSg&xJq|QyO3H=wi;9ohmZY@Z;xmfSw)HZ{Pwjh^mUrX zOk*6M-j;PM5Pxx?2jJ57`BSZ>ZuRB;wdAz@;emj``VXCdm;GyL&zY02o>X12+tef+ zd63^{&&;WT`jSw)ZGYc3GH*4KS_2$qBQ5zW72IqG8cQPVc$@yyEnETb-xd5_U)nI$ z+EF-iC;z@ZZp>yqLtp)CzZ%26_Uy;M_E&7%%m1ajex#Y-YiRVx0H4eiSl#Y_ZWWm# z;H5a}@T@IU^tLS3i+nTSg z`_6!NF|Ic~_sEY_&L`=7Rd7n&?#S{w8s1HiBs zw{qki>CK6Jn0#LGgTt$~DorKn=hH{FEBW&EtbAP;__MXAX<5j)ls=z*J_-DsJdc#b5!)NJ|gVOdhakr#e2jRrcxKf{^|1HTZ zx=~s^e8#{|3Vtun_FT(z`_GCX6fD(r1g==|jQzmRmXpQO#5EJXY^@xAA`>^+;IFKD zV0gC=-0O|5MMwUT_Q*qfduILQZ!1C?q1!V^zon z&H405lmC+c>up}6*7wrC=Kic&Fm*~h_1AU;Zz#jP_-pY%z&5y3Qx2(>>+BA{Y0EcM6@3$@#`TXzvGNLO+T@#;n(v!LMoe+{FhU*>|YPJ zgi=ezW36tjmck`N!llQW-F)D)=Tpg$q+3GCOmi8W9|h;xfkep+TvT$S5PVI5Gnqw) z;QB?={8Rt69q?@K2lN8y>p!0wN*q&~Ibok|XP!M&mh0dwBQ1C&9qw%$%=B@#PT_OB zItakU_;UT0T|Fy92g2IY(j4;}`4>cjN{H9raHWDbtJfmJ$VHZtSHT;6 zHi`W6=9m1R$?{)IXTgw1>&StH@3q0zGqFxYngU5KaP%C(>Q&Z@16cx@T^$U`X|kWf zk1qb~D>Jd~H@Mj`^ zF{9n;s9c(K>)N@@Gur3Q$hLftZDb-307NV~Po0sy3NXnZ10d-pvAlToUgh^2+5eP; z5sYQTIXC!4OwQ2t`x_XDnd@;tv#e1g(V%ep<8phI>as-G=MX>A_kJ;ZtMfSr?kG>A zZQwZ#n&jP&|2W5`s^$B_T~^uuake^GAD}G0>pXJ%qu!R@jFvh66~j+!F5xb%zaGZI z3O&M#Ce8X@;A~~yfeeMkHGMBtyG)S!Z|Am9_)+f0Nxd-@1{{Tk9Q+8Mi}3L#`m9XKd^_~U(a{i z<)|M1AJ3mK<=09MN2UNg@(XM!k&fom?zG8vuUxJRHqXsQ{Pv*w!1LLJxV#@nGC_(O z9-C#K_dRiB?n0c==x9v+hu^-YX-sUds{e3m!NXcU7QP+d8oBcZu>Ua5h?Wr1=U(r= z*f+f8MF83KORs2sCJ@fGZ!Su2{lmEqm$y4|W9xWbDXZUh4j04_}6qy*y~^Dgt*CNa0FXdE?3|+K+3bU4aXDY9iPvp0%CQEq zFsJf_=L2(G_m{O6=J^9>)}BRN0dNy$0>SBjq+qV?|X9<#do z$CGA0)4IYqxF^42k`4I7>?RC3s?%cXCp$&8ep^ur?M~B(tRElk4Kz^N^!wH=g8vm% z02Be^g6Qv{;*-KVyKG_p$!0B8h3=>@BXDwvlYKv7F(hURcaWf2Z?_k z{e0o~Me?Qo8CY<7tJmIDxY7+G5dS!KgNR09)WG}L%7b>5)PeUP`O7)ub5J2($?<-x4ZD{q@+{g}?n<=&k5B;9`ob{)roH`- zCN}O<#3{GkJU1sU6dc>lLvOS#F@JL&{QUb{?v>!bXZ+i0e~&P1geBnUgF3St+U3{> zH3pp*a}3Nc?C7&${gkxfZ_6u5b_bUK(kE(=%r} z=m|d@bl|58!)amh=ivMy7?ofvQ=tB%;nX?v%&53ebpw$`?!VP2m!9ufJgUC7MNREe zYu!6vJsZ)1OUYw|Co`Ju^9d(Ei;ny1tvBEErGEUnIlg%NJzoPijVEL3C4QUZml|h8 zOom18MH75(tcCa*SA>4-9<%BD|2lgUc&OUkne#f!eYX3YIdi|S z>wUei`yh)oB6d!;`v{K&>a|oOrTWIsUb!_?U?4rlA9fj=LC?=Oq!oCbYbGC~FaUJUgO?>KxwFHqXcP!Ez#IzXtnM zMhdOLk#?&1+ZdM_N|4&OoMpW# zE$2Zy0pOm)e)%Jw2Ht8y_v>r&e<) zG_Mo#N@+*6#84CV+(XQ;;&JCwiM1a+bZ2uE@E9vhzd3(B2tpb2t}ecW&F(gFIJP2S|AU;8lTfNH;f^j-8Sj(OV4 z7zF;UHKEHh9v2?>2s_d4B`{OJJs562k=wiX%r^JL#u%Q&dauF3nZLXQ(q97~hY7brUe=6LgapB-{8wL|WaC{zyhcfBlF@CaSVfgC$I4SRp(L{2A zM4(OA5h1&SwmqN0Gvb=_+;}(kt9%_n$~%NZ#ILGk%>B}RCD)5j)4tY7WGofM zG$e9oXy4r0cEg^R?bBRiXelTDgvo9F#nTv#&L4+~yt7@!)aV5S`b-Xl=WnD#=+y`8 z!M_;;P$2~9x=!xVP6J^UZ$cR;{b0T!PGRsU6nA(L_9s3M!a$1Zgc(mCVNO;l6-gYg*hRZM8C zidnv&!0S<9H-JGkoK6KSfq&R4h^&NY1n3J{0?-%h0=efI&*r`! zaCjkfV(zpEsqpU-4~1dH8gXixK-aedoq%GRbC>z2yt7FHMC$@;*xX^+F@gH58^^eZ zJRO-Rzx1O}3$xmgzY44iXLe)!jx!3_^ z@A&9M|4)*#OHP5hrk445z{Eep!UYD@XQd_WA;tpc%Ff0O|17gnAjSb^BNjs?fD`b- zoC*aY0Q&drd?i6*@F*jY06FJ>3=i_7KkDrFcH^fyyIPIo{~90T?tOkHbvJ>khYpt= zE+))3+H^W4QY)zyAOTUwrxPOa6flqlGbm7(@Z|1d~W^GJjee z3}eGtw?IqS`&4JQDz2%xtJ9>BhMPK59~bUikRqY1QZslo{A!{!WS1-fdIsKu2{?@= z6paY)$P_0ShtXYS2;)&cT2uVjmh$fmXV~%}jP03@1;;8r<4x zcB_`DepgOvDsI+@cqe(odYoXzX(yy#C-hx8;VH&;Jmdj2yL@ZMbdBU`v~A}g-y5d| z#I#p7egTm^Ea=rfU9CEL!(m*J`tpVz7>~kZGVUr(V|yXzFy>R|yA#OoxKQG?e1+F& zuw=Te%q+BQxVC^BVnhEG(nfWb9l`B-0&4rVV>)PsRmdEyo*)mwi0@=tshp|aj zkDs)$?W=1DvQv6rFsEQwhG~uWbNtiKop|6k>ZhM4Q7X!>JPzLK$sXhC z@8^v8B;Lqg^wyvPW!mLoi2fYA$1In#=3%!Ih1}BCHS5hD;oVxYfY=gi=$95;MRR!A zecbGXd$#vH26a@$*lJDV;AH~FMfnlY`K&B4IgzF#a@0DQi+*x=Hlg=8_T3h8MeVH5 zt+{)&Rdiznc=-)Pz!wNTRiOtVE-wjDc+27=JSmHC+^6NTxBwCSz&%%c1q^-u&hXp4 zhO}6GU(GsNVXt`)u>P%3QZm%*&?P(K+(R76u#=*Q5uc2&o0!+IVjrMB?R$k&olO2ODkpjv?!XSzDb>_q?{c zBMiU$v%{0Us{sMO)U5}=e`>c<#jSxhiYF$)7(E;}ktt4Lc=mHYaBYOnKI}*lb?Ait zlf-@zZv|P$A$c34B{_3%rz9b}_EkaB8`} z{Uc;qbnh{9F68T*FD~+`JO+^j%c{U)1$a7~(w9K0q;|=uQ%t2IXR}YUqet#iKNbD-0Yp`?_n6wciGPI zLEEPbDsg0b0xqQ+xn- zO!q+0nf;Zy+;Pb8s=YfKMM(3zO*po4N7m2k{ZQW!rnUR1rk1=|m7zwsdm;s^ymRm4 zJao&I+b%zyJ(~JaDLlnWYJ0@iWf)uJ%J;j18l0$+a=$QBVh&Lh33D`L9xbDG*6;RQ z;v)Jp>Hpu&0Pw$QJPPV zt7k>M@{L}#tOcy@Xx8YLK7V$yO zEvpDx&QU4ov*7pWCAQCH3{a5|+|hYzpwe_+Vws6j2P_kygiw{(+LhO}XgJ^>&#ES{ z^Z*PSgKm>R)Wg|4Wp)XW4~^8AbYUOSn|&x0E@ELD9GbNs=iT8wZWcJH>h_aHLEg(- zr5P&hQH|zX%|0%TidjH-EFj({5XzM;_FbY-y7wAAaOdDvRCFJ|gT3$uE#}B^Hdj?d zq_1%AM6>^u`WDrcX16U86a5knJOOF;=1lVr!Q#<+7qh$e+oIp|Xo9QLf{{|?G|J*lk z^yk?|pSeD7iBJ4xdmJNrzwke8PSgqPlpW)l>WU^j$&c%r?8&vNC^vkq>7A(UeXi7> zD(FrKbolJ9{JN-G<+(XccihTM4*ai(?&3cS-w?+W+H7hG>&n_Yb`BEdcUs($QA?N6 zdJ2%j*q-wp^yK^8p38zG53C3SBQya?BOo1vcutI7!ax{^0>F#`_k;nKG8^7RXA+iJ z24L1aGsjW+7p}gRy1jS~;8#8PE69TGSb1i$=FQ?KGT3K6(=4#Jg3R0JeM(2jBA1$PVI_oX!d7NQ1O!#e~Us^Kb($*d^ zJzj*z=Fjs?dR*+t2~K=m_{lV$Uy;U*RdpM`GGO!dQ9{7DrF!<^3cfFqm}9gfiXjKl z(d|w;qVFrFvxIcoqwMsQY2dMc!uJfAJ`#RwtTRr0H z6nsT1z*h<)e=UY5i0Yu?|HhMaD$WAE0wg+sX#=rfViZeU01O2B0R38#s11*5Ahc{+ zKzOV5X99k50>5P@8~Xj?)KGK}|eH)WWkI-BwY%fEekV!_WGG$D-QUl*1E4gdRU?%>dYnRf#_p z4=9OkJ$Z?&XoHmbgu$TqG7AMZSm+kSkURPZ0oaxr?K5G>6K1c#HDNnTy+BV0e0|vN zk6x3Q%~-rz#!XxyRYl1A@P`!Ajc*_WzO=h5sJ!J&VeMci=pkSM@yTodLH?Q%W6UqO zl0Kl4^r*#RhyrFPAf-ZNCG;hfWx5q6`Z9EkkK2x(->@vuup5pY=+_k$c~8Da){?!t zLJYjj&H*ce=+uJkE~SD;8LlFA2(#JQFTU<)&he-&r!lkPzRCGV(Yy~;sssTM#7AJm z3r)<3^^LbH=0{uTkDC2*jy@RDu3r<-zJPFoFlPb5K9@0e88UugNdn6vVoEF}N;*wA zjqfo8i5(|x5`kaOjQ20WdnqNydE|&r?d)xg$4=LzuW-~MyH{0qBpI?og!o1-kz?Ay z`t!c#cRwro>w(oKyaPw#m4tMnI&>}(;OQ6X5)5tcqJxb za3VF&cm<0VfGiEVY*IKU#vyrNDHG5DF#$kl_%FZ>5FA;W zqt`}Am{>9QjWZdQ@f>;*dP}MFC!zf#bqL4Pg*oh`EN;s^W#Qu&AchxhmoEqOgQ4l2 zOp6drRYM=$0~U%jc0L}?7tUeHQyF6-MWYX8^#-P-EV51*M)&U8-#jT6E_!KowZT=f zAE<42itnmEchnzMvnv2$4YdRUSF!gXxV9V&_%l8H7sF_oD)O~OfqY;JRrCa8U_jA# zi8Yjew=NVuj>gP@D+AtHq?#dN7&0ynIK_EkN-4-TvIE1oh}$w=IbP~aEI~z43(XS7 zIK+yjaJ&^?&|j_@>Z-o_4E}WBe;8mluEiNrQ|m)3M%Ip8@0+(NA0vs?2(7Niy&X8P z58O1DnvWA-D42wNj`pwXgBO>IuouKGm&H_SAuPWVRbUx?$_sN3Y z1kTboqqvH_m?mP_ddIK`v-8#v#D@x--x2H;<4=F{Z7e;KW6Nuw!N>)~a6eX!6xyGD zE^9t_#z44DoF4oz#rbxpfnUcR^9|iYuMyK~kv_LXAHWntB7-^^tO#8)=xvt{D+B)} zMq%UA?(qv4QD$wL_RiD<(5&{F%8pzCW^P-KLq5I(dl%e$WH=eTXDUEB$95#@S;e3! zf$M|n+3va$sw3f9yJBKQa*wkOrZPUrN~|hIVtrK5{Iu?+*@xs_YGR%u?U}}xek?9z z;@cTjV1Eb@*o;Y;Y23M1M9$r%(%FP|_m5d{(X zc)HHei@jV0M*k_GFN8gPAO~Q@H;zi;OL9!{)}S*VjhmIO(dWK7>BaW1XOIYC}E@QTda@-uEO6Yn9R+U*si_}p9kN<>;K@UU#XnzBdjR*6Ud2KH^ zmPrj@*#V5zxWC#9CV(j;Z2>Na3mF3%N{F#A7x)VLpNdo!*_>&0$Jv~aE+fGaX(p~y zt&tf%t22#x9xE6|jO4!4m@Z=+1tL5iPa!X~EmhjMS;oRfBEl@%?+Wq)^?7OWrL!-O zD2@>uLZ{S#I~fA*$1GN22(msH%ob7$mNot!%V0(_F36Z|EB#6fV+a&LdoK*=f@N02 zUWie6*6%2&@M8g?(Kk;djC7Nab}P9-Rs(E0T;JZt4rZ~SptWx_-}Qi?R!yID zVsbbn2m@E<0eiYFPRBRqYZFah*}1PPD1LWXcb^_`n(id+4gi5|e~Pl);|vLsa1>#C ziEE)DUr#mPEk6z4;*HlDU(mj)s|?xFwGgl%LaD}w8V=D|jqB#D=7&rq8kUlbnamoVvVUNtjLI~$mc0*nWpl*lyu0L?w>V3bskWnAbn|CDPH z5cV`T_5^7%=Y+t!3F~pICNl1dkRA{fD_V?HB?!rvuje{-@0%JS{mA06&OYxe*pPt( zwtTQ-;Tv3aX`R<^5{l(%8dClx6z>#nRx|)#S&;(dFCZGR+X4y_JOw1da%f*bQ0xIT zU#DO+e8zDbqJ2B9dU9*3)xBR)!n%JcNA!y4e43M)$BTKrxWWC$gqpU15G)iS;r<3> z3HsBx)py)j#klgrX}=*IFljEltPy_W`jFFt6iYRo zjXdTy{#1y2>A1~enuFaomh|C=p2g1$be5ypj92*W1;o3dm@QYPPpr?rAvK}6*997@ z(8scK(7Y@eUHNme=4YX-&(H*zZ$GF^+c2Scq5^Y!zM3ZsTH!n70bzD6y zV+g1NXaW)aF6>#AIeZaojbuBlHHXIemjM*!x~ zX(#{_P`M=M0@8CJx0aThc!{vm2=uB*&VwKa3nVKfGQ|f=f(g4NN;}AHoE#ow8TYq$ z&Sp@adSe3oIE&Si!%VwvOS@uMD667!J$qFWl~jYgG?~F0hWrrZF+k}Mi&+aOG!IL{ z0Qvl^Km@E7_!qCAk59=-kW*bC&NzO+(5s;`fB(75H6drmH5vs_db9-MtZvF4Z!312 zQ0Gyzb023#*rVGMsvY{f2zCEFjxnF~XHf`nq+?N+0OukAeV;~Y`w0+VfRua(_<@H1 za^L=h20C`rwRW%?flkjKU;rZU-9I|zmazR&PEELSl#4SieD;Z@J5#-{0*A8Xsa z>!Vv73$1H@DeAqlnh``g#I??XamkHBk=w)MIDVSO>gF+3>G=@$w;fpXSwVKYQg`CG zB1dz;bi%BV-mrVd-+G8^VSGQ z--F6_qodCyxAb@@+`c+GFC?}%svpC9L@0NsXF?T3F+f^Jh#6t%Kj>K*AZG*mQQ({n zwKaEUf2dOv~}eAm;Z?(3_xlA`*?F zSH1~cQ`Zd*x3KueN_wG-QE~i~qi`3zG+l*O$J0u0??Z8Vq=6;XFJ8RE|qHh`o23 zvA>B9{>Y#d`s`<|##A!uXt{IOnXY>64T~Aiq2VK^ ze32<=y!$8Lpc*{@7zg;UOgdtD$|GH`04fF5%X`%;!Yz76BKp~4&S5xlmz&FR$dR6b zQ3zrIbaDtzs1B2ocmCJ8e~Gn#MMo01DCD_=XUUE}f#+GHFj0ANzZUJ#<$L{(a7PD3 zncp@(e|e!?QO7x1zi%{E-Tzjc?gRP zL$g+`Wy%c~=RhEUS;%Xi#S4z}PtPo!Sf?NPayAq~SOSO~01)Z9f=%tyR-Da7;h8HsIVtvb{ z&;Ocu2etUGA;lj9W2I}Ek$gHu{=X^Z8S#H0vroYrtSbnkA8<)x-_n@6+rIu^`}%+o zF*&Cw-bejn?E^VW_RpuN|XWlJKmva)&$=A)9(xih0H1@vi*h# z!3B`810A~}QX@K|Uq*(oC*b5rZ>62*Z-g>fETbbv2(gZ-i~mhC4>R4clAeJa6bDFp zPags|3XW?fq6nwN$|*-(ijzY0-k*e2`9Ph|z?S8m4-_c*bwe_`#e_1CT%Gs@V?qFLI>fu=^*^H5R?=z<^@@p-?5A>UYLw`?XlQL8?V0c2=d}Doq4xJO@I8p%=xTStQ0mzGMpHs z!1vnuM;_d7nQ=0wnAvk;$LXB_fTLyR7ChB{xCpF!&+SR+BC^+~ZM9Q{(())L`MB^& ztLDCNgWQ7Ggj*_Ce(Ih1xtMDJEwd62z=BTa1E8l8T}*@5tAdi^WSD9D(A2$SteBun zb=}{LTa~TH$VBU*It)UNAQY8{QS-j=Qp|)Pw3rT`PN?>`pYHF(=KxxnP8ov<(vftX z8%9^KI_x*l6?m0P&xM1J54d?Dul$!FC+{m!f;7+5KAzHveROuh9LmY#VWq<{)8gPM z)>O2?LkS?Ppem6wvv|mHjvw2StJ5{1=oNxA_XEJD=oPdL`9p>_K^BV^zJs-He`(&A z;)1)7y(9;pohGE3jLsGxBE6I7v7ne-O@L;ZWx0&(I5_2=MV~`?a`c6)(~v7G z24~%$z(z}0Ow*Ix76p7wfSz8Gk5Av8xqDNDCCI;L9jz&rrO^y_YjVY#Gm#XmHo!T~ypWqE+JK+Sm8$k!a z!0)=R5BB5W+j}NDOp|4|JA97o1x!`Zs zzyy9jsYP$!4@Hs^6hF{^oRa_Vg&_YP&c+8OjoY{_l#B;w<1^IwK#>o+IARPupw~d}xX#fU z(DK{KRu@Nwj~J7F%f!dJa9*Hjn#AQV9r}ujHye;#UC3f#Ui=TpwkB&kduVUko-f^o zHGh6X_DtZS)}Lh*(5)4{h64uOwV0EDNC&F+<<2bKgY^amM)JV&-CQjj4>28G*wY@O zcKk7PLA@e{fL@Wj77!apuYhFbe=0a^wvHH=ew$+rCFFda_`&<3!(2kOT+nF4-Pno36rV($YBzC@+)+U7Eia z>N^PbhoKpICqj^9AEXp6@yJ;VSN6Bea<$;Cq4YndxdGSlx6yh>mr}XjGouxP6#bpi z8!eM7Kz9lE@YY}y&@qNl8VFSp`>Chp&I26nNy06;P6b{<+6ydCm1>Z1vyi0oNy3e; z#nsEU{bPZJ|4?^5zyvtw4sq>dZpOf%epys-uwDbpf?1mA|G&=Lpcgwk(%X|O4pQ?O zCJ4hm0rjC@)gLuwT`yRpjqP2llWhFn9N2Uxl$8zdWHc;ZFyz|HP;>^ENqa(P6)l3q zcn^OxFbwOW9%+xSE#*(cU0|;MKc|{NmE8ft>k=(`IdGgEngP9Bj!U#aoOKGs48YRu z4zH3qKpw!B4wO9z@4?&|Q0CBT#!(pv>FtCS*NZ{wiP zOumHs9SRTA;LKJ$Hu#A!Y_*YU2wZeUuZKQWB-c2NxO2rr)ksSwvjF?=VC8=n0#gWL zA0Q4KcKPX638Pmc>0MX?Y^VHpKSdY8?u&}NAtravA`rmZrxfRI5xT|o-}U&<8vEii zB+%ch1=9b(E&jjM;s36=e|xcV7~VikNl9zMB2y>kTrW9D*6)j0)yZbNslr<| zdkhL}LDxXe-j;evU!&;V8!`GYV)l0Q$0F#6pc3kK2uktKmdFNK|8(-CrOp}Zp6GXa zgOM>Y1d%Qb3kTywp7u_pE@j_Cl!i6W&VYKN*!AMA7>_y%EOzhom%=m<{7$4|Nrk7 z4-REs3s+;!Y|hh4&jg`o#8l~lp#OO$SWT2~mjY=XXt3J~aG*QM9pKGrY^%UKDZz^; z=^s$A;;$VmdG;ORK6w%DAaVs8cqL_d>hGV--B3vy|GRl(FNISUjNQQ-lvjRW&Vx?u zrQP7opiNU#DZAkbG)i+Fz@pRUHEU;4kJkp#cVLG)vGzbfy*4A*Zf;1>ByYuq6r|3U z4L79b?M_Y8PR%iXf&P#d8MC`R$;ilL%Y{UQ$e|TM4>y%7-$YDEwtW78SaWkVc+a5q zoLUP-Z{>v)Bj|I6ndq`$ukL ziKR8@m$|R_#P%n+q6-4ptxj^_GIjVa_kS~T%xKCra&@v7Hv;vx|7XQbgftJO0h73u zmIbcW1lg-=dEdzB{CVeBIcLb__1Zb-9idyafJn%@i9me*q<;)qExAuX4uRMZZ)Ef| zM#(6NmfBqljukhiKiPT+u||#UWnIpZTutx9>^uzzW;(}guS%2Wy)j69S&y3dp>;{d zuevMpkL7#E&#!Qwa!fye)#xE*@0(^^l3StNXSSpIHxtS#a495v-_>h2-aL+-)|j$X zJ@>JIlfavO9rVL%Wnq?B)fv!Yka;n`+l*m zl?cC74k)kl^-wI{*c87i_wn8aO*VJ!jHlgD!;PKz4zLWN$y`4aQ=NoBHdo+>_R<%Bj$*ZX?%@CjN_nyBt&|0C;gMJ$+VXAYj_T1K|oedklpKi~H9wg z*ZitG*!^{3cg(@GUi!f^PnQu|jrF5DO%J|$&=`1ux;-i`0aRzWj%pjMBq3-RtJNIh zS|A7ROw}e5Me%jlk5+VJpy}1pY`dXWuV%;Un9O9}xAWOL?{rm_&yPFU69&PN3o|(O zdboj|TBQ7>FdDr1(alMe(LvI1X~up~!|^J%XY6rs>Gv_43ZZ=IWE3dw;g{jj#Yiy9 z2SK@hvN$MzmypG{83#(r!p~?t%H(>O@<uPG4?Ha&tU0` zxd^tKAC6<^&yU;iXY0Jl8g}SZP$W+k3`3V6b>>e~?WgkQ(nrDNM_qNS*RGrg)xc)%A1@)lb*?1CTeF3W z@$Uy)_xit$R1(Z4f!BC~`w{hE<;8VLCav2+1wc2`W*Lozy!o*w2Ef(7n1=oq%=elC z5e4))^IspM$bQmz6+%E}^_n+0Q!6pV#V0q{;bV78P+|z+@lD_An0MgY^~oOlJehhw zx1=b}eWcfKLH68{!C!eY))oztd6E=ibHdwYpLfeXOIE=zI?c|qPw3h`U~~p`ItKIo z>Q(1)a`}hOfA>5($ z2oiYx^y*q#$biw+t7FEPdgol%^G2up5r};knMS3b@Sz*plcf^w#Z+&B+Rd{;HDvy{+XK*UE^?bUZ$%(r3|qMav32$8RnUAMru=A! zmpEvdjj$&7y|zplO*liS_o5E0L~On|wZf+bu}Mw(pY;Ge5E~Lc?%3$}6~Mxj@9Lv# zCbUz_pho@7l~%C7k;#{@yTHW!m{Hy}OcAl(4ImYC6#kVvu!uFc;Q6(m5qVp{7Dh&= zBje80R&>Rc?^)bDYX&xZhc5>}Fv_g2_$%}t+AJ&&J(j-;_IxMrHe8XUD9l)EwwiA}-)eW}q64*6 zjjUjRiTMEM!r6VAB1a@4F8khqe970OKM1*!l&W* zY0C@C4qVCLfog$-t$GC8O312bG!WoL6Kue){fqn1%6%t!=vF;gy8@8~tXSrU?a*4p zLBwAxJ|GZ}8D(s?&B-@$i0>D~g1NOs!?Z-B#3hQw*Od7~^I=+fCxIage>U&g!+viy z+acEB{CPUqes1Df70@!hb-&6Q(bzgI{{hk1VvF0yF2;WNZhGf20=yUz5r5?4iVwzX zZyrE!t?1}j;mdXiys!na>WP;4s_>N>&pwRsG+8%=UDT3$wBZ^}OFRNT+4{|^e0^_@ zt}eaf`vETSr^r14^|21qJDfRQRih>O6jV?fs>^0n7%#8T#g}~-lGcO8b>C63KSQ%l z4r)UeP|K@*EHiUzQ}BIDu($q=`>0q-5zlMU)xH~2&q?06Wxqp`ZF9fu3jF(f{t0rQ z^~%M-osm3ra;DUGJuh%lR#AoZ#qmEmNKXuI{)P18`D^oPL|me_oL)p)tVb_%=)vob zYaN>~riz|^SERWq30IFvuI~$pZhaOJn7_h!C^hYAX;^y3){%%o-7Q9@AxcVaQ3Web zZWfj^eXo3#uQV9G#4aDcQ^scz(INfnPmWz~81_6ISP)_TOJ17Db+jq>;&*U85+ae> zFSRT7WL4~SHt^jL7}Ak3QLb|E*d2t{)3DTx#6}yjkZeN3<$=vjo|I>KDWY{){hUj8 z`OQ~7-&efxUxzI_T2D1~1s-T_SKa$XH$*f0#rxFmu9`hrRZ3i~_&_%U-!g*eIe8z? zF9WoQ8)gmUH)@ZM?N<^eJ>OPmO#Ax&fEn+=QzE>@hDSddg{#KwQ*E7(g`ZW3uYRz? z&b5tq_$hn<%NZ^H;DX&G={oF%)G%F?W|qwwQU&i5c@xkL>-iUfr_tbKT1g~c-HYE; zF5bJ>YZ7w%Nh1GS9eTZ>tuL1(7iBpg=3U&f>HWo$?7AT>r5&FN_I%M2ht70cBTV_~ zm1B0o@>y8-4sy1UXp~-{_)A+4;ZL^|G(zB=6Uk#$7n{b9J*vhFn(_WkzW{TRkZSL9 zMQ9iKx?JcA`4aixr=OKU2g);Q7J4=^ae*Rv!%JhGQBU54 zZvB><`lv71wvG4iq_s~2JBf7%?x+4}IO?F*QFW>b>ppcP`P)F*$h)uI`>)Qe-ebF7)=4^z>$ml2Yj75CV*C`X@IKiDdV+k9C|OmY(! z`NJ-ZW`yoGfvx*7zWc=eB?}X@5hv$AKjs!YfbXoTpY%V3kX+Bb8G{hrBZ=TS8i(z= zQJ)y4V3ei*RfT9`8)2`zRazUEcpEnC{o-JqD5TI09;;5?pU3 zn0E-(uhfo&|MU^2U5WF%lcJlTwq!Mei~Z2c3F09H+&VnA{?s&kw@jV=#Q`I2ROn}! z16J=(O@eY}k( zT0{Gwr7$hIbz&Gzg6_pVdzAO>*|UFJzODU<+*9)k4m&=+2^(fB*??h2-A)TzK=dBKG}Tgdhz!Fl$eb$2L*5eR-EYz- zakLi`e%tkjQLo>u+|IRTXG+j7$L_bhmr>6#3y%beStUoxGczs0n`n;koC701g9Fla zw>_Oc$7Yawj|{5yzX4bzbbJw`aQxF{@^vq+6Vvb8yidUbh2$7!i))(6;H~$%>&Q|` z=ST1+yBj@s#I53alV_AZd4lkCf1~#6ACoUlwfj%ME9W&hL?{^xlewP`)=rUD?Um8E z4b6R=bvHE(vH?fUzhsV9@+dBQeMb8|w+2b13OZiemZxtUwew%+fpK<$iECPs=|O0V z?DwCwzX`4HKYcw_NIJ`j0FL@-;C_VrPH-eE&-Sj*v06M4LtvhBod-!EbKX-l_V8yPkZ07Z*GZb!DK^Ij(oG6 p((T;ZT@upJlg>x_w6^np>K8}trf)`|UMU=I$91Gp#o`ve{ePxI2( Date: Sat, 22 Jul 2017 17:05:25 +0300 Subject: [PATCH 033/338] remove deprecated libs --- assets/lib/document.class.inc.php | 283 ----------------- assets/lib/resourse.php | 493 ------------------------------ 2 files changed, 776 deletions(-) delete mode 100644 assets/lib/document.class.inc.php delete mode 100644 assets/lib/resourse.php diff --git a/assets/lib/document.class.inc.php b/assets/lib/document.class.inc.php deleted file mode 100644 index 888c41b596..0000000000 --- a/assets/lib/document.class.inc.php +++ /dev/null @@ -1,283 +0,0 @@ -Set('parent',$folder); - $doc->Set('alias','post'.time()); - $doc->Set('content','document content'); - $doc->Set('template','GuestBookComments'); - $doc->Set('tvComment','post to comment'); - $doc->Save(); - - Area of use: - guestbooks, blogs, forums, frontend manager modules - - TODO: - * document_groups - - Important: - 2) Not to be used just for receiving TV values or deleting docs. Use - $modx->getTemplateVars(); and $modx->db->delete(); instead. - -***************************************************************/ -class Document{ - public $fields; // doc fields array - public $tvs; // TV array - - public $tvNames; // TV names array - public $oldTVs; // TV values array - public $isNew; // true - new doc, false - existing doc - - /*********************************************** - Initializing class - $id - existing doc id or 0 for new doc - $fields - comma delimited field list - ************************************************/ - function __construct($id=0,$fields="*"){ - global $modx; - $this->isNew = $id==0; - if(!$this->isNew){ - $this->fields = $modx->getPageInfo($id,0,$fields); - $this->fields['id']=$id; - } - else - $this->fields = array( - 'pagetitle' => 'New document', - 'alias' => '', - 'parent' => 0, - 'createdon' => time(), - 'createdby' => '0', - 'editedon' => '0', - 'editedby' => '0', - 'published' => '1', - 'deleted' => '0', - 'hidemenu' => '1', - 'template' => '0', - 'content' => '' - ); - $this->oldTVs=$this->fillOldTVValues(); - } - - /*********************************************** - Saving/Updating document - ************************************************/ - function Save($clearcache=1){ - global $modx; - $tablename=$modx->getFullTableName('site_content'); - $fields = $modx->db->escape($this->fields); - if($this->isNew){ - $this->fields['id']=$modx->db->insert($fields, $tablename); - $this->isNew = false; - } else { - $id=$this->fields['id']; - $modx->db->update($fields, $tablename, "id='{$id}'"); - } - if(is_array($this->tvs)) $this->saveTVs(); - if ($clearcache == 1) { - $modx->clearCache('full'); - } - } - - - /*********************************************** - Receiving doc values ot TV - $field - doc value or TV with 'tv' prefix - Result: doc value, TV or null - ************************************************/ - function Get($field){ - switch(1){ - case substr($field,0,2)=='tv': return $this->GetTV(substr($field,2)); - default: return isset($this->fields[$field]) ? $this->fields[$field] : null; - } - } - - /*********************************************** - Setting doc or TV value - $field - doc or TV (with prefix 'tv') name - $value - value - Result: true or false - ************************************************/ - function Set($field, $value){ - switch(1){ - case substr($field,0,2)=='tv': return $this->SetTV(substr($field,2), $value); - case $field=='template': return $this->SetTemplate($value); - default: $this->fields[$field]=$value; return true; - } - } - - - /*********************************************** - Receiving TV - $name - TV name - ************************************************/ - function GetTV($tv){ - if(!is_array($this->tvs)){ - if($this->isNew) return null; - $this->tvs=array(); - } - // Look in the values created by Set() function - if(isset($this->tvs[$tv])) return $this->tvs[$tv]; - // Look in the TVs already defined for the document - // Call fillOldTVValues() if not yet retrieved - if(!is_array($this->oldTVs)){ - if($this->isNew) return null; - $this->oldTVs=$this->fillOldTVValues(); - } - if(isset($this->oldTVs[$tv])) return $this->oldTVs[$tv]; - return null; - } - - /*********************************************** - Setting TV value - ************************************************/ - function SetTV($tv,$value){ - if(!is_array($this->tvs)) $this->tvs=array(); - $this->tvs[$tv]=$value; - } - - /*********************************************** - Setting doc template - $tpl - template name or id - ************************************************/ - function SetTemplate($tpl){ - global $modx; - // Retrieve id of template if name is given - if(!is_numeric($tpl)) { - $tpl = $modx->db->getValue($modx->db->select('id', $modx->getFullTableName('site_templates'), "templatename='{$tpl}'", '', 1)); - if(empty($tpl)) return false; - } - - $this->fields['template']=$tpl; - return true; - } - - /************************************************************ - Deleting doc with TVs - *************************************************************/ - function Delete(){ - if($this->isNew) return; - global $modx; - $id=$this->fields['id']; - $modx->db->delete($modx->getFullTableName('site_content'),"id='{$id}'"); - $modx->db->delete($modx->getFullTableName('site_tmplvar_contentvalues'),"contentid='{$id}'"); - $this->isNew=true; - } - - /************************************************************ - Duplicatig doc with TVs - *************************************************************/ - function Duplicate(){ - if($this->isNew) return; - $all_tvs=$this->fillOldTVValues(); - foreach($all_tvs as $tv=>$value) - if(!isset($this->tvs[$tv])) $this->tvs[$tv]=$value; - $this->oldTVs=array(); - $this->isNew=true; - unset($this->fields['id']); - } - - /************************************************************ - Saving TV values, maintenance function. Only $tvNames values are saved, - If a TV exists in oldTVs, then updating, else inserting - *************************************************************/ - function saveTVs(){ - global $modx; - if(!is_array($this->tvNames))$this->fillTVNames(); - //if(!is_array($this->oldTVs) && !$this->isNew) - if(!$this->isNew) - $this->oldTVs=$this->fillOldTVValues(); - else - $this->oldTVs = array(); - - $tvc = $modx->getFullTableName('site_tmplvar_contentvalues'); - foreach($this->tvs as $tv=>$value) - if(isset($this->tvNames[$tv])){ - $fields = array( - 'tmplvarid' => $this->tvNames[$tv], - 'contentid' => $this->fields['id'], - 'value' => $value, - ); - $fields = $modx->db->escape($fields); - if(isset($this->oldTVs[$tv])){ - if($this->oldTVs[$tv]==$this->tvNames[$tv]) continue; - $modx->db->update($fields, $tvc, "tmplvarid='{$fields['tmplvarid']}' AND contentid='{$fields['contentid']}'"); - } - else - $modx->db->insert($fields, $tvc); - } - } - - /************************************************************ - Filling TV array ($oldTVs), maintenance function. - Differs from $modx->getTemplateVars - *************************************************************/ - function fillOldTVValues(){ - global $modx; - if (($this->isNew) && (!$this->fields['id'] || $this->fields['id'] == '')) { - return array(); - } - $tvc = $modx->getFullTableName('site_tmplvar_contentvalues'); - $tvs = $modx->getFullTableName('site_tmplvars'); - $result = $modx->db->select( - 'tvs.name as name, tvc.value as value', - $modx->getFullTableName('site_tmplvar_contentvalues')." tvc - INNER JOIN ".$modx->getFullTableName('site_tmplvars')." tvs ON tvs.id=tvc.tmplvarid WHERE tvc.contentid =".$this->fields['id']."" - ); - $TVs = array(); - while ($row = $modx->db->getRow($result)) $TVs[$row['name']] = $row['value']; - return $TVs; - } - - /************************************************************ - Fillin TV names array ($tvNames)), maintenance function. - *************************************************************/ - function fillTVNames(){ - global $modx; - $this->tvNames = array(); - $result = $modx->db->select('id, name', $modx->getFullTableName('site_tmplvars')); - while ($row = $modx->db->getRow($result)) $this->tvNames[$row['name']] = $row['id']; - } - - function setAlias ($alias = '') { - $iso = array("Р°"=>"a", "Р±"=>"b", "РІ"=>"v", "Рі"=>"g", "Рґ"=>"d", "Рµ"=>"e", - "С‘"=>"jo", "Р¶"=>"zh", "Р·"=>"z", "Рё"=>"i", "Р№"=>"jj", "Рє"=>"k", "Р»"=>"l", - "Рј"=>"m", "РЅ"=>"n", "Рѕ"=>"o", "Рї"=>"p", "СЂ"=>"r", "СЃ"=>"s", "С‚"=>"t", "Сѓ"=>"u", - "С„"=>"f", "С…"=>"kh", "С†"=>"c", "С‡"=>"ch", "С€"=>"sh", "С‰"=>"shh", "С‹"=>"y", - "СЌ"=>"eh", "СЋ"=>"yu", "СЏ"=>"ya", "Рђ"=>"a", "Р‘"=>"b", "Р’"=>"v", "Р“"=>"g", - "Р”"=>"d", "Р•"=>"e", "РЃ"=>"jo", "Р–"=>"zh", "Р—"=>"z", "И"=>"i", "Р™"=>"jj", - "Рљ"=>"k", "Р›"=>"l", "Рњ"=>"m", "Рќ"=>"n", "Рћ"=>"o", "Рџ"=>"p", "Р "=>"r", "РЎ"=>"s", - "Рў"=>"t", "РЈ"=>"u", "Р¤"=>"f", "РҐ"=>"kh", "Р¦"=>"c", "Р§"=>"ch", "РЁ"=>"sh", - "Р©"=>"shh", "Р«"=>"y", "Р­"=>"eh", "Р®"=>"yu", "РЇ"=>"ya", " "=>"-", "."=>"-", - ","=>"-", "_"=>"-", "+"=>"", ":"=>"", ";"=>"", "!"=>"", "?"=>"", "/"=>"", "\\"=>""); - - if ($alias == '') { - if (!isset($this->fields['id']) - || $this->fields['id'] == 0 - || !isset($this->fields['pagetitle']) - || $this->fields['pagetitle'] == '') { - return; - } else { - - $title = mb_convert_encoding($this->fields['pagetitle'], 'cp-1251', 'UTF-8'); - $alias = strtr($title, $iso); - $alias2 = $this->fields['id'];// .'-'. $alias; - } - } else { - $alias = strtr($alias, $iso); - - } - - $this->Set('alias', $alias2); - $this->Save(); - return $alias; -} - -} -?> \ No newline at end of file diff --git a/assets/lib/resourse.php b/assets/lib/resourse.php deleted file mode 100644 index 985118f328..0000000000 --- a/assets/lib/resourse.php +++ /dev/null @@ -1,493 +0,0 @@ - - -USE: -require_once('assets/libs/resourse.php'); -$resourse=resourse::Instance($modx); - -#------------------------------------------------------ -* Add new document without invoke event and clear cache -$resourse->document()->set('titl','Пропаганда')->set('pagetitle',$i)->save(null,false); - -* Add new document without invoke event and call clear cache -$resourse->document()->set('titl','Пропаганда')->set('pagetitle',$i)->save(null,true); - -* Add new document call event and without clear cache -$resourse->document()->set('titl','Пропаганда')->set('pagetitle',$i)->save(true,false); - -#------------------------------------------------------- -#Edit resourse #13 -$resourse->edit(13)->set('pagetitle','new pagetitle')->save(null,false); - -#------------------------------------------------------- -$resourse->delete(8); - - -//JSON && PHP < 5.3 -$t = test::Instance(); -function asd($json){ - $t = test::Instance(); - foreach($json as $key=>$val){ - $t->set($key,$val); - } -} -$t->fromJson($json,'asd'); - -//JSON && PHP >= 5.3 -$t = test::Instance(); -$t->fromJson($json, function($json) use ($t){ - foreach($json as $key=>$val){ - $t->set($key,$val); - } -}); -*/ - - -if(!defined('MODX_BASE_PATH')) {die('What are you doing? Get out of here!');} - - -class resourse { - static $_instance = null; - private $_modx = null; - private $id = 0; - private $field = array(); - private $tv = array(); - private $tvid = array(); - private $log = array(); - private $edit = 0; - private $default_field ; - private $table=array('"'=>'_',"'"=>'_',' '=>'_','.'=>'_',','=>'_','а'=>'a','б'=>'b','в'=>'v', - 'г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'zh','з'=>'z','и'=>'i','й'=>'y','к'=>'k', - 'л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u', - 'ф'=>'f','х'=>'h','ц'=>'c','ч'=>'ch','ш'=>'sh','щ'=>'sch','ь'=>'','ы'=>'y','ъ'=>'', - 'э'=>'e','ю'=>'yu','я'=>'ya','А'=>'A','Б'=>'B','В'=>'V','Г'=>'G','Д'=>'D','Е'=>'E', - 'Ё'=>'E','Ж'=>'Zh','З'=>'Z','И'=>'I','Й'=>'Y','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N', - 'О'=>'O','П'=>'P','Р'=>'R','С'=>'S','Т'=>'T','У'=>'U','Ф'=>'F','Х'=>'H','Ц'=>'C', - 'Ч'=>'Ch','Ш'=>'Sh','Щ'=>'Sch','Ь'=>'','Ы'=>'Y','Ъ'=>'','Э'=>'E','Ю'=>'Yu','Я'=>'Ya','/'=>'-', - ); - - private $set; - private $flag = false; - private $_table = array('site_content','site_tmplvar_contentvalues','site_tmplvars','site_templates','web_user_settings'); - - private function __construct($modx){ - try{ - if($modx instanceof DocumentParser){ - $this->modx = $modx; - } else throw new Exception('MODX should be instance of DocumentParser'); - - if(!$this->makeTable()) throw new Exception('Not exists table'); - - }catch(Exception $e){ die($e->getMessage()); } - - $this->get_TV(); - } - - private final function __clone(){throw new Exception('Clone is not allowed');} - - static public function Instance($modx){ - if (self::$_instance == NULL){self::$_instance = new self($modx);} - return self::$_instance; - } - - public function document($id=0){ - $this->newDoc = $id == 0; - $this->id = $id; - $this->field=array(); - $this->set=array(); - $this->default_field = array( - 'type'=>'document', - 'contentType'=>'text/html', - 'pagetitle'=>'New document', - 'longtitle'=>'', - 'description'=>'', - 'alias'=>'', - 'link_attributes'=>'', - 'published'=>'1', - 'pub_date'=>'0', - 'unpub_date'=>'0', - 'parent'=>'0', - 'isfolder'=>'0', - 'introtext'=>'', - 'content'=>'', - 'richtext'=>'1', - 'template'=>'0', - 'menuindex'=>'0', - 'searchable'=>'1', - 'cacheable'=>'1', - 'createdon'=>time(), - 'createdby'=>'0', - 'editedon'=>'0', - 'editedby'=>'0', - 'deleted'=>'0', - 'deletedon'=>'0', - 'deletedby'=>'0', - 'publishedon'=>'0', - 'publishedby'=>'0', - 'menutitle'=>'', - 'donthit'=>'0', - 'haskeywords'=>'0', - 'hasmetatags'=>'0', - 'privateweb'=>'0', - 'privatemgr'=>'0', - 'content_dispo'=>'0', - 'hidemenu'=>'1', - 'alias_visible'=>'1' - ); - $this->flag = true; - return $this; - } - - private function makeTable(){ - //@TODO: check exists table - $flag = true; - foreach($this->_table as $item){ - $this->_table[$item] = $this->modx->getFullTableName($item); - } - return $flag; - } - - private function Uset($key){ - if(!isset($this->field[$key])){ - $this->set[$key]= ""; - $this->log[] = "{$key} is empty"; - } else { - try{ - if(is_scalar($this->field[$key])){ - $this->set[$key]= $this->field[$key]; - } else throw new Exception("{$key} is not scalar

    ".print_r($this->field[$key],true)."
    "); - }catch(Exception $e){ die($e->getMessage()); } - } - return $this; - } - - private function invokeEvent($name,$data=array(),$flag=false){ - $flag = (isset($flag) && $flag!='') ? (bool)$flag : false; - if($flag){ - $this->modx->invokeEvent($name,$data); - } - return $this; - } - - public function clearCache($fire_events = null){ - $this->modx->clearCache('full'); - $this->invokeEvent('OnSiteRefresh',array(),$fire_events); - } - - public function list_log($flush = false){ - echo '
    '.print_r($this->log,true).'
    '; - if($flush) $this->clearLog(); - return $this; - } - - public function clearLog(){ - $this->log = array(); - return $this; - } - - public function set($key,$value){ - $value = str_replace("'", "\'", $value ); - if(is_scalar($value) && is_scalar($key) && !empty($key)){ - switch($key){ - case 'template': { - $value = trim($value); - $value = $this->setTemplate($value); - break; - } - } - $this->field[$key] = $value; - } - return $this; - } - - private function setTemplate($tpl) { - if(!is_numeric($tpl) || $tpl != (int) $tpl) { - try{ - if(is_scalar($tpl)){ - $rs = $this->modx->db->select('id', $this->_table['site_templates'], "templatename = '{$tpl}'"); - if($this->modx->db->getRecordCount($rs) <= 0) throw new Exception("Template {$tpl} is not exists"); - $tpl = $this->modx->db->getValue($rs); - } else throw new Exception("Invalid template name: ".print_r($tpl,1)); - }catch(Exception $e){ - $tpl = 0; - die($e->getMessage()); - } - } - return (int)$tpl; - } - - public function get($key){ - return isset($this->field[$key]) ? $this->field[$key] : null; - } - - private function getAlias(){ - if ($this->modx->config['friendly_urls'] && $this->modx->config['automatic_alias'] && $this->get('alias') == ''){ - $alias = mb_strtolower(strtr($this->get('pagetitle'), $this->table)); - }else{ - if($this->get('alias')!=''){ - $alias = $this->get('alias'); - }else{ - $alias = ''; - } - } - return $this->checkAlias($alias); - } - - public function get_TV(){ - $result = $this->modx->db->select('id,name', $this->_table['site_tmplvars']); - while($row = $this->modx->db->getRow($result)) { - $this->tv[$row['name']] = $row['id']; - $this->tvid[$row['id']] = $row['name']; - } - } - - public function fromArray($data){ - foreach($data as $key=>$value) $this->set($key,$value); - return $this; - } - - public function edit($id){ - if(!$this->flag) $this->document($id); - - $result = $this->modx->db->select('*', $this->_table['site_content'], "id=".(int)$id); - $this->fromArray($this->modx->db->getRow($result)); - - $result = $this->modx->db->select('*', $this->_table['site_tmplvar_contentvalues'], "contentid=".(int)$id); - while ($row = $this->modx->db->getRow($result)){ - $this->set($this->tvid[$row['tmplvarid']], $row['value']); - } - unset($this->field['id']); - return $this; - } - - private function systemID(){ - $ignore = array( - 0, //empty document - (int)$this->modx->config['site_start'], - (int)$this->modx->config['error_page'], - (int)$this->modx->config['unauthorized_page'], - (int)$this->modx->config['site_unavailable_page'] - ); - $data = $this->modx->db->select('DISTINCT setting_value', $this->_table['web_user_settings'], "setting_name='login_home' AND setting_value!=''"); - $data = $this->modx->db->makeArray($data); - foreach($data as $item){ - $ignore[]=(int)$item['setting_value']; - } - return array_unique($ignore); - - } - - public function delete($ids,$fire_events = null){ - //@TODO: delete with SET deleted=1 - $ignore = $this->systemID(); - $_ids = $this->cleanIDs($ids, ',', $ignore); - try{ - if(is_array($_ids) && $_ids!=array()){ - $this->invokeEvent('OnBeforeEmptyTrash',array( - "ids"=>$_ids - ),$fire_events); - - $id = $this->sanitarIn($_ids); - $this->modx->db->delete($this->_table['site_content'], "id IN ({$id})"); - $this->modx->db->delete($this->_table['site_tmplvar_contentvalues'], "contentid IN ({$id})"); - - $this->invokeEvent('OnEmptyTrash',array( - "ids"=>$_ids - ),$fire_events); - } else throw new Exception('Invalid IDs list for delete:
    '.print_r($ids,1).'
    please, check ignore list:
    '.print_r($ignore,1).'
    '); - }catch(Exception $e){ die($e->getMessage()); } - - return $this; - } - - final private function cleanIDs($IDs,$sep=',',$ignore = array()) { - $out=array(); - if(!is_array($IDs)){ - try{ - if(is_scalar($IDs)){ - $IDs=explode($sep, $IDs); - } else { - $IDs = array(); - throw new Exception('Invalid IDs list
    '.print_r($IDs,1).'
    '); - } - } catch(Exception $e){ die($e->getMessage()); } - } - foreach($IDs as $item){ - $item = trim($item); - if(is_numeric($item) && (int)$item>=0){ //Fix 0xfffffffff - if(!empty($ignore) && in_array((int)$item, $ignore, true)){ - $this->log[] = 'Ignore id '.(int)$item; - }else{ - $out[]=(int)$item; - } - } - } - print_r($ignore); - $out = array_unique($out); - return $out; - } - - final protected function check($id){ - return (is_array($id) && $id!=array()) ? true : false; - } - - final protected function sanitarIn($data,$sep=','){ - if(!is_array($data)){ - $data=explode($sep,$data); - } - $out = $this->modx->db->escape($data); - $out="'".implode("','",$out)."'"; - return $out; - } - - public function fromJson($data,$callback=null){ - try{ - if(is_scalar($data) && !empty($data)){ - $json = json_decode($data); - }else throw new Exception("json is not string with json data"); - if ($this->jsonError($json)) { - if(isset($callback) && is_callable($callback)){ - call_user_func_array($callback,array($json)); - }else{ - if(isset($callback)) throw new Exception("Can't call callback JSON unpack
    ".print_r($callback,1)."
    "); - foreach($json as $key=>$val){ - $this->set($key,$val); - } - } - } else throw new Exception('Error from JSON decode:
    '.print_r($data,1).'
    '); - }catch(Exception $e){ die($e->getMessage()); } - return $this; - } - - public function toJson($callback=null){ - try{ - $data = $this->toArray(); - $json = json_encode($data); - if(!$this->jsonError($data,$json)) { - $json = false; - throw new Exception('Error from JSON decode:
    '.print_r($data,1).'
    '); - } - }catch(Exception $e){ die($e->getMessage()); } - return $json; - } - - private function jsonError($data){ - $flag = false; - if(!function_exists('json_last_error')){ - function json_last_error(){ - return JSON_ERROR_NONE; - } - } - if(json_last_error() === JSON_ERROR_NONE && is_object($data) && $data instanceof stdClass){ - $flag = true; - } - return $flag; - } - - public function toArray(){ - return $this->field; - } - - private function checkAlias($alias, $i=1){ - if($this->modx->config['friendly_urls']){ - $flag = false; - $_alias = $this->modx->db->escape($alias); - if(!$this->modx->config['allow_duplicate_alias'] || ($this->modx->config['allow_duplicate_alias'] && $this->modx->conifg['use_alias_path'])){ - $flag = $this->modx->db->getValue($this->modx->db->select('id', $this->_table['site_content'], "alias='{$_alias}' AND parent={$this->get('parent')}", '', 1)); - } else { - $flag = $this->modx->db->getValue($this->modx->db->select('id', $this->_table['site_content'], "alias='{$_alias}'", '', 1)); - } - if(($flag && $this->newDoc) || (!$this->newDoc && $flag && $this->id != $flag)){ - /*$suffix = substr($alias, -2); - if(preg_match('/-(\d+)/',$suffix,$tmp) && isset($tmp[1]) && (int)$tmp[1]>1){ - $suffix = (int)$tmp[1] + 1; - $alias = substr($alias, 0, -2) . '-'. $suffix; - }else{ - $alias .= '-2'; - }*/ - $alias = $this->checkAlias($alias.'-'.$i,$i+1); - } - } - return $alias; - } - - public function save($fire_events = null,$clearCache = false){ - try{ - if(!$this->flag){ - throw new Exception('You need flush document field before set and save resource'); - } - }catch(Exception $e){ die($e->getMessage()); } - - if ($this->field['pagetitle'] == '') { - $this->log[] = 'Pagetitle is empty in
    '.print_r($this->field,true).'
    '; - return false; - } - $this->set('alias',$this->getAlias()); - - $this->invokeEvent('OnBeforeDocFormSave',array ( - "mode" => $this->newDoc ? "new" : "upd", - "id" => $this->id ? $this->id : '' - ),$fire_events); - - $fld = $this->toArray(); - foreach($this->default_field as $key=>$value){ - if ($this->newDoc && $this->get($key) == '' && $this->get($key)!==$value){ - $this->set($key,$value); - } - $this->Uset($key,$value); - unset($fld[$key]); - } - if (!empty($this->set)){ - if($this->newDoc){ - $this->modx->db->insert($this->set, $this->_table['site_content']); - }else{ - $this->modx->db->update($this->set, $this->_table['site_content'], "id = '{$this->id}'"); - } - } - - if($this->newDoc) $this->id = $this->modx->db->getInsertId(); - - foreach($fld as $key=>$value){ - #if ($value=='') continue; - if ($this->tv[$key]!=''){ - $fields = array( - 'tmplvarid' => $this->tv[$key], - 'contentid' => $this->id, - 'value' => $this->modx->db->escape($value), - ); - - $rs = $this->modx->db->select('value', $this->_table['site_tmplvar_contentvalues'], "contentid = '{$fields['contentid']}' AND tmplvarid = '{$fields['tmplvarid']}'"); - - if ( $this->modx->db->getRecordCount($rs) > 0 ) { - $row = $this->modx->db->getRow($rs); - if ($row['value'] != $value) { - $this->modx->db->update($fields, $this->_table['site_tmplvar_contentvalues'], "contentid = '{$fields['contentid']}' AND tmplvarid = '{$fields['tmplvarid']}'"); - } - }else{ - $this->modx->db->insert($fields, $this->_table['site_tmplvar_contentvalues']); - } - - } - } - $this->invokeEvent('OnDocFormSave',array ( - "mode" => $this->newDoc ? "new" : "upd", - "id" => $this->id - ),$fire_events); - - if($clearCache){ - $this->clearCache($fire_events); - } - $this->flag = false; - return $this->id; - } -} \ No newline at end of file From dde367cdd7cbec2950d79e3f01c72dfbf96bdc7c Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sat, 22 Jul 2017 17:31:36 +0300 Subject: [PATCH 034/338] fix #83 --- manager/actions/search.static.php | 197 +++++++++++++++++------------- 1 file changed, 113 insertions(+), 84 deletions(-) diff --git a/manager/actions/search.static.php b/manager/actions/search.static.php index 864436366a..ce5e5d17bd 100644 --- a/manager/actions/search.static.php +++ b/manager/actions/search.static.php @@ -95,6 +95,7 @@ //TODO: сделать поиск по уму пока сделаю что б одно поле было для id,longtitle,pagetitle,alias далее нужно думаю добавить что б и в елементах искало if(isset($_REQUEST['submitok'])) { $tbl_site_content = $modx->getFullTableName('site_content'); + $tbldg = $modx->getFullTableName('document_groups'); $searchfields = htmlentities($_POST['searchfields'], ENT_QUOTES, $modx_manager_charset); $searchlongtitle = $modx->db->escape($_REQUEST['searchfields']); @@ -124,45 +125,58 @@ // Handle Input "Search in main fields" if($searchfields != '') { if(ctype_digit($searchfields)) { - $sqladd .= "id='{$searchfields}'"; + $sqladd .= "sc.id='{$searchfields}'"; } if($idFromAlias) { $sqladd .= $sqladd != '' ? ' OR ' : ''; - $sqladd .= "id='{$idFromAlias}'"; + $sqladd .= "sc.id='{$idFromAlias}'"; } $sqladd = $sqladd ? "({$sqladd})" : $sqladd; if(!ctype_digit($searchfields)) { $sqladd .= $sqladd != '' ? ' AND' : ''; - $sqladd .= " pagetitle LIKE '%{$searchfields}%'"; - $sqladd .= " OR longtitle LIKE '%{$searchlongtitle}%'"; - $sqladd .= " OR description LIKE '%{$searchlongtitle}%'"; - $sqladd .= " OR introtext LIKE '%{$searchlongtitle}%'"; - $sqladd .= " OR menutitle LIKE '%{$searchlongtitle}%'"; - $sqladd .= " OR alias LIKE '%{$search_alias}%'"; + $sqladd .= " sc.pagetitle LIKE '%{$searchfields}%'"; + $sqladd .= " OR sc.longtitle LIKE '%{$searchlongtitle}%'"; + $sqladd .= " OR sc.description LIKE '%{$searchlongtitle}%'"; + $sqladd .= " OR sc.introtext LIKE '%{$searchlongtitle}%'"; + $sqladd .= " OR sc.menutitle LIKE '%{$searchlongtitle}%'"; + $sqladd .= " OR sc.alias LIKE '%{$search_alias}%'"; } } else if($idFromAlias) { - $sqladd .= " id='{$idFromAlias}'"; + $sqladd .= " sc.id='{$idFromAlias}'"; } // Handle Input "Search by template ID" if($templateid !== '') { $sqladd .= $sqladd != '' ? ' AND' : ''; - $sqladd .= " template='{$templateid}'"; + $sqladd .= " sc.template='{$templateid}'"; } // Handle Input "Search by content" if($searchcontent !== '') { $sqladd .= $sqladd != '' ? ' AND' : ''; - $sqladd .= $searchcontent != '' ? " content LIKE '%{$searchcontent}%'" : ''; + $sqladd .= $searchcontent != '' ? " sc.content LIKE '%{$searchcontent}%'" : ''; } + // get document groups for current user + $docgrp = (isset($_SESSION['mgrDocgroups']) && is_array($_SESSION['mgrDocgroups'])) ? implode(',', $_SESSION['mgrDocgroups']) : ''; + $showProtected = false; + if(isset ($modx->config['tree_show_protected'])) { + $showProtected = (boolean) $modx->config['tree_show_protected']; + } + $mgrRole = (isset ($_SESSION['mgrRole']) && (string) $_SESSION['mgrRole'] === '1') ? '1' : '0'; + if($showProtected == false) { + $sqladd = '(' . $sqladd . ") AND (1={$mgrRole} OR sc.privatemgr=0" . (!$docgrp ? ')' : " OR dg.document_group IN ({$docgrp}))"); + } + $docgrp_cond = $docgrp ? "OR dg.document_group IN ({$docgrp})" : ''; + + $fields = 'DISTINCT sc.id, contenttype, pagetitle, longtitle, description, introtext, menutitle, deleted, published, isfolder, type, MAX(IF(1=' . $mgrRole . ' OR sc.privatemgr=0 ' . $docgrp_cond . ', 1, 0)) AS hasAccess'; + $sqladd .= ' GROUP BY sc.id'; - $fields = 'id, contenttype, pagetitle, longtitle, description, introtext, menutitle, deleted, published, isfolder, type'; $where = $sqladd; if($where) { - $rs = $modx->db->select($fields, $tbl_site_content, $where, 'id'); + $rs = $modx->db->select($fields, $tbl_site_content . ' AS sc LEFT JOIN ' . $tbldg . ' AS dg ON dg.document=sc.id', $where, 'sc.id'); $limit = $modx->db->getRecordCount($rs); } else { $limit = 0; @@ -262,99 +276,114 @@ $output = ''; //docs - $docscounts = $modx->db->getRecordCount($rs); - if($docscounts > 0) { - $output .= '
  • ' . $_lang["manage_documents"] . ' (' . $docscounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['pagetitle'] . ' (' . $row['id'] . ')', $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('new_document') && $modx->hasPermission('edit_document') && $modx->hasPermission('save_document')) { + $docscounts = $modx->db->getRecordCount($rs); + if($docscounts > 0) { + $output .= '
  • ' . $_lang["manage_documents"] . ' (' . $docscounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['pagetitle'] . ' (' . $row['id'] . ')', $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } //templates - $rs = $modx->db->select("id,templatename", $modx->getFullTableName('site_templates'), "`id` like '%" . $searchfields . "%' - OR `templatename` like '%" . $searchfields . "%' - OR `description` like '%" . $searchfields . "%' - OR `content` like '%" . $searchfields . "%'"); - $templatecounts = $modx->db->getRecordCount($rs); - if($templatecounts > 0) { - $output .= '
  • ' . $_lang["manage_templates"] . ' (' . $templatecounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['templatename'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('edit_template')) { + $rs = $modx->db->select("id,templatename", $modx->getFullTableName('site_templates'), "`id` like '%" . $searchfields . "%' + OR `templatename` like '%" . $searchfields . "%' + OR `description` like '%" . $searchfields . "%' + OR `content` like '%" . $searchfields . "%'"); + $templatecounts = $modx->db->getRecordCount($rs); + if($templatecounts > 0) { + $output .= '
  • ' . $_lang["manage_templates"] . ' (' . $templatecounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['templatename'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } //tvs - $rs = $modx->db->select("id,name", $modx->getFullTableName('site_tmplvars'), "`id` like '%" . $searchfields . "%' - OR `name` like '%" . $searchfields . "%' - OR `description` like '%" . $searchfields . "%' - OR `type` like '%" . $searchfields . "%' - OR `elements` like '%" . $searchfields . "%' - OR `display` like '%" . $searchfields . "%' - OR `display_params` like '%" . $searchfields . "%' - OR `default_text` like '%" . $searchfields . "%'"); - $tvscounts = $modx->db->getRecordCount($rs); - if($tvscounts > 0) { - $output .= '
  • ' . $_lang["settings_templvars"] . ' (' . $tvscounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('edit_template') && $modx->hasPermission('edit_snippet') && $modx->hasPermission('edit_chunk') && $modx->hasPermission('edit_plugin')) { + $rs = $modx->db->select("id,name", $modx->getFullTableName('site_tmplvars'), "`id` like '%" . $searchfields . "%' + OR `name` like '%" . $searchfields . "%' + OR `description` like '%" . $searchfields . "%' + OR `type` like '%" . $searchfields . "%' + OR `elements` like '%" . $searchfields . "%' + OR `display` like '%" . $searchfields . "%' + OR `display_params` like '%" . $searchfields . "%' + OR `default_text` like '%" . $searchfields . "%'"); + $tvscounts = $modx->db->getRecordCount($rs); + if($tvscounts > 0) { + $output .= '
  • ' . $_lang["settings_templvars"] . ' (' . $tvscounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } - // //Chunks - $rs = $modx->db->select("id,name", $modx->getFullTableName('site_htmlsnippets'), "`id` like '%" . $searchfields . "%' - OR `name` like '%" . $searchfields . "%' - OR `description` like '%" . $searchfields . "%' - OR `snippet` like '%" . $searchfields . "%'"); - $chunkscounts = $modx->db->getRecordCount($rs); - if($chunkscounts > 0) { - $output .= '
  • ' . $_lang["manage_htmlsnippets"] . ' (' . $chunkscounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('edit_chunk')) { + $rs = $modx->db->select("id,name", $modx->getFullTableName('site_htmlsnippets'), "`id` like '%" . $searchfields . "%' + OR `name` like '%" . $searchfields . "%' + OR `description` like '%" . $searchfields . "%' + OR `snippet` like '%" . $searchfields . "%'"); + $chunkscounts = $modx->db->getRecordCount($rs); + if($chunkscounts > 0) { + $output .= '
  • ' . $_lang["manage_htmlsnippets"] . ' (' . $chunkscounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } //Snippets - $rs = $modx->db->select("id,name", $modx->getFullTableName('site_snippets'), "`id` like '%" . $searchfields . "%' - OR `name` like '%" . $searchfields . "%' - OR `description` like '%" . $searchfields . "%' - OR `snippet` like '%" . $searchfields . "%' - OR `properties` like '%" . $searchfields . "%' - OR `moduleguid` like '%" . $searchfields . "%'"); - $snippetscounts = $modx->db->getRecordCount($rs); - if($snippetscounts > 0) { - $output .= '
  • ' . $_lang["manage_snippets"] . ' (' . $snippetscounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('edit_snippet')) { + $rs = $modx->db->select("id,name", $modx->getFullTableName('site_snippets'), "`id` like '%" . $searchfields . "%' + OR `name` like '%" . $searchfields . "%' + OR `description` like '%" . $searchfields . "%' + OR `snippet` like '%" . $searchfields . "%' + OR `properties` like '%" . $searchfields . "%' + OR `moduleguid` like '%" . $searchfields . "%'"); + $snippetscounts = $modx->db->getRecordCount($rs); + if($snippetscounts > 0) { + $output .= '
  • ' . $_lang["manage_snippets"] . ' (' . $snippetscounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } + //plugins - $rs = $modx->db->select("id,name", $modx->getFullTableName('site_plugins'), "`id` like '%" . $searchfields . "%' - OR `name` like '%" . $searchfields . "%' - OR `description` like '%" . $searchfields . "%' - OR `plugincode` like '%" . $searchfields . "%' - OR `properties` like '%" . $searchfields . "%' - OR `moduleguid` like '%" . $searchfields . "%'"); - $pluginscounts = $modx->db->getRecordCount($rs); - if($pluginscounts > 0) { - $output .= '
  • ' . $_lang["manage_plugins"] . ' (' . $pluginscounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('edit_plugin')) { + $rs = $modx->db->select("id,name", $modx->getFullTableName('site_plugins'), "`id` like '%" . $searchfields . "%' + OR `name` like '%" . $searchfields . "%' + OR `description` like '%" . $searchfields . "%' + OR `plugincode` like '%" . $searchfields . "%' + OR `properties` like '%" . $searchfields . "%' + OR `moduleguid` like '%" . $searchfields . "%'"); + $pluginscounts = $modx->db->getRecordCount($rs); + if($pluginscounts > 0) { + $output .= '
  • ' . $_lang["manage_plugins"] . ' (' . $pluginscounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } + //modules - $rs = $modx->db->select("id,name", $modx->getFullTableName('site_modules'), "`id` like '%" . $searchfields . "%' - OR `name` like '%" . $searchfields . "%' - OR `description` like '%" . $searchfields . "%' - OR `modulecode` like '%" . $searchfields . "%' - OR `properties` like '%" . $searchfields . "%' - OR `guid` like '%" . $searchfields . "%' - OR `resourcefile` like '%" . $searchfields . "%'"); - $modulescounts = $modx->db->getRecordCount($rs); - if($modulescounts > 0) { - $output .= '
  • ' . $_lang["modules"] . ' (' . $modulescounts . ')
  • '; - while($row = $modx->db->getRow($rs)) { - $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + if($modx->hasPermission('exec_module')) { + $rs = $modx->db->select("id,name", $modx->getFullTableName('site_modules'), "`id` like '%" . $searchfields . "%' + OR `name` like '%" . $searchfields . "%' + OR `description` like '%" . $searchfields . "%' + OR `modulecode` like '%" . $searchfields . "%' + OR `properties` like '%" . $searchfields . "%' + OR `guid` like '%" . $searchfields . "%' + OR `resourcefile` like '%" . $searchfields . "%'"); + $modulescounts = $modx->db->getRecordCount($rs); + if($modulescounts > 0) { + $output .= '
  • ' . $_lang["modules"] . ' (' . $modulescounts . ')
  • '; + while($row = $modx->db->getRow($rs)) { + $output .= '
  • ' . highlightingCoincidence($row['name'], $_REQUEST['searchfields']) . $_style['icons_external_link'] . '
  • '; + } } } From c90042e4e036ad46154e850885c13159fc2b3de1 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sat, 22 Jul 2017 18:15:44 +0300 Subject: [PATCH 035/338] fix #83 --- manager/frames/nodes.functions.inc.php | 4 +--- manager/media/style/default/ajax.php | 5 +++-- manager/media/style/default/css/tree.css | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/manager/frames/nodes.functions.inc.php b/manager/frames/nodes.functions.inc.php index da25a7fd54..1e8ff2cbd1 100644 --- a/manager/frames/nodes.functions.inc.php +++ b/manager/frames/nodes.functions.inc.php @@ -87,8 +87,7 @@ function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') { $nodetitleDisplay = $nodetitle; $treeNodeClass = 'node'; - - $protectedClass = $row['hasAccess'] == 0 ? ' protected' : ''; + $treeNodeClass .= $row['hasAccess'] == 0 ? ' protected' : ''; if($row['deleted'] == 1) { $treeNodeClass .= ' deleted'; @@ -98,7 +97,6 @@ function makeHTML($indent, $parent, $expandAll, $theme, $hereid = '') { //$nodetitleDisplay = sprintf('%s', $nodetitle); } elseif($row['hidemenu'] == 1) { $treeNodeClass .= ' hidemenu'; - $treeNodeClass .= $protectedClass; //$nodetitleDisplay = sprintf('%s', $protectedClass, $nodetitle); } else { //$nodetitleDisplay = sprintf('%s', $protectedClass, $nodetitle); diff --git a/manager/media/style/default/ajax.php b/manager/media/style/default/ajax.php index 80440801ba..e2b172a44a 100644 --- a/manager/media/style/default/ajax.php +++ b/manager/media/style/default/ajax.php @@ -21,6 +21,7 @@ $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : ''; $frame = isset($_REQUEST['f']) ? $_REQUEST['f'] : ''; $role = isset($_SESSION['mgrRole']) ? $_SESSION['mgrRole'] : 0; +$docGroups = isset($_SESSION['mgrDocgroups']) && is_array($_SESSION['mgrDocgroups']) ? implode(',', $_SESSION['mgrDocgroups']) : ''; // set limit sql query $limit = !empty($modx->config['number_of_results']) ? $modx->config['number_of_results'] : 100; @@ -476,10 +477,10 @@ if($modx->db->getRecordCount($sql)) { $document_groups = array(); while($row = $modx->db->getRow($sql)) { - $document_groups[$row['document']]['roles'][] = $row['document_group']; + $document_groups[$row['document']]['groups'][] = $row['document_group']; } foreach($document_groups as $key => $value) { - if(($key == $parent || $key == $parentOld || $key == $id) && !in_array($role, $value['roles'])) { + if(($key == $parent || $key == $parentOld || $key == $id) && !in_array($role, $value['groups'])) { $json['errors'] = $_lang["error_no_privileges"]; } } diff --git a/manager/media/style/default/css/tree.css b/manager/media/style/default/css/tree.css index a5a13df59f..9b37143f40 100644 --- a/manager/media/style/default/css/tree.css +++ b/manager/media/style/default/css/tree.css @@ -23,7 +23,7 @@ #treeRoot a.deleted .title { color: #A52A2A; text-decoration: line-through; } #treeRoot a.unpublished .title { color: #B68282; font-style: italic; } #treeRoot a.hidemenu .title { color: #404040; } -#treeRoot a.protected .title { color: #aaa; } +#treeRoot a.protected { position: relative; opacity: .5; background-color: transparent !important; } #treeRoot a .lockedResource { cursor: pointer; } #treeRoot a .editResource { margin-left: 0.2em } #treeRoot .indent { position: relative; z-index: -1; float: left; height: 1.5em; } From 4b0a4fc30fecbe3e00ab35eaa8892658a0bbb6c2 Mon Sep 17 00:00:00 2001 From: Pathologic Date: Sat, 22 Jul 2017 18:17:56 +0300 Subject: [PATCH 036/338] fix #103 --- assets/modules/store/installer/index.php | 7 ---- .../store/installer/instprocessor-fast.php | 4 -- .../ajaxSearch/plugin.advSearchHighlight.tpl | 14 ++----- .../ajaxSearch/plugin.searchHighlight.tpl | 14 ++----- assets/snippets/eform/eform.inc.php | 1 - assets/snippets/jot/jot.class.inc.php | 3 -- install/assets/plugins/searchhighlight.tpl | 15 ++----- install/connection.databasetest.php | 8 ---- install/index.php | 5 --- .../includes/document.parser.class.inc.php | 20 ++------- manager/includes/quotes_stripper.inc.php | 23 ---------- manager/index.php | 7 ---- manager/media/browser/mcpuk/core/uploader.php | 4 -- manager/media/browser/mcpuk/js_localize.php | 2 - .../media/browser/mcpuk/lib/class_input.php | 42 ------------------- 15 files changed, 14 insertions(+), 155 deletions(-) delete mode 100755 manager/includes/quotes_stripper.inc.php diff --git a/assets/modules/store/installer/index.php b/assets/modules/store/installer/index.php index f3c59924e0..f68465ad4e 100755 --- a/assets/modules/store/installer/index.php +++ b/assets/modules/store/installer/index.php @@ -18,13 +18,6 @@ if(IN_MANAGER_MODE!='true' && !$modx->hasPermission('exec_module')) die('INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly.'); - - - -if (version_compare(phpversion(), "5.3") < 0) { - @ ini_set('magic_quotes_runtime', 0); - @ ini_set('magic_quotes_sybase', 0); -} $moduleurl = $modx->config['site_url'].'assets/modules/store/installer/index.php'; $modulePath = MODX_BASE_PATH.'assets/modules/store/installer/'; $self = $modulePath.'/index.php'; diff --git a/assets/modules/store/installer/instprocessor-fast.php b/assets/modules/store/installer/instprocessor-fast.php index 812862345e..1cfce13137 100644 --- a/assets/modules/store/installer/instprocessor-fast.php +++ b/assets/modules/store/installer/instprocessor-fast.php @@ -6,10 +6,6 @@ include_once(MODX_BASE_PATH."assets/cache/siteManager.php"); define('MGR',MODX_BASE_PATH.MGR_DIR); -if (version_compare(phpversion(), "5.3") < 0) { - @ ini_set('magic_quotes_runtime', 0); - @ ini_set('magic_quotes_sybase', 0); -} $moduleurl = 'assets/modules/store/installer/index.php'; $modulePath = dirname(__FILE__); $self = $modulePath.'/index.php'; diff --git a/assets/snippets/ajaxSearch/plugin.advSearchHighlight.tpl b/assets/snippets/ajaxSearch/plugin.advSearchHighlight.tpl index 9a9b1c42cd..aaed4650bf 100644 --- a/assets/snippets/ajaxSearch/plugin.advSearchHighlight.tpl +++ b/assets/snippets/ajaxSearch/plugin.advSearchHighlight.tpl @@ -86,17 +86,9 @@ if (isset($_REQUEST['searched']) && isset($_REQUEST['highlight'])) { $dbCharset = $database_connection_charset; $pgCharset = array_key_exists($dbCharset,$pageCharset) ? $pageCharset[$dbCharset] : $dbCharset; - // magic quotes check - if (get_magic_quotes_gpc()){ - $searched = strip_tags(stripslashes($_REQUEST['searched'])); - $highlight = strip_tags(stripslashes($_REQUEST['highlight'])); - if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags(stripslashes($_REQUEST['advsearch'])); - } - else { - $searched = strip_tags($_REQUEST['searched']); - $highlight = strip_tags($_REQUEST['highlight']); - if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags($_REQUEST['advsearch']); - } + $searched = strip_tags($_REQUEST['searched']); + $highlight = strip_tags($_REQUEST['highlight']); + if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags($_REQUEST['advsearch']); if ($advsearch != 'nowords') { diff --git a/assets/snippets/ajaxSearch/plugin.searchHighlight.tpl b/assets/snippets/ajaxSearch/plugin.searchHighlight.tpl index a00f897e36..8aaaac077d 100644 --- a/assets/snippets/ajaxSearch/plugin.searchHighlight.tpl +++ b/assets/snippets/ajaxSearch/plugin.searchHighlight.tpl @@ -81,17 +81,9 @@ if (isset($_REQUEST['searched']) && isset($_REQUEST['highlight'])) { $dbCharset = $database_connection_charset; $pgCharset = array_key_exists($dbCharset,$pageCharset) ? $pageCharset[$dbCharset] : $dbCharset; - // magic quotes check - if (get_magic_quotes_gpc()){ - $searched = strip_tags(stripslashes($_REQUEST['searched'])); - $highlight = strip_tags(stripslashes($_REQUEST['highlight'])); - if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags(stripslashes($_REQUEST['advsearch'])); - } - else { - $searched = strip_tags($_REQUEST['searched']); - $highlight = strip_tags($_REQUEST['highlight']); - if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags($_REQUEST['advsearch']); - } + $searched = strip_tags($_REQUEST['searched']); + $highlight = strip_tags($_REQUEST['highlight']); + if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags($_REQUEST['advsearch']); if ($advsearch != 'nowords') { diff --git a/assets/snippets/eform/eform.inc.php b/assets/snippets/eform/eform.inc.php index c92aac5312..ff983cc130 100644 --- a/assets/snippets/eform/eform.inc.php +++ b/assets/snippets/eform/eform.inc.php @@ -169,7 +169,6 @@ function eForm($modx,$params) { if(is_array($value)){ // type="checkbox" etc. remove empty values $value = array_filter($value,create_function('$v','return (!empty($v));')); } else { - if(get_magic_quotes_gpc()) $value = stripslashes($value); // For before PHP 5.3 if(!$allowhtml || $formats[$name][2]!='html') $value = strip_tags($value); } $fields[$name] = $value; diff --git a/assets/snippets/jot/jot.class.inc.php b/assets/snippets/jot/jot.class.inc.php index 07c308066b..58c1d00b2b 100644 --- a/assets/snippets/jot/jot.class.inc.php +++ b/assets/snippets/jot/jot.class.inc.php @@ -487,9 +487,6 @@ function processForm($id=0) { // For every field posted loop foreach($_POST as $n=>$v) { - // Stripslashes if needed - if (get_magic_quotes_gpc()) { $v = stripslashes($v); } - // Avoid XSS $v = $modx->htmlspecialchars($v, ENT_QUOTES); diff --git a/install/assets/plugins/searchhighlight.tpl b/install/assets/plugins/searchhighlight.tpl index 932062c411..5099f73a60 100644 --- a/install/assets/plugins/searchhighlight.tpl +++ b/install/assets/plugins/searchhighlight.tpl @@ -83,17 +83,10 @@ if (isset($_REQUEST['searched']) && isset($_REQUEST['highlight'])) { $dbCharset = $database_connection_charset; $pgCharset = array_key_exists($dbCharset,$pageCharset) ? $pageCharset[$dbCharset] : $dbCharset; - // magic quotes check - if (get_magic_quotes_gpc()){ - $searched = strip_tags(stripslashes($_REQUEST['searched'])); - $highlight = strip_tags(stripslashes($_REQUEST['highlight'])); - if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags(stripslashes($_REQUEST['advsearch'])); - } - else { - $searched = strip_tags($_REQUEST['searched']); - $highlight = strip_tags($_REQUEST['highlight']); - if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags($_REQUEST['advsearch']); - } + $searched = strip_tags($_REQUEST['searched']); + $highlight = strip_tags($_REQUEST['highlight']); + if (isset($_REQUEST['advsearch'])) $advsearch = strip_tags($_REQUEST['advsearch']); + if ($advsearch != 'nowords') { diff --git a/install/connection.databasetest.php b/install/connection.databasetest.php index e5403a700e..f11b1d0fca 100644 --- a/install/connection.databasetest.php +++ b/install/connection.databasetest.php @@ -20,14 +20,6 @@ $output .= ''.$_lang['status_failed'].''; } else { - if (version_compare(phpversion(), "5.3") < 0) { - if(get_magic_quotes_gpc()) { - $_POST['database_name'] = stripslashes($_POST['database_name']); - $_POST['tableprefix'] = stripslashes($_POST['tableprefix']); - $_POST['database_collation'] = stripslashes($_POST['database_collation']); - $_POST['database_connection_method'] = stripslashes($_POST['database_connection_method']); - } - } $database_name = mysqli_real_escape_string($conn, $_POST['database_name']); $database_name = str_replace("`", "", $database_name); $tableprefix = mysqli_real_escape_string($conn, $_POST['tableprefix']); diff --git a/install/index.php b/install/index.php index 05725a4521..dbdb283f0f 100644 --- a/install/index.php +++ b/install/index.php @@ -2,11 +2,6 @@ /** * EVO Installer */ -// do a little bit of environment cleanup if possible -if (version_compare(phpversion(), "5.3") < 0) { - @ ini_set('magic_quotes_runtime', 0); - @ ini_set('magic_quotes_sybase', 0); -} $autoloader = realpath(__DIR__.'/../vendor/autoload.php'); if (file_exists($autoloader) && is_readable($autoloader)) { diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index d704338844..17456c454c 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -4161,16 +4161,16 @@ function getLoginUserName($context= '') { if(!empty($context)){ if(is_scalar($context) && isset($_SESSION[$context . 'Validated'])){ - $out = $this->stripslashes($_SESSION[$context . 'Shortname']); + $out = $_SESSION[$context . 'Shortname']; } }else{ switch(true){ case ($this->isFrontend() && isset ($_SESSION['webValidated'])):{ - $out = $this->stripslashes($_SESSION['webShortname']); + $out = $_SESSION['webShortname']; break; } case ($this->isBackend() && isset ($_SESSION['mgrValidated'])):{ - $out = $this->stripslashes($_SESSION['mgrShortname']); + $out = $_SESSION['mgrShortname']; break; } } @@ -4533,7 +4533,6 @@ function invokeEvent($evtName, $extParams= array ()) { $results= array (); foreach($this->pluginEvent[$evtName] as $pluginName) { // start for loop if ($this->dumpPlugins) $eventtime = $this->getMicroTime(); - $pluginName = $this->stripslashes($pluginName); // reset event object $e= & $this->event; $e->_resetEventObject(); @@ -4739,7 +4738,7 @@ function parseDocBlockFromString($string, $escapeValues=false) { $description_found = $r['description_found']; $docblock_end_found = $r['docblock_end_found']; $param = $r['param']; - $val = $this->stripslashes($r['val']); + $val = $r['val']; if(!$docblock_start_found) continue; if($docblock_end_found) break; if(!empty($param)) { @@ -4921,17 +4920,6 @@ function cleanUpMODXTags($content='') { return $content; } - // Required in PHP 5.3 or earlier environment. However, since PHP 5.3 has already finished support on August 14, 2014, Evolution does not intend to support the stripslashes function for long time. - // http://php.net/manual/en/function.get-magic-quotes-gpc.php - function stripslashes($str='') { - - if(!get_magic_quotes_gpc()) return $str; - - $str = stripslashes($str); - modx_sanitize_gpc($str); - return $str; - } - function strip_tags($str='', $allowable_tags='') { $str = strip_tags($str, $allowable_tags); modx_sanitize_gpc($str); diff --git a/manager/includes/quotes_stripper.inc.php b/manager/includes/quotes_stripper.inc.php deleted file mode 100755 index cc6d9bf3cc..0000000000 --- a/manager/includes/quotes_stripper.inc.php +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/manager/index.php b/manager/index.php index fbebbbdbaf..e47891fa83 100644 --- a/manager/index.php +++ b/manager/index.php @@ -117,13 +117,6 @@ $incPath = str_replace("\\","/",dirname(__FILE__)."/includes/"); // Mod by Raymond set_include_path(get_include_path() . PATH_SEPARATOR . $incPath); -if (version_compare(phpversion(), "5.4") < 0) { - @set_magic_quotes_runtime(0); - - // include_once the magic_quotes_gpc workaround - include_once "quotes_stripper.inc.php"; -} - if (!defined("ENT_COMPAT")) define("ENT_COMPAT", 2); if (!defined("ENT_NOQUOTES")) define("ENT_NOQUOTES", 0); if (!defined("ENT_QUOTES")) define("ENT_QUOTES", 3); diff --git a/manager/media/browser/mcpuk/core/uploader.php b/manager/media/browser/mcpuk/core/uploader.php index 0f07d89c46..6597332163 100644 --- a/manager/media/browser/mcpuk/core/uploader.php +++ b/manager/media/browser/mcpuk/core/uploader.php @@ -110,10 +110,6 @@ public function __get($property) { public function __construct($modx) { - // DISABLE MAGIC QUOTES - if (function_exists('set_magic_quotes_runtime')) - @set_magic_quotes_runtime(false); - //MODX try { if ($modx instanceof DocumentParser) { diff --git a/manager/media/browser/mcpuk/js_localize.php b/manager/media/browser/mcpuk/js_localize.php index 9e214de148..46413f2b28 100644 --- a/manager/media/browser/mcpuk/js_localize.php +++ b/manager/media/browser/mcpuk/js_localize.php @@ -13,8 +13,6 @@ */ require "core/autoload.php"; -if (function_exists('set_magic_quotes_runtime')) - @set_magic_quotes_runtime(false); $input = new input(); if (!isset($input->get['lng']) || ($input->get['lng'] == 'en')) { header("Content-Type: text/javascript"); diff --git a/manager/media/browser/mcpuk/lib/class_input.php b/manager/media/browser/mcpuk/lib/class_input.php index 40879c22b3..d9073311b7 100755 --- a/manager/media/browser/mcpuk/lib/class_input.php +++ b/manager/media/browser/mcpuk/lib/class_input.php @@ -26,24 +26,7 @@ class input { * @var array */ public $cookie; - /** magic_quetes_gpc ini setting flag - * @var bool */ - protected $magic_quotes_gpc; - - /** magic_quetes_sybase ini setting flag - * @var bool */ - protected $magic_quotes_sybase; - public function __construct() { - $this->magic_quotes_gpc = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); - $this->magic_quotes_sybase = ini_get('magic_quotes_sybase'); - $this->magic_quotes_sybase = $this->magic_quotes_sybase - ? !in_array(strtolower(trim($this->magic_quotes_sybase)), - array('off', 'no', 'false')) - : false; - $_GET = $this->filter($_GET); - $_POST = $this->filter($_POST); - $_COOKIE = $this->filter($_COOKIE); $this->get = &$_GET; $this->post = &$_POST; $this->cookie = &$_COOKIE; @@ -56,31 +39,6 @@ public function __construct() { public function __get($property) { return property_exists($this, $property) ? $this->$property : null; } - - /** Filter the given subject. If magic_quotes_gpc and/or magic_quotes_sybase - * ini settings are turned on, the method will remove backslashes from some - * escaped characters. If the subject is an array, elements with non- - * alphanumeric keys will be removed - * @param mixed $subject - * @return mixed */ - - public function filter($subject) { - if ($this->magic_quotes_gpc) { - if (is_array($subject)) { - foreach ($subject as $key => $val) - if (!preg_match('/^[a-z\d_]+$/si', $key)) - unset($subject[$key]); - else - $subject[$key] = $this->filter($val); - } elseif (is_scalar($subject)) - $subject = $this->magic_quotes_sybase - ? str_replace("\\'", "'", $subject) - : stripslashes($subject); - - } - - return $subject; - } } ?> \ No newline at end of file From b3cdd621f6dc527780f15fe11a0ae3b253080a54 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sat, 22 Jul 2017 19:57:43 +0300 Subject: [PATCH 037/338] fix #63 --- manager/frames/1.php | 1 - manager/media/style/default/css/page.css | 1 + manager/media/style/default/js/modx.js | 8 +++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/manager/frames/1.php b/manager/frames/1.php index ce3d12aa95..011d4f4cd1 100644 --- a/manager/frames/1.php +++ b/manager/frames/1.php @@ -83,7 +83,6 @@ - ', '
    ', $pinfo); $pinfo = str_replace('width="600"', 'width="90%"', $pinfo); $pinfo = str_replace('src,input', 'src, input', $pinfo); -echo $pinfo; -?> \ No newline at end of file +?> + diff --git a/manager/actions/sysinfo.static.php b/manager/actions/sysinfo.static.php index b29598d66b..cfd5b7714a 100644 --- a/manager/actions/sysinfo.static.php +++ b/manager/actions/sysinfo.static.php @@ -1,9 +1,9 @@ INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('logs')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('logs')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } $res = $modx->db->query("show variables like 'character_set_database'"); @@ -12,126 +12,139 @@ $collation = $modx->db->getRow($res, 'num'); $serverArr = array( - $_lang['modx_version'] => $modx->getVersionData('version') . ' ' . $newversiontext, - $_lang['release_date'] => $modx->getVersionData('release_date'), - 'PHP Version' => phpversion(), - 'phpInfo()' => '' . $_lang['view'] . '', - $_lang['access_permissions'] => ($use_udperms == 1 ? $_lang['enabled'] : $_lang['disabled']), - $_lang['servertime'] => strftime('%H:%M:%S', time()), - $_lang['localtime'] => strftime('%H:%M:%S', time() + $server_offset_time), - $_lang['serveroffset'] => $server_offset_time / (60 * 60) . ' h', - $_lang['database_name'] => trim($dbase, '`'), - $_lang['database_server'] => $database_server, - $_lang['database_version'] => $modx->db->getVersion(), - $_lang['database_charset'] => $charset[1], - $_lang['database_collation'] => $collation[1], - $_lang['table_prefix'] => $modx->db->config['table_prefix'], - $_lang['cfg_base_path'] => MODX_BASE_PATH, - $_lang['cfg_base_url'] => MODX_BASE_URL, - $_lang['cfg_manager_url'] => MODX_MANAGER_URL, - $_lang['cfg_manager_path'] => MODX_MANAGER_PATH, - $_lang['cfg_site_url'] => MODX_SITE_URL + $_lang['modx_version'] => $modx->getVersionData('version') . ' ' . $newversiontext, + $_lang['release_date'] => $modx->getVersionData('release_date'), + 'PHP Version' => phpversion(), + 'phpInfo()' => '' . $_lang['view'] . '', + $_lang['access_permissions'] => ($use_udperms == 1 ? $_lang['enabled'] : $_lang['disabled']), + $_lang['servertime'] => strftime('%H:%M:%S', time()), + $_lang['localtime'] => strftime('%H:%M:%S', time() + $server_offset_time), + $_lang['serveroffset'] => $server_offset_time / (60 * 60) . ' h', + $_lang['database_name'] => trim($dbase, '`'), + $_lang['database_server'] => $database_server, + $_lang['database_version'] => $modx->db->getVersion(), + $_lang['database_charset'] => $charset[1], + $_lang['database_collation'] => $collation[1], + $_lang['table_prefix'] => $modx->db->config['table_prefix'], + $_lang['cfg_base_path'] => MODX_BASE_PATH, + $_lang['cfg_base_url'] => MODX_BASE_URL, + $_lang['cfg_manager_url'] => MODX_MANAGER_URL, + $_lang['cfg_manager_path'] => MODX_MANAGER_PATH, + $_lang['cfg_site_url'] => MODX_SITE_URL ); ?>

    - +

    -
    -
    Server
    -
    - - $value) { - echo ' - - - - '; - } - ?> -
    ' . $key . ' ' . $value . '
    -
    +
    +
    +

    Server

    +
    +
    + + + $value) { + ?> + + + + + + + +
     
    +
    +
    +
    - -
    -
    -
    -

    - - - - - - - - - - - - - -  

    - $sql = "SHOW TABLE STATUS FROM $dbase LIKE '" . $modx->db->escape($modx->db->config['table_prefix']) . "%';"; - $rs = $modx->db->query($sql); - $i = 0; - while($log_status = $modx->db->getRow($rs)) { - $bgcolor = ($i++ % 2) ? '#EEEEEE' : '#FFFFFF'; - ?> - - - + +
    +
    +

    +

    +
    +
    +
    + + + + + + + + + + + + + db->escape($modx->db->config['table_prefix']) . "%';"; + $rs = $modx->db->query($sql); + $i = 0; + while ($log_status = $modx->db->getRow($rs)) { + ?> + + + - db->config['table_prefix'] . 'event_log', - $modx->db->config['table_prefix'] . 'manager_log', - ); - if($modx->hasPermission('settings') && in_array($log_status['Name'], $truncateable)) { - echo ""; - } else { - echo ""; - } + db->config['table_prefix'] . 'event_log', + $modx->db->config['table_prefix'] . 'manager_log', + ); + if ($modx->hasPermission('settings') && in_array($log_status['Name'], $truncateable)) { + echo ""; + } else { + echo ""; + } - if($modx->hasPermission('settings')) { - echo ""; - } else { - echo ""; - } - ?> - - - - - - - - - - - - - -
    "; - echo "" . $modx->nicesize($log_status['Data_length'] + $log_status['Data_free']) . ""; - echo "" . $modx->nicesize($log_status['Data_length'] + $log_status['Data_free']) . ""; + echo "" . $modx->nicesize($log_status['Data_length'] + $log_status['Data_free']) . ""; + echo "" . $modx->nicesize($log_status['Data_length'] + $log_status['Data_free']) . "" . ($log_status['Data_free'] > 0 ? "" . $modx->nicesize($log_status['Data_free']) . "" : "-") . "" . ($log_status['Data_free'] > 0 ? $modx->nicesize($log_status['Data_free']) : "-") . "nicesize($log_status['Data_length'] - $log_status['Data_free']); ?>nicesize($log_status['Index_length']); ?>nicesize($log_status['Index_length'] + $log_status['Data_length'] + $log_status['Data_free']); ?>
      0 ? "" . $modx->nicesize($totaloverhead) . "
    (" . number_format($totaloverhead) . " B)" : "-"; ?>
     " . $modx->nicesize($total) . "
    (" . number_format($total) . " B)"; ?>
    - 0) { ?> -

    - -
    + if ($modx->hasPermission('settings')) { + echo "
    " . ($log_status['Data_free'] > 0 ? "" . $modx->nicesize($log_status['Data_free']) . "" : "-") . "" . ($log_status['Data_free'] > 0 ? $modx->nicesize($log_status['Data_free']) : "-") . "nicesize($log_status['Data_length'] - $log_status['Data_free']) ?>nicesize($log_status['Index_length']) ?>nicesize($log_status['Index_length'] + $log_status['Data_length'] + $log_status['Data_free']) ?>
      0 ? "" . $modx->nicesize($totaloverhead) . "
    (" . number_format($totaloverhead) . " B)" : "-" ?>
     " . $modx->nicesize($total) . "
    (" . number_format($total) . " B)" ?>
    + + + 0) { ?> +

    + + diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index de342e14ef..b3094819f1 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -93,9 +93,9 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan #actions .actionButtons .dropdown-menu > span { display: block; padding: 0 10px; height: 32px; line-height: 30px; border: none; border-top: 1px solid #f2f2f2; cursor: pointer; } #actions .actionButtons .dropdown-menu > span:hover { background-color: #fbfbfb; } #actions .actionButtons select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; padding: 0 10px; margin: -100% 0 -32px 0; font-size: 1em; opacity: 0; visibility: hidden; } -#actions .actionButtons #Button1 a, #actions .actionButtons .plus { color: #fff; border-color: #32AB9A; background: #32AB9A linear-gradient(#32AB9A, #00948E); } +#actions .actionButtons #Button1 a, #actions .actionButtons .plus { color: #fff; border-color: #32ab9a; background: #32ab9a linear-gradient(#32ab9a, #00948e); } #actions .actionButtons #Button1 a:hover, #actions .actionButtons .plus:hover { background: #2b9385 linear-gradient(#2b9385, #007571); border-color: #2b9385; } -#actions .actionButtons #Button1 a:active, #actions .actionButtons .plus:active { background: #32AB9A; border-color: #32AB9A; } +#actions .actionButtons #Button1 a:active, #actions .actionButtons .plus:active { background: #32ab9a; border-color: #32ab9a; } @media (max-width: 900px) { #actions .actionButtons li a, #actions .actionButtons .dropdown-menu span { font-size: 0 } #actions .actionButtons li a .fa, #actions .actionButtons .dropdown-menu span .fa { display: inline-block; font-size: 14px; line-height: 30px } @@ -110,15 +110,16 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .table.data th, .table.data thead td { padding: 0.75rem; text-transform: uppercase; white-space: nowrap; font-size: 0.675rem; color: #777; border-bottom: 2px solid #eceeef } .table.data td { padding: 0.55rem 0.75rem; } .table.data td, .table.data th, .table.data thead td { vertical-align: top; border-top: 1px solid #eceeef } -.table.data td:first-child, .table.data th:first-child { padding-left: 1.3rem } -.table.data td:last-child, .table.data th:last-child { padding-right: 1.3rem } +.table.data td:first-child, .table.data th:first-child, .table.data.table-sm td:first-child, .table.data.table-sm th:first-child { padding-left: 1.3rem } +.table.data td:last-child, .table.data th:last-child, .table.data.table-sm td:last-child, .table.data.table-sm th:last-child { padding-right: 1.3rem } .table.data thead { background-color: #fff; } .table.data > tbody > tr { background-color: #f9f9f9; transition-duration: .5s } .table.data > tbody > tr:nth-child(2n) { background-color: #fff } .table.data > tbody > tr:hover { cursor: default; background-color: rgba(93, 109, 202, 0.16); transition-duration: .05s } -.table.data a { color: #555 } +.table.data tr.unstyled:hover { background-color: inherit } .table.data .actions { white-space: nowrap } -.table.data .actions a .fa, .table.data .actions span .fa { position: relative; margin: 0 0.375rem; font-size: 0.9rem; } +.table.data .actions a, .table.data a .fa { color: #555 } +.table.data .actions a .fa, .table.data .actions span .fa { position: relative; margin: 0 0.375rem; font-size: 0.9rem; color: #555 } .table.data .actions a:hover .fa { color: #000; } .table.data .actions a:hover .fa.fa-trash { color: #d80030 } .table.data .actions a .fa::before { position: relative; z-index: 2; } @@ -133,6 +134,9 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .table.data thead .sortable.reverseSort a::after, .table.data thead .sortable-text.reverseSort a::after { opacity: 1; content: "\f107"; color: #d9534f } .table.data thead .sortable a:hover::after, .table.data thead .sortable-text a:hover::after { opacity: 1 } .table.data thead .sortable-text span, .table.data thead .sortable-numeric span, .table.data thead .sortable-date span { display: none } +/* table-data-sm */ +.table.data.table-sm td, .table.data.table-sm th { padding: .25rem .5rem; } +.table.data.table-sm th, .table.data.table-sm thead td { font-size: 0.75rem; text-transform: none; } /* table-data-docs */ .table.data .doc-item .fa { width: 1.2em; font-size: 0.9rem; text-align: center; margin-right: 0.25rem } .table.data .doc-item { text-decoration: none } @@ -188,7 +192,7 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .grid > tbody > tr:nth-child(2n) > td { background-color: rgba(0, 0, 0, 0.03) } .gridItem { background-color: #fff; padding: 3px; } .gridAltItem { background-color: #f7f7f7; padding: 3px; } -.grid tbody tr:hover td { background: #E9EDF3; } +.grid tbody tr:hover td { background: #e9edf3; } .grid a { text-decoration: none; } .grid img { vertical-align: middle; padding-right: 4px; } /* SORTABLELIST */ @@ -202,16 +206,16 @@ ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0 #helpPane pre { border: 1px solid rgba(0, 0, 0, 0.1); padding: 1em; } /* [ DARK THEME ] */ .dark .section-editor textarea { background-color: #282c34; color: #abb2bf } -.dark .tab-page, .dark .tab-row .tab.selected, .dark .tab-row .tab.selected.hover, .dark .tab-row .tab.selected:before, .dark .tab-row .tab.selected span { background: #F9F9F9; } +.dark .tab-page, .dark .tab-row .tab.selected, .dark .tab-row .tab.selected.hover, .dark .tab-row .tab.selected:before, .dark .tab-row .tab.selected span { background: #f9f9f9; } .dark, .dark .resourceTable .panel-heading { background: #ecf0f1 !important; } .dark .resourceTable .panel-heading:hover { background: #ecf0f1 !important; } -.dark .multitv .list li.element a.copy, .multitv .list li.element a.remove { background: #F9F9F9 !important; } -.dark .multitv .list li.element { background: #FEFEFE !important; } +.dark .multitv .list li.element a.copy, .multitv .list li.element a.remove { background: #f9f9f9 !important; } +.dark .multitv .list li.element { background: #fefefe !important; } .dark .split { border-color: rgba(0, 0, 0, .05) } .dark hr { background: transparent; } -.dark .content-blocks .block { background: #FEFEFE; border: 1px solid #e3e3e3; } +.dark .content-blocks .block { background: #fefefe; border: 1px solid #e3e3e3; } .dark .content-blocks .block .fields-group { border: 1px dashed #e2e2e2; } -.dark .content-blocks input[type="text"], .dark .content-blocks input[type="password"], .dark .content-blocks input[type="number"], .dark .content-blocks textarea { background-color: #FBFBFB !important; border-color: #dbdbdb !important; } +.dark .content-blocks input[type="text"], .dark .content-blocks input[type="password"], .dark .content-blocks input[type="number"], .dark .content-blocks textarea { background-color: #fbfbfb !important; border-color: #dbdbdb !important; } .dark .content-blocks .controls { background: transparent !important; } /* OTHERS COMPONENTS */ /* Manage Files */ @@ -222,7 +226,7 @@ ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0 #ManageFiles #imageviewer img { display: inline-block; max-width: 100%; margin-top: 1rem } #FilesTable { margin-bottom: 1rem; border-bottom: 1px solid #ddd; } #file_editfile.section .sectionHeader { margin: 0; padding: 0.5rem 1rem; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; background-color: #f9f9f9 } -#file_editfile.section .sectionBody { margin: 0 !important; padding: 0 0 1rem; border: none; border-bottom: 1px solid #ddd; background-color: #F9F9F9 } +#file_editfile.section .sectionBody { margin: 0 !important; padding: 0 0 1rem; border: none; border-bottom: 1px solid #ddd; background-color: #f9f9f9 } #file_editfile td { padding: 0 !important; } #file_editfile #content { float: left; width: 100%; min-height: 25rem; border: none; border-bottom: 1px solid rgba(0, 0, 0, .15) } /* extras */ diff --git a/manager/media/style/default/css/fonts.css b/manager/media/style/default/css/fonts.css index a2371f1a33..373493cf69 100644 --- a/manager/media/style/default/css/fonts.css +++ b/manager/media/style/default/css/fonts.css @@ -63,6 +63,8 @@ a:not([href]):not([tabindex]):focus { outline: 0 } .text-white { color: #fff !important } .text-muted { color: #818a91 !important } .text-decoration-through { text-decoration: line-through !important } +.text-underline { text-decoration: underline !important } +a.text-underline:hover { text-decoration: none !important } a.text-muted:focus, a.text-muted:hover { color: #4b5257 !important } .text-primary { color: #0275d8 !important } a.text-primary:focus, a.text-primary:hover { color: #025aa5 !important } From d62b4f9b486db2902a3384f91badab07146b0a88 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Wed, 26 Jul 2017 00:57:10 +0300 Subject: [PATCH 072/338] update data sortable --- manager/media/style/default/css/custom.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index b3094819f1..6d6c43267d 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -127,12 +127,13 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .table.data .actions a:hover .fa::after { background-color: #fff } .table.data .actions .disabled { visibility: hidden } /* table-data-sortable */ -.table.data thead .sortable a, .table.data thead .sortable-text a { text-decoration: none !important; } +.table.data thead .sortable a, .table.data thead .sortable-text a { color: #777; text-decoration: none !important; } .table.data thead .sortable a:hover, .table.data thead .sortable-text a:hover { color: #222 } .table.data thead .sortable a::after, .table.data thead .sortable-text a::after { content: "\f107"; font-family: FontAwesome; opacity: .3; margin-left: .5em; } .table.data thead .sortable.forwardSort a::after, .table.data thead .sortable-text.forwardSort a::after { opacity: 1; content: "\f106"; color: #d9534f } .table.data thead .sortable.reverseSort a::after, .table.data thead .sortable-text.reverseSort a::after { opacity: 1; content: "\f107"; color: #d9534f } -.table.data thead .sortable a:hover::after, .table.data thead .sortable-text a:hover::after { opacity: 1 } +.table.data thead .sortable:hover a::after, .table.data thead .sortable-text:hover a::after, .table.data thead .sortable-numeric:hover a::after, .table.data thead .sortable-date:hover a::after { opacity: 1 } +.table.data thead .sortable, .table.data thead .sortable-text, .table.data thead .sortable-numeric, .table.data thead .sortable-date { cursor: pointer } .table.data thead .sortable-text span, .table.data thead .sortable-numeric span, .table.data thead .sortable-date span { display: none } /* table-data-sm */ .table.data.table-sm td, .table.data.table-sm th { padding: .25rem .5rem; } From 07a6e60438bbe83034af2c7bcddcab247ade2144 Mon Sep 17 00:00:00 2001 From: Deesen Date: Wed, 26 Jul 2017 09:00:10 +0200 Subject: [PATCH 073/338] [I] #55 @FILE for chunks - {{@FILE:assets/chunks/header.html}} --- manager/includes/document.parser.class.inc.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 17456c454c..725b6e3b2c 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -3532,6 +3532,8 @@ function getChunk($chunkName) { if(empty($chunkName)) return $out; if (isset ($this->chunkCache[$chunkName])) { $out = $this->chunkCache[$chunkName]; + } else if(stripos($chunkName,'@FILE')===0) { + $out = $this->chunkCache[$chunkName] = $this->atBindFileContent($chunkName); } else { $where = sprintf("`name`='%s'", $this->db->escape($chunkName)); $rs= $this->db->select('snippet', '[+prefix+]site_htmlsnippets', $where); @@ -4997,7 +4999,7 @@ function atBindFileContent($str='') { $search_path = array('assets/tvs/', 'assets/chunks/', 'assets/templates/', $this->config['rb_base_url'].'files/', ''); - if(strpos($str,'@FILE')!==0) return $str; + if(stripos($str,'@FILE')!==0) return $str; if(strpos($str,"\n")!==false) $str = substr($str,0,strpos("\n",$str)); if($this->getExtFromFilename($str)==='.php') return 'Could not retrieve PHP file.'; @@ -5472,7 +5474,7 @@ function isJson($string, $returnData=false) { } function splitKeyAndFilter($key) { - if($this->config['enable_filter']==1 && strpos($key,':')!==false) + if($this->config['enable_filter']==1 && strpos($key,':')!==false && stripos($key,'@FILE')!==0) list($key,$modifiers) = explode(':', $key, 2); else $modifiers = false; From 129a0a4c325d20a56458cbc45dfee86924e6f7a2 Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Wed, 26 Jul 2017 13:35:38 +0300 Subject: [PATCH 074/338] =?UTF-8?q?Delete=20060=5F=D0=90=D0=B2=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0=B9.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...21\202\320\265\320\273\320\265\320\271.md" | 117 ------------------ 1 file changed, 117 deletions(-) delete mode 100644 "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" deleted file mode 100644 index 841e652207..0000000000 --- "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" +++ /dev/null @@ -1,117 +0,0 @@ -## Авторизация пользователей - -Контроллер Login позволяет авторизировать пользователей как по имени, так и по email. Кроме этого, можно дополнительно использовать плагин userHelper, который ведет учет количества логинов и времени последнего логина, а также реализует автологин и выход из учетной записи. - -## Параметры контроллера - -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### loginField -Поле, содержащее имя пользователя. - -Возможные значения - имя поля. - -Значение по умолчанию - username. - -### passwordField -Поле, содержащее пароль пользователя. - -Возможные значения - имя поля. - -Значение по умолчанию - password. - -### rememberField -Поле для запоминания пользователя. Если значение поля приводится к true, то при успешной авторизации будет установлена кука с параметрами автологина. Имя куки и ее время жизни задаются параметрами cookieName и cookieLifetime. - -Можно также задать поле rememberme в параметре defaults, чтобы запоминание происходило без участия пользователя: -``` -&defaults=`{"rememberme":1}` -``` - -Возможные значения - имя поля. - -Значение по умолчанию - rememberme. - -### checkActivation -Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). - -Возможные значения - 0 или 1. - -Значение по умолчанию - 1. - -### context -Контекст авторизации. - -Возможные значения - mgr или web. - -Значение по умолчанию - web. - -### cookieName -Имя куки для хранения параметров автологина. - -Значение по умолчанию - WebLoginPE. - -### cookieLifetime -Время жизни вышеуказанной куки. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 157680000 (5 лет). - -### redirectTo -Перенаправляет пользователя на страницу c указанным id после авторизации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет уже авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной авторизации. В шаблоне можно использовать данные пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Login с ключом [+login.default_successTpl+] - -### skipTpl -Шаблон сообщения о том, что пользователь уже авторизован. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Login с ключом [+login.default_skipTpl+] - -## Параметры плагина userHelper -### logoutKey -Имя GET-параметра для запуска выхода из учетной записи. Если в ссылке на страницу сайта указан параметр с соответствующим именем (например, http://sitename.ru/page.html?logout), будет произведен выход из учетной записи. - -Значение по умолчанию - logout. - -### cookieName -Имя куки для хранения параметров автологина. - -Значение по умолчанию - WebLoginPE. - -### cookieLifetime -Время жизни вышеуказанной куки. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 157680000 (5 лет). From 11b1366f6d035a0a5a87fe1696ce3b6036e35158 Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Wed, 26 Jul 2017 13:36:28 +0300 Subject: [PATCH 075/338] =?UTF-8?q?Delete=20070=5F=D0=A0=D0=B5=D0=B3=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0=B8?= =?UTF-8?q?=CC=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...20\265\320\273\320\265\320\270\314\206.md" | 137 ------------------ 1 file changed, 137 deletions(-) delete mode 100644 "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\270\314\206.md" diff --git "a/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\270\314\206.md" "b/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\270\314\206.md" deleted file mode 100644 index 58843c8e7a..0000000000 --- "a/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\270\314\206.md" +++ /dev/null @@ -1,137 +0,0 @@ -## Регистрация пользователей - -Контроллер Register позволяет регистрировать пользователей в заданные группы и отправлять уведомления о регистрации. Контроллер является расширением контроллера Form, соответственно можно использовать соответствующие параметры для отправки писем при регистрации. - -Имена полей в форме должны соответствовать полям модели [modUsers](http://docs.evolution-cms.com/Extras/Snippets/DocLister/MODxAPI). - -Если в форме не задано поле username, то ему присваивается значение поля email. Таким образом можно регистрировать пользователей только по email. - -Если в форме не задано поле password, то значение поля генерируется автоматически. То есть регистрацию пользователя можно свести к указанию email. - -При регистрации с паролем, в форме может присутствовать поле repeatPassword. Если заданы правила валидации для полей password и repeatPassword, то при наличии для поля repeatPassword правила equals, оно будет автоматически скорректировано для проверки равенства значений полей password и repeatPassword: -``` -"repeatPassword":{ - "required":"Введите пароль еще раз", - "equals":{ - "params" : "Этот ключ в описании правила можно не задавать, он будет сформирован контроллером автоматически", - "message":"Пароли не совпадают" - } -} -``` - -При регистрации следует проверять уникальность имени пользователя и email. В контроллере предусмотрены соответствующие правила: -``` -&rules=`{ - "username":{ - "required":"Введите имя пользователя", - "alphaNumeric":"Только буквы и цифры", - "custom":{ - "function":"\\FormLister\\Register::uniqueUsername", - "message":"Имя уже занято" - } - }, - "email":{ - "required":"Введите email", - "email":"Неверный email", - "custom":{ - "function":"\\FormLister\\Register::uniqueEmail", - "message":"Этот email уже использует другой пользователь" - } - } -}` -``` -В шаблонах доступны все поля модели для созданной записи. Дополнительно задается поле user.password с незашифрованным паролем. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### allowedFields -Разрешенные для обработки поля. Поля, не указанные в списке, игнорируются. Поля username, email и password всегда разрешены. - -Если не задано, то разрешены все поля. - -Возможные значения - имена полей формы, разделенные запятой. - -Значение по умолчанию - пусто. - -### forbiddenFields -Запрещенные для обработки поля. Поля, указанные в списке, игнорируются. Поля username, email и password удаляются из списка запрещенных. - -Возможные значения - имена полей формы, разделенные запятой. - -Значение по умолчанию - пусто. - -### userGroups -Добавляет зарегистрированного пользователя в указанные группы. - -Возможные значения - имена групп, разделенные запятой (если имена содержат запятую в названии, то можно задать значение параметра массивом). - -Значение по умолчанию - пусто. - -### checkActivation -Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). При этом после сохранения записи будет установлено поле activate.url, содержащее ссылку на страницу с вызовом сниппета для активации учетной записи. - -Возможные значения - 1 или 0. - -Значение по умолчанию - 0. - -### activateTo -Если включена проверка активации, то в этом параметре необходимо указать id страницы, на которой вызывается сниппет для активации. - -Возможные значения - id страницы. - -Значение по умолчанию - значение $modx->config['site_start']. - -### preparePostProcess -Позволяет выполнить обработку данных после сохранения. - -Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. - -Значение по умолчанию - пусто. - -### redirectTo -Перенаправляет пользователя на указанную страницу после регистрации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет уже авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для уже авторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Register с ключом [+register.default_skipTpl+] - -### successTpl -Шаблон сообщения об успешной регистрации. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Register с ключом [+register.default_successTpl+] - -### passwordLength -Длина пароля (если создается автоматически). - -Возможные значения - число символов больше 6. - -Значение по умолчанию - 6. From 268d46aa2c310267581b8253872ecac0257af9be Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Wed, 26 Jul 2017 13:36:51 +0300 Subject: [PATCH 076/338] =?UTF-8?q?Delete=20075=5F=D0=90=D0=BA=D1=82=D0=B8?= =?UTF-8?q?=D0=B2=D0=B0=D1=86=D0=B8=D1=8F=20=D1=83=D1=87=D0=B5=D1=82=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5=D0=B8=CC=86?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...20\270\321\201\320\265\320\270\314\206.md" | 84 ------------------- 1 file changed, 84 deletions(-) delete mode 100644 "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\270\314\206.md" diff --git "a/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\270\314\206.md" "b/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\270\314\206.md" deleted file mode 100644 index ce0f37925c..0000000000 --- "a/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\270\314\206.md" +++ /dev/null @@ -1,84 +0,0 @@ -## Активация учетных записей - -Контроллер Activate реализует активацию учетных записей. Таким образом появляется возможность требовать у пользователя подтверждение учетной записи путем перехода по специальной ссылке из письма, отправленного при регистрации. - -Если по какой-то причине пользователь не получил письмо, то c помощью контроллера Activate он может запросить его повторную отправку. - -Учетная запись пользователя считается неактивированной если в поле logincount записано -1. - -В вызовах сниппета для регистрации и авторизации пользователей должен присутствовать параметр &checkActivation=`1`. - -Поэтому если при регистрации пользователь указывал пароль самостоятельно, то нужно запрашивать пароль для отправки письма со ссылкой для активации. Иначе будет генерироваться новый пароль, потому что раз пользователь запрашивает письмо для активации вручную, значит письмо после регистрации он не получил и не знает созданный при регистрации пароль. - -В шаблонах доступны все поля модели для обрабатываемой записи. В шаблоне reportTpl задается поле user.password с незашифрованным паролем и поле activate.url со ссылкой для активации. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### redirectTo -Перенаправляет пользователя на указанную страницу после активации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для авторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Register с ключом [+register.default_skipTpl+] - -### reportTpl -Шаблон письма с информацией для активации учетной записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### reportTpl -Шаблон письма с информацией для активации учетной записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной отправке письма с данными для активации. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Activate с ключом [+activate.default_successTpl+] - -### activateSuccessTpl -Шаблон сообщения об успешной активации. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Activate с ключом [+activate.default_activateSuccessTpl+] - -### passwordLength -Длина создаваемого пароля. - -Возможные значения - число символов больше 6. - -Значение по умолчанию - 6. From 6dce1e32de15c8decb2dd81311e7761800c5f954 Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Wed, 26 Jul 2017 13:37:09 +0300 Subject: [PATCH 077/338] =?UTF-8?q?Delete=20090=5F=D0=92=D0=BE=D1=81=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=B0=D1=80=D0=BE=D0=BB=D0=B5=D0=B8=CC=86=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8F?= =?UTF-8?q?=D0=BC=D0=B8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...20\265\320\273\321\217\320\274\320\270.md" | 143 ------------------ 1 file changed, 143 deletions(-) delete mode 100644 "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\270\314\206 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" diff --git "a/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\270\314\206 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\270\314\206 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" deleted file mode 100644 index e9b507dd4f..0000000000 --- "a/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\270\314\206 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" +++ /dev/null @@ -1,143 +0,0 @@ -## Восстановление паролей пользователями - -Контроллер Reminder позволяет web-пользователям восстанавливать забытые пароли. Расширяет контроллер Form. - -Восстановление паролей происходит по следующей схеме: - -- пользователь вводит в форме свой идентификатор (им может быть имя пользователя или email); -- пользователь получает письмо, в котором содержится ссылка для восстановления; -- при переходе по ссылке пользователь получает возможность ввести новый пароль либо пароль будет сгенерирован автоматически; -- пользователю отправляется письмо с новым паролем и показыается сообщение (в сообщении можно также вывести новый пароль). - -Параметр to перезаписывается значением email пользователя. Обязательно должен быть задан параметр resetTo. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### hashField -Имя поля для хранения хэша данных пользователя. - -Значение по умолчанию - hash. - -### userField -Имя поля для хранения идентификатора пользователя (имя пользователя или email). - -Значение по умолчанию - email. - -### uidField -Имя поля, которое используется для идентификации пользователя при переходе по ссылке. - -Значение по умолчанию - id. - -### exitTo -Перенаправляет авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### resetTo -Страница, на которую будет указывать ссылка для восстановления паролей. Обязательный параметр. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - id документа, в котором вызван контроллер. - -### redirectTo -Перенаправляет на указанную страницу после успешного восстановления пароля. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для авторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_skipTpl+]. - -### formTpl -Шаблон формы для ввода идентификатора пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### resetTpl -Шаблон формы для ввода нового пароля. Если параметр не задан, то пароль будет сгенерирован автоматически. - -Поля для ввода паролей должны называться password и repeatPassword. В форме должны также присутствовать скрытые поля с именами из параметров uidField и hashField. Значение для поля hashField задается через плейсхолдер [+user.hash+]. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной отправке письма со ссылкой для восстановления пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.). - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_successTpl+]. - -### resetSuccessTpl -Шаблон сообщения об успешном восстановлении пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_resetSuccessTpl+]. - -### reportTpl -Шаблон письма со ссылкой для восстановления пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). Ссылка для восстановлени пароля в письме задается через плейсхолдер [+reset.url+] - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_reportTpl+].. - -### resetReportTpl -Шаблон письма об успешном восстановлении пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). Если не задан, то письмо пользователю отправляться не будет. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### rules -Правила валидации для формы идентификации пользователя. - -Возможные значения - см. раздел "Валидация данных". - -Значение по умолчанию - пусто. - -### resetRules -Правила валидации для формы установки нового пароля. Если заданы правила валидации для полей password и repeatPassword, то при наличии для поля repeatPassword правила equals, оно будет автоматически скорректировано для проверки равенства значений полей password и repeatPassword: -``` -"repeatPassword":{ - "required":"Введите пароль еще раз", - "equals":{ - "params" : "Этот ключ в описании правила можно не задавать, он будет сформирован контроллером автоматически", - "message":"Пароли не совпадают" - } -} -``` -Возможные значения - см. раздел "Валидация данных". - -Значение по умолчанию - пусто. - -### passwordLength -Длина пароля (если создается автоматически). - -Возможные значения - число символов больше 6. - -Значение по умолчанию - 6. From 48e9dfff4fd120b0608b1d8dfcf08bb2c6c63167 Mon Sep 17 00:00:00 2001 From: Deesen Date: Wed, 26 Jul 2017 13:52:31 +0200 Subject: [PATCH 078/338] [F] #99 Use config['docid_incrmnt_method'] when duplicating resources --- .../processors/duplicate_content.processor.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/manager/processors/duplicate_content.processor.php b/manager/processors/duplicate_content.processor.php index 5dc23f8ca4..428b65dd00 100755 --- a/manager/processors/duplicate_content.processor.php +++ b/manager/processors/duplicate_content.processor.php @@ -54,7 +54,22 @@ function duplicateDocument($docid, $parent=null, $_toplevel=0) { $rs = $modx->db->select('*', $tblsc, "id='{$docid}'"); $content = $modx->db->getRow($rs); - unset($content['id']); // remove the current id. + // Handle incremental ID + switch($modx->config['docid_incrmnt_method']) + { + case '1': + $from = "{$tblsc} AS T0 LEFT JOIN {$tblsc} AS T1 ON T0.id + 1 = T1.id"; + $rs = $modx->db->select('MIN(T0.id)+1', $from, "T1.id IS NULL"); + $content['id'] = $modx->db->getValue($rs); + break; + case '2': + $rs = $modx->db->select('MAX(id)+1',$tblsc); + $content['id'] = $modx->db->getValue($rs); + break; + + default: + unset($content['id']); // remove the current id. + } // Once we've grabbed the document object, start doing some modifications if ($_toplevel == 0) { From 58da6fe7600f12f526032d4823c08bc504449be9 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Wed, 26 Jul 2017 19:49:30 +0300 Subject: [PATCH 079/338] fix #121 --- manager/includes/document.parser.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 17456c454c..131ddebe41 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -3499,7 +3499,7 @@ function getVersionData($data=null) { function runSnippet($snippetName, $params= array ()) { if (isset ($this->snippetCache[$snippetName])) { $snippet = $this->snippetCache[$snippetName]; - $properties = $this->snippetCache[$snippetName . "Props"]; + $properties = !empty($this->snippetCache[$snippetName . "Props"]) ? $this->snippetCache[$snippetName . "Props"] : ''; } else { // not in cache so let's check the db $sql = "SELECT ss.`name`, ss.`snippet`, ss.`properties`, sm.properties as `sharedproperties` FROM " . $this->getFullTableName("site_snippets") . " as ss LEFT JOIN ".$this->getFullTableName('site_modules')." as sm on sm.guid=ss.moduleguid WHERE ss.`name`='" . $this->db->escape($snippetName) . "';"; $result = $this->db->query($sql); From 33414537ff3d9778b3f64f29a0c6b73d422e2caa Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 27 Jul 2017 00:38:40 +0300 Subject: [PATCH 080/338] resolve #90 --- manager/actions/refresh_site.dynamic.php | 8 + manager/frames/mainmenu.php | 36 ++- manager/frames/tree.php | 2 +- manager/includes/menu.class.inc.php | 26 +- manager/media/style/default/css/custom.css | 29 +- manager/media/style/default/css/forms.css | 268 ++----------------- manager/media/style/default/css/mainmenu.css | 34 ++- manager/media/style/default/css/page.css | 50 ++-- manager/media/style/default/js/modx.js | 4 +- manager/media/style/default/style.css | 53 ++-- 10 files changed, 145 insertions(+), 365 deletions(-) diff --git a/manager/actions/refresh_site.dynamic.php b/manager/actions/refresh_site.dynamic.php index b3270c7c1d..008de9590f 100644 --- a/manager/actions/refresh_site.dynamic.php +++ b/manager/actions/refresh_site.dynamic.php @@ -18,6 +18,14 @@

    +
    +
    + + + +
    +
    +
    " . $_lang["refresh_published"] . "

    ", $num_rows_pub) ?> diff --git a/manager/frames/mainmenu.php b/manager/frames/mainmenu.php index 5ad9c154db..e5bb6e972b 100644 --- a/manager/frames/mainmenu.php +++ b/manager/frames/mainmenu.php @@ -336,17 +336,27 @@ // Tools Menu $sitemenu['refresh_site'] = array( - 'refresh_site', - 'tools', - '' . $_lang['refresh_site'], - 'index.php?a=26', - $_lang['refresh_site'], - '', - '', - 'main', - 0, - 5, - '' + 'refresh_site', + 'tools', + '' . $_lang['refresh_site'], + 'index.php?a=26', + $_lang['refresh_site'], + '', + '', + 'main', + 0, + 5, + 'item-group', + array( + 'refresh_site_in_window' => array( + 'a', // tag + 'javascript:;', // href + 'btn btn-secondary', // class or btn-success + 'modx.openWindow({url:\'index.php?a=26\', title:\'' . $_lang['refresh_site'] . '\'})', // onclick + $_lang['refresh_site'], // title + '' // innerHTML + ) + ) ); $sitemenu['search'] = array( @@ -431,10 +441,10 @@ if(is_array($menu)) { $newmenu = array(); foreach($menu as $item){ - if(is_array(unserialize($item))){ + if(is_array(unserialize($item))){ $newmenu = array_merge($newmenu, unserialize($item)); } - } + } if(count($newmenu)> 0) $sitemenu = $newmenu; } diff --git a/manager/frames/tree.php b/manager/frames/tree.php index 60f35140a0..8c2a1bb582 100644 --- a/manager/frames/tree.php +++ b/manager/frames/tree.php @@ -46,7 +46,7 @@ - +
    diff --git a/manager/includes/menu.class.inc.php b/manager/includes/menu.class.inc.php index 70f65af881..379475d571 100644 --- a/manager/includes/menu.class.inc.php +++ b/manager/includes/menu.class.inc.php @@ -70,13 +70,25 @@ function DrawSub($parentid, $level) { $ph['LinkAttr'] = $this->getLinkAttr($id); $ph['itemName'] = $value[2] . $this->getItemName($id); - if(isset($this->menu[$id])) { - $level++; - $ph['DrawSub'] = $this->DrawSub($id, $level); - $level--; - } else { - $ph['DrawSub'] = ''; - } + $ph['DrawSub'] = ''; + + if(isset($this->menu[$id])) { + $level++; + $ph['DrawSub'] = $this->DrawSub($id, $level); + $level--; + // Optional buttons + } else if(isset($value[11]) && !empty($value[11])) { + $optionalButton = ''; + if(is_array($value[11])) { + foreach ($value[11] as $opt) { + $optionalButton .= sprintf('<%s href="%s" class="%s" onclick="%s" title="%s">%s', $opt[0], $opt[1], $opt[2], $opt[3], $opt[4], $opt[5], $opt[0]); + } + } else { + $opt = $value[11]; + $optionalButton = sprintf('<%s href="%s" class="%s" onclick="%s" title="%s">%s', $opt[0], $opt[1], $opt[2], $opt[3], $opt[4], $opt[5], $opt[0]); + } + $ph['DrawSub'] = $optionalButton; + } $output .= $modx->parseText($itemTpl, $ph); } diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 6d6c43267d..9f81ebc869 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -2,33 +2,7 @@ .row { margin-left: -1.3rem; margin-right: -1.3rem } .container { padding-left: 1.3rem; padding-right: 1.3rem; width: 100% } .container-body { padding: 1.3rem } -.navbar.navbar-editor { padding: .5rem 1.3rem; border-radius: 0 } /* [ FORMS ] */ -legend { font-size: 1em; } -label { cursor: pointer; display: inline-block; margin-bottom: .5em } -label:not([for]) { cursor: default } -[type=checkbox], [type=radio] { width: auto !important; margin-right: 0.2em; vertical-align: -0.2em } -button, input, optgroup, select, textarea { position: relative; font-family: sans-serif; font-size: 100%; line-height: 1.15; margin: 0 } -.form-control, input[type=text]:not(.form-control), input[type=password], input[type=number], input[type=email], input[type=date], input[type=url], input[type=search], select, textarea { display: inline-block; width: 100%; max-width: 100%; padding: 0.375em .5em; font-size: 0.8rem; line-height: 1.5; color: #464a4c; background-color: #fff; background-image: none; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #d4d4d4; border-radius: .1em; -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s, -webkit-box-shadow ease-in-out .15s } -.form-control:focus, input:not([type=radio]):not([type=checkbox]):focus, select:focus, textarea:focus, .btn.focus, .btn:focus { z-index: 3; outline-offset: -1px; outline: rgba(77, 142, 249, 0.5) solid 2px; } -.btn, button:not(.btn), input[type="button"]:not(.btn), input[type="submit"]:not(.btn) { display: inline-block; font-weight: 400; line-height: 1.5; text-align: center; text-decoration: none; white-space: nowrap; vertical-align: middle; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #fff; border: 1px solid #d4d4d4; padding: .375em 1em; font-size: 0.8rem; border-radius: .1em; -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out } -.form-control-sm, .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn, input.form-control-sm, .btn-group-sm > .btn, .btn-sm, .input-group-addon.form-control-sm, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .input-group-addon.btn { font-size: .675rem; border-radius: .1rem; } -.form-control-lg, .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn, input.form-control-lg, .btn-group-lg > .btn, .btn-lg, .input-group-addon.form-control-lg, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .input-group-addon.btn { font-size: 1.15rem; border-radius: .1rem; } -.btn:focus, .btn:hover { text-decoration: none } -.btn-primary { color: #fff; background-color: #0275d8; border-color: #0275d8 } -.btn-primary:hover { color: #fff; background-color: #025aa5; border-color: #01549b } -.btn-secondary { color: #292b2c; background-color: #fff; border-color: #d4d4d4 } -.btn-secondary:hover { color: #292b2c; background-color: #e6e6e6; border-color: #adadad } -.btn-success { color: #fff; background-color: #5cb85c; border-color: #56ac56 } -.btn-success:hover { color: #fff; background-color: #449d44; border-color: #419641 } -.btn-danger { color: #fff; background-color: #d9534f; border-color: #d9534f } -.btn-danger:hover { color: #fff; background-color: #c9302c; border-color: #c12e2a } -.btn-default { color: #bbb; background-color: #202329; border-color: #202329 } -.btn-default:hover { color: #fff; background-color: #1a1c21; border-color: #1a1c21 } -textarea { width: 100%; overflow: auto; resize: vertical } -select.form-control:not([size]):not([multiple]), select:not([multiple]) { min-height: calc(2.235em + 2px); height: auto; } -optgroup { font-style: normal; font-weight: 500; background-color: #ddd; } -optgroup option { font-weight: normal; background-color: #fff; } .form-row { margin-bottom: 0.25rem; } .form-row.row { margin-left: 0; margin-right: -1rem } .form-row label { margin-bottom: 0.15rem } @@ -43,7 +17,6 @@ optgroup option { font-weight: normal; background-color: #fff; } .form-control-name .custom-control .fa-lock { margin-top: 0.6em; font-size: 1.5em } .form-control-name .custom-control .fa-lock::before { content: "\f09c"; color: #ddd } .form-control-name .custom-control input:checked ~ .fa-lock::before { content: "\f023"; color: #d9534f } -.input-group-addon { padding: 0.375em .5em; font-size: 0.8rem; line-height: 1.5; border: 1px solid rgba(0, 0, 0, .15); border-radius: .1em; } input[type=date]:not(.unstyled), input[name*=date]:not(.unstyled), input[name=createdon], input[name=editedon], input[size="1"], select[size="1"]:not(.unstyled), select[name=usergroup]:not(.unstyled), select[name=docgroup]:not(.unstyled) { width: auto !important; vertical-align: middle } input[name*=date]:not(.unstyled) + .input-group-addon { float: left; width: auto; } input[size="50"], select[size="50"] { width: 10rem !important } @@ -52,6 +25,8 @@ select[name=docgroup] + input[type=submit] { float: none; margin: 0; } input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } #settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype], input[name=photo] { float: left; width: calc(100% - 6rem) !important; border-top-right-radius: 0; border-bottom-right-radius: 0 } #settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button] { float: right; width: 6rem !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } +/* [ Editor ] */ +.navbar.navbar-editor { padding: .5rem 1.3rem; border-radius: 0 } .navbar-editor > label { margin-bottom: 0 } .section-editor textarea { float: left; border-left: none; border-right: none; font-family: 'Inconsolata', 'Monaco', 'Consolas', 'Courier New', 'Courier', monospace; font-weight: 300; font-size: 0.875rem; } /* [ Action Buttons ] */ diff --git a/manager/media/style/default/css/forms.css b/manager/media/style/default/css/forms.css index 19242dc13f..45ca5bc4b8 100644 --- a/manager/media/style/default/css/forms.css +++ b/manager/media/style/default/css/forms.css @@ -1,260 +1,28 @@ +/* [ FORMS ] */ +legend { font-size: 1em; } +label { cursor: pointer; display: inline-block; margin-bottom: .5em } +label:not([for]) { cursor: default } +[type=checkbox], [type=radio] { width: auto !important; margin-right: 0.2em; vertical-align: -0.2em } button, input, optgroup, select, textarea { position: relative; font-family: sans-serif; font-size: 100%; line-height: 1.15; margin: 0 } -button, input { overflow: visible } -button, select { text-transform: none } -[type=reset], [type=submit], button, html [type=button] { -webkit-appearance: button } -[type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner, button::-moz-focus-inner { border-style: none; padding: 0 } -[type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring, button:-moz-focusring { outline: 1px dotted ButtonText } -fieldset { border: 0; margin: 0; padding: 0 } -legend { -webkit-box-sizing: border-box; box-sizing: border-box; color: inherit; display: table; max-width: 100%; padding: 0; white-space: normal; margin-bottom: .5rem; font-size: 1em; line-height: inherit } -textarea { overflow: auto; resize: vertical } -[type=checkbox], [type=radio] { -webkit-box-sizing: border-box; box-sizing: border-box; margin-right: 0.2em; padding: 0; vertical-align: -0.2em } -[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button { height: auto } -[type=search] { -webkit-appearance: textfield; outline-offset: -2px } -[type=search]::-webkit-search-cancel-button, [type=search]::-webkit-search-decoration { -webkit-appearance: none } -::-webkit-file-upload-button { -webkit-appearance: button; font: inherit } -[role=button] { cursor: pointer } -[role=button], a, area, button, input, label, select, summary, textarea { -ms-touch-action: manipulation; touch-action: manipulation } -label { display: inline-block; margin-bottom: .5rem } -button:focus, input[type=button], input[type=submit] { outline: none; } -button, input, select, textarea { line-height: inherit } -input[type=checkbox]:disabled, input[type=radio]:disabled { cursor: not-allowed } -input[type=date], input[type=time], input[type=datetime-local], input[type=month] { -webkit-appearance: listbox } -input[type=search] { -webkit-appearance: none } -.form-control, input[type=text], input[type=password], input[type=number], input[type=email], input[type=date], input[type=url], input[type=search], select, textarea { display: inline-block; width: 100%; max-width: 100%; padding: 0.375em .5em; font-size: 0.8rem; line-height: 1.5; color: #464a4c; background-color: #fff; background-image: none; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, .15); border-radius: .1em; -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s, -webkit-box-shadow ease-in-out .15s } -.form-control::-ms-expand { background-color: transparent; border: 0 } -.form-control:focus { color: #464a4c; background-color: #fff; border-color: #5cb3fd; outline: 0 } -.form-control::-webkit-input-placeholder { color: #636c72; opacity: 1 } -.form-control::-moz-placeholder { color: #636c72; opacity: 1 } -.form-control:-ms-input-placeholder { color: #636c72; opacity: 1 } -.form-control::placeholder { color: #636c72; opacity: 1 } -.form-control:disabled, .form-control[readonly] { background-color: #eceeef; opacity: 1 } -.form-control:disabled { cursor: not-allowed } -select.form-control:not([size]):not([multiple]), select:not([multiple]) { height: calc(2.235em + 2px); /*padding: 0.592em 0.5em;*/ } -select.form-control:focus::-ms-value { color: #464a4c; background-color: #fff } +.form-control, input[type=text]:not(.form-control), input[type=password], input[type=number], input[type=email], input[type=date], input[type=url], input[type=search], select, textarea { display: inline-block; width: 100%; max-width: 100%; padding: 0.375em .5em; font-size: 0.8rem; line-height: 1.5; color: #464a4c; background-color: #fff; background-image: none; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #d4d4d4; border-radius: .1em; -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s, -webkit-box-shadow ease-in-out .15s } .form-control:focus, input:not([type=radio]):not([type=checkbox]):focus, select:focus, textarea:focus, .btn.focus, .btn:focus { z-index: 3; outline-offset: -1px; outline: rgba(77, 142, 249, 0.5) solid 2px; } -.form-control-file, .form-control-range { display: block } -.col-form-label { padding-top: calc(.5rem - 1px * 2); padding-bottom: calc(.5rem - 1px * 2); margin-bottom: 0 } -.col-form-label-lg { padding-top: calc(.75rem - 1px * 2); padding-bottom: calc(.75rem - 1px * 2); font-size: 1.25rem } -.col-form-label-sm { padding-top: calc(.25rem - 1px * 2); padding-bottom: calc(.25rem - 1px * 2); font-size: .875rem } -.col-form-legend { padding-top: .5rem; padding-bottom: .5rem; margin-bottom: 0; font-size: 0.8rem } -.form-control-static { padding-top: .5rem; padding-bottom: .5rem; margin-bottom: 0; line-height: 1.25; border: solid transparent; border-width: 1px 0 } -.form-control-static.form-control-lg, .form-control-static.form-control-sm, .input-group-lg > .form-control-static.form-control, .input-group-lg > .form-control-static.input-group-addon, .input-group-lg > .input-group-btn > .form-control-static.btn, .input-group-sm > .form-control-static.form-control, .input-group-sm > .form-control-static.input-group-addon, .input-group-sm > .input-group-btn > .form-control-static.btn { padding-right: 0; padding-left: 0 } -.form-control-sm, .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn, input.form-control-sm { font-size: 0.675rem; } -.input-group-sm > .input-group-btn > select.btn:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), .input-group-sm > select.input-group-addon:not([size]):not([multiple]), select.form-control-sm:not([size]):not([multiple]) { /*height: 1.8125em*/ } -.form-control-lg, .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn, input.form-control-lg { font-size: 1.15rem; } -.input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]), .input-group-lg > select.input-group-addon:not([size]):not([multiple]), select.form-control-lg:not([size]):not([multiple]) { /*height: 3.166667em*/ } -.form-group { margin-bottom: 1rem } -.form-text { display: block; margin-top: .25rem } -.form-check { position: relative; display: block; margin-bottom: .5rem } -.form-check.disabled .form-check-label { color: #636c72; cursor: not-allowed } -.form-check-label { padding-left: 1.25rem; margin-bottom: 0; cursor: pointer } -.form-check-input { position: absolute; margin-top: .25rem; margin-left: -1.25rem } -.form-check-input:only-child { position: static } -.form-check-inline { display: inline-block } -.form-check-inline .form-check-label { vertical-align: middle } -.form-check-inline + .form-check-inline { margin-left: .75rem } -.form-control-feedback { margin-top: .25rem } -.form-control-danger, .form-control-success, .form-control-warning { padding-right: 2.25rem; background-repeat: no-repeat; background-position: center right .5625rem; -webkit-background-size: 1.125rem 1.125rem; background-size: 1.125rem 1.125rem } -.has-success .col-form-label, .has-success .custom-control, .has-success .form-check-label, .has-success .form-control-feedback, .has-success .form-control-label { color: #5cb85c } -.has-success .form-control { border-color: #5cb85c } -.has-success .input-group-addon { color: #5cb85c; border-color: #5cb85c; background-color: #eaf6ea } -.has-success .form-control-success { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") } -.has-warning .col-form-label, .has-warning .custom-control, .has-warning .form-check-label, .has-warning .form-control-feedback, .has-warning .form-control-label { color: #f0ad4e } -.has-warning .form-control { border-color: #f0ad4e } -.has-warning .input-group-addon { color: #f0ad4e; border-color: #f0ad4e; background-color: #fff } -.has-warning .form-control-warning { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E") } -.has-danger .col-form-label, .has-danger .custom-control, .has-danger .form-check-label, .has-danger .form-control-feedback, .has-danger .form-control-label { color: #d9534f } -.has-danger .form-control { border-color: #d9534f } -.has-danger .input-group-addon { color: #d9534f; border-color: #d9534f; background-color: #fdf7f7 } -.has-danger .form-control-danger { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E") } -@media (min-width: 576px) { -.form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle } -.form-inline .form-control { display: inline-block; width: auto; vertical-align: middle } -.form-inline .form-control-static { display: inline-block } -.form-inline .input-group { display: inline-table; width: auto; vertical-align: middle } -.form-inline .input-group .form-control, .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn { width: auto } -.form-inline .input-group > .form-control { width: 100% } -.form-inline .form-control-label { margin-bottom: 0; vertical-align: middle } -.form-inline .form-check { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle } -.form-inline .form-check-label { padding-left: 0 } -.form-inline .form-check-input { position: relative; margin-left: 0 } -.form-inline .has-feedback .form-control-feedback { top: 0 } -} -.btn, button, input[type="button"], input[type="submit"] { display: inline-block; font-weight: 400; line-height: 1.5; text-align: center; text-decoration: none; white-space: nowrap; vertical-align: middle; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border: 1px solid transparent; padding: .375em 1em; font-size: 0.8rem; border-radius: .1em; -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out } +.btn, button:not(.btn), input[type="button"]:not(.btn), input[type="submit"]:not(.btn) { display: inline-block; font-weight: 400; line-height: 1.5; text-align: center; text-decoration: none; white-space: nowrap; vertical-align: middle; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #fff; border: 1px solid #d4d4d4; padding: .375em 1em; font-size: 0.8rem; border-radius: .1em; -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out } +.form-control-sm, .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn, input.form-control-sm, .btn-group-sm > .btn, .btn-sm, .input-group-addon.form-control-sm, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .input-group-addon.btn { font-size: .675rem; border-radius: .1rem; } +.form-control-lg, .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn, input.form-control-lg, .btn-group-lg > .btn, .btn-lg, .input-group-addon.form-control-lg, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .input-group-addon.btn { font-size: 1.15rem; border-radius: .1rem; } .btn:focus, .btn:hover { text-decoration: none } -.btn.disabled, .btn:disabled { cursor: not-allowed; opacity: .65 } -.btn.active, .btn:active { background-image: none } -a.btn.disabled, fieldset[disabled] a.btn { pointer-events: none } .btn-primary { color: #fff; background-color: #0275d8; border-color: #0275d8 } .btn-primary:hover { color: #fff; background-color: #025aa5; border-color: #01549b } -.btn-primary.focus, .btn-primary:focus { -webkit-box-shadow: 0 0 0 2px rgba(2, 117, 216, .5); box-shadow: 0 0 0 2px rgba(2, 117, 216, .5) } -.btn-primary.disabled, .btn-primary:disabled { background-color: #0275d8; border-color: #0275d8 } -.btn-primary.active, .btn-primary:active, .show > .btn-primary.dropdown-toggle { color: #fff; background-color: #025aa5; background-image: none; border-color: #01549b } -.btn-secondary { color: #292b2c; background-color: #fff; border-color: #ccc } +.btn-secondary { color: #292b2c; background-color: #fff; border-color: #d4d4d4 } .btn-secondary:hover { color: #292b2c; background-color: #e6e6e6; border-color: #adadad } -.btn-secondary.focus, .btn-secondary:focus { -webkit-box-shadow: 0 0 0 2px rgba(204, 204, 204, .5); box-shadow: 0 0 0 2px rgba(204, 204, 204, .5) } -.btn-secondary.disabled, .btn-secondary:disabled { background-color: #fff; border-color: #ccc } -.btn-secondary.active, .btn-secondary:active, .show > .btn-secondary.dropdown-toggle { color: #292b2c; background-color: #e6e6e6; background-image: none; border-color: #adadad } -.btn-info { color: #fff; background-color: #5bc0de; border-color: #5bc0de } -.btn-info:hover { color: #fff; background-color: #31b0d5; border-color: #2aabd2 } -.btn-info.focus, .btn-info:focus { -webkit-box-shadow: 0 0 0 2px rgba(91, 192, 222, .5); box-shadow: 0 0 0 2px rgba(91, 192, 222, .5) } -.btn-info.disabled, .btn-info:disabled { background-color: #5bc0de; border-color: #5bc0de } -.btn-info.active, .btn-info:active, .show > .btn-info.dropdown-toggle { color: #fff; background-color: #31b0d5; background-image: none; border-color: #2aabd2 } .btn-success { color: #fff; background-color: #5cb85c; border-color: #56ac56 } .btn-success:hover { color: #fff; background-color: #449d44; border-color: #419641 } -.btn-success.focus, .btn-success:focus { -webkit-box-shadow: 0 0 0 2px rgba(92, 184, 92, .5); box-shadow: 0 0 0 2px rgba(92, 184, 92, .5) } -.btn-success.disabled, .btn-success:disabled { background-color: #5cb85c; border-color: #56ac56 } -.btn-success.active, .btn-success:active, .show > .btn-success.dropdown-toggle { color: #fff; background-color: #449d44; background-image: none; border-color: #419641 } -.btn-warning { color: #fff; background-color: #f0ad4e; border-color: #f0ad4e } -.btn-warning:hover { color: #fff; background-color: #ec971f; border-color: #eb9316 } -.btn-warning.focus, .btn-warning:focus { -webkit-box-shadow: 0 0 0 2px rgba(240, 173, 78, .5); box-shadow: 0 0 0 2px rgba(240, 173, 78, .5) } -.btn-warning.disabled, .btn-warning:disabled { background-color: #f0ad4e; border-color: #f0ad4e } -.btn-warning.active, .btn-warning:active, .show > .btn-warning.dropdown-toggle { color: #fff; background-color: #ec971f; background-image: none; border-color: #eb9316 } .btn-danger { color: #fff; background-color: #d9534f; border-color: #d9534f } .btn-danger:hover { color: #fff; background-color: #c9302c; border-color: #c12e2a } -.btn-danger.focus, .btn-danger:focus { -webkit-box-shadow: 0 0 0 2px rgba(217, 83, 79, .5); box-shadow: 0 0 0 2px rgba(217, 83, 79, .5) } -.btn-danger.disabled, .btn-danger:disabled { background-color: #d9534f; border-color: #d9534f } -.btn-danger.active, .btn-danger:active, .show > .btn-danger.dropdown-toggle { color: #fff; background-color: #c9302c; background-image: none; border-color: #c12e2a } -.btn-outline-primary { color: #0275d8; background-image: none; background-color: transparent; border-color: #0275d8 } -.btn-outline-primary:hover { color: #fff; background-color: #0275d8; border-color: #0275d8 } -.btn-outline-primary.focus, .btn-outline-primary:focus { -webkit-box-shadow: 0 0 0 2px rgba(2, 117, 216, .5); box-shadow: 0 0 0 2px rgba(2, 117, 216, .5) } -.btn-outline-primary.disabled, .btn-outline-primary:disabled { color: #0275d8; background-color: transparent } -.btn-outline-primary.active, .btn-outline-primary:active, .show > .btn-outline-primary.dropdown-toggle { color: #fff; background-color: #0275d8; border-color: #0275d8 } -.btn-outline-secondary { color: #ccc; background-image: none; background-color: transparent; border-color: #ccc } -.btn-outline-secondary:hover { color: #fff; background-color: #ccc; border-color: #ccc } -.btn-outline-secondary.focus, .btn-outline-secondary:focus { -webkit-box-shadow: 0 0 0 2px rgba(204, 204, 204, .5); box-shadow: 0 0 0 2px rgba(204, 204, 204, .5) } -.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { color: #ccc; background-color: transparent } -.btn-outline-secondary.active, .btn-outline-secondary:active, .show > .btn-outline-secondary.dropdown-toggle { color: #fff; background-color: #ccc; border-color: #ccc } -.btn-outline-info { color: #5bc0de; background-image: none; background-color: transparent; border-color: #5bc0de } -.btn-outline-info:hover { color: #fff; background-color: #5bc0de; border-color: #5bc0de } -.btn-outline-info.focus, .btn-outline-info:focus { -webkit-box-shadow: 0 0 0 2px rgba(91, 192, 222, .5); box-shadow: 0 0 0 2px rgba(91, 192, 222, .5) } -.btn-outline-info.disabled, .btn-outline-info:disabled { color: #5bc0de; background-color: transparent } -.btn-outline-info.active, .btn-outline-info:active, .show > .btn-outline-info.dropdown-toggle { color: #fff; background-color: #5bc0de; border-color: #5bc0de } -.btn-outline-success { color: #5cb85c; background-image: none; background-color: transparent; border-color: #5cb85c } -.btn-outline-success:hover { color: #fff; background-color: #5cb85c; border-color: #5cb85c } -.btn-outline-success.focus, .btn-outline-success:focus { -webkit-box-shadow: 0 0 0 2px rgba(92, 184, 92, .5); box-shadow: 0 0 0 2px rgba(92, 184, 92, .5) } -.btn-outline-success.disabled, .btn-outline-success:disabled { color: #5cb85c; background-color: transparent } -.btn-outline-success.active, .btn-outline-success:active, .show > .btn-outline-success.dropdown-toggle { color: #fff; background-color: #5cb85c; border-color: #5cb85c } -.btn-outline-warning { color: #f0ad4e; background-image: none; background-color: transparent; border-color: #f0ad4e } -.btn-outline-warning:hover { color: #fff; background-color: #f0ad4e; border-color: #f0ad4e } -.btn-outline-warning.focus, .btn-outline-warning:focus { -webkit-box-shadow: 0 0 0 2px rgba(240, 173, 78, .5); box-shadow: 0 0 0 2px rgba(240, 173, 78, .5) } -.btn-outline-warning.disabled, .btn-outline-warning:disabled { color: #f0ad4e; background-color: transparent } -.btn-outline-warning.active, .btn-outline-warning:active, .show > .btn-outline-warning.dropdown-toggle { color: #fff; background-color: #f0ad4e; border-color: #f0ad4e } -.btn-outline-danger { color: #d9534f; background-image: none; background-color: transparent; border-color: #d9534f } -.btn-outline-danger:hover { color: #fff; background-color: #d9534f; border-color: #d9534f } -.btn-outline-danger.focus, .btn-outline-danger:focus { -webkit-box-shadow: 0 0 0 2px rgba(217, 83, 79, .5); box-shadow: 0 0 0 2px rgba(217, 83, 79, .5) } -.btn-outline-danger.disabled, .btn-outline-danger:disabled { color: #d9534f; background-color: transparent } -.btn-outline-danger.active, .btn-outline-danger:active, .show > .btn-outline-danger.dropdown-toggle { color: #fff; background-color: #d9534f; border-color: #d9534f } -.btn-link { font-weight: 400; color: #0275d8; border-radius: 0 } -.btn-link, .btn-link.active, .btn-link:active, .btn-link:disabled { background-color: transparent } -.btn-link, .btn-link:active, .btn-link:focus { border-color: transparent } -.btn-link:hover { border-color: transparent } -.btn-link:focus, .btn-link:hover { color: #014c8c; text-decoration: underline; background-color: transparent } -.btn-link:disabled { color: #636c72 } -.btn-link:disabled:focus, .btn-link:disabled:hover { text-decoration: none } -.btn-group-lg > .btn, .btn-lg { font-size: 1.15rem; } -.btn-group-sm > .btn, .btn-sm { font-size: .675rem; } -.btn-block { display: block; width: 100% } -.btn-block + .btn-block { margin-top: .5em } -input[type=button].btn-block, input[type=reset].btn-block, input[type=submit].btn-block { width: 100% } -.btn-group, .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle } -.btn-group-vertical > .btn, .btn-group > .btn { position: relative; float: left; margin-bottom: 0 } -.btn-group-vertical > .btn:hover, .btn-group > .btn:hover { z-index: 2 } -.btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus { z-index: 2 } -.btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group, .btn-group-vertical .btn + .btn, .btn-group-vertical .btn + .btn-group, .btn-group-vertical .btn-group + .btn, .btn-group-vertical .btn-group + .btn-group { margin-left: -1px } -.btn-toolbar { margin-left: -.5rem } -.btn-toolbar .input-group { width: auto } -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0 } -.btn-group > .btn:first-child { margin-left: 0 } -.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 0; border-top-right-radius: 0 } -.btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { border-bottom-left-radius: 0; border-top-left-radius: 0 } -.btn-group > .btn-group { float: left } -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0 } -.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-top-right-radius: 0 } -.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-bottom-left-radius: 0; border-top-left-radius: 0 } -.btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0 } -.btn + .dropdown-toggle-split { padding-right: .75rem; padding-left: .75rem } -.btn + .dropdown-toggle-split::after { margin-left: 0 } -.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { padding-right: .375em; padding-left: .375em } -.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { padding-right: 1.125em; padding-left: 1.125em } -.btn-group-vertical { } -.btn-group-vertical .btn, .btn-group-vertical .btn-group { width: 100% } -.btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0 } -.btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0 } -.btn-group-vertical > .btn:first-child:not(:last-child) { border-bottom-right-radius: 0; border-bottom-left-radius: 0 } -.btn-group-vertical > .btn:last-child:not(:first-child) { border-top-right-radius: 0; border-top-left-radius: 0 } -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0 } -.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0 } -.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-right-radius: 0; border-top-left-radius: 0 } -[data-toggle=buttons] > .btn input[type=checkbox], [data-toggle=buttons] > .btn input[type=radio], [data-toggle=buttons] > .btn-group > .btn input[type=checkbox], [data-toggle=buttons] > .btn-group > .btn input[type=radio] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none } -.input-group { position: relative; width: 100%; display: table; border-collapse: separate } -.input-group .form-control { position: relative; z-index: 2; float: left; width: 100%; margin-bottom: 0 } -.input-group .form-control:active, .input-group .form-control:focus, .input-group .form-control:hover { z-index: 3 } -.input-group .form-control, .input-group-addon, .input-group-btn { display: table-cell } -.input-group .form-control:not(:first-child):not(:last-child), .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child) { border-radius: 0 } -.input-group-addon, .input-group-btn { width: 1%; white-space: nowrap; vertical-align: middle } -.input-group-addon { padding: .5em .75em; margin-bottom: 0; font-size: 0.8rem; font-weight: 400; line-height: 1.25; color: #464a4c; text-align: center; background-color: #eceeef; border: 1px solid rgba(0, 0, 0, .15); border-radius: .1em } -.input-group-addon.form-control-sm, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .input-group-addon.btn { font-size: .675rem; } -.input-group-addon.form-control-lg, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .input-group-addon.btn { font-size: 1.15rem; } -.input-group-addon input[type=checkbox], .input-group-addon input[type=radio] { margin-top: 0 } -.input-group .form-control:not(:last-child), .input-group-addon:not(:last-child), .input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn, .input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:not(:last-child) > .btn, .input-group-btn:not(:last-child) > .btn-group > .btn, .input-group-btn:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-top-right-radius: 0 } -.input-group-addon:not(:last-child) { border-right: 0 } -.input-group .form-control:not(:first-child), .input-group-addon:not(:first-child), .input-group-btn:not(:first-child) > .btn, .input-group-btn:not(:first-child) > .btn-group > .btn, .input-group-btn:not(:first-child) > .dropdown-toggle, .input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn, .input-group-btn:not(:last-child) > .btn:not(:first-child) { border-bottom-left-radius: 0; border-top-left-radius: 0 } -.form-control + .input-group-addon:not(:first-child) { border-left: 0 } -.input-group-btn { position: relative; font-size: 0; white-space: nowrap } -.input-group-btn > .btn { position: relative; } -.input-group-btn > .btn + .btn { margin-left: -1px } -.input-group-btn > .btn:active, .input-group-btn > .btn:focus, .input-group-btn > .btn:hover { z-index: 3 } -.input-group-btn:not(:last-child) > .btn, .input-group-btn:not(:last-child) > .btn-group { margin-right: -1px } -.input-group-btn:not(:first-child) > .btn, .input-group-btn:not(:first-child) > .btn-group { z-index: 2; margin-left: -1px } -.input-group-btn:not(:first-child) > .btn-group:active, .input-group-btn:not(:first-child) > .btn-group:focus, .input-group-btn:not(:first-child) > .btn-group:hover, .input-group-btn:not(:first-child) > .btn:active, .input-group-btn:not(:first-child) > .btn:focus, .input-group-btn:not(:first-child) > .btn:hover { z-index: 3 } -.custom-control { position: relative; display: inline-block; min-height: 1.5rem; padding-left: 1.5rem; margin-right: 1rem; cursor: pointer } -.custom-control-input { position: absolute; z-index: -1; opacity: 0 } -.custom-control-input:checked ~ .custom-control-indicator { color: #fff; background-color: #0275d8 } -.custom-control-input:focus ~ .custom-control-indicator { -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 3px #0275d8; box-shadow: 0 0 0 1px #fff, 0 0 0 3px #0275d8 } -.custom-control-input:active ~ .custom-control-indicator { color: #fff; background-color: #8fcafe } -.custom-control-input:disabled ~ .custom-control-indicator { cursor: not-allowed; background-color: #eceeef } -.custom-control-input:disabled ~ .custom-control-description { color: #636c72; cursor: not-allowed } -.custom-control-indicator { position: absolute; top: .25rem; left: 0; display: block; width: 1rem; height: 1rem; pointer-events: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #ddd; background-repeat: no-repeat; background-position: center center; -webkit-background-size: 50% 50%; background-size: 50% 50% } -.custom-checkbox .custom-control-indicator { border-radius: .25rem } -.custom-checkbox .custom-control-input:checked ~ .custom-control-indicator { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E") } -.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-indicator { background-color: #0275d8; background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E") } -.custom-radio .custom-control-indicator { border-radius: 50% } -.custom-radio .custom-control-input:checked ~ .custom-control-indicator { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E") } -.custom-select { display: inline-block; max-width: 100%; height: calc(2.25rem + 2px); padding: .375rem 1.75rem .375rem .75rem; line-height: 1.25; color: #464a4c; vertical-align: middle; background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center; -webkit-background-size: 8px 10px; background-size: 8px 10px; border: 1px solid rgba(0, 0, 0, .15); border-radius: .25rem; -moz-appearance: none; -webkit-appearance: none } -.custom-select:focus { border-color: #5cb3fd; outline: 0 } -.custom-select:focus::-ms-value { color: #464a4c; background-color: #fff } -.custom-select:disabled { color: #636c72; cursor: not-allowed; background-color: #eceeef } -.custom-select::-ms-expand { opacity: 0 } -.custom-select-sm { padding-top: .375rem; padding-bottom: .375rem; font-size: 75% } -.custom-file { position: relative; display: inline-block; max-width: 100%; height: 2.5rem; margin-bottom: 0; cursor: pointer } -.custom-file-input { min-width: 14rem; max-width: 100%; height: 2.5rem; margin: 0; filter: alpha(opacity=0); opacity: 0 } -.custom-file-control { position: absolute; top: 0; right: 0; left: 0; z-index: 5; height: 2.5rem; padding: .5rem 1rem; line-height: 1.5; color: #464a4c; pointer-events: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #fff; border: 1px solid rgba(0, 0, 0, .15); border-radius: .25rem } -.custom-file-control:lang(en)::after { content: "Choose file..." } -.custom-file-control::before { position: absolute; top: -1px; right: -1px; bottom: -1px; z-index: 6; display: block; height: 2.5rem; padding: .5rem 1rem; line-height: 1.5; color: #464a4c; background-color: #eceeef; border: 1px solid rgba(0, 0, 0, .15); border-radius: 0 .25rem .25rem 0 } -.custom-file-control:lang(en)::before { content: "Browse" } -/* custom */ -.form-row { margin-bottom: 0.1875rem; } -.form-row.row { margin-left: 0; margin-right: -1rem } -.form-row label { margin-bottom: 0.15rem } -.form-row .col, .form-row .col-1, .form-row .col-10, .form-row .col-11, .form-row .col-12, .form-row .col-2, .form-row .col-3, .form-row .col-4, .form-row .col-5, .form-row .col-6, .form-row .col-7, .form-row .col-8, .form-row .col-9, .form-row .col-lg, .form-row .col-lg-1, .form-row .col-lg-10, .form-row .col-lg-11, .form-row .col-lg-12, .form-row .col-lg-2, .form-row .col-lg-3, .form-row .col-lg-4, .form-row .col-lg-5, .form-row .col-lg-6, .form-row .col-lg-7, .form-row .col-lg-8, .form-row .col-lg-9, .form-row .col-md, .form-row .col-md-1, .form-row .col-md-10, .form-row .col-md-11, .form-row .col-md-12, .form-row .col-md-2, .form-row .col-md-3, .form-row .col-md-4, .form-row .col-md-5, .form-row .col-md-6, .form-row .col-md-7, .form-row .col-md-8, .form-row .col-md-9, .form-row .col-sm, .form-row .col-sm-1, .form-row .col-sm-10, .form-row .col-sm-11, .form-row .col-sm-12, .form-row .col-sm-2, .form-row .col-sm-3, .form-row .col-sm-4, .form-row .col-sm-5, .form-row .col-sm-6, .form-row .col-sm-7, .form-row .col-sm-8, .form-row .col-sm-9, .form-row .col-xl, .form-row .col-xl-1, .form-row .col-xl-10, .form-row .col-xl-11, .form-row .col-xl-12, .form-row .col-xl-2, .form-row .col-xl-3, .form-row .col-xl-4, .form-row .col-xl-5, .form-row .col-xl-6, .form-row .col-xl-7, .form-row .col-xl-8, .form-row .col-xl-9 { padding-left: 0 } -.form-row .form-control { float: left; } -.container-body > .form-group:last-child, .container-body > .form-row:last-child { margin-bottom: 0 } -.form-control-name { position: relative; } -.form-control-name .form-control { padding-right: 2em } -.form-control-name .custom-control { display: block; overflow: hidden; position: absolute; z-index: 3; top: 0; right: 0; width: 2em; height: 100%; margin: 0; padding: 0; cursor: pointer } -.form-control-name .custom-control input { position: absolute; left: -100% } -.form-control-name .custom-control .fa-lock { margin-top: 0.6em; font-size: 1.5em } -.form-control-name .custom-control .fa-lock::before { content: "\f09c"; color: #ddd } -.form-control-name .custom-control input:checked ~ .fa-lock::before { content: "\f023"; color: #d9534f } -[type=checkbox], [type=radio] { width: auto !important } -input[type=date], input[name*=date], input[size="1"], select[size="1"], select[name=usergroup], select[name=docgroup] { width: auto !important; vertical-align: middle } -input[size="50"], select[size="50"] { width: 10rem !important } -select[name=usergroup], select[name=docgroup] { margin: 0 0.5em; } -select[name=docgroup] + input[type=submit] { float: none; margin: 0; } -input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } -#settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype], input[name=photo] { float: left; width: calc(100% - 6rem) !important; border-top-right-radius: 0; border-bottom-right-radius: 0 } -#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button] { float: right; width: 6rem !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } -.navbar-editor > label { margin-bottom: 0 } -.section-editor textarea { float: left; border-left: none; border-right: none; font-family: 'Inconsolata', 'Monaco', 'Consolas', 'Courier New', 'Courier', monospace; font-weight: 300; font-size: 0.875rem; } -.dark .section-editor textarea { background-color: #282c34; color: #abb2bf } +.btn-default { color: #bbb; background-color: #202329; border-color: #202329 } +.btn-default:hover { color: #fff; background-color: #1a1c21; border-color: #1a1c21 } +textarea { width: 100%; overflow: auto; resize: vertical } +select.form-control:not([size]):not([multiple]), select:not([multiple]) { min-height: calc(2.235em + 2px); height: auto; } +optgroup { font-style: normal; font-weight: 500; background-color: #ddd; } +optgroup option { font-weight: normal; background-color: #fff; } +.input-group-addon { padding: 0.375em .5em; font-size: 0.8rem; line-height: 1.5; border: 1px solid rgba(0, 0, 0, .15); border-radius: .1em; } +.form-control.dropdown-item:focus, .form-control.dropdown-item:hover { background-color: inherit } \ No newline at end of file diff --git a/manager/media/style/default/css/mainmenu.css b/manager/media/style/default/css/mainmenu.css index 9380e00dae..fc1d051ed9 100644 --- a/manager/media/style/default/css/mainmenu.css +++ b/manager/media/style/default/css/mainmenu.css @@ -12,7 +12,8 @@ #mainMenu .nav > li.active > a { color: #fff; background-color: rgba(255, 255, 255, 0.07) } #mainMenu .nav > li > a, #mainMenu .nav .label_searchid { display: block; position: relative; z-index: 1; padding: 0 1rem; height: 2.2rem; line-height: 2.4rem; text-decoration: none; color: #bbb; transition-duration: 0.15s } #mainMenu .nav > li > a:hover, #mainMenu .nav .label_searchid:hover { color: #f3f3f3; } -/*#mainMenu.show .nav > li.dropdown:hover > a, */#mainMenu.show .nav > li.dropdown.hover > a { background-color: #fff; color: #444; } +/*#mainMenu.show .nav > li.dropdown:hover > a, */ +#mainMenu.show .nav > li.dropdown.hover > a { background-color: #fff; color: #444; } #mainMenu .nav > li > a .icon { display: inline-block; overflow: hidden; width: auto; height: 2rem; line-height: 2rem; font-size: 1.5em; text-align: center; margin: 0.05rem 0 0 0.5rem; vertical-align: top; border-radius: 50%; background: no-repeat 50% 50%; background-size: cover; } #mainMenu .nav > li > a .icon.photo { width: 2rem } #mainMenu .nav > li > a .icon .fa { font-size: 1.2rem; line-height: 2.1rem } @@ -20,9 +21,10 @@ #mainMenu #nav > li > a > .fa { margin-right: 0.5rem; } #mainMenu #nav #bars .fa { display: inline-block; width: 1.5rem; margin: 0; text-align: center; overflow: hidden; -webkit-transition-duration: 0.15s; transition-duration: 0.15s } .sidebar-closed #mainMenu #nav #bars .fa { width: 0.25rem; margin: 0 0.625rem; } -#mainMenu .nav .caret, #mainMenu .nav .divider { display: none } -#mainMenu .nav > li > ul { display: block; position: absolute; z-index: 0; overflow: auto; top: 100%; left: 0; margin: 0; padding: 0 0 0.25rem; min-width: 15rem; max-height: -webkit-calc(100vh - 2.2rem); max-height: calc(100vh - 2.2rem); border: none; border-radius: 0 0 0.25rem 0.25rem; background-color: #fff; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2); opacity: 0; visibility: hidden; -webkit-transition-duration: 0.1s; transition-duration: 0.1s; } -/*#mainMenu.show .nav > li:hover > a + ul, */#mainMenu.show .nav > li.hover > a + ul, #mainMenu.show .nav > li.hover > ul.sub-menu.show { opacity: 1; visibility: visible } +#mainMenu .nav .caret, #mainMenu .nav .divider, .dropdown-toggle::after { display: none } +#mainMenu .nav > li > ul { display: block; position: absolute; z-index: 0; overflow: auto; top: 100%; left: 0; margin: 0; padding: 0 0 0.25rem; min-width: 15rem; max-height: -webkit-calc(100vh - 2.2rem); max-height: calc(100vh - 2.2rem); font-size: 1em; border: none; border-radius: 0 0 0.25rem 0.25rem; background-color: #fff; box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2); opacity: 0; visibility: hidden; -webkit-transition-duration: 0.1s; transition-duration: 0.1s; } +/*#mainMenu.show .nav > li:hover > a + ul, */ +#mainMenu.show .nav > li.hover > a + ul, #mainMenu.show .nav > li.hover > ul.sub-menu.show { opacity: 1; visibility: visible } #mainMenu.show .nav > li > ul.sub-menu { left: 15rem; opacity: 0; visibility: hidden; } #mainMenu.show .nav > li:hover > ul.sub-menu { } #mainMenu.show .nav > li:hover > ul.sub-menu.show { } @@ -30,23 +32,27 @@ #mainMenu .nav > li > ul > li { border-bottom: 1px solid rgba(0, 0, 0, 0.05); margin-bottom: -1px; } #mainMenu .nav > li > ul > li:last-child { border: none; margin-bottom: 0 } #mainMenu .nav > li > ul > li.item-input { padding: 0.35em 0.5em; } -#mainMenu .nav > li > ul > li > a, #mainMenu .nav > li > ul > li > span { display: block; position: relative; padding: 0 2rem 0 1rem; line-height: 2.2rem; color: #444; text-decoration: none } -#mainMenu .nav > li > ul > li.hover > a { color: #fff; background-color: #1976D2; } -#mainMenu .nav > li > ul > li > span { padding: 0 1em; text-align: center; font-size: 0.875em; color: #aaa; } -#mainMenu .nav > li > ul > li > a > .fa { width: 1.5em; margin-right: 0.25em; font-size: 1em; line-height: 1em; text-align: center; text-indent: -0.5em; vertical-align: baseline } -#mainMenu .nav > li > ul > li.selected a::before { content: ''; position: absolute; right: 0.25em; top: 0.25em; width: 0.5em; height: 0.5em; background-color: #FFC107; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } +#mainMenu .nav > li > ul > li > a:first-child, #mainMenu .nav > li > ul > li > span { display: block; position: relative; padding: 0 2rem 0 1rem; line-height: 2.2rem; color: #444; text-decoration: none } +#mainMenu .nav > li > ul > li.hover > a:first-child { color: #fff; background-color: #1976d2; } +#mainMenu .nav > li > ul > li > span:first-child { padding: 0 1em; text-align: center; font-size: 0.875em; color: #aaa; } +#mainMenu .nav > li > ul > li .fa { width: 1.3em; margin-right: 0.5em; font-size: .8rem; line-height: .8rem; text-align: center; vertical-align: baseline } +#mainMenu .nav > li > ul > li.selected a:first-child::before { content: ''; position: absolute; right: 0.25em; top: 0.25em; width: 0.5em; height: 0.5em; background-color: #ffc107; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } #mainMenu .nav > li > ul > li.toggle-dropdown > a::after { content: "\f105"; position: absolute; top: 0.6em; right: 0.6em; font: normal normal normal 1.2em/1 FontAwesome; } #mainMenu .nav > li > ul > li.disabled > a { opacity: 0.5; color: #7d2a24; } #mainMenu .nav > li > ul > li.locked > a { font-style: italic } #mainMenu .nav > li > ul > li > a small { line-height: 1em } -#mainMenu .account #msgCounter { display: none; position: absolute; z-index: 1; right: 0.4rem; top: 0.4rem; width: 0.4rem; height: 0.4rem; background-color: #FFC107; font-size: 0; border-radius: 50%;; } +#mainMenu .nav li.item-group { display: table; width: 100%; border-collapse: separate } +#mainMenu .nav li.item-group > * { display: table-cell !important; width: 1%; padding: 0 .75rem; border: none !important; border-left: 1px solid rgba(0, 0, 0, 0.05) !important; border-radius: 0 } +#mainMenu .nav li.item-group > *:first-child { width: 100% } +#mainMenu .nav li.item-group > *:not(:first-child) .fa { margin-right: 0 } +#mainMenu .account #msgCounter { display: none; position: absolute; z-index: 1; right: 0.4rem; top: 0.4rem; width: 0.4rem; height: 0.4rem; background-color: #ffc107; font-size: 0; border-radius: 50%;; } #mainMenu .account #newMail { display: none } /* statusbar */ #statusbar { position: relative; width: 1rem; height: 2.2rem; line-height: 2.4rem; font-size: 0.875em; white-space: nowrap; float: left; } #statusbar .fa { font-size: 0.875rem } #statusbar #buildText, #statusbar #workText { display: none } #statusbar .fa { margin-right: 0.375rem } -#statusbar .fa-warning { color: #F44336 } +#statusbar .fa-warning { color: #f44336 } /* search */ #mainMenu #searchform { position: relative } #mainMenu #searchform label { position: relative; z-index: 1; margin: 0; cursor: pointer; } @@ -66,14 +72,14 @@ #searchresult .ajaxSearchResults a { color: #1377c5; padding: 0.25rem 2rem 0.25rem 1rem; text-decoration: none; } #searchresult .ajaxSearchResults a:hover { color: #333; background-color: #f2f2f2; } #searchresult .ajaxSearchResults a > i { position: absolute; right: 0; top: 50%; width: 2rem; height: 2rem; margin-top: -1rem; line-height: 2rem; text-align: center; } -#searchresult .ajaxSearchResults a.selected { z-index: 1; background-color: #1976D2; color: #fff; font-weight: 700; } +#searchresult .ajaxSearchResults a.selected { z-index: 1; background-color: #1976d2; color: #fff; font-weight: 700; } #searchresult .ajaxSearchResults a .text-danger { color: #333; font-weight: 700 } -#searchresult .ajaxSearchResults a.selected .text-danger { color: #FFC107; text-shadow: 0 0 1px rgba(0, 0, 0, 0.5); } +#searchresult .ajaxSearchResults a.selected .text-danger { color: #ffc107; text-shadow: 0 0 1px rgba(0, 0, 0, 0.5); } @media (min-width: 1020px) { /*#mainMenu #nav > li > a > .fa { font-size: 1.2rem }*/ } @media (max-width: 1020px) { -#mainMenu .nav > li > a, #mainMenu .nav .label_searchid { padding: 0 0.75rem; } +#mainMenu .nav > li > a, #mainMenu .nav > li > ul > li > a, #mainMenu .nav > li > ul > li > span, #mainMenu .nav .label_searchid { padding: 0 0.75rem; } } @media (max-width: 840px) { #mainMenu .nav > li { position: static; } diff --git a/manager/media/style/default/css/page.css b/manager/media/style/default/css/page.css index 0e58c9c58e..efbdbcb23e 100644 --- a/manager/media/style/default/css/page.css +++ b/manager/media/style/default/css/page.css @@ -1,10 +1,11 @@ +@import "../../common/bootstrap/css/bootstrap.min.css?v=4.0.0-alpha.5"; @import "../../common/font-awesome/css/font-awesome.min.css?v=4.7.0"; -@import 'fonts.css?v=1.3.2'; -@import "forms.css?v=1.3.2"; -@import "mainmenu.css?v=1.3.2"; -@import "contextmenu.css"; +@import 'fonts.css?v=1.3.3'; +@import "forms.css?v=1.3.3"; +@import "mainmenu.css?v=1.3.3"; @import "tree.css"; @import "tabpane.css"; +@import "contextmenu.css"; #frameset { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; } #mainMenu, #tree, #main { position: absolute; } #mainMenu { top: 0; left: 0; width: 100%; height: 2.2rem; z-index: 100; } @@ -44,25 +45,26 @@ to { transform: rotate(360deg) } .dark #main { background-color: #ecf0f1 } .dark #mainloader { background-color: rgba(236, 240, 241, 0.64); } /* ElementsInTree */ -.ElementsInTree .treeframebody { background-color: #fafafa !important; border-right: 1px solid rgba(0, 0, 0, .1) } -.ElementsInTree #treeHolder { height: 100%; max-height: 100%; overflow: hidden; padding: 10px } -.ElementsInTree #treeHolder #tabDoc::before { display: none } -.ElementsInTree #treeHolder .actionButtons--eit { top: 3.7rem; right: 1rem } -.ElementsInTree #treeHolder .actionButtons--eit li { float: left; margin: 0 0 0 5px !important; } -.ElementsInTree #treeHolder .actionButtons--eit li a { padding: 0.5rem; } -.ElementsInTree #treeHolder #treePane .tab-page { padding: 0.8rem !important; } -.ElementsInTree #treeHolder #treePane .tab-page .panel-group .panel, .ElementsInTree #treeHolder #treePane #tabDoc.tab-page > div { max-height: calc(100vh - 11rem) !important; overflow: auto; } -.ElementsInTree #treeHolder #treePane .tab-page .panel-group { overflow: visible !important; max-height: none !important; box-sizing: border-box !important } -.ElementsInTree .tab-row { padding: 0; margin-bottom: -1px; } -.ElementsInTree .tab-row .tab { height: 2rem; line-height: 2rem; } -.ElementsInTree .tab-page { background-color: #fff; border: 1px solid #ddd; } -.ElementsInTree .form-control { padding: 0.25rem; font-size: 0.8rem; } +.ElementsInTree #tree .treeframebody { background-color: #fafafa !important; border-right: 1px solid rgba(0, 0, 0, .1) } +.ElementsInTree #tree #treeHolder { height: 100%; max-height: 100%; overflow: hidden; padding: 10px } +.ElementsInTree #tree #tabDoc::before { display: none } +.ElementsInTree #tree .actionButtons--eit { top: 3.7rem; right: 1rem } +.ElementsInTree #tree .actionButtons--eit li { float: left; margin: 0 0 0 5px !important; } +.ElementsInTree #tree .actionButtons--eit li a { padding: 0.5rem; } +.ElementsInTree #tree .tab-page { padding: 0.8rem !important; } +.ElementsInTree #tree .tab-page .panel-group .panel, .ElementsInTree #tree #tabDoc.tab-page > div { max-height: calc(100vh - 11rem) !important; overflow: auto; } +.ElementsInTree #tree .tab-page .panel-group { overflow: visible !important; max-height: none !important; box-sizing: border-box !important } +.ElementsInTree #tree .tab-row { padding: 0; margin-bottom: -1px; } +.ElementsInTree #tree .tab-row .tab { height: 2rem; line-height: 2rem; } +.ElementsInTree #tree .tab-page { background-color: #fff; border: 1px solid #ddd; } +.ElementsInTree #tree .form-control { padding: 0.25rem; font-size: 0.8rem; } +.ElementsInTree #tree .eltree { line-height: 1.5 } +.ElementsInTree #tree .eltree img { width: 0.8em; height: 0.8em } .ElementsInTree.treeframebody { -webkit-box-shadow: none; box-shadow: none } -.ElementsInTree .eltree img { width: 0.8em; height: 0.8em } .dark.ElementsInTree #tree .treeframebody { background-color: #1d2023 !important; color: #828282 } -.dark.ElementsInTree .tab-row .tab { color: #7b7b7b; } -.dark.ElementsInTree .tab-row .tab.selected { background-color: #1d2023; border-color: rgba(255, 255, 255, .1); color: #bfbfbf; } -.dark.ElementsInTree .tab-page { background-color: transparent; border-color: rgba(255, 255, 255, .1) } -.dark.ElementsInTree .form-control { background-color: rgba(0, 0, 0, 0.4); border-color: rgba(255, 255, 255, 0.09); color: #c7c7c7; } -.dark.ElementsInTree a { color: #b7b7b7 } -.dark.ElementsInTree .disabledPlugin a { color: #B68282 } +.dark.ElementsInTree #tree .tab-row .tab { color: #7b7b7b; } +.dark.ElementsInTree #tree .tab-row .tab.selected { background-color: #1d2023; border-color: rgba(255, 255, 255, .1); color: #bfbfbf; } +.dark.ElementsInTree #tree .tab-page { background-color: transparent; border-color: rgba(255, 255, 255, .1) } +.dark.ElementsInTree #tree .form-control { background-color: rgba(0, 0, 0, 0.4); border-color: rgba(255, 255, 255, 0.09); color: #c7c7c7; } +.dark.ElementsInTree #tree a { color: #b7b7b7 } +.dark.ElementsInTree #tree .disabledPlugin a { color: #b68282 } diff --git a/manager/media/style/default/js/modx.js b/manager/media/style/default/js/modx.js index 40f0df689f..2f89cef5fa 100644 --- a/manager/media/style/default/js/modx.js +++ b/manager/media/style/default/js/modx.js @@ -784,8 +784,7 @@ }, toggleTheme: function(e) { var myCodeMirrors = w.main.myCodeMirrors, key; - if(e.currentTarget.classList.contains('rotate180')) { - e.currentTarget.classList.remove('rotate180'); + if(d.body.classList.contains('dark')) { d.body.classList.remove('dark'); w.main.document.body.classList.remove('dark'); d.cookie = 'MODX_themeColor='; @@ -798,7 +797,6 @@ } } } else { - e.currentTarget.classList.add('rotate180'); d.body.classList.add('dark'); w.main.document.body.classList.add('dark'); d.cookie = 'MODX_themeColor=dark'; diff --git a/manager/media/style/default/style.css b/manager/media/style/default/style.css index 2fffc497ef..34ccb96e43 100644 --- a/manager/media/style/default/style.css +++ b/manager/media/style/default/style.css @@ -1,54 +1,55 @@ @import "../common/bootstrap/css/bootstrap.min.css?v=4.0.0-alpha.5"; @import "../common/font-awesome/css/font-awesome.min.css?v=4.7.0"; -@import "css/fonts.css?v=1.3.2"; -@import "css/custom.css?v=1.3.2"; +@import "css/fonts.css?v=1.3.3"; +@import "css/forms.css?v=1.3.3"; +@import "css/custom.css?v=1.3.3"; @import "css/tabpane.css"; @import "css/contextmenu.css"; /* -------------------------[ Misc stuff ]--- */ -.sectionBody fieldset { background: none repeat scroll 0 0 #FDFDFD; border: 1px solid #CCCCCC; padding: 1rem !important; } +.sectionBody fieldset { background: none repeat scroll 0 0 #fdfdfd; border: 1px solid #ccc; padding: 1rem !important; } .sectionBody legend { font-weight: 500; padding: 5px 1rem; background: #fff; border: 1px solid #ccc; -moz-box-shadow: 1px 1px 3px #ccc; -webkit-box-shadow: 1px 1px 3px #ccc; box-shadow: 1px 1px 3px #ccc; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .sectionBody fieldset h3 { font-size: 14px; color: #789; font-weight: 500; padding-bottom: 0; margin-bottom: 0; } -.sectionHeader, .showHideVisible { color: #333; margin: 0 1rem; padding: 5px 3px 5px; zoom: 1; font-weight: 500; text-shadow: 0 1px 0 #FFF; } +.sectionHeader, .showHideVisible { color: #333; margin: 0 1rem; padding: 5px 3px 5px; zoom: 1; font-weight: 500; text-shadow: 0 1px 0 #fff; } .sectionHeader + .sectionBody, .showHideVisible + .sectionBody { margin-top: -1px !important } .tab-page .sectionHeader { margin: 1rem 3px 0; } .sectionBody, .layerVisible { position: relative; } -.tab-page .sectionBody, .tab-page .section .sectionBody, .sectionBody .sectionBody { border-top: 1px solid #CCCCCC; margin: 0 3px 1rem; padding: 7px; } -.section .sectionBody { margin: 0 1rem 1rem; padding: 1rem; background-color: #fff; border: 1px solid #CCCCCC; } +.tab-page .sectionBody, .tab-page .section .sectionBody, .sectionBody .sectionBody { border-top: 1px solid #ccc; margin: 0 3px 1rem; padding: 7px; } +.section .sectionBody { margin: 0 1rem 1rem; padding: 1rem; background-color: #fff; border: 1px solid #ccc; } .sectionBody > p:first-child { margin-left: 1rem; margin-right: 1rem } .showHideVisible, .layerVisible { margin: 0 10px 4px; } .comment { font-size: 11px; color: #999; padding: 4px 0; } -thead, .fancyrow { color: #333; height: 18px !important; background-color: #E4E4E4; } +thead, .fancyrow { color: #333; height: 18px !important; background-color: #e4e4e4; } thead td { color: #333; border-top: 1px solid #fff; } -.fancyrow2 { height: 18px !important; background: #F0A62F repeat-x top; border-bottom: 1px solid #fff; color: #fff; } +.fancyrow2 { height: 18px !important; background: #f0a62f repeat-x top; border-bottom: 1px solid #fff; color: #fff; } .screen { border: 1px solid #ddd; text-align: center; } -.even { background: #D9E7C2; } +.even { background: #d9e7c2; } .odd { background: #fff; } /* -------------------------[ end sortable table ]--- */ .disabledImage { width: 20px; opacity: 0.3; filter: alpha(opacity=30); } .disabledImage img { border: 0; } .editorCell { border-top: 1px solid #808080; text-align: left; vertical-align: baseline; } /* */ -.unpublished a, .unpublish { color: #B68282; font-style: italic; } +.unpublished a, .unpublish { color: #b68282; font-style: italic; } .notInMenuNode { color: #39515d; text-decoration: none; } #treeSplitter { width: 10px; height: 100%; position: absolute; right: -10px; } -.deleted { color: #A52A2A; text-decoration: line-through; } +.deleted { color: #a52a2a; text-decoration: line-through; } label.disabled { color: #aaa; } /* -------------------------[ search bar ]--- */ .searchbar { width: 100%; } .searchbar table { margin-top: -3px; } /*.searchtext { margin-top: -5px !important; height: 18px; padding: 2px; }*/ -.searchbutton { width: 22px; padding: 5px; text-decoration: none; background: #fff; border: 1px solid #D1D8DF; } -.searchbutton:hover { text-decoration: none; background: #fff; border: 1px solid #88939E; } +.searchbutton { width: 22px; padding: 5px; text-decoration: none; background: #fff; border: 1px solid #d1d8df; } +.searchbutton:hover { text-decoration: none; background: #fff; border: 1px solid #88939e; } .searchbutton img { vertical-align: middle; margin: 0; padding: 0 } -.searchtoolbarbtn { text-decoration: none; border: 1px solid #D1D8DF; text-decoration: none !important; background: #fff; padding: 5px 5px 5px 2px; } +.searchtoolbarbtn { text-decoration: none; border: 1px solid #d1d8df; text-decoration: none !important; background: #fff; padding: 5px 5px 5px 2px; } .searchtoolbarbtn img { vertical-align: middle; padding: 3px; } -.searchtoolbarbtn:hover { text-decoration: none; border: 1px solid #88939E; background: #fff; } +.searchtoolbarbtn:hover { text-decoration: none; border: 1px solid #88939e; background: #fff; } /* -------------------------[ home page main links ]--- */ /*a.hometblink, a.hometblink:active, .hometblink { text-decoration: underline; color: #333; font-weight: 500; font-size: 12px; } a.hometblink:hover { text-decoration: underline; color: Gray; }*/ .notice { width: 100%; padding: 5px; border: 1px solid #eee; background-color: #f5f5f5; color: #707070; } /* -------------------------[ Settings Table ]--- */ -.filelist td { border-bottom: 1px solid #C2C3CF; } +.filelist td { border-bottom: 1px solid #c2c3cf; } /* -------------------------[ Tabs ]--- */ .tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } .sectionBody > .tab-pane > .tab-page { padding: 1.3rem; } @@ -62,7 +63,7 @@ a.hometblink:hover { text-decoration: underline; color: Gray; }*/ .sortabletable thead tr { color: #333; font-weight: 500; white-space: nowrap; background-color: #d2d2d2; text-align: left; } .sortabletable tr { background: #fff; } .sortabletable tr.even { background: #f7f7f7; } -.sortabletable tbody tr:hover { background: #E9F0F3; } +.sortabletable tbody tr:hover { background: #e9f0f3; } .sortabletable td, .sortabletable th { padding: 5px !important; border: 1px solid #ccc; } .sortabletable th { text-align: left; cursor: pointer; color: #333; } .sortabletable th a { text-decoration: none; color: #333; } @@ -72,7 +73,7 @@ a.hometblink:hover { text-decoration: underline; color: Gray; }*/ #pagination { margin: 10px 0; } #pagination ul { margin: 10px 0; display: inline; } #pagination li { list-style: none; display: inline; width: 1rem; margin: 0 0 0 1px; } -#pagination li a { padding: 3px 8px; border: 1px solid #D9E7C2; text-decoration: none; color: #333; } +#pagination li a { padding: 3px 8px; border: 1px solid #d9e7c2; text-decoration: none; color: #333; } #pagination li.currentPage a, #pagination li a:hover { color: #060; border: 1px solid #060; } fieldset.tab-page { border: 1px solid #e4e4e4 !important; } h2#edit_document_title { font-size: 0.9rem; color: #f5f5f5; width: 100%; border-bottom: none; padding: 5px 10px; } @@ -83,7 +84,7 @@ fieldset#preview h2.tab { float: right; } .actionButtons li:before, .mmTagList li:before, .rTable li:before, .tab-pane ul li ul li:before, .dashboard li:before, div#idShowHideSocialBox.sectionBody > div.btn-group.ope > ul.dropdown-menu > li:before, .sectionBody .multitv .list li:before { display: none; content: ''; } .actionButtons img { vertical-align: top; margin-top: 1px; filter: alpha(opacity=30); -moz-opacity: 0.3; opacity: 0.3; } .actionButtons:hover img { filter: alpha(opacity=100); -moz-opacity: 1; opacity: 1; } -.actionButtons a:hover { border-color: #999; -moz-box-shadow: 1px 1px 2px #aaa; -webkit-box-shadow: 1px 1px 2px #aaa; box-shadow: 1px 1px 2px #aaa; -webkit-transition: all .3s ease; -moz-transition: all .3s ease; -o-transition: all .3s ease; transition: .3s ease; background: -moz-linear-gradient(#FFFFFF, #F5F5F5); background: -webkit-gradient(linear, 0 0, 0 100%, from(#FFFFFF), to(#F5F5F5)); background: -o-linear-gradient(#FFFFFF, #F5F5F5); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFFFFF, endColorstr=#F5F5F5); +.actionButtons a:hover { border-color: #999; -moz-box-shadow: 1px 1px 2px #aaa; -webkit-box-shadow: 1px 1px 2px #aaa; box-shadow: 1px 1px 2px #aaa; -webkit-transition: all .3s ease; -moz-transition: all .3s ease; -o-transition: all .3s ease; transition: .3s ease; background: -moz-linear-gradient(#fff, #f5f5f5); background: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f5f5f5)); background: -o-linear-gradient(#fff, #f5f5f5); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#fff, endColorstr=#f5f5f5); zoom: 1; text-decoration: none !important; } .actionButtons a:active { background: #92aac4 bottom left; -webkit-box-shadow: 0 0 10px #b8c7d6; -moz-box-shadow: 0 0 10px #b8c7d6; box-shadow: 0 0 10px #b8c7d6; } /*.actionButtons li.primary a, .actionButtons a.primary, .actionButtons a.default { color: #fff; border-color: #658f1a; text-shadow: 0 -1px 0 #2B5F0C; background: #66901b; background: -moz-linear-gradient(#8aae4b, #66901b); background: -webkit-gradient(linear, 0 0, 0 100%, from(#8aae4b), to(#66901b)); background: -o-linear-gradient(#8aae4b, #66901b); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#8aae4b, endColorstr=#66901b); } @@ -193,7 +194,7 @@ strong[style*='color:#EF1D1D'] { color: yellow !important; } code { font-size: inherit; font-family: Consolas, 'Courier New', 'Courier', monospace; background-color: #eee; border: 1px solid #ccc; padding: 1px 2px; } #resourcesPane .disabledPlugin a:hover { color: #aaa; } /* breadcrumbs */ -ul.breadcrumbs { margin: 0 1rem 12px 1rem; padding: 0 0 9px 0; line-height: normal; font-size: 0; border-bottom: 1px dotted #CECACA; } +ul.breadcrumbs { margin: 0 1rem 12px 1rem; padding: 0 0 9px 0; line-height: normal; font-size: 0; border-bottom: 1px dotted #cecaca; } li.breadcrumbs__li { list-style: none; display: inline-block; padding: 0; margin: 0; } a.breadcrumbs__a { font-size: 12px; text-decoration: none; } .breadcrumbs__sep { font-size: 13px; margin: 0 6px; color: #777; } @@ -258,7 +259,7 @@ a.man_el_name:hover { text-decoration: none; } .resourceTable .panel-heading { margin: 0 -1.3rem !important; background-color: #f5f5f5; border-top: 1px dotted #dedede; border-bottom: 1px dotted #dedede; } .resourceTable .panel-title > a { padding: 5px 1.3rem; text-decoration: none } .resourceTable ul.elements { margin: 0 -1.3rem; padding: 0 0 10px 0; } -.resourceTable ul.elements > li { padding: 0 !important; border-bottom: 1px dotted #dedede; border-left: 3px solid #FFF; transition: all 0.1s ease; margin: 0 !important; } +.resourceTable ul.elements > li { padding: 0 !important; border-bottom: 1px dotted #dedede; border-left: 3px solid #fff; transition: all 0.1s ease; margin: 0 !important; } .resourceTable ul.elements > li:hover { background: #f9f9f9; border-left: 3px solid #1377c5; } .resourceTable ul.elements > li::before { display: none } #resourcesPane .panel-group ul { } @@ -287,12 +288,12 @@ ul.elements_buttonbar .fa { font-size: 0.875rem; padding: 1px 1px 0; } .resourceTable.flex .elements_descr { display: block; margin-left: 1.5em; } /* action buttons */ .actionButtons a { float: left; padding: 5px 10px; height: 32px; font-size: 13px; font-weight: 500; } -.actionButtons a, .actionButtons li.primary a, .actionButtons a.primary, .actionButtons a.default { text-shadow: none; background: #fff; color: #555; border: 1px solid #E4E4E4; border-radius: 3px; /*box-shadow: 0 0 0 1px #E4E4E4;*/ box-shadow: none; transition: none; } -.actionButtons a:hover { background: #1377c5; box-shadow: none; border-color: #1377c5; color: #FFF !important; transition: none; } +.actionButtons a, .actionButtons li.primary a, .actionButtons a.primary, .actionButtons a.default { text-shadow: none; background: #fff; color: #555; border: 1px solid #e4e4e4; border-radius: 3px; /*box-shadow: 0 0 0 1px #E4E4E4;*/ box-shadow: none; transition: none; } +.actionButtons a:hover { background: #1377c5; box-shadow: none; border-color: #1377c5; color: #fff !important; transition: none; } .actionButtons a:active { background-color: #3189ba; border-color: #3189ba; } -.actionButtons li.primary a, .actionButtons a.primary { color: #fff; border-color: #32AB9A; background: #32AB9A linear-gradient(#32AB9A, #00948E); } +.actionButtons li.primary a, .actionButtons a.primary { color: #fff; border-color: #32ab9a; background: #32ab9a linear-gradient(#32ab9a, #00948e); } .actionButtons li.primary a:hover, .actionButtons a.primary:hover { background: #2b9385 linear-gradient(#2b9385, #007571); border-color: #2b9385; } -.actionButtons li.primary a:active, .actionButtons a.primary:active { background: #32AB9A; border-color: #32AB9A; } +.actionButtons li.primary a:active, .actionButtons a.primary:active { background: #32ab9a; border-color: #32ab9a; } .actionButtons img { display: none; } #treePane .actionButtons img { display: inline; } .actionButtons--tableheader .fa { font-size: 14px; } @@ -325,7 +326,7 @@ table.actionButtons .searchtext { padding: 5px; height: 24px; width: 150px; } .btn-small { padding: 2px 4px !important; font-size: 11px !important; } .relative { position: relative; } .modx-alert { display: block; margin: 60px 10px 10px 10px; padding: 1em; } -.modx-alert.alert-error { background-color: #ffd0d0; border: 1px solid #ff0000; color: #000; } +.modx-alert.alert-error { background-color: #ffd0d0; border: 1px solid #f00; color: #000; } tr.userIdle td { color: #aaa; } tr.userIdle td strong:before { font-family: "FontAwesome"; font-style: normal; font-weight: normal; color: #aaa; padding: 0 5px 0 0; content: '\f017'; } #modxonline_widget td strong:before { font-family: "FontAwesome"; font-style: normal; font-weight: normal; color: #3d5764; padding: 0 5px 0 0; content: '\f2be'; } From 87bf03d2cc0239f7030f1333a7e458b64c28503b Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 27 Jul 2017 00:42:20 +0300 Subject: [PATCH 081/338] format code --- manager/includes/menu.class.inc.php | 232 ++++++++++++++-------------- 1 file changed, 120 insertions(+), 112 deletions(-) diff --git a/manager/includes/menu.class.inc.php b/manager/includes/menu.class.inc.php index 379475d571..63316ff224 100644 --- a/manager/includes/menu.class.inc.php +++ b/manager/includes/menu.class.inc.php @@ -4,82 +4,86 @@ menu->Build('id','parent','name','link','alt','onclick','permission','target','divider 1/0','menuindex') */ -class EVOmenu { - var $defaults = array(); - var $menu; - var $output; - - function Build($menu, $setting = array()) { - $this->defaults['outerClass'] = 'nav'; - $this->defaults['parentClass'] = 'dropdown'; - $this->defaults['parentLinkClass'] = 'dropdown-toggle'; - $this->defaults['parentLinkAttr'] = 'data-toggle="dropdown"'; - $this->defaults['parentLinkIn'] = ''; - $this->defaults['innerClass'] = 'subnav'; - - $this->defaults = $setting + $this->defaults; - $this->Structurise($menu); - $this->output = $this->DrawSub('main', 0); - echo $this->output; - } - - function Structurise($menu) { - foreach($menu as $key => $row) { - $data[$key] = $row[9]; - } - - array_multisort($data, SORT_ASC, $menu); - - foreach($menu as $key => $value) { - $new[$value[1]][] = $value; - } - - $this->menu = $new; - } - - function DrawSub($parentid, $level) { - global $modx; - - $output = ''; - - if(isset($this->menu[$parentid])) { - - $countChild = 0; - $itemTpl = ' +class EVOmenu +{ + var $defaults = array(); + var $menu; + var $output; + + function Build($menu, $setting = array()) + { + $this->defaults['outerClass'] = 'nav'; + $this->defaults['parentClass'] = 'dropdown'; + $this->defaults['parentLinkClass'] = 'dropdown-toggle'; + $this->defaults['parentLinkAttr'] = 'data-toggle="dropdown"'; + $this->defaults['parentLinkIn'] = ''; + $this->defaults['innerClass'] = 'subnav'; + + $this->defaults = $setting + $this->defaults; + $this->Structurise($menu); + $this->output = $this->DrawSub('main', 0); + echo $this->output; + } + + function Structurise($menu) + { + foreach ($menu as $key => $row) { + $data[$key] = $row[9]; + } + + array_multisort($data, SORT_ASC, $menu); + + foreach ($menu as $key => $value) { + $new[$value[1]][] = $value; + } + + $this->menu = $new; + } + + function DrawSub($parentid, $level) + { + global $modx; + + $output = ''; + + if (isset($this->menu[$parentid])) { + + $countChild = 0; + $itemTpl = '
  • [+itemName+][+DrawSub+]
  • '; - $outerTpl = '
      [+output+]
    '; - foreach($this->menu[$parentid] as $key => $value) { - if($value[6] !== '') { - $permissions = explode(',', $value[6]); - foreach($permissions as $val) { - if(!$modx->hasPermission($val)) { - continue; - } - } - } - - $countChild++; - $id = $value[0]; - $ph['id'] = $id; - $ph['li_class'] = $this->get_li_class($id) . $value[10]; - $ph['href'] = $value[3]; - $ph['alt'] = $value[4]; - $ph['target'] = $value[7]; - $ph['onclick'] = 'setLastClickedElement(0,0);' . $value[5]; - $ph['a_class'] = $this->get_a_class($id); - $ph['LinkAttr'] = $this->getLinkAttr($id); - $ph['itemName'] = $value[2] . $this->getItemName($id); + $outerTpl = '
      [+output+]
    '; + foreach ($this->menu[$parentid] as $key => $value) { + if ($value[6] !== '') { + $permissions = explode(',', $value[6]); + foreach ($permissions as $val) { + if (!$modx->hasPermission($val)) { + continue; + } + } + } + + $countChild++; + $id = $value[0]; + $ph['id'] = $id; + $ph['li_class'] = $this->get_li_class($id) . $value[10]; + $ph['href'] = $value[3]; + $ph['alt'] = $value[4]; + $ph['target'] = $value[7]; + $ph['onclick'] = 'setLastClickedElement(0,0);' . $value[5]; + $ph['a_class'] = $this->get_a_class($id); + $ph['LinkAttr'] = $this->getLinkAttr($id); + $ph['itemName'] = $value[2] . $this->getItemName($id); $ph['DrawSub'] = ''; - if(isset($this->menu[$id])) { + if (isset($this->menu[$id])) { $level++; $ph['DrawSub'] = $this->DrawSub($id, $level); $level--; // Optional buttons - } else if(isset($value[11]) && !empty($value[11])) { + } else if (isset($value[11]) && !empty($value[11])) { $optionalButton = ''; - if(is_array($value[11])) { + if (is_array($value[11])) { foreach ($value[11] as $opt) { $optionalButton .= sprintf('<%s href="%s" class="%s" onclick="%s" title="%s">%s', $opt[0], $opt[1], $opt[2], $opt[3], $opt[4], $opt[5], $opt[0]); } @@ -90,49 +94,53 @@ function DrawSub($parentid, $level) { $ph['DrawSub'] = $optionalButton; } - $output .= $modx->parseText($itemTpl, $ph); - } - - $ph = array(); - if($countChild > 0) { - $ph['id'] = $level == 0 ? $this->defaults['outerClass'] : ''; - $ph['class'] = $level == 0 ? $this->defaults['outerClass'] : $this->defaults['innerClass']; - $ph['output'] = $output; - $output = $modx->parseText($outerTpl, $ph); - } - } - return $output; - } - - function get_li_class($id) { - if(isset($this->menu[$id])) { - return $this->defaults['parentClass'] . ' '; - } else { - return ''; - } - } - - function get_a_class($id) { - if(isset($this->menu[$id])) { - return ' class="' . $this->defaults['parentLinkClass'] . '"'; - } else { - return ''; - } - } - - function getLinkAttr($id) { - if(isset($this->menu[$id])) { - return $this->defaults['parentLinkAttr']; - } else { - return ''; - } - } - - function getItemName($id) { - if(isset($this->menu[$id])) { - return $this->defaults['parentLinkIn']; - } else { - return ''; - } - } + $output .= $modx->parseText($itemTpl, $ph); + } + + $ph = array(); + if ($countChild > 0) { + $ph['id'] = $level == 0 ? $this->defaults['outerClass'] : ''; + $ph['class'] = $level == 0 ? $this->defaults['outerClass'] : $this->defaults['innerClass']; + $ph['output'] = $output; + $output = $modx->parseText($outerTpl, $ph); + } + } + return $output; + } + + function get_li_class($id) + { + if (isset($this->menu[$id])) { + return $this->defaults['parentClass'] . ' '; + } else { + return ''; + } + } + + function get_a_class($id) + { + if (isset($this->menu[$id])) { + return ' class="' . $this->defaults['parentLinkClass'] . '"'; + } else { + return ''; + } + } + + function getLinkAttr($id) + { + if (isset($this->menu[$id])) { + return $this->defaults['parentLinkAttr']; + } else { + return ''; + } + } + + function getItemName($id) + { + if (isset($this->menu[$id])) { + return $this->defaults['parentLinkIn']; + } else { + return ''; + } + } } From 9927da82d945d47e6ccdd2f7d698c674bdccfcad Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 27 Jul 2017 02:49:44 +0300 Subject: [PATCH 082/338] update width columns --- manager/actions/logging.static.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager/actions/logging.static.php b/manager/actions/logging.static.php index ce1008edde..44f1a871b7 100644 --- a/manager/actions/logging.static.php +++ b/manager/actions/logging.static.php @@ -270,11 +270,11 @@ function record_sort($array, $key) - + - + From 94ddd2fd310b3829c5bab6c0c30b3c9a683677e8 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Fri, 21 Jul 2017 23:34:29 +0900 Subject: [PATCH 083/338] Refactor --- install/connection.collation.php | 69 +++++++++++++++++--------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/install/connection.collation.php b/install/connection.collation.php index 4d80000ddd..a91eac19df 100644 --- a/install/connection.collation.php +++ b/install/connection.collation.php @@ -14,41 +14,46 @@ } require_once('lang.php'); -if ($conn = mysqli_connect($host, $uid, $pwd)) { - // get collation - $rs = mysqli_query($conn, "SHOW COLLATION"); - if (mysqli_num_rows($rs) > 0) { - $output = ''; +$conn = mysqli_connect($host, $uid, $pwd); +if(!$conn) exit('can not connect'); + +// get collation +$rs = mysqli_query($conn, "SHOW COLLATION"); +if (mysqli_num_rows($rs) > 0) { + $output = ''; } + echo $output; +exit; + + function sortItem($array=array(),$order='utf8mb4,utf8') { $rs = array('recommend'=>''); From 91a53c458733299d127c6ad5c32238902058bc0b Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 27 Jul 2017 21:02:11 +0300 Subject: [PATCH 084/338] update searchbar refactor code --- manager/actions/eventlog.dynamic.php | 30 +- manager/actions/resource_selector.static.php | 334 +++++++++--------- manager/actions/user_management.static.php | 26 +- .../actions/web_user_management.static.php | 26 +- manager/media/style/default/css/custom.css | 8 +- manager/media/style/default/style.css | 16 +- manager/media/style/default/style.php | 1 + 7 files changed, 220 insertions(+), 221 deletions(-) diff --git a/manager/actions/eventlog.dynamic.php b/manager/actions/eventlog.dynamic.php index 373362f164..597db9afd0 100644 --- a/manager/actions/eventlog.dynamic.php +++ b/manager/actions/eventlog.dynamic.php @@ -109,19 +109,19 @@ function menuAction(a) {
    - +
    pageClass = 'page-item'; $grd->selPageClass = 'page-item active'; $grd->noRecordMsg = $_lang['no_records_found']; - $grd->cssClass = "table data"; + $grd->cssClass = "table data nowrap"; $grd->columnHeaderClass = "tableHeader"; $grd->itemClass = "tableItem"; $grd->altItemClass = "tableAltItem"; $grd->fields = "type,source,createdon,eventid,username"; $grd->columns = $_lang['type'] . " ," . $_lang['source'] . " ," . $_lang['date'] . " ," . $_lang['event_id'] . " ," . $_lang['sysinfo_userid']; - $grd->colWidths = "1%,,150,1%,1%"; + $grd->colWidths = "1%,,1%,1%,1%"; $grd->colAligns = "center,,,center,center"; $grd->colTypes = "template:||template:[+source+]||date: " . $modx->toDateFormat(null, 'formatOnly') . ' %I:%M %p'; if($listmode == '1') { diff --git a/manager/actions/resource_selector.static.php b/manager/actions/resource_selector.static.php index 8e581ea9b5..a83143eab2 100644 --- a/manager/actions/resource_selector.static.php +++ b/manager/actions/resource_selector.static.php @@ -1,37 +1,13 @@ INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('edit_module')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('edit_module')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } $mxla = $modx_lang_attribute ? $modx_lang_attribute : 'en'; -?> - -> - - <?php echo $content["name"] . " " . $_lang['element_selector_title']; ?> - - - " /> - - - - - - -db->escape($query); // select SQL -switch($rt) { - case "snip": - $title = $_lang["snippet"]; - $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_snippets"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); - break; - - case "tpl": - $title = $_lang["template"]; - $ds = $modx->db->select('id,templatename as name,description', $modx->getFullTableName("site_templates"), ($sqlQuery ? "(templatename LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'templatename'); - break; - - case("tv"): - $title = $_lang["tv"]; - $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_tmplvars"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); - break; - - case("chunk"): - $title = $_lang["chunk"]; - $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_htmlsnippets"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); - break; - - case("plug"): - $title = $_lang["plugin"]; - $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_plugins"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); - break; - - case("doc"): - $title = $_lang["resource"]; - $ds = $modx->db->select('id,pagetitle as name,longtitle as description', $modx->getFullTableName("site_content"), ($sqlQuery ? "(pagetitle LIKE '%{$sqlQuery}%') OR (longtitle LIKE '%{$sqlQuery}%')" : ""), 'pagetitle'); - break; +switch ($rt) { + case "snip": + $title = $_lang["snippet"]; + $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_snippets"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); + break; + + case "tpl": + $title = $_lang["template"]; + $ds = $modx->db->select('id,templatename as name,description', $modx->getFullTableName("site_templates"), ($sqlQuery ? "(templatename LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'templatename'); + break; + + case("tv"): + $title = $_lang["tv"]; + $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_tmplvars"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); + break; + + case("chunk"): + $title = $_lang["chunk"]; + $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_htmlsnippets"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); + break; + + case("plug"): + $title = $_lang["plugin"]; + $ds = $modx->db->select('id,name,description', $modx->getFullTableName("site_plugins"), ($sqlQuery ? "(name LIKE '%{$sqlQuery}%') OR (description LIKE '%{$sqlQuery}%')" : ""), 'name'); + break; + + case("doc"): + $title = $_lang["resource"]; + $ds = $modx->db->select('id,pagetitle as name,longtitle as description', $modx->getFullTableName("site_content"), ($sqlQuery ? "(pagetitle LIKE '%{$sqlQuery}%') OR (longtitle LIKE '%{$sqlQuery}%')" : ""), 'pagetitle'); + break; } +include_once MODX_MANAGER_PATH . "includes/header.inc.php"; ?> + +

    + +

    + +
    +
    + + +
    +
    + +
    +
    +
    +
    - - - - - - - - -
    -
    -

    -
    - -
    - - - - - - -
    - -
    - noRecordMsg = $_lang["no_records_found"]; - $grd->cssClass = "grid"; - $grd->columnHeaderClass = "gridHeader"; - $grd->itemClass = "gridItem"; - $grd->altItemClass = "gridAltItem"; - $grd->columns = $_lang["name"] . " ," . $_lang["description"]; - $grd->colTypes = "template: [+value+]"; - $grd->colWidths = "45%"; - $grd->fields = "name,description"; - if($_REQUEST['listmode'] == '1') { - $grd->pageSize = 0; - } - echo $grd->render(); - ?> -
    -
    + + + + + + + + + +
    +
    + +
    +
    + noRecordMsg = $_lang["no_records_found"]; + $grd->cssClass = "table data nowrap"; + $grd->columnHeaderClass = "tableHeader"; + $grd->itemClass = "tableItem"; + $grd->altItemClass = "tableAltItem"; + $grd->columns = $_lang["name"] . " ," . $_lang["description"]; + $grd->colTypes = "template: [+value+]"; + $grd->colWidths = "45%"; + $grd->fields = "name,description"; + if ($_REQUEST['listmode'] == '1') { + $grd->pageSize = 0; + } + echo $grd->render(); + ?> +
    +
    +
    +
    \ No newline at end of file diff --git a/manager/actions/user_management.static.php b/manager/actions/user_management.static.php index 712aef77a1..0e09051be4 100644 --- a/manager/actions/user_management.static.php +++ b/manager/actions/user_management.static.php @@ -104,19 +104,19 @@ function menuAction(a) {
    - +
    - +
    Date: Fri, 28 Jul 2017 07:39:50 +0300 Subject: [PATCH 085/338] update style table nowrap format code --- manager/actions/bkmanager.static.php | 1439 ++++++++++---------- manager/actions/sysinfo.static.php | 21 +- manager/media/style/default/css/custom.css | 3 +- manager/media/style/default/css/fonts.css | 2 +- manager/media/style/default/style.css | 18 +- 5 files changed, 746 insertions(+), 737 deletions(-) diff --git a/manager/actions/bkmanager.static.php b/manager/actions/bkmanager.static.php index 028a369f6b..c7bbab523f 100644 --- a/manager/actions/bkmanager.static.php +++ b/manager/actions/bkmanager.static.php @@ -1,465 +1,473 @@ INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('bk_manager')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('bk_manager')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } $dbase = trim($dbase, '`'); -if(!isset($modx->config['snapshot_path'])) { - if(is_dir(MODX_BASE_PATH . 'temp/backup/')) { - $modx->config['snapshot_path'] = MODX_BASE_PATH . 'temp/backup/'; - } else { - $modx->config['snapshot_path'] = MODX_BASE_PATH . 'assets/backup/'; - } +if (!isset($modx->config['snapshot_path'])) { + if (is_dir(MODX_BASE_PATH . 'temp/backup/')) { + $modx->config['snapshot_path'] = MODX_BASE_PATH . 'temp/backup/'; + } else { + $modx->config['snapshot_path'] = MODX_BASE_PATH . 'assets/backup/'; + } } // Backup Manager by Raymond: $mode = isset($_POST['mode']) ? $_POST['mode'] : ''; -if($mode == 'restore1') { - if(isset($_POST['textarea']) && !empty($_POST['textarea'])) { - $source = trim($_POST['textarea']); - $_SESSION['textarea'] = $source . "\n"; - } else { - $source = file_get_contents($_FILES['sqlfile']['tmp_name']); - } - import_sql($source); - header('Location: index.php?r=9&a=93'); - exit; -} elseif($mode == 'restore2') { - $path = $modx->config['snapshot_path'] . $_POST['filename']; - if(file_exists($path)) { - $source = file_get_contents($path); - import_sql($source); - if(headers_sent()) { - echo "\n"; - } else { - header("Location: index.php?r=9&a=93"); - } - } - exit; -} elseif($mode == 'backup') { - $tables = isset($_POST['chk']) ? $_POST['chk'] : ''; - if(!is_array($tables)) { - $modx->webAlertAndQuit("Please select a valid table from the list below."); - } - - /* - * Code taken from Ralph A. Dahlgren MySQLdumper Snippet - Etomite 0.6 - 2004-09-27 - * Modified by Raymond 3-Jan-2005 - * Perform MySQLdumper data dump - */ - @set_time_limit(120); // set timeout limit to 2 minutes - $dumper = new Mysqldumper($database_server, $database_user, $database_password, $dbase); - $dumper->setDBtables($tables); - $dumper->setDroptables((isset($_POST['droptables']) ? true : false)); - $dumpfinished = $dumper->createDump('dumpSql'); - if($dumpfinished) { - exit; - } else { - $modx->webAlertAndQuit('Unable to Backup Database'); - } - - // MySQLdumper class can be found below -} elseif($mode == 'snapshot') { - if(!is_dir(rtrim($modx->config['snapshot_path'], '/'))) { - mkdir(rtrim($modx->config['snapshot_path'], '/')); - @chmod(rtrim($modx->config['snapshot_path'], '/'), 0777); - } - if(!is_file("{$modx->config['snapshot_path']}.htaccess")) { - $htaccess = "order deny,allow\ndeny from all\n"; - file_put_contents("{$modx->config['snapshot_path']}.htaccess", $htaccess); - } - if(!is_writable(rtrim($modx->config['snapshot_path'], '/'))) { - $modx->webAlertAndQuit(parsePlaceholder($_lang["bkmgr_alert_mkdir"], array('snapshot_path' => $modx->config['snapshot_path']))); - } - $sql = "SHOW TABLE STATUS FROM `{$dbase}` LIKE '" . $modx->db->escape($modx->db->config['table_prefix']) . "%'"; - $rs = $modx->db->query($sql); - $tables = $modx->db->getColumn('Name', $rs); - //$today = $modx->toDateFormat(time()); - //$today = str_replace(array('/',' '), '-', $today); - //$today = str_replace(':', '', $today); - //$today = strtolower($today); - $today = date('Y-m-d_H-i-s'); - global $path; - $path = "{$modx->config['snapshot_path']}{$today}.sql"; - - @set_time_limit(120); // set timeout limit to 2 minutes - $dumper = new Mysqldumper($database_server, $database_user, $database_password, $dbase); - $dumper->setDBtables($tables); - $dumper->setDroptables(true); - $dumpfinished = $dumper->createDump('snapshot'); - - $pattern = "{$modx->config['snapshot_path']}*.sql"; - $files = glob($pattern, GLOB_NOCHECK); - $total = ($files[0] !== $pattern) ? count($files) : 0; - arsort($files); - while(10 < $total && $limit < 50) { - $del_file = array_pop($files); - unlink($del_file); - $total = count($files); - $limit++; - } - - if($dumpfinished) { - $_SESSION['result_msg'] = 'snapshot_ok'; - header("Location: index.php?a=93"); - exit; - } else { - $modx->webAlertAndQuit('Unable to Backup Database'); - } +if ($mode == 'restore1') { + if (isset($_POST['textarea']) && !empty($_POST['textarea'])) { + $source = trim($_POST['textarea']); + $_SESSION['textarea'] = $source . "\n"; + } else { + $source = file_get_contents($_FILES['sqlfile']['tmp_name']); + } + import_sql($source); + header('Location: index.php?r=9&a=93'); + exit; +} elseif ($mode == 'restore2') { + $path = $modx->config['snapshot_path'] . $_POST['filename']; + if (file_exists($path)) { + $source = file_get_contents($path); + import_sql($source); + if (headers_sent()) { + echo "\n"; + } else { + header("Location: index.php?r=9&a=93"); + } + } + exit; +} elseif ($mode == 'backup') { + $tables = isset($_POST['chk']) ? $_POST['chk'] : ''; + if (!is_array($tables)) { + $modx->webAlertAndQuit("Please select a valid table from the list below."); + } + + /* + * Code taken from Ralph A. Dahlgren MySQLdumper Snippet - Etomite 0.6 - 2004-09-27 + * Modified by Raymond 3-Jan-2005 + * Perform MySQLdumper data dump + */ + @set_time_limit(120); // set timeout limit to 2 minutes + $dumper = new Mysqldumper($database_server, $database_user, $database_password, $dbase); + $dumper->setDBtables($tables); + $dumper->setDroptables((isset($_POST['droptables']) ? true : false)); + $dumpfinished = $dumper->createDump('dumpSql'); + if ($dumpfinished) { + exit; + } else { + $modx->webAlertAndQuit('Unable to Backup Database'); + } + + // MySQLdumper class can be found below +} elseif ($mode == 'snapshot') { + if (!is_dir(rtrim($modx->config['snapshot_path'], '/'))) { + mkdir(rtrim($modx->config['snapshot_path'], '/')); + @chmod(rtrim($modx->config['snapshot_path'], '/'), 0777); + } + if (!is_file("{$modx->config['snapshot_path']}.htaccess")) { + $htaccess = "order deny,allow\ndeny from all\n"; + file_put_contents("{$modx->config['snapshot_path']}.htaccess", $htaccess); + } + if (!is_writable(rtrim($modx->config['snapshot_path'], '/'))) { + $modx->webAlertAndQuit(parsePlaceholder($_lang["bkmgr_alert_mkdir"], array('snapshot_path' => $modx->config['snapshot_path']))); + } + $sql = "SHOW TABLE STATUS FROM `{$dbase}` LIKE '" . $modx->db->escape($modx->db->config['table_prefix']) . "%'"; + $rs = $modx->db->query($sql); + $tables = $modx->db->getColumn('Name', $rs); + //$today = $modx->toDateFormat(time()); + //$today = str_replace(array('/',' '), '-', $today); + //$today = str_replace(':', '', $today); + //$today = strtolower($today); + $today = date('Y-m-d_H-i-s'); + global $path; + $path = "{$modx->config['snapshot_path']}{$today}.sql"; + + @set_time_limit(120); // set timeout limit to 2 minutes + $dumper = new Mysqldumper($database_server, $database_user, $database_password, $dbase); + $dumper->setDBtables($tables); + $dumper->setDroptables(true); + $dumpfinished = $dumper->createDump('snapshot'); + + $pattern = "{$modx->config['snapshot_path']}*.sql"; + $files = glob($pattern, GLOB_NOCHECK); + $total = ($files[0] !== $pattern) ? count($files) : 0; + arsort($files); + while (10 < $total && $limit < 50) { + $del_file = array_pop($files); + unlink($del_file); + $total = count($files); + $limit++; + } + + if ($dumpfinished) { + $_SESSION['result_msg'] = 'snapshot_ok'; + header("Location: index.php?a=93"); + exit; + } else { + $modx->webAlertAndQuit('Unable to Backup Database'); + } } else { - include_once MODX_MANAGER_PATH . "includes/header.inc.php"; // start normal header + include_once MODX_MANAGER_PATH . "includes/header.inc.php"; // start normal header } -if(isset($_SESSION['result_msg']) && $_SESSION['result_msg'] != '') { - switch($_SESSION['result_msg']) { - case 'import_ok': - $ph['result_msg_import'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; - $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; - break; - case 'snapshot_ok': - $ph['result_msg_import'] = ''; - $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_snapshot_ok"] . '
    '; - break; - } - $_SESSION['result_msg'] = ''; +if (isset($_SESSION['result_msg']) && $_SESSION['result_msg'] != '') { + switch ($_SESSION['result_msg']) { + case 'import_ok': + $ph['result_msg_import'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; + $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_import_ok"] . '
    '; + break; + case 'snapshot_ok': + $ph['result_msg_import'] = ''; + $ph['result_msg_snapshot'] = '
    ' . $_lang["bkmgr_snapshot_ok"] . '
    '; + break; + } + $_SESSION['result_msg'] = ''; } else { - $ph['result_msg_import'] = ''; - $ph['result_msg_snapshot'] = ''; + $ph['result_msg_import'] = ''; + $ph['result_msg_snapshot'] = ''; } ?> - - -

    - -

    - - - -
    -
    - - -
    -

    - -
    - -

    -

    - - -

    - - - - - - - - - - - - - - - db->escape($modx->db->config['table_prefix']) . "%'"; - $rs = $modx->db->query($sql); - $i = 0; - while($db_status = $modx->db->getRow($rs)) { - //$bgcolor = ($i++ % 2) ? '#EEEEEE' : '#FFFFFF'; - - if(isset($tables)) { - $table_string = implode(',', $table); - } else { - $table_string = ''; - } - - echo '' . "\n" . '' . "\n" . '' . "\n"; - echo '' . "\n"; - - // Enable record deletion for certain tables (TRUNCATE TABLE) if they're not already empty - $truncateable = array( - $modx->db->config['table_prefix'] . 'event_log', - $modx->db->config['table_prefix'] . 'manager_log', - ); - if($modx->hasPermission('settings') && in_array($db_status['Name'], $truncateable) && $db_status['Rows'] > 0) { - echo '' . "\n"; - } else { - echo '' . "\n"; - } - - if($modx->hasPermission('settings')) { - echo '' . "\n"; - } else { - echo '' . "\n"; - } - - echo '' . "\n" . '' . "\n" . '' . "\n" . ""; - - $total = $total + $db_status['Index_length'] + $db_status['Data_length']; - $totaloverhead = $totaloverhead + $db_status['Data_free']; - } - ?> - - - - - - - - - - -
    ' . $db_status['Rows'] . '' . $db_status['Collation'] . '' . '' . $modx->nicesize($db_status['Data_length'] + $db_status['Data_free']) . '' . '' . $modx->nicesize($db_status['Data_length'] + $db_status['Data_free']) . '' . ($db_status['Data_free'] > 0 ? '' . $modx->nicesize($db_status['Data_free']) . '' : '-') . '' . ($db_status['Data_free'] > 0 ? $modx->nicesize($db_status['Data_free']) : '-') . '' . $modx->nicesize($db_status['Data_length'] - $db_status['Data_free']) . '' . $modx->nicesize($db_status['Index_length']) . '' . $modx->nicesize($db_status['Index_length'] + $db_status['Data_length'] + $db_status['Data_free']) . '
      0 ? '' . $modx->nicesize($totaloverhead) . '
    (' . number_format($totaloverhead) . ' B)' : '-' ?>
     " . $modx->nicesize($total) . "
    (" . number_format($total) . " B)" ?>
    - 0) { - echo '

    ' . $_lang['database_overhead'] . '

    '; - } - ?> -
    -
    - - -
    -

    - - -
    - -
    -
    - - - - $v) { - $title[] = $k; - } - $result = '
    ' . implode('', $title) . '
    ' . implode('', $result_value) . '
    ' . $result . '
    '; - } - } - - function checked($cond) { - if($cond) { - return ' checked'; - } - } - - ?> -

    - - -

    -
    -
    - -
    - - - -

    ' . $_lang["bkmgr_run_sql_result"] . '

    ' . $result . ''; - } - ?> - - -
    -

    - - -
    - "snapshot_path={$modx->config['snapshot_path']}")) ?> -
    -
    - - - - - -
    - -
    -
    -
    - - - - config['snapshot_path']}*.sql"; - $files = glob($pattern, GLOB_NOCHECK); - $total = ($files[0] !== $pattern) ? count($files) : 0; - $detailFields = array( - 'MODX Version', - 'Host', - 'Generation Time', - 'Server version', - 'PHP Version', - 'Database', - 'Description' - ); - if(is_array($files) && 0 < $total) { - echo ''; - echo "\n"; - arsort($files); - $tpl = '' . "\n"; - while($file = array_shift($files)) { - $filename = substr($file, strrpos($file, '/') + 1); - $filesize = $modx->nicesize(filesize($file)); - - $file = fopen($file, "r"); - $count = 0; - $details = array(); - while($count < 11) { - $line = fgets($file); - foreach($detailFields as $label) { - $fileLabel = '# ' . $label; - if(strpos($line, $fileLabel) !== false) { - $details[$label] = htmlentities(trim(str_replace(array( - $fileLabel, - ':', - '`' - ), '', $line)), ENT_QUOTES, $modx_manager_charset); - } - } - $count++; - }; - fclose($file); - - $tooltip = "Generation Time: " . $details["Generation Time"] . "\n"; - $tooltip .= "Server version: " . $details["Server version"] . "\n"; - $tooltip .= "PHP Version: " . $details["PHP Version"] . "\n"; - $tooltip .= "Host: " . $details["Host"] . "\n"; - - echo str_replace(array( - '[+filename+]', - '[+filesize+]', - '[+filedesc+]', - '[+modx_version+]', - '[+database_name+]', - '[+tooltip+]' - ), array( - $filename, - $filesize, - $details['Description'], - $details['MODX Version'], - $details['Database'], - $tooltip - ), $tpl); - } - echo '
    {$_lang["files_filename"]}{$_lang["files_filesize"]}{$_lang["description"]}{$_lang["modx_version"]}{$_lang["database_name"]}{$_lang["onlineusers_action"]}
    [+filename+][+filesize+][+filedesc+][+modx_version+][+database_name+]' . $_lang["bkmgr_restore_submit"] . '
    '; - } else { - echo $_lang["bkmgr_snapshot_nothing"]; - } - ?> - -
    -
    -
    - - - - - + + +

    + +

    + + + + +
    + + +
    +

    + + +
    +
    + +
    +

    + + +

    +
    +
    + + + + + + + + + + + + + + + db->escape($modx->db->config['table_prefix']) . "%'"; + $rs = $modx->db->query($sql); + $i = 0; + while ($db_status = $modx->db->getRow($rs)) { + if (isset($tables)) { + $table_string = implode(',', $table); + } else { + $table_string = ''; + } + + echo '' . "\n" . '' . "\n" . '' . "\n"; + echo '' . "\n"; + + // Enable record deletion for certain tables (TRUNCATE TABLE) if they're not already empty + $truncateable = array( + $modx->db->config['table_prefix'] . 'event_log', + $modx->db->config['table_prefix'] . 'manager_log', + ); + if ($modx->hasPermission('settings') && in_array($db_status['Name'], $truncateable) && $db_status['Rows'] > 0) { + echo '' . "\n"; + } else { + echo '' . "\n"; + } + + if ($modx->hasPermission('settings')) { + echo '' . "\n"; + } else { + echo '' . "\n"; + } + + echo '' . "\n" . '' . "\n" . '' . "\n" . ""; + + $total = $total + $db_status['Index_length'] + $db_status['Data_length']; + $totaloverhead = $totaloverhead + $db_status['Data_free']; + } + ?> + + + + + + + + + + +
    ' . $db_status['Rows'] . '' . $db_status['Collation'] . '' . $modx->nicesize($db_status['Data_length'] + $db_status['Data_free']) . '' . '' . $modx->nicesize($db_status['Data_length'] + $db_status['Data_free']) . '' . ($db_status['Data_free'] > 0 ? '' . $modx->nicesize($db_status['Data_free']) . '' : '-') . '' . ($db_status['Data_free'] > 0 ? $modx->nicesize($db_status['Data_free']) : '-') . '' . $modx->nicesize($db_status['Data_length'] - $db_status['Data_free']) . '' . $modx->nicesize($db_status['Index_length']) . '' . $modx->nicesize($db_status['Index_length'] + $db_status['Data_length'] + $db_status['Data_free']) . '
      0 ? '' . $modx->nicesize($totaloverhead) . '
    (' . number_format($totaloverhead) . ' B)' : '-' ?>
     " . $modx->nicesize($total) . "
    (" . number_format($total) . " B)" ?>
    +
    +
    + 0) { ?> +
    +

    + +
    +
    +
    + + +
    +

    + + +
    + +
    + +
    +
    + + + + $v) { + $title[] = $k; + } + $result = '
    ' . implode('', $title) . '
    ' . implode('', $result_value) . '
    ' . $result . '
    '; + } + } + + function checked($cond) + { + if ($cond) { + return ' checked'; + } + } + + ?> +

    + + +

    +
    +
    + +
    + + + +

    ' . $_lang["bkmgr_run_sql_result"] . '

    ' . $result . ''; + } + ?> + + + +
    +

    + + + +
    +
    + "snapshot_path={$modx->config['snapshot_path']}")) ?> +
    +
    + + + +
    + +
    + +
    +
    + +
    + +
    + + + + config['snapshot_path']}*.sql"; + $files = glob($pattern, GLOB_NOCHECK); + $total = ($files[0] !== $pattern) ? count($files) : 0; + $detailFields = array( + 'MODX Version', + 'Host', + 'Generation Time', + 'Server version', + 'PHP Version', + 'Database', + 'Description' + ); + if (is_array($files) && 0 < $total) { + echo ''; + echo "\n"; + arsort($files); + $tpl = '' . "\n"; + while ($file = array_shift($files)) { + $filename = substr($file, strrpos($file, '/') + 1); + $filesize = $modx->nicesize(filesize($file)); + + $file = fopen($file, "r"); + $count = 0; + $details = array(); + while ($count < 11) { + $line = fgets($file); + foreach ($detailFields as $label) { + $fileLabel = '# ' . $label; + if (strpos($line, $fileLabel) !== false) { + $details[$label] = htmlentities(trim(str_replace(array( + $fileLabel, + ':', + '`' + ), '', $line)), ENT_QUOTES, $modx_manager_charset); + } + } + $count++; + }; + fclose($file); + + $tooltip = "Generation Time: " . $details["Generation Time"] . "\n"; + $tooltip .= "Server version: " . $details["Server version"] . "\n"; + $tooltip .= "PHP Version: " . $details["PHP Version"] . "\n"; + $tooltip .= "Host: " . $details["Host"] . "\n"; + + echo str_replace(array( + '[+filename+]', + '[+filesize+]', + '[+filedesc+]', + '[+modx_version+]', + '[+database_name+]', + '[+tooltip+]' + ), array( + $filename, + $filesize, + $details['Description'], + $details['MODX Version'], + $details['Database'], + $tooltip + ), $tpl); + } + echo '
    {$_lang["files_filename"]}{$_lang["files_filesize"]}{$_lang["description"]}{$_lang["modx_version"]}{$_lang["database_name"]}{$_lang["onlineusers_action"]}
    [+filename+][+filesize+][+filedesc+][+modx_version+][+database_name+]' . $_lang["bkmgr_restore_submit"] . '
    '; + } else { + echo $_lang["bkmgr_snapshot_nothing"]; + } + ?> + +
    +
    +
    + + tpDBM.setSelectedIndex( ' . $_GET['tab'] . ' );'; +if (is_numeric($_GET['tab'])) { + echo ''; } include_once "footer.inc.php"; // send footer @@ -480,285 +488,300 @@ function checked($cond) { * **/ -class Mysqldumper { - var $_dbtables; - var $_isDroptables; - var $database_server; - var $dbname; - - function __construct($database_server, $database_user, $database_password, $dbname) { - // Don't drop tables by default. - $this->dbname = $dbname; - $this->setDroptables(false); - } - - function setDroptables($state) { - $this->_isDroptables = $state; - } - - // If set to true, it will generate 'DROP TABLE IF EXISTS'-statements for each table. - - function setDBtables($dbtables) { - $this->_dbtables = $dbtables; - } - - function createDump($callBack) { - global $modx; - - // Set line feed - $lf = "\n"; - $tempfile_path = $modx->config['base_path'] . 'assets/backup/temp.php'; - - $result = $modx->db->query('SHOW TABLES'); - $tables = $this->result2Array(0, $result); - foreach($tables as $tblval) { - $result = $modx->db->query("SHOW CREATE TABLE `{$tblval}`"); - $createtable[$tblval] = $this->result2Array(1, $result); - } - - $version = $modx->getVersionData(); - - // Set header - $output = "#{$lf}"; - $output .= "# " . addslashes($modx->config['site_name']) . " Database Dump{$lf}"; - $output .= "# MODX Version:{$version['version']}{$lf}"; - $output .= "# {$lf}"; - $output .= "# Host: {$this->database_server}{$lf}"; - $output .= "# Generation Time: " . $modx->toDateFormat(time()) . $lf; - $output .= "# Server version: " . $modx->db->getVersion() . $lf; - $output .= "# PHP Version: " . phpversion() . $lf; - $output .= "# Database: `{$this->dbname}`{$lf}"; - $output .= "# Description: " . trim($_REQUEST['backup_title']) . "{$lf}"; - $output .= "#"; - file_put_contents($tempfile_path, $output, FILE_APPEND | LOCK_EX); - $output = ''; - - // Generate dumptext for the tables. - if(isset($this->_dbtables) && count($this->_dbtables)) { - $this->_dbtables = implode(',', $this->_dbtables); - } else { - unset($this->_dbtables); - } - foreach($tables as $tblval) { - // check for selected table - if(isset($this->_dbtables)) { - if(strstr(",{$this->_dbtables},", ",{$tblval},") === false) { - continue; - } - } - if($callBack === 'snapshot') { - /* - switch($tblval) - { - case $modx->db->config['table_prefix'].'event_log': - case $modx->db->config['table_prefix'].'manager_log': - continue 2; - }*/ - if(!preg_match('@^' . $modx->db->config['table_prefix'] . '@', $tblval)) { - continue; - } - } - $output .= "{$lf}{$lf}# --------------------------------------------------------{$lf}{$lf}"; - $output .= "#{$lf}# Table structure for table `{$tblval}`{$lf}"; - $output .= "#{$lf}{$lf}"; - // Generate DROP TABLE statement when client wants it to. - if($this->isDroptables()) { - $output .= "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;{$lf}"; - $output .= "DROP TABLE IF EXISTS `{$tblval}`;{$lf}"; - $output .= "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;{$lf}{$lf}"; - } - $output .= "{$createtable[$tblval][0]};{$lf}"; - $output .= $lf; - $output .= "#{$lf}# Dumping data for table `{$tblval}`{$lf}#{$lf}"; - $result = $modx->db->select('*', $tblval); - $rows = $this->loadObjectList('', $result); - foreach($rows as $row) { - $insertdump = $lf; - $insertdump .= "INSERT INTO `{$tblval}` VALUES ("; - $arr = $this->object2Array($row); - foreach($arr as $key => $value) { - if(is_null($value)) { - $value = 'NULL'; - } else { - $value = addslashes($value); - $value = str_replace(array( - "\r\n", - "\r", - "\n" - ), '\\n', $value); - $value = "'{$value}'"; - } - $insertdump .= $value . ','; - } - $output .= rtrim($insertdump, ',') . ");\n"; - if(1048576 < strlen($output)) { - file_put_contents($tempfile_path, $output, FILE_APPEND | LOCK_EX); - $output = ''; - } - } - file_put_contents($tempfile_path, $output, FILE_APPEND | LOCK_EX); - $output = ''; - } - $output = file_get_contents($tempfile_path); - if(!empty($output)) { - unlink($tempfile_path); - } - - switch($callBack) { - case 'dumpSql': - dumpSql($output); - break; - case 'snapshot': - snapshot($output); - break; - } - return true; - } - - function result2Array($numinarray = 0, $resource) { - global $modx; - $array = array(); - while($row = $modx->db->getRow($resource, 'num')) { - $array[] = $row[$numinarray]; - } - $modx->db->freeResult($resource); - return $array; - } - - // Private function object2Array. - - function isDroptables() { - return $this->_isDroptables; - } - - // Private function loadObjectList. - - function loadObjectList($key = '', $resource) { - global $modx; - $array = array(); - while($row = $modx->db->getRow($resource, 'object')) { - if($key) { - $array[$row->$key] = $row; - } else { - $array[] = $row; - } - } - $modx->db->freeResult($resource); - return $array; - } - - // Private function result2Array. - - function object2Array($obj) { - $array = null; - if(is_object($obj)) { - $array = array(); - foreach(get_object_vars($obj) as $key => $value) { - if(is_object($value)) { - $array[$key] = $this->object2Array($value); - } else { - $array[$key] = $value; - } - } - } - return $array; - } +class Mysqldumper +{ + var $_dbtables; + var $_isDroptables; + var $database_server; + var $dbname; + + function __construct($database_server, $database_user, $database_password, $dbname) + { + // Don't drop tables by default. + $this->dbname = $dbname; + $this->setDroptables(false); + } + + function setDroptables($state) + { + $this->_isDroptables = $state; + } + + // If set to true, it will generate 'DROP TABLE IF EXISTS'-statements for each table. + + function setDBtables($dbtables) + { + $this->_dbtables = $dbtables; + } + + function createDump($callBack) + { + global $modx; + + // Set line feed + $lf = "\n"; + $tempfile_path = $modx->config['base_path'] . 'assets/backup/temp.php'; + + $result = $modx->db->query('SHOW TABLES'); + $tables = $this->result2Array(0, $result); + foreach ($tables as $tblval) { + $result = $modx->db->query("SHOW CREATE TABLE `{$tblval}`"); + $createtable[$tblval] = $this->result2Array(1, $result); + } + + $version = $modx->getVersionData(); + + // Set header + $output = "#{$lf}"; + $output .= "# " . addslashes($modx->config['site_name']) . " Database Dump{$lf}"; + $output .= "# MODX Version:{$version['version']}{$lf}"; + $output .= "# {$lf}"; + $output .= "# Host: {$this->database_server}{$lf}"; + $output .= "# Generation Time: " . $modx->toDateFormat(time()) . $lf; + $output .= "# Server version: " . $modx->db->getVersion() . $lf; + $output .= "# PHP Version: " . phpversion() . $lf; + $output .= "# Database: `{$this->dbname}`{$lf}"; + $output .= "# Description: " . trim($_REQUEST['backup_title']) . "{$lf}"; + $output .= "#"; + file_put_contents($tempfile_path, $output, FILE_APPEND | LOCK_EX); + $output = ''; + + // Generate dumptext for the tables. + if (isset($this->_dbtables) && count($this->_dbtables)) { + $this->_dbtables = implode(',', $this->_dbtables); + } else { + unset($this->_dbtables); + } + foreach ($tables as $tblval) { + // check for selected table + if (isset($this->_dbtables)) { + if (strstr(",{$this->_dbtables},", ",{$tblval},") === false) { + continue; + } + } + if ($callBack === 'snapshot') { + /* + switch($tblval) + { + case $modx->db->config['table_prefix'].'event_log': + case $modx->db->config['table_prefix'].'manager_log': + continue 2; + }*/ + if (!preg_match('@^' . $modx->db->config['table_prefix'] . '@', $tblval)) { + continue; + } + } + $output .= "{$lf}{$lf}# --------------------------------------------------------{$lf}{$lf}"; + $output .= "#{$lf}# Table structure for table `{$tblval}`{$lf}"; + $output .= "#{$lf}{$lf}"; + // Generate DROP TABLE statement when client wants it to. + if ($this->isDroptables()) { + $output .= "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;{$lf}"; + $output .= "DROP TABLE IF EXISTS `{$tblval}`;{$lf}"; + $output .= "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;{$lf}{$lf}"; + } + $output .= "{$createtable[$tblval][0]};{$lf}"; + $output .= $lf; + $output .= "#{$lf}# Dumping data for table `{$tblval}`{$lf}#{$lf}"; + $result = $modx->db->select('*', $tblval); + $rows = $this->loadObjectList('', $result); + foreach ($rows as $row) { + $insertdump = $lf; + $insertdump .= "INSERT INTO `{$tblval}` VALUES ("; + $arr = $this->object2Array($row); + foreach ($arr as $key => $value) { + if (is_null($value)) { + $value = 'NULL'; + } else { + $value = addslashes($value); + $value = str_replace(array( + "\r\n", + "\r", + "\n" + ), '\\n', $value); + $value = "'{$value}'"; + } + $insertdump .= $value . ','; + } + $output .= rtrim($insertdump, ',') . ");\n"; + if (1048576 < strlen($output)) { + file_put_contents($tempfile_path, $output, FILE_APPEND | LOCK_EX); + $output = ''; + } + } + file_put_contents($tempfile_path, $output, FILE_APPEND | LOCK_EX); + $output = ''; + } + $output = file_get_contents($tempfile_path); + if (!empty($output)) { + unlink($tempfile_path); + } + + switch ($callBack) { + case 'dumpSql': + dumpSql($output); + break; + case 'snapshot': + snapshot($output); + break; + } + return true; + } + + function result2Array($numinarray = 0, $resource) + { + global $modx; + $array = array(); + while ($row = $modx->db->getRow($resource, 'num')) { + $array[] = $row[$numinarray]; + } + $modx->db->freeResult($resource); + return $array; + } + + // Private function object2Array. + + function isDroptables() + { + return $this->_isDroptables; + } + + // Private function loadObjectList. + + function loadObjectList($key = '', $resource) + { + global $modx; + $array = array(); + while ($row = $modx->db->getRow($resource, 'object')) { + if ($key) { + $array[$row->$key] = $row; + } else { + $array[] = $row; + } + } + $modx->db->freeResult($resource); + return $array; + } + + // Private function result2Array. + + function object2Array($obj) + { + $array = null; + if (is_object($obj)) { + $array = array(); + foreach (get_object_vars($obj) as $key => $value) { + if (is_object($value)) { + $array[$key] = $this->object2Array($value); + } else { + $array[$key] = $value; + } + } + } + return $array; + } } -function import_sql($source, $result_code = 'import_ok') { - global $modx, $e; - - if($modx->getLockedElements() !== array()) { - $modx->webAlertAndQuit("At least one Resource is still locked or edited right now by any user. Remove locks or ask users to log out before proceeding."); - } - - $settings = getSettings(); - - if(strpos($source, "\r") !== false) { - $source = str_replace(array( - "\r\n", - "\n", - "\r" - ), "\n", $source); - } - $sql_array = preg_split('@;[ \t]*\n@', $source); - foreach($sql_array as $sql_entry) { - $sql_entry = trim($sql_entry, "\r\n; "); - if(empty($sql_entry)) { - continue; - } - $rs = $modx->db->query($sql_entry); - } - restoreSettings($settings); - - $modx->clearCache(); - - $_SESSION['last_result'] = $modx->db->makeArray($rs); - - $_SESSION['result_msg'] = $result_code; +function import_sql($source, $result_code = 'import_ok') +{ + global $modx, $e; + + if ($modx->getLockedElements() !== array()) { + $modx->webAlertAndQuit("At least one Resource is still locked or edited right now by any user. Remove locks or ask users to log out before proceeding."); + } + + $settings = getSettings(); + + if (strpos($source, "\r") !== false) { + $source = str_replace(array( + "\r\n", + "\n", + "\r" + ), "\n", $source); + } + $sql_array = preg_split('@;[ \t]*\n@', $source); + foreach ($sql_array as $sql_entry) { + $sql_entry = trim($sql_entry, "\r\n; "); + if (empty($sql_entry)) { + continue; + } + $rs = $modx->db->query($sql_entry); + } + restoreSettings($settings); + + $modx->clearCache(); + + $_SESSION['last_result'] = $modx->db->makeArray($rs); + + $_SESSION['result_msg'] = $result_code; } -function dumpSql(&$dumpstring) { - global $modx; - $today = $modx->toDateFormat(time(), 'dateOnly'); - $today = str_replace('/', '-', $today); - $today = strtolower($today); - $size = strlen($dumpstring); - if(!headers_sent()) { - header('Expires: 0'); - header('Cache-Control: private'); - header('Pragma: cache'); - header('Content-type: application/download'); - header("Content-Length: {$size}"); - header("Content-Disposition: attachment; filename={$today}_database_backup.sql"); - } - echo $dumpstring; - return true; +function dumpSql(&$dumpstring) +{ + global $modx; + $today = $modx->toDateFormat(time(), 'dateOnly'); + $today = str_replace('/', '-', $today); + $today = strtolower($today); + $size = strlen($dumpstring); + if (!headers_sent()) { + header('Expires: 0'); + header('Cache-Control: private'); + header('Pragma: cache'); + header('Content-type: application/download'); + header("Content-Length: {$size}"); + header("Content-Disposition: attachment; filename={$today}_database_backup.sql"); + } + echo $dumpstring; + return true; } -function snapshot(&$dumpstring) { - global $path; - file_put_contents($path, $dumpstring, FILE_APPEND); - return true; +function snapshot(&$dumpstring) +{ + global $path; + file_put_contents($path, $dumpstring, FILE_APPEND); + return true; } -function getSettings() { - global $modx; - $tbl_system_settings = $modx->getFullTableName('system_settings'); - - $rs = $modx->db->select('setting_name, setting_value', $tbl_system_settings); - - $settings = array(); - while($row = $modx->db->getRow($rs)) { - switch($row['setting_name']) { - case 'rb_base_dir': - case 'filemanager_path': - case 'site_url': - case 'base_url': - $settings[$row['setting_name']] = $row['setting_value']; - break; - } - } - return $settings; +function getSettings() +{ + global $modx; + $tbl_system_settings = $modx->getFullTableName('system_settings'); + + $rs = $modx->db->select('setting_name, setting_value', $tbl_system_settings); + + $settings = array(); + while ($row = $modx->db->getRow($rs)) { + switch ($row['setting_name']) { + case 'rb_base_dir': + case 'filemanager_path': + case 'site_url': + case 'base_url': + $settings[$row['setting_name']] = $row['setting_value']; + break; + } + } + return $settings; } -function restoreSettings($settings) { - global $modx; - $tbl_system_settings = $modx->getFullTableName('system_settings'); +function restoreSettings($settings) +{ + global $modx; + $tbl_system_settings = $modx->getFullTableName('system_settings'); - foreach($settings as $k => $v) { - $modx->db->update(array('setting_value' => $v), $tbl_system_settings, "setting_name='{$k}'"); - } + foreach ($settings as $k => $v) { + $modx->db->update(array('setting_value' => $v), $tbl_system_settings, "setting_name='{$k}'"); + } } -function parsePlaceholder($tpl = '', $ph = array()) { - if(empty($ph) || empty($tpl)) { - return $tpl; - } - - foreach($ph as $k => $v) { - $k = "[+{$k}+]"; - $tpl = str_replace($k, $v, $tpl); - } - return $tpl; +function parsePlaceholder($tpl = '', $ph = array()) +{ + if (empty($ph) || empty($tpl)) { + return $tpl; + } + + foreach ($ph as $k => $v) { + $k = "[+{$k}+]"; + $tpl = str_replace($k, $v, $tpl); + } + return $tpl; } diff --git a/manager/actions/sysinfo.static.php b/manager/actions/sysinfo.static.php index cfd5b7714a..decc8bac43 100644 --- a/manager/actions/sysinfo.static.php +++ b/manager/actions/sysinfo.static.php @@ -52,13 +52,13 @@ function viewPHPInfo()

    Server

    - +
    $value) { ?> - + @@ -81,16 +81,16 @@ function viewPHPInfo()

    -
     
    +
    - - - - - - + + + + + + @@ -144,7 +144,8 @@ function viewPHPInfo() 0) { ?> -

    +
    +

    diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 8dea788ad9..455058b7b5 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -2,6 +2,7 @@ .row { margin-left: -1.3rem; margin-right: -1.3rem } .container { padding-left: 1.3rem; padding-right: 1.3rem; width: 100% } .container-body { padding: 1.3rem } +.tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } /* [ FORMS ] */ .form-row { margin-bottom: 0.25rem; } .form-row.row { margin-left: 0; margin-right: -1rem } @@ -186,7 +187,7 @@ ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0 #helpPane pre { border: 1px solid rgba(0, 0, 0, 0.1); padding: 1em; } /* [ DARK THEME ] */ .dark .section-editor textarea { background-color: #282c34; color: #abb2bf } -.dark .tab-page, .dark .tab-row .tab.selected, .dark .tab-row .tab.selected.hover, .dark .tab-row .tab.selected:before, .dark .tab-row .tab.selected span { background: #f9f9f9; } +.dark .tab-page, .dark .sectionBody .tab-page, .dark .tab-row .tab.selected, .dark .tab-row .tab.selected.hover, .dark .tab-row .tab.selected:before, .dark .tab-row .tab.selected span { background-color: #f9f9f9; } .dark, .dark .resourceTable .panel-heading { background: #ecf0f1 !important; } .dark .resourceTable .panel-heading:hover { background: #ecf0f1 !important; } .dark .multitv .list li.element a.copy, .multitv .list li.element a.remove { background: #f9f9f9 !important; } diff --git a/manager/media/style/default/css/fonts.css b/manager/media/style/default/css/fonts.css index 373493cf69..082df7380f 100644 --- a/manager/media/style/default/css/fonts.css +++ b/manager/media/style/default/css/fonts.css @@ -98,4 +98,4 @@ h1 small { margin-left: 0.5em; line-height: 1em } .messageRead { color: #333; } .messageUnread { color: #3CB371; font-weight: 500; } .element-edit-message { display: none } -.element-edit-message p:last-child { margin-bottom: 0 } +.element-edit-message p:last-child, .element-edit-message-tab p:last-child { margin-bottom: 0 } diff --git a/manager/media/style/default/style.css b/manager/media/style/default/style.css index 5fa1df4611..15f597cf5f 100644 --- a/manager/media/style/default/style.css +++ b/manager/media/style/default/style.css @@ -18,9 +18,6 @@ .sectionBody > p:first-child { margin-left: 1rem; margin-right: 1rem } .showHideVisible, .layerVisible { margin: 0 10px 4px; } .comment { font-size: 11px; color: #999; padding: 4px 0; } -thead, .fancyrow { color: #333; height: 18px !important; background-color: #e4e4e4; } -thead td { color: #333; border-top: 1px solid #fff; } -.fancyrow2 { height: 18px !important; background: #f0a62f repeat-x top; border-bottom: 1px solid #fff; color: #fff; } .screen { border: 1px solid #ddd; text-align: center; } .even { background: #d9e7c2; } .odd { background: #fff; } @@ -34,16 +31,6 @@ thead td { color: #333; border-top: 1px solid #fff; } #treeSplitter { width: 10px; height: 100%; position: absolute; right: -10px; } .deleted { color: #a52a2a; text-decoration: line-through; } label.disabled { color: #aaa; } -/* -------------------------[ search bar ]--- */ -.sectionBody .searchbar { width: 100%; } -.sectionBody .searchbar table { margin-top: -3px; } -/*.searchtext { margin-top: -5px !important; height: 18px; padding: 2px; }*/ -.sectionBody .searchbutton { width: 22px; padding: 5px; text-decoration: none; background: #fff; border: 1px solid #d1d8df; } -.sectionBody .searchbutton:hover { text-decoration: none; background: #fff; border: 1px solid #88939e; } -.sectionBody .searchbutton img { vertical-align: middle; margin: 0; padding: 0 } -.sectionBody .searchtoolbarbtn { text-decoration: none; border: 1px solid #d1d8df; text-decoration: none !important; background: #fff; padding: 5px 5px 5px 2px; } -.sectionBody .searchtoolbarbtn img { vertical-align: middle; padding: 3px; } -.sectionBody .searchtoolbarbtn:hover { text-decoration: none; border: 1px solid #88939e; background: #fff; } /* -------------------------[ home page main links ]--- */ /*a.hometblink, a.hometblink:active, .hometblink { text-decoration: underline; color: #333; font-weight: 500; font-size: 12px; } a.hometblink:hover { text-decoration: underline; color: Gray; }*/ @@ -51,7 +38,7 @@ a.hometblink:hover { text-decoration: underline; color: Gray; }*/ /* -------------------------[ Settings Table ]--- */ .filelist td { border-bottom: 1px solid #c2c3cf; } /* -------------------------[ Tabs ]--- */ -.tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } +.sectionBody .tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } .sectionBody > .tab-pane > .tab-page { padding: 1.3rem; } .sectionHeader { padding: 7px 0px; } .tab-page .sectionBody { padding: 12px 0px; } @@ -87,9 +74,6 @@ fieldset#preview h2.tab { float: right; } .actionButtons a:hover { border-color: #999; -moz-box-shadow: 1px 1px 2px #aaa; -webkit-box-shadow: 1px 1px 2px #aaa; box-shadow: 1px 1px 2px #aaa; -webkit-transition: all .3s ease; -moz-transition: all .3s ease; -o-transition: all .3s ease; transition: .3s ease; background: -moz-linear-gradient(#fff, #f5f5f5); background: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f5f5f5)); background: -o-linear-gradient(#fff, #f5f5f5); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#fff, endColorstr=#f5f5f5); zoom: 1; text-decoration: none !important; } .actionButtons a:active { background: #92aac4 bottom left; -webkit-box-shadow: 0 0 10px #b8c7d6; -moz-box-shadow: 0 0 10px #b8c7d6; box-shadow: 0 0 10px #b8c7d6; } -/*.actionButtons li.primary a, .actionButtons a.primary, .actionButtons a.default { color: #fff; border-color: #658f1a; text-shadow: 0 -1px 0 #2B5F0C; background: #66901b; background: -moz-linear-gradient(#8aae4b, #66901b); background: -webkit-gradient(linear, 0 0, 0 100%, from(#8aae4b), to(#66901b)); background: -o-linear-gradient(#8aae4b, #66901b); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#8aae4b, endColorstr=#66901b); } -.actionButtons li.disabled a { color: #777; border: 0 solid #657587; pointer-events: none; } -.actionButtons li.disabled a img { opacity: .3; filter: alpha(opacity=30); }*/ /* * Generic styles for all form elements */ From 29781a47d929ceea41a8bd66482520441b6d3dcb Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 28 Jul 2017 08:56:54 +0300 Subject: [PATCH 086/338] update viewport --- manager/frames/1.php | 5 ++--- manager/includes/header.inc.php | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/manager/frames/1.php b/manager/frames/1.php index 9645f6cdb5..a4200f7d09 100644 --- a/manager/frames/1.php +++ b/manager/frames/1.php @@ -80,9 +80,8 @@ <?= $site_name ?>- (EVO CMS Manager) - - - + + ', 0); - - -# -# Dumping data for table `site_keywords` -# - - -REPLACE INTO `{PREFIX}site_keywords` VALUES ('1','MODX'); - - -REPLACE INTO `{PREFIX}site_keywords` VALUES ('2','content management system'); - - -REPLACE INTO `{PREFIX}site_keywords` VALUES ('3','Front End Editing'); - - -REPLACE INTO `{PREFIX}site_keywords` VALUES ('4','login'); - - # # Dumping data for table `site_tmplvar_contentvalues` # diff --git a/install/setup.sql b/install/setup.sql index 4e89b503eb..ad1e61ea45 100755 --- a/install/setup.sql +++ b/install/setup.sql @@ -77,15 +77,6 @@ CREATE TABLE IF NOT EXISTS `{PREFIX}event_log` ( KEY `user`(`user`) ) ENGINE=MyISAM COMMENT='Stores event and error logs'; - -CREATE TABLE IF NOT EXISTS `{PREFIX}keyword_xref` ( - `content_id` int(11) NOT NULL default '0', - `keyword_id` int(11) NOT NULL default '0', - KEY `content_id` (`content_id`), - KEY `keyword_id` (`keyword_id`) -) ENGINE=MyISAM COMMENT='Cross reference bewteen keywords and content'; - - CREATE TABLE IF NOT EXISTS `{PREFIX}manager_log` ( `id` int(10) NOT NULL auto_increment, `timestamp` int(20) NOT NULL default '0', @@ -160,8 +151,6 @@ CREATE TABLE IF NOT EXISTS `{PREFIX}site_content` ( `publishedby` int(10) NOT NULL default '0' COMMENT 'ID of user who published the document', `menutitle` varchar(255) NOT NULL DEFAULT '' COMMENT 'Menu title', `donthit` tinyint(1) NOT NULL default '0' COMMENT 'Disable page hit count', - `haskeywords` tinyint(1) NOT NULL default '0' COMMENT 'has links to keywords', - `hasmetatags` tinyint(1) NOT NULL default '0' COMMENT 'has links to meta tags', `privateweb` tinyint(1) NOT NULL default '0' COMMENT 'Private web document', `privatemgr` tinyint(1) NOT NULL default '0' COMMENT 'Private manager document', `content_dispo` tinyint(1) NOT NULL default '0' COMMENT '0-inline, 1-attachment', @@ -176,14 +165,6 @@ CREATE TABLE IF NOT EXISTS `{PREFIX}site_content` ( ) ENGINE=MyISAM COMMENT='Contains the site document tree.'; -CREATE TABLE IF NOT EXISTS `{PREFIX}site_content_metatags` ( - `content_id` int(11) NOT NULL default '0', - `metatag_id` int(11) NOT NULL default '0', - KEY `content_id` (`content_id`), - KEY `metatag_id` (`metatag_id`) -) ENGINE=MyISAM COMMENT='Reference table between meta tags and content'; - - CREATE TABLE IF NOT EXISTS `{PREFIX}site_htmlsnippets` ( `id` int(10) NOT NULL auto_increment, `name` varchar(100) NOT NULL default '', @@ -200,25 +181,6 @@ CREATE TABLE IF NOT EXISTS `{PREFIX}site_htmlsnippets` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM COMMENT='Contains the site chunks.'; - -CREATE TABLE IF NOT EXISTS `{PREFIX}site_keywords` ( - `id` int(11) NOT NULL auto_increment, - `keyword` varchar(40) NOT NULL default '', - PRIMARY KEY (`id`), - UNIQUE KEY `keyword` (`keyword`) -) ENGINE=MyISAM COMMENT='Site keyword list'; - - -CREATE TABLE IF NOT EXISTS `{PREFIX}site_metatags` ( - `id` integer NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL DEFAULT '', - `tag` varchar(50) NOT NULL DEFAULT '' COMMENT 'tag name', - `tagvalue` varchar(255) NOT NULL DEFAULT '', - `http_equiv` tinyint NOT NULL DEFAULT 0 COMMENT '1 - use http_equiv tag style, 0 - use name', - PRIMARY KEY(`id`) -) ENGINE=MyISAM COMMENT='Site meta tags'; - - CREATE TABLE IF NOT EXISTS `{PREFIX}site_modules` ( `id` integer NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL DEFAULT '', @@ -480,8 +442,6 @@ CREATE TABLE IF NOT EXISTS `{PREFIX}user_roles` ( `exec_module` int(1) NOT NULL DEFAULT 0, `view_eventlog` int(1) NOT NULL DEFAULT 0, `delete_eventlog` int(1) NOT NULL DEFAULT 0, - `manage_metatags` int(1) NOT NULL DEFAULT 0 COMMENT 'manage site meta tags and keywords', - `edit_doc_metatags` int(1) NOT NULL DEFAULT 0 COMMENT 'edit document meta tags and keywords' , `new_web_user` int(1) NOT NULL default '0', `edit_web_user` int(1) NOT NULL default '0', `save_web_user` int(1) NOT NULL default '0', @@ -929,9 +889,9 @@ REPLACE INTO `{PREFIX}user_attributes` REPLACE INTO `{PREFIX}user_roles` -(id,name,description,frames,home,view_document,new_document,save_document,publish_document,delete_document,empty_trash,action_ok,logout,help,messages,new_user,edit_user,logs,edit_parser,save_parser,edit_template,settings,credits,new_template,save_template,delete_template,edit_snippet,new_snippet,save_snippet,delete_snippet,edit_chunk,new_chunk,save_chunk,delete_chunk,empty_cache,edit_document,change_password,error_dialog,about,file_manager,save_user,delete_user,save_password,edit_role,save_role,delete_role,new_role,access_permissions,bk_manager,new_plugin,edit_plugin,save_plugin,delete_plugin,new_module,edit_module,save_module,exec_module,delete_module,view_eventlog,delete_eventlog,manage_metatags,edit_doc_metatags,new_web_user,edit_web_user,save_web_user,delete_web_user,web_access_permissions,view_unpublished,import_static,export_static,remove_locks,assets_images,assets_files,change_resourcetype,display_locks,category_manager) VALUES -(2,'Editor','Limited to managing content',1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0), -(3,'Publisher','Editor with expanded permissions including manage users\, update Elements and site settings',1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,1,1,1,1,0); +(id,name,description,frames,home,view_document,new_document,save_document,publish_document,delete_document,empty_trash,action_ok,logout,help,messages,new_user,edit_user,logs,edit_parser,save_parser,edit_template,settings,credits,new_template,save_template,delete_template,edit_snippet,new_snippet,save_snippet,delete_snippet,edit_chunk,new_chunk,save_chunk,delete_chunk,empty_cache,edit_document,change_password,error_dialog,about,file_manager,save_user,delete_user,save_password,edit_role,save_role,delete_role,new_role,access_permissions,bk_manager,new_plugin,edit_plugin,save_plugin,delete_plugin,new_module,edit_module,save_module,exec_module,delete_module,view_eventlog,delete_eventlog,new_web_user,edit_web_user,save_web_user,delete_web_user,web_access_permissions,view_unpublished,import_static,export_static,remove_locks,assets_images,assets_files,change_resourcetype,display_locks,category_manager) VALUES +(2,'Editor','Limited to managing content',1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0), +(3,'Publisher','Editor with expanded permissions including manage users\, update Elements and site settings',1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,0,1,0,0,1,1,1,1,1,0); # ]]non-upgrade-able @@ -988,8 +948,8 @@ INSERT IGNORE INTO `{PREFIX}system_settings` ('theme_refresher',''); REPLACE INTO `{PREFIX}user_roles` -(id,name,description,frames,home,view_document,new_document,save_document,publish_document,delete_document,empty_trash,action_ok,logout,help,messages,new_user,edit_user,logs,edit_parser,save_parser,edit_template,settings,credits,new_template,save_template,delete_template,edit_snippet,new_snippet,save_snippet,delete_snippet,edit_chunk,new_chunk,save_chunk,delete_chunk,empty_cache,edit_document,change_password,error_dialog,about,file_manager,save_user,delete_user,save_password,edit_role,save_role,delete_role,new_role,access_permissions,bk_manager,new_plugin,edit_plugin,save_plugin,delete_plugin,new_module,edit_module,save_module,exec_module,delete_module,view_eventlog,delete_eventlog,manage_metatags,edit_doc_metatags,new_web_user,edit_web_user,save_web_user,delete_web_user,web_access_permissions,view_unpublished,import_static,export_static,remove_locks,assets_images,assets_files,change_resourcetype,display_locks,category_manager) VALUES -(1, 'Administrator', 'Site administrators have full access to all functions',1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); +(id,name,description,frames,home,view_document,new_document,save_document,publish_document,delete_document,empty_trash,action_ok,logout,help,messages,new_user,edit_user,logs,edit_parser,save_parser,edit_template,settings,credits,new_template,save_template,delete_template,edit_snippet,new_snippet,save_snippet,delete_snippet,edit_chunk,new_chunk,save_chunk,delete_chunk,empty_cache,edit_document,change_password,error_dialog,about,file_manager,save_user,delete_user,save_password,edit_role,save_role,delete_role,new_role,access_permissions,bk_manager,new_plugin,edit_plugin,save_plugin,delete_plugin,new_module,edit_module,save_module,exec_module,delete_module,view_eventlog,delete_eventlog,new_web_user,edit_web_user,save_web_user,delete_web_user,web_access_permissions,view_unpublished,import_static,export_static,remove_locks,assets_images,assets_files,change_resourcetype,display_locks,category_manager) VALUES +(1, 'Administrator', 'Site administrators have full access to all functions',1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); # 1 - "Parser Service Events", 2 - "Manager Access Events", 3 - "Web Access Service Events", 4 - "Cache Service Events", 5 - "Template Service Events", 6 - Custom Events @@ -1150,8 +1110,6 @@ UPDATE `{PREFIX}user_roles` SET exec_module=1, view_eventlog = 1, delete_eventlog = 1, - manage_metatags = 1, - edit_doc_metatags = 1, new_web_user = 1, edit_web_user = 1, save_web_user = 1, diff --git a/manager/actions/document_data.static.php b/manager/actions/document_data.static.php index 1f0bffbd66..cbfee5167a 100644 --- a/manager/actions/document_data.static.php +++ b/manager/actions/document_data.static.php @@ -304,46 +304,6 @@ class="' . $_style["icons_move_document"] . '">' . $icon_pub_unpub : '') config['show_meta'] === '1'): - $tbl_keyword_xref = $modx->getFullTableName('keyword_xref'); - $tbl_site_keywords = $modx->getFullTableName('site_keywords'); - $tbl_site_content_metatags = $modx->getFullTableName('site_content_metatags'); - $tbl_site_metatags = $modx->getFullTableName('site_metatags'); - // Get list of current keywords for this document - $keywords = array(); - $rs = $modx->db->select('k.keyword', "{$tbl_site_keywords} AS k, {$tbl_keyword_xref} AS x ", "k.id = x.keyword_id AND x.content_id='{$id}'", 'k.keyword ASC'); - $keywords = $modx->db->getColumn('keyword', $rs); - - // Get list of selected site META tags for this document - $metatags_selected = array(); - $rs = $modx->db->select('meta.id, meta.name, meta.tagvalue', "{$tbl_site_metatags} AS meta LEFT JOIN {$tbl_site_content_metatags} AS sc ON sc.metatag_id = meta.id", "sc.content_id='{$content['id']}'"); - while($row = $modx->db->getRow($rs)) { - $metatags_selected[] = $row['name'] . ': ' . $row['tagvalue'] . ''; - } - ?> - - - - - - - - - diff --git a/manager/actions/manage_metatags.dynamic.php b/manager/actions/manage_metatags.dynamic.php deleted file mode 100644 index eff482c05c..0000000000 --- a/manager/actions/manage_metatags.dynamic.php +++ /dev/null @@ -1,227 +0,0 @@ -INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); -if(!$modx->hasPermission('manage_metatags')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); -} - -// initialize page view state - the $_PAGE object -$modx->manager->initPageViewState(); - -?> - - - - - - -
    - -
    -
    -

    -
    -
    " . $_lang['not_set'] . ")" ?>
    :" . $_lang['not_set'] . ")"; - } - ?>
    :', $metatags_selected); - } else { - echo "(" . $_lang['not_set'] . ")"; - } - ?>
     
    - - - -
    - - - - - - - - - - -

    -

    -

    -

    - " name="cmdsavetag" onclick="addTag()" /> " name="cmdcanceltag" onclick="cancelTag()" />

    -
    -
    -
    - db->select('*', $modx->getFullTableName("site_metatags"), '', 'name'); - include_once MODX_MANAGER_PATH."includes/controls/datagrid.class.php"; - $grd = new DataGrid('',$ds,$number_of_results); // set page size to 0 t show all items - $grd->noRecordMsg = $_lang["no_records_found"]; - $grd->cssClass="grid"; - $grd->columnHeaderClass="gridHeader"; - $grd->itemClass="gridItem"; - $grd->altItemClass="gridAltItem"; - $grd->fields="id,name,tag,tagvalue"; - $grd->columns=$_lang["delete"]." ,".$_lang["name"]." ,".$_lang["tag"]." ,".$_lang["value"]; - $grd->colWidths="40"; - $grd->colAligns="center"; - $grd->colTypes="template:||". - "template:[+value+]"; - echo $grd->render(); - ?> -
    - - - - - -
     
    - " onclick="deleteTag();" /> -
    -
    - - - -
    -
    -

    -db->select('*', $modx->getFullTableName('site_keywords'), '', 'keyword ASC'); - $grd = new DataGrid('',$ds,$number_of_results); // set page size to 0 t show all items - $grd->noRecordMsg = $_lang["no_keywords_found"]; - $grd->cssClass="grid"; - $grd->columnHeaderClass="gridHeader"; - $grd->itemClass="gridItem"; - $grd->altItemClass="gridAltItem"; - $grd->fields="id,keyword,keyword"; - $grd->columns=$_lang["delete"]." ,".$_lang["keyword"]." ,".$_lang["rename"]; - $grd->colWidths="40"; - $grd->colAligns="center"; - $grd->colTypes="template:||". - "template:[+keyword+]||". - "template:"; - echo $grd->render(); -?> - - - - - - - -
     
    -   -   - -
    -
    -
    - - diff --git a/manager/actions/mutate_content.dynamic.php b/manager/actions/mutate_content.dynamic.php index 9544f1ed42..d7aae22a13 100644 --- a/manager/actions/mutate_content.dynamic.php +++ b/manager/actions/mutate_content.dynamic.php @@ -46,11 +46,7 @@ $tbl_member_groups = $modx->getFullTableName('member_groups'); $tbl_membergroup_access = $modx->getFullTableName('membergroup_access'); $tbl_document_groups = $modx->getFullTableName('document_groups'); -$tbl_keyword_xref = $modx->getFullTableName('keyword_xref'); $tbl_site_content = $modx->getFullTableName('site_content'); -$tbl_site_content_metatags = $modx->getFullTableName('site_content_metatags'); -$tbl_site_keywords = $modx->getFullTableName('site_keywords'); -$tbl_site_metatags = $modx->getFullTableName('site_metatags'); $tbl_site_templates = $modx->getFullTableName('site_templates'); $tbl_site_tmplvar_access = $modx->getFullTableName('site_tmplvar_access'); $tbl_site_tmplvar_contentvalues = $modx->getFullTableName('site_tmplvar_contentvalues'); @@ -276,20 +272,6 @@ function checkParentChildRelation(pId, pName) { return true; } - function clearKeywordSelection() { - var opt = document.mutate.elements["keywords[]"].options; - for(var i = 0; i < opt.length; i++) { - opt[i].selected = false; - } - } - - function clearMetatagSelection() { - var opt = document.mutate.elements["metatags[]"].options; - for(var i = 0; i < opt.length; i++) { - opt[i].selected = false; - } - } - var curTemplate = -1; var curTemplateIndex = 0; @@ -1222,82 +1204,9 @@ function SetUrl(url, width, height, alt) { - - - hasPermission('edit_doc_metatags') && $modx->config['show_meta']) { - // get list of site keywords - $keywords = array(); - $ds = $modx->db->select('id, keyword', $tbl_site_keywords, '', 'keyword ASC'); - while($row = $modx->db->getRow($ds)) { - $keywords[$row['id']] = $row['keyword']; - } - // get selected keywords using document's id - if(isset ($content['id']) && count($keywords) > 0) { - $keywords_selected = array(); - $ds = $modx->db->select('keyword_id', $tbl_keyword_xref, "content_id='{$content['id']}'"); - while($row = $modx->db->getRow($ds)) { - $keywords_selected[$row['keyword_id']] = ' selected="selected"'; - } - } - - // get list of site META tags - $metatags = array(); - $ds = $modx->db->select('id, name', $tbl_site_metatags); - while($row = $modx->db->getRow($ds)) { - $metatags[$row['id']] = $row['name']; - } - // get selected META tags using document's id - if(isset ($content['id']) && count($metatags) > 0) { - $metatags_selected = array(); - $ds = $modx->db->select('metatag_id', $tbl_site_content_metatags, "content_id='{$content['id']}'"); - while($row = $modx->db->getRow($ds)) { - $metatags_selected[$row['metatag_id']] = ' selected="selected"'; - } - } - ?> - -
    -

    - - - - - - -


    - - - - -

    - -
    - -

    - -
    - -
    -
    -
    + 'Editing Chunk (HTML Snippet)', '79' => 'Saving Chunk (HTML Snippet)', '80' => 'Deleting Chunk (HTML Snippet)', - '81' => 'Managing keywords', - '81' => 'Managing keywords', '83' => 'Exporting a resource to HTML', '84' => 'Load Element Selector', '85' => 'Create Folder', diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index e7d364e743..3beb08c9a9 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -2071,7 +2071,6 @@ function parseDocumentSource($source) { $source = $this->mergeSettingsContent($source); $source = $this->mergeDocumentContent($source); $source = $this->mergeChunkContent($source); - if ($this->config['show_meta']) $source = $this->mergeDocumentMETATags($source); //TODO: Remove in next major release $source = $this->evalSnippets($source); $source = $this->mergePlaceholderContent($source); diff --git a/manager/includes/extenders/deprecated.functions.inc.php b/manager/includes/extenders/deprecated.functions.inc.php index 76a506ad3a..74a6094ee3 100644 --- a/manager/includes/extenders/deprecated.functions.inc.php +++ b/manager/includes/extenders/deprecated.functions.inc.php @@ -73,61 +73,6 @@ function changePassword($o, $n) { return changeWebUserPassword($o, $n); } // deprecated - function mergeDocumentMETATags($template) { - global $modx; - if ($modx->documentObject['haskeywords'] == 1) { - // insert keywords - $keywords = $modx->getKeywords(); - if (is_array($keywords) && count($keywords) > 0) { - $keywords = implode(", ", $keywords); - $metas= "\t\n"; - } - - // Don't process when cached - $modx->documentObject['haskeywords'] = '0'; - } - if ($modx->documentObject['hasmetatags'] == 1) { - // insert meta tags - $tags= $modx->getMETATags(); - foreach ($tags as $n => $col) { - $tag= strtolower($col['tag']); - $tagvalue= $col['tagvalue']; - $tagstyle= $col['http_equiv'] ? 'http-equiv' : 'name'; - $metas .= "\t\n"; - } - - // Don't process when cached - $modx->documentObject['hasmetatags'] = '0'; - } - if (!empty($metas)) $template = preg_replace("/()/i", "\\1\n\t" . trim($metas), $template); - return $template; - } - - function getMETATags($id= 0) { - global $modx; - if ($id == 0) { - $id= $modx->documentObject['id']; - } - $sql= "SELECT smt.* " . - "FROM " . $modx->getFullTableName("site_metatags") . " smt " . - "INNER JOIN " . $modx->getFullTableName("site_content_metatags") . " cmt ON cmt.metatag_id=smt.id " . - "WHERE cmt.content_id = '$id'"; - $ds= $modx->db->query($sql); - $limit= $modx->db->getRecordCount($ds); - $metatags= array (); - if ($limit > 0) { - for ($i= 0; $i < $limit; $i++) { - $row= $modx->db->getRow($ds); - $metatags[$row['name']]= array ( - "tag" => $row['tag'], - "tagvalue" => $row['tagvalue'], - "http_equiv" => $row['http_equiv'] - ); - } - } - return $metatags; - } - function userLoggedIn() { global $modx; $userdetails= array (); @@ -151,187 +96,6 @@ function userLoggedIn() { } } - function getKeywords($id= 0) { - global $modx; - if ($id == 0) { - $id= $modx->documentObject['id']; - } - $tblKeywords= $modx->getFullTableName('site_keywords'); - $tblKeywordXref= $modx->getFullTableName('keyword_xref'); - $sql= "SELECT keywords.keyword FROM " . $tblKeywords . " AS keywords INNER JOIN " . $tblKeywordXref . " AS xref ON keywords.id=xref.keyword_id WHERE xref.content_id = '$id'"; - $result= $modx->db->query($sql); - $limit= $modx->db->getRecordCount($result); - $keywords= array (); - if ($limit > 0) { - for ($i= 0; $i < $limit; $i++) { - $row= $modx->db->getRow($result); - $keywords[]= $row['keyword']; - } - } - return $keywords; - } - - /*############################################ - Etomite_dbFunctions.php - New database functions for Etomite CMS - Author: Ralph A. Dahlgren - rad14701@yahoo.com - Etomite ID: rad14701 - See documentation for usage details - ############################################*/ - function getIntTableRows($fields= "*", $from= "", $where= "", $sort= "", $dir= "ASC", $limit= "") { - // function to get rows from ANY internal database table - global $modx; - if ($from == "") { - return false; - } else { - $where= ($where != "") ? "WHERE $where" : ""; - $sort= ($sort != "") ? "ORDER BY $sort $dir" : ""; - $limit= ($limit != "") ? "LIMIT $limit" : ""; - $tbl= $modx->getFullTableName($from); - $sql= "SELECT $fields FROM $tbl $where $sort $limit;"; - $result= $modx->db->query($sql); - $resourceArray= array (); - for ($i= 0; $i < @ $modx->db->getRecordCount($result); $i++) { - array_push($resourceArray, @ $modx->db->getRow($result)); - } - return $resourceArray; - } - } - - function putIntTableRow($fields= "", $into= "") { - // function to put a row into ANY internal database table - global $modx; - if (($fields == "") || ($into == "")) { - return false; - } else { - $tbl= $modx->getFullTableName($into); - $sql= "INSERT INTO $tbl SET "; - foreach ($fields as $key => $value) { - $sql .= $key . "="; - if (is_numeric($value)) - $sql .= $value . ","; - else - $sql .= "'" . $value . "',"; - } - $sql= rtrim($sql, ","); - $sql .= ";"; - $result= $modx->db->query($sql); - return $result; - } - } - - function updIntTableRow($fields= "", $into= "", $where= "", $sort= "", $dir= "ASC", $limit= "") { - // function to update a row into ANY internal database table - global $modx; - if (($fields == "") || ($into == "")) { - return false; - } else { - $where= ($where != "") ? "WHERE $where" : ""; - $sort= ($sort != "") ? "ORDER BY $sort $dir" : ""; - $limit= ($limit != "") ? "LIMIT $limit" : ""; - $tbl= $modx->getFullTableName($into); - $sql= "UPDATE $tbl SET "; - foreach ($fields as $key => $value) { - $sql .= $key . "="; - if (is_numeric($value)) - $sql .= $value . ","; - else - $sql .= "'" . $value . "',"; - } - $sql= rtrim($sql, ","); - $sql .= " $where $sort $limit;"; - $result= $modx->db->query($sql); - return $result; - } - } - - function getExtTableRows($host= "", $user= "", $pass= "", $dbase= "", $fields= "*", $from= "", $where= "", $sort= "", $dir= "ASC", $limit= "") { - // function to get table rows from an external MySQL database - global $modx; - if (($host == "") || ($user == "") || ($pass == "") || ($dbase == "") || ($from == "")) { - return false; - } else { - $where= ($where != "") ? "WHERE $where" : ""; - $sort= ($sort != "") ? "ORDER BY $sort $dir" : ""; - $limit= ($limit != "") ? "LIMIT $limit" : ""; - $tbl= $dbase . "." . $from; - $this->dbExtConnect($host, $user, $pass, $dbase); - $sql= "SELECT $fields FROM $tbl $where $sort $limit;"; - $result= $modx->db->query($sql); - $resourceArray= array (); - for ($i= 0; $i < @ $modx->db->getRecordCount($result); $i++) { - array_push($resourceArray, @ $modx->db->getRow($result)); - } - return $resourceArray; - } - } - - function putExtTableRow($host= "", $user= "", $pass= "", $dbase= "", $fields= "", $into= "") { - // function to put a row into an external database table - global $modx; - if (($host == "") || ($user == "") || ($pass == "") || ($dbase == "") || ($fields == "") || ($into == "")) { - return false; - } else { - $this->dbExtConnect($host, $user, $pass, $dbase); - $tbl= $dbase . "." . $into; - $sql= "INSERT INTO $tbl SET "; - foreach ($fields as $key => $value) { - $sql .= $key . "="; - if (is_numeric($value)) - $sql .= $value . ","; - else - $sql .= "'" . $value . "',"; - } - $sql= rtrim($sql, ","); - $sql .= ";"; - $result= $modx->db->query($sql); - return $result; - } - } - - function updExtTableRow($host= "", $user= "", $pass= "", $dbase= "", $fields= "", $into= "", $where= "", $sort= "", $dir= "ASC", $limit= "") { - // function to update a row into an external database table - global $modx; - if (($fields == "") || ($into == "")) { - return false; - } else { - $this->dbExtConnect($host, $user, $pass, $dbase); - $tbl= $dbase . "." . $into; - $where= ($where != "") ? "WHERE $where" : ""; - $sort= ($sort != "") ? "ORDER BY $sort $dir" : ""; - $limit= ($limit != "") ? "LIMIT $limit" : ""; - $sql= "UPDATE $tbl SET "; - foreach ($fields as $key => $value) { - $sql .= $key . "="; - if (is_numeric($value)) - $sql .= $value . ","; - else - $sql .= "'" . $value . "',"; - } - $sql= rtrim($sql, ","); - $sql .= " $where $sort $limit;"; - $result= $modx->db->query($sql); - return $result; - } - } - - function dbExtConnect($host, $user, $pass, $dbase) { - // function to connect to external database - global $modx; - $tstart= $modx->getMicroTime(); - if (@ !$modx->rs= $modx->db->connect($host, $user, $pass)) { - $modx->messageQuit("Failed to create connection to the $dbase database!"); - } else { - $modx->db->selectDb($dbase); - $tend= $modx->getMicroTime(); - $totaltime= $tend - $tstart; - if ($modx->dumpSQL) { - $modx->queryCode .= "
    Database connection" . sprintf("Database connection to %s was created in %2.4f s", $dbase, $totaltime) . "

    "; - } - $modx->queryTime= $modx->queryTime + $totaltime; - } - } - function getFormVars($method= "", $prefix= "", $trim= "", $REQUEST_METHOD) { // function to retrieve form results into an associative array global $modx; diff --git a/manager/index.php b/manager/index.php index cfdc20333d..22a4944d37 100644 --- a/manager/index.php +++ b/manager/index.php @@ -863,17 +863,6 @@ function includeFileProcessor ($filepath,$manager_theme) { include_once(includeFileProcessor("includes/footer.inc.php",$manager_theme)); break; /********************************************************************/ -/* keywords management */ -/********************************************************************/ - case 81: - include_once(includeFileProcessor("includes/header.inc.php",$manager_theme)); - include_once(includeFileProcessor("actions/manage_metatags.dynamic.php",$manager_theme)); - include_once(includeFileProcessor("includes/footer.inc.php",$manager_theme)); - break; - case 82: - include_once(includeFileProcessor("processors/metatags.processor.php",$manager_theme)); - break; -/********************************************************************/ /* Export to file */ /********************************************************************/ case 83: diff --git a/manager/processors/duplicate_content.processor.php b/manager/processors/duplicate_content.processor.php index 428b65dd00..d709c7365a 100755 --- a/manager/processors/duplicate_content.processor.php +++ b/manager/processors/duplicate_content.processor.php @@ -113,8 +113,7 @@ function duplicateDocument($docid, $parent=null, $_toplevel=0) { // Duplicate the Document $newparent = $modx->db->insert($content, $tblsc); - // duplicate document's TVs & Keywords - duplicateKeywords($docid, $newparent); + // duplicate document's TVs duplicateTVs($docid, $newparent); duplicateAccess($docid, $newparent); @@ -134,18 +133,6 @@ function duplicateDocument($docid, $parent=null, $_toplevel=0) { return $newparent; } -// Duplicate Keywords -function duplicateKeywords($oldid,$newid){ - global $modx; - - $tblkw = $modx->getFullTableName('keyword_xref'); - - $modx->db->insert( - array('content_id'=>'', 'keyword_id'=>''), $tblkw, // Insert into - "{$newid}, keyword_id", $tblkw, "content_id='{$oldid}'" // Copy from - ); -} - // Duplicate Document TVs function duplicateTVs($oldid,$newid){ global $modx; diff --git a/manager/processors/metatags.processor.php b/manager/processors/metatags.processor.php deleted file mode 100644 index e4f3cdee4b..0000000000 --- a/manager/processors/metatags.processor.php +++ /dev/null @@ -1,98 +0,0 @@ -INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); -if(!$modx->hasPermission('manage_metatags')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); -} - -// get op code -$opcode = isset($_POST['op']) ? $_POST['op'] : "keys" ; - -// add tag -if($opcode=="addtag") { - list($tag,$http_equiv) = explode(";",$_POST["tag"]); - $f = array( - 'name' => $modx->db->escape($_POST["tagname"]), - 'tag' => $modx->db->escape($tag), - 'tagvalue' => $modx->db->escape($_POST["tagvalue"]), - 'http_equiv' => intval($http_equiv) - ); - if($f["name"] && $f["tagvalue"]) { - $modx->db->insert($f,$modx->getFullTableName("site_metatags")); - } -} -// edit tag -else if($opcode=="edttag") { - $id = intval($_POST["id"]); - list($tag,$http_equiv) = explode(";",$_POST["tag"]); - $f = array( - 'name' => $modx->db->escape($_POST["tagname"]), - 'tag' => $modx->db->escape($tag), - 'tagvalue' => $modx->db->escape($_POST["tagvalue"]), - 'http_equiv' => intval($http_equiv) - ); - if($f["name"] && $f["tagvalue"]) { - $modx->db->update($f,$modx->getFullTableName("site_metatags"),"id='{$id}'"); - } -} -// delete -else if($opcode=="deltag") { - $f = $_POST["tag"]; - if(is_array($f) && count($f)>0) { - $f = $modx->db->escape($f); - $modx->db->delete($modx->getFullTableName("site_metatags"),"id IN('".implode("','",$f)."')"); - } -} -else { - $delete_keywords = isset($_POST['delete_keywords']) ? $_POST['delete_keywords'] : array() ; - $orig_keywords = isset($_POST['orig_keywords']) ? $_POST['orig_keywords'] : array() ; - $rename_keywords = isset($_POST['rename_keywords']) ? $_POST['rename_keywords'] : array() ; - - // do any renaming that has to be done - foreach($orig_keywords as $key => $value) { - if($rename_keywords[$key]!=$value) { - $rs = $modx->db->select('count(*)', $modx->getFullTableName('site_keywords'), "BINARY keyword='".$modx->db->escape($rename_keywords[$key])."'"); - $limit = $modx->db->getValue($rs); - if($limit > 0) { - $modx->webAlertAndQuit("Keyword '{$rename_keywords[$key]}' already been defined!"); - } else { - $modx->db->update( - array( - 'keyword' => $modx->db->escape($rename_keywords[$key]), - ), $modx->getFullTableName('site_keywords'), "keyword='".$modx->db->escape($value)."'"); - } - } - } - - // delete any keywords that need to be deleted - if(count($delete_keywords)>0) { - $keywords_array = array_keys($delete_keywords); - - $modx->db->delete($modx->getFullTableName('keyword_xref'), "keyword_id IN(".implode(",", $keywords_array).")"); - - $modx->db->delete($modx->getFullTableName('site_keywords'), "id IN(".implode(",", $keywords_array).")"); - - } - - // add new keyword - if(!empty($_POST['new_keyword'])) { - $nk = $_POST['new_keyword']; - - $rs = $modx->db->select('count(*)', $modx->getFullTableName('site_keywords'), "keyword='".$modx->db->escape($nk)."'"); - $limit = $modx->db->getValue($rs); - if($limit > 0) { - $modx->webAlertAndQuit("Keyword '{$nk}' already exists!"); - } else { - $modx->db->insert( - array( - 'keyword' => $modx->db->escape($nk), - ), $modx->getFullTableName('site_keywords')); - } - } -} - -// empty cache -$modx->clearCache('full'); - -$header="Location: index.php?a=81"; -header($header); -?> \ No newline at end of file diff --git a/manager/processors/save_content.processor.php b/manager/processors/save_content.processor.php index d0e4e3dd24..aaea75b8ce 100644 --- a/manager/processors/save_content.processor.php +++ b/manager/processors/save_content.processor.php @@ -25,8 +25,6 @@ $unpub_date = $_POST['unpub_date']; $document_groups = (isset($_POST['chkalldocs']) && $_POST['chkalldocs'] == 'on') ? array() : $_POST['docgroups']; $type = $_POST['type']; -$keywords = $_POST['keywords']; -$metatags = $_POST['metatags']; $contentType = $modx->db->escape($_POST['contentType']); $contentdispo = intval($_POST['content_dispo']); $longtitle = $modx->db->escape($_POST['longtitle']); @@ -57,9 +55,7 @@ $tbl_documentgroup_names = $modx->getFullTableName('documentgroup_names'); $tbl_member_groups = $modx->getFullTableName('member_groups'); $tbl_membergroup_access = $modx->getFullTableName('membergroup_access'); -$tbl_keyword_xref = $modx->getFullTableName('keyword_xref'); $tbl_site_content = $modx->getFullTableName('site_content'); -$tbl_site_content_metatags = $modx->getFullTableName('site_content_metatags'); $tbl_site_tmplvar_access = $modx->getFullTableName('site_tmplvar_access'); $tbl_site_tmplvar_contentvalues = $modx->getFullTableName('site_tmplvar_contentvalues'); $tbl_site_tmplvar_templates = $modx->getFullTableName('site_tmplvar_templates'); @@ -402,9 +398,6 @@ $modx->db->update($fields, $tbl_site_content, "id='{$_REQUEST['parent']}'"); } - // save META Keywords - saveMETAKeywords($key); - // invoke OnDocFormSave event $modx->invokeEvent("OnDocFormSave", array ( "mode" => "new", @@ -635,8 +628,6 @@ $modx->db->update($fields, $tbl_site_content, "id='{$oldparent}'"); } - // save META Keywords - saveMETAKeywords($id); // invoke OnDocFormSave event $modx->invokeEvent("OnDocFormSave", array ( @@ -691,40 +682,4 @@ $modx->webAlertAndQuit("No operation set in request."); } -// -- Save META Keywords -- -function saveMETAKeywords($id) { - global $modx, $keywords, $metatags, - $tbl_keyword_xref, - $tbl_site_content, - $tbl_site_content_metatags; - - if ($modx->hasPermission('edit_doc_metatags')) { - // keywords - remove old keywords first - $modx->db->delete($tbl_keyword_xref, "content_id=$id"); - for ($i = 0; $i < count($keywords); $i++) { - $kwid = $keywords[$i]; - $flds = array ( - 'content_id' => $id, - 'keyword_id' => $kwid - ); - $modx->db->insert($flds, $tbl_keyword_xref); - } - // meta tags - remove old tags first - $modx->db->delete($tbl_site_content_metatags, "content_id=$id"); - for ($i = 0; $i < count($metatags); $i++) { - $kwid = $metatags[$i]; - $flds = array ( - 'content_id' => $id, - 'metatag_id' => $kwid - ); - $modx->db->insert($flds, $tbl_site_content_metatags); - } - $flds = array ( - 'haskeywords' => (count($keywords) ? 1 : 0), - 'hasmetatags' => (count($metatags) ? 1 : 0) - ); - $modx->db->update($flds, $tbl_site_content, "id='{$id}'"); - } -} - ?> \ No newline at end of file diff --git a/manager/processors/save_tmplvars.processor.php b/manager/processors/save_tmplvars.processor.php index f068c8dfae..74983969c3 100755 --- a/manager/processors/save_tmplvars.processor.php +++ b/manager/processors/save_tmplvars.processor.php @@ -57,7 +57,7 @@ $modx->webAlertAndQuit(sprintf($_lang['duplicate_name_found_general'], $_lang['tv'], $name), "index.php?a=300"); } // disallow reserved names - if (in_array($name, array('id', 'type', 'contentType', 'pagetitle', 'longtitle', 'description', 'alias', 'link_attributes', 'published', 'pub_date', 'unpub_date', 'parent', 'isfolder', 'introtext', 'content', 'richtext', 'template', 'menuindex', 'searchable', 'cacheable', 'createdby', 'createdon', 'editedby', 'editedon', 'deleted', 'deletedon', 'deletedby', 'publishedon', 'publishedby', 'menutitle', 'donthit', 'haskeywords', 'hasmetatags', 'privateweb', 'privatemgr', 'content_dispo', 'hidemenu', 'alias_visible'))) { + if (in_array($name, array('id', 'type', 'contentType', 'pagetitle', 'longtitle', 'description', 'alias', 'link_attributes', 'published', 'pub_date', 'unpub_date', 'parent', 'isfolder', 'introtext', 'content', 'richtext', 'template', 'menuindex', 'searchable', 'cacheable', 'createdby', 'createdon', 'editedby', 'editedon', 'deleted', 'deletedon', 'deletedby', 'publishedon', 'publishedby', 'menutitle', 'donthit', 'privateweb', 'privatemgr', 'content_dispo', 'hidemenu', 'alias_visible'))) { $_POST['name'] = ''; $modx->manager->saveFormValues(300); $modx->webAlertAndQuit(sprintf($_lang['reserved_name_warning'], $_lang['tv'], $name), "index.php?a=300"); @@ -120,7 +120,7 @@ $modx->webAlertAndQuit(sprintf($_lang['duplicate_name_found_general'], $_lang['tv'], $name), "index.php?a=301&id={$id}"); } // disallow reserved names - if (in_array($name, array('id', 'type', 'contentType', 'pagetitle', 'longtitle', 'description', 'alias', 'link_attributes', 'published', 'pub_date', 'unpub_date', 'parent', 'isfolder', 'introtext', 'content', 'richtext', 'template', 'menuindex', 'searchable', 'cacheable', 'createdby', 'createdon', 'editedby', 'editedon', 'deleted', 'deletedon', 'deletedby', 'publishedon', 'publishedby', 'menutitle', 'donthit', 'haskeywords', 'hasmetatags', 'privateweb', 'privatemgr', 'content_dispo', 'hidemenu', 'alias_visible'))) { + if (in_array($name, array('id', 'type', 'contentType', 'pagetitle', 'longtitle', 'description', 'alias', 'link_attributes', 'published', 'pub_date', 'unpub_date', 'parent', 'isfolder', 'introtext', 'content', 'richtext', 'template', 'menuindex', 'searchable', 'cacheable', 'createdby', 'createdon', 'editedby', 'editedon', 'deleted', 'deletedon', 'deletedby', 'publishedon', 'publishedby', 'menutitle', 'donthit', 'privateweb', 'privatemgr', 'content_dispo', 'hidemenu', 'alias_visible'))) { $modx->manager->saveFormValues(300); $modx->webAlertAndQuit(sprintf($_lang['reserved_name_warning'], $_lang['tv'], $name), "index.php?a=301&id={$id}"); } From 456b6e200b989ae1ac426b21b81a8a2498f8d660 Mon Sep 17 00:00:00 2001 From: Pathologic Date: Tue, 1 Aug 2017 05:24:01 +0300 Subject: [PATCH 126/338] update demo content --- install/setup.data.sql | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/install/setup.data.sql b/install/setup.data.sql index 3536328bd2..48d2abd580 100644 --- a/install/setup.data.sql +++ b/install/setup.data.sql @@ -17,43 +17,43 @@ REPLACE INTO `{PREFIX}documentgroup_names` VALUES ('1','Site Admin Pages','0','0 # Dumping data for table `site_content` # -REPLACE INTO `{PREFIX}site_content` VALUES ('1','document','text/html','Home','Welcome to MODX','Introduction to MODX','index','','1','0','0','0','0','Create and do amazing things with MODX','

    Install successful!

    \n

    You have successfully installed and configured MODX. We hope you find this site an adequate starting configuration for many small business, organization or personal websites; just change the template and content, and you\'ll be good to go! This site is preconfigured with a variety of options we hope are helpful, relevant and just plain cool for many marketing or personal sites:

    \n
      \n
    • Simple Blog. When logged into your site, you\'ll be able to create new entries from the front end. This can also be turned into a News publishing or PR publishing system. View example blog
    • \n
    • Easy Comments. When logged into your site, your registered site users can comment on your posts. View example
    • \n
    • RSS Feeds. Your site visitors can stay up to date using your site feeds. View RSS feed
    • \n
    • Automatic User Registration. Those that wish to comment on blogs must first create an account. This comes pre-configured with a \"Captcha\" anti-robot registration feature. View registration form
    • \n
    • QuickEdit. When you\'re logged into the manager, you can edit a page directly from the front end! More about CMS features
    • \n
    • Integrated Site Search. Allows visitors to search only the pages you wish them to search. Uses Ajax to display results without loading a new page.
    • \n
    • Powerful Navigation Builder. Duplicate or build virtually any navigation system with our dynamic menu builder code. The menu above, for example. More about menu features
    • \n
    • Ajax ready. You\'re on your way to Web 2.0 and AJAX goodness. More about Ajax features
    • \n
    • Custom \"page not found (404)\" page. Help visitors who go astray to find what they\'re looking for. View 404 page
    • \n
    • Contact Us form. A highly configurable contact form you should customize to point to the right email address. Comes pre-configured to prevent mail-form-injection so your site does not become a source for spam. View form
    • \n
    • Newest documents list. Shows your visitor the most recently added pages (configurable).
    • \n
    • Customizable Content Manager. Preview uploaded images, hide or rename fields and lots more. See ManagerManager\'s documentation for details and instructions. Quick start: ManagerManager by default will look for \"rules\" in a Chunk named \"mm_rules\". Simply copy or rename the Chunk named \"mm_demo_rules\" to \"mm_rules\" and try it out!
    • \n
    • phpThumb. Examples to use phpThumb to crop images.
    • \n
    \n

    Full documentation can be found on the official documentation site.

    \n

    To log into the MODX Control Panel and start customizing this site, point your browser to /manager/.

    ','1','{BOOTSTRAP_SQL_ID}','0','1','1','1','1144904400','1','1378084284','0','0','0','0','0','Home','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('1','document','text/html','Home','Welcome to MODX','Introduction to MODX','index','','1','0','0','0','0','Create and do amazing things with MODX','

    Install successful!

    \n

    You have successfully installed and configured MODX. We hope you find this site an adequate starting configuration for many small business, organization or personal websites; just change the template and content, and you\'ll be good to go! This site is preconfigured with a variety of options we hope are helpful, relevant and just plain cool for many marketing or personal sites:

    \n
      \n
    • Simple Blog. When logged into your site, you\'ll be able to create new entries from the front end. This can also be turned into a News publishing or PR publishing system. View example blog
    • \n
    • Easy Comments. When logged into your site, your registered site users can comment on your posts. View example
    • \n
    • RSS Feeds. Your site visitors can stay up to date using your site feeds. View RSS feed
    • \n
    • Automatic User Registration. Those that wish to comment on blogs must first create an account. This comes pre-configured with a \"Captcha\" anti-robot registration feature. View registration form
    • \n
    • QuickEdit. When you\'re logged into the manager, you can edit a page directly from the front end! More about CMS features
    • \n
    • Integrated Site Search. Allows visitors to search only the pages you wish them to search. Uses Ajax to display results without loading a new page.
    • \n
    • Powerful Navigation Builder. Duplicate or build virtually any navigation system with our dynamic menu builder code. The menu above, for example. More about menu features
    • \n
    • Ajax ready. You\'re on your way to Web 2.0 and AJAX goodness. More about Ajax features
    • \n
    • Custom \"page not found (404)\" page. Help visitors who go astray to find what they\'re looking for. View 404 page
    • \n
    • Contact Us form. A highly configurable contact form you should customize to point to the right email address. Comes pre-configured to prevent mail-form-injection so your site does not become a source for spam. View form
    • \n
    • Newest documents list. Shows your visitor the most recently added pages (configurable).
    • \n
    • Customizable Content Manager. Preview uploaded images, hide or rename fields and lots more. See ManagerManager\'s documentation for details and instructions. Quick start: ManagerManager by default will look for \"rules\" in a Chunk named \"mm_rules\". Simply copy or rename the Chunk named \"mm_demo_rules\" to \"mm_rules\" and try it out!
    • \n
    • phpThumb. Examples to use phpThumb to crop images.
    • \n
    \n

    Full documentation can be found on the official documentation site.

    \n

    To log into the MODX Control Panel and start customizing this site, point your browser to /manager/.

    ','1','{BOOTSTRAP_SQL_ID}','0','1','1','1','1144904400','1','1378084284','0','0','0','0','0','Home','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('2','document','text/html','Blog','My Blog','','blog','','1','0','0','0','1','','[[Ditto? &parents=`2` &display=`2` &removeChunk=`Comments` &tpl=`ditto_blog` &paginate=`1` &extenders=`summary,dateFilter` &paginateAlwaysShowLinks=`1` &tagData=`documentTags`]]\n\n

    Showing [+start+] - [+stop+] of [+total+] Articles

    \n\n
    [+previous+] [+pages+] [+next+]
    \n\n
     
    \n\n[[Reflect? &config=`wordpress` &dittoSnippetParameters=`parents:2` &id=`wp` &getDocuments=`1`]]','1','{BOOTSTRAP_SQL_ID}','1','0','0','1','1144904400','1','1159818696','0','0','0','0','0','Blog','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('2','document','text/html','Blog','My Blog','','blog','','1','0','0','0','1','','[[Ditto? &parents=`2` &display=`2` &removeChunk=`Comments` &tpl=`ditto_blog` &paginate=`1` &extenders=`summary,dateFilter` &paginateAlwaysShowLinks=`1` &tagData=`documentTags`]]\n\n

    Showing [+start+] - [+stop+] of [+total+] Articles

    \n\n
    [+previous+] [+pages+] [+next+]
    \n\n
     
    \n\n[[Reflect? &config=`wordpress` &dittoSnippetParameters=`parents:2` &id=`wp` &getDocuments=`1`]]','1','{BOOTSTRAP_SQL_ID}','1','0','0','1','1144904400','1','1159818696','0','0','0','0','0','Blog','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('4','document','text/html','[*loginName*]','Login to Enable to Comments','','login','','1','0','0','0','0','','

    In order to comment on blog entries, you must be a registered user of [(site_name)]. If you haven\'t already registered, you can request an account.

    \n
    [!WebLogin? &tpl=`WebLogin_tplForm` &loginhomeid=`2`!]
    ','1','{BOOTSTRAP_SQL_ID}','9','0','0','1','1144904400','1','1144904400','0','0','0','0','0','[*loginName*]','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('4','document','text/html','[*loginName*]','Login to Enable to Comments','','login','','1','0','0','0','0','','

    In order to comment on blog entries, you must be a registered user of [(site_name)]. If you haven\'t already registered, you can request an account.

    \n
    [!WebLogin? &tpl=`WebLogin_tplForm` &loginhomeid=`2`!]
    ','1','{BOOTSTRAP_SQL_ID}','9','0','0','1','1144904400','1','1144904400','0','0','0','0','0','[*loginName*]','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('5','document','text/html','Request an Account','Sign Up for Full Site Privileges','','request-an-account','','1','0','0','0','0','','[[WebSignup? &tpl=`FormSignup` &groups=`Registered Users`]]','1','{BOOTSTRAP_SQL_ID}','7','0','0','1','1144904400','1','1158320704','0','0','0','0','0','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('5','document','text/html','Request an Account','Sign Up for Full Site Privileges','','request-an-account','','1','0','0','0','0','','[[WebSignup? &tpl=`FormSignup` &groups=`Registered Users`]]','1','{BOOTSTRAP_SQL_ID}','7','0','0','1','1144904400','1','1158320704','0','0','0','0','0','','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('6','document','text/html','Contact Us','Contact [(site_name)]','','contact-us','','1','0','0','0','0','','\n\n[!eForm? \n &formid=`ContactForm`\n &vericode=`1`\n &subject=`[+subject+]`\n &to=`[(emailsender)]` \n &ccsender=`1`\n &tpl=`ContactForm`\n &report=`ContactFormReport`\n &invalidClass=`invalidValue`\n &requiredClass=`requiredValue`\n &gotoid=`46`\n!]\n','0','{BOOTSTRAP_SQL_ID}','5','1','0','1','1144904400','1','1159303922','0','0','0','0','0','Contact us','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('6','document','text/html','Contact Us','Contact [(site_name)]','','contact-us','','1','0','0','0','0','','\n\n[!eForm? \n &formid=`ContactForm`\n &vericode=`1`\n &subject=`[+subject+]`\n &to=`[(emailsender)]` \n &ccsender=`1`\n &tpl=`ContactForm`\n &report=`ContactFormReport`\n &invalidClass=`invalidValue`\n &requiredClass=`requiredValue`\n &gotoid=`46`\n!]\n','0','{BOOTSTRAP_SQL_ID}','5','1','0','1','1144904400','1','1159303922','0','0','0','0','0','Contact us','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('7','document','text/html','404 - Document Not Found','Uh oh ... it\'s a 404! (Page Not Found)','','doc-not-found','','1','0','0','0','0','','

    Looks like you tried to go somewhere that does not exist... perhaps you need to login or you\'d like one of the following pages instead:

    \n\n[[Wayfinder? &startId=`0` &showDescription=`1`]]\n\n

    Want to find it the old fashioned way? Use the site search at the top of this site to find what you seek.

    \n\n','1','{BOOTSTRAP_SQL_ID}','12','0','1','1','1144904400','1','1159301173','0','0','0','0','0','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('7','document','text/html','404 - Document Not Found','Uh oh ... it\'s a 404! (Page Not Found)','','doc-not-found','','1','0','0','0','0','','

    Looks like you tried to go somewhere that does not exist... perhaps you need to login or you\'d like one of the following pages instead:

    \n\n[[Wayfinder? &startId=`0` &showDescription=`1`]]\n\n

    Want to find it the old fashioned way? Use the site search at the top of this site to find what you seek.

    \n\n','1','{BOOTSTRAP_SQL_ID}','12','0','1','1','1144904400','1','1159301173','0','0','0','0','0','','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('8','document','text/html','Search Results','Your Search Results','','search-results','','1','0','0','0','0','','[!AjaxSearch? &showInputForm=`0` &ajaxSearch=`0`!]','0','{BOOTSTRAP_SQL_ID}','10','0','0','1','1144904400','1','1158613055','0','0','0','0','0','','1','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('8','document','text/html','Search Results','Your Search Results','','search-results','','1','0','0','0','0','','[!AjaxSearch? &showInputForm=`0` &ajaxSearch=`0`!]','0','{BOOTSTRAP_SQL_ID}','10','0','0','1','1144904400','1','1158613055','0','0','0','0','0','','1','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('9','document','text/html','Mini-Blog HOWTO','How to Start Posting with MODX Mini-Blogs','','article-1126081344','','1','0','0','2','0','','

    Setting up a mini-blog is relatively simple. Here\'s what you need to do to get started with making new posts:

    \n
      \n
    1. Login to the MODX Control Panel.
    2. \n
    3. Press the plus-sign next to the Blog(2) container resource to see the blog entries posted there.
    4. \n
    5. To make a new Blog entry, simply right-click the Blog container document and choose the \"Create Resource here\" menu option. To edit an existing blog article, right click the entry and choose the \"Edit Resource\" menu option.
    6. \n\n
    7. Write or edit the content and press save, making sure the document is published.
    8. \n
    9. Everything else is automatic; you\'re done!
    10. \n
    \n{{Comments}}','1','{BOOTSTRAP_SQL_ID}','0','1','1','-1','1144904400','1','1378084370','0','0','0','0','0','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('9','document','text/html','Mini-Blog HOWTO','How to Start Posting with MODX Mini-Blogs','','article-1126081344','','1','0','0','2','0','','

    Setting up a mini-blog is relatively simple. Here\'s what you need to do to get started with making new posts:

    \n
      \n
    1. Login to the MODX Control Panel.
    2. \n
    3. Press the plus-sign next to the Blog(2) container resource to see the blog entries posted there.
    4. \n
    5. To make a new Blog entry, simply right-click the Blog container document and choose the \"Create Resource here\" menu option. To edit an existing blog article, right click the entry and choose the \"Edit Resource\" menu option.
    6. \n\n
    7. Write or edit the content and press save, making sure the document is published.
    8. \n
    9. Everything else is automatic; you\'re done!
    10. \n
    \n{{Comments}}','1','{BOOTSTRAP_SQL_ID}','0','1','1','-1','1144904400','1','1378084370','0','0','0','0','0','','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('11','document','text/xml','RSS Feed','[(site_name)] RSS Feed','','feed.rss','','1','0','0','0','0','','[[Ditto? &parents=`2` &format=`rss` &display=`20` &total=`20` &removeChunk=`Comments`]]','0','0','11','0','0','1','1144904400','1','1160062859','0','0','0','0','0','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('11','document','text/xml','RSS Feed','[(site_name)] RSS Feed','','feed.rss','','1','0','0','0','0','','[[Ditto? &parents=`2` &format=`rss` &display=`20` &total=`20` &removeChunk=`Comments`]]','0','0','11','0','0','1','1144904400','1','1160062859','0','0','0','0','0','','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('14','document','text/html','Content Management','Ways to manage content','','cms','','1','0','0','15','0','','

    Manage your content in the backend

    \n

    The Manager is a skinnable feature-packed tool for admin users. You can add extra users and limit what functions they can access. MODX\'s Manager makes creating content and managing templates and reusable elements easy. Modules can be added to work with other datasets or make management tasks easier.

    \n

    Manage your content in the frontend

    \n

    The QuickEdit bar lets manager users edit content whilst browsing the site. Most content fields and template variables can be edited quickly and easily.

    \n

    Enable web users to add content

    \n

    Custom data entry is easy to code using the MODX API - so you can design forms and collect whatever information you need.

    ','1','{BOOTSTRAP_SQL_ID}','3','1','1','1','1144904400','1','1378086298','0','0','0','1378086298','1','Manage Content','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('14','document','text/html','Content Management','Ways to manage content','','cms','','1','0','0','15','0','','

    Manage your content in the backend

    \n

    The Manager is a skinnable feature-packed tool for admin users. You can add extra users and limit what functions they can access. MODX\'s Manager makes creating content and managing templates and reusable elements easy. Modules can be added to work with other datasets or make management tasks easier.

    \n

    Manage your content in the frontend

    \n

    The QuickEdit bar lets manager users edit content whilst browsing the site. Most content fields and template variables can be edited quickly and easily.

    \n

    Enable web users to add content

    \n

    Custom data entry is easy to code using the MODX API - so you can design forms and collect whatever information you need.

    ','1','{BOOTSTRAP_SQL_ID}','3','1','1','1','1144904400','1','1378086298','0','0','0','1378086298','1','Manage Content','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('15','document','text/html','MODX Features','MODX Features','','features','','1','0','0','0','1','','[[Wayfinder?startId=`[*id*]` &outerClass=`topnav`]]','1','{BOOTSTRAP_SQL_ID}','2','1','1','1','1144904400','1','1158452722','0','0','0','1144777367','1','Features','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('15','document','text/html','MODX Features','MODX Features','','features','','1','0','0','0','1','','[[Wayfinder?startId=`[*id*]` &outerClass=`topnav`]]','1','{BOOTSTRAP_SQL_ID}','2','1','1','1','1144904400','1','1158452722','0','0','0','1144777367','1','Features','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('16','document','text/html','Ajax','Ajax and Web 2.0 ready','','ajax','','1','1159264800','0','15','0','','Ajax ready out-of-the-box\n

    MODX empowers users to build engaging sites today, with its pre-integrated Mootools javascript library.

    \n\n

    Check out the Ajax-powered search in this example site. The libraries are also used with QuickEdit, our front-end editing tool.

    \n\n

    Smart integration means the scripts are only included in the document head when needed - no unnecessary bloat on simple pages!

    \n\nWeb 2.0 today\n

    MODX makes child\'s play of building content managed sites with validating, accessible CSS layouts - so web standards compliance is easy. (You can create a site with excessively nested tables too, if you really want to).

    \n','1','{BOOTSTRAP_SQL_ID}','1','1','1','1','1144904400','1','1159307504','0','0','0','0','0','Ajax','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('16','document','text/html','Ajax','Ajax and Web 2.0 ready','','ajax','','1','1159264800','0','15','0','','Ajax ready out-of-the-box\n

    MODX empowers users to build engaging sites today, with its pre-integrated Mootools javascript library.

    \n\n

    Check out the Ajax-powered search in this example site. The libraries are also used with QuickEdit, our front-end editing tool.

    \n\n

    Smart integration means the scripts are only included in the document head when needed - no unnecessary bloat on simple pages!

    \n\nWeb 2.0 today\n

    MODX makes child\'s play of building content managed sites with validating, accessible CSS layouts - so web standards compliance is easy. (You can create a site with excessively nested tables too, if you really want to).

    \n','1','{BOOTSTRAP_SQL_ID}','1','1','1','1','1144904400','1','1159307504','0','0','0','0','0','Ajax','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('18','document','text/html','Just a pretend, older post','This post should in fact be archived','','article-1128398162','','1','0','0','2','0','','

    Not so exciting, after all, eh?

    \n','1','{BOOTSTRAP_SQL_ID}','2','1','1','-1','1144904400','1','1159306886','0','0','0','0','0','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('18','document','text/html','Just a pretend, older post','This post should in fact be archived','','article-1128398162','','1','0','0','2','0','','

    Not so exciting, after all, eh?

    \n','1','{BOOTSTRAP_SQL_ID}','2','1','1','-1','1144904400','1','1159306886','0','0','0','0','0','','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('22','document','text/html','Menus and Lists','Flexible Menus and Lists','','menus','','1','1159178400','0','15','0','','

    Your documents - listed how you want them

    \n

    MODX\'s document data structure has been designed to allow many different routines to redisplay the information in ways that suit your needs, such as a dynamic menu in your template.

    \n

    Since the last release of MODX, the community has produced many great snippets - reusable functions that you can call in your content or template. Two of the most widely useful are Ditto and Wayfinder.

    \n

    Wayfinder - the menu builder

    \n

    Allows you to template every part of the menu. On this site, Wayfinder is being used to generate the drop-down menus, but many types of menus and sitemaps are possible.

    \n

    Ditto - the document lister

    \n

    Uses include listing the most recent blog posts, producing a site map, listing related documents (using a TV filter) and generating an RSS feed. You could even write a menu with it. On this site, Ditto is being used for the blog posts list on the Blog page, and the list on the right of some templates.

    \n

    Unlimited Customization

    \n

    If you can\'t quite get your desired effect using templating and the many options of Ditto and Wayfinder, you can write your own routine, or look for other snippets in the MODX repository. MODX\'s fields for Menu Title, summaries, menu position etc can be used via the API to produce anything you can imagine.

    ','1','{BOOTSTRAP_SQL_ID}','2','1','1','1','1144904400','1','1160148522','0','0','0','0','0','Menus and Lists','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('22','document','text/html','Menus and Lists','Flexible Menus and Lists','','menus','','1','1159178400','0','15','0','','

    Your documents - listed how you want them

    \n

    MODX\'s document data structure has been designed to allow many different routines to redisplay the information in ways that suit your needs, such as a dynamic menu in your template.

    \n

    Since the last release of MODX, the community has produced many great snippets - reusable functions that you can call in your content or template. Two of the most widely useful are Ditto and Wayfinder.

    \n

    Wayfinder - the menu builder

    \n

    Allows you to template every part of the menu. On this site, Wayfinder is being used to generate the drop-down menus, but many types of menus and sitemaps are possible.

    \n

    Ditto - the document lister

    \n

    Uses include listing the most recent blog posts, producing a site map, listing related documents (using a TV filter) and generating an RSS feed. You could even write a menu with it. On this site, Ditto is being used for the blog posts list on the Blog page, and the list on the right of some templates.

    \n

    Unlimited Customization

    \n

    If you can\'t quite get your desired effect using templating and the many options of Ditto and Wayfinder, you can write your own routine, or look for other snippets in the MODX repository. MODX\'s fields for Menu Title, summaries, menu position etc can be used via the API to produce anything you can imagine.

    ','1','{BOOTSTRAP_SQL_ID}','2','1','1','1','1144904400','1','1160148522','0','0','0','0','0','Menus and Lists','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('24','document','text/html','Extendable by design','Extendable by design','','extendable','','1','1159092732','0','15','0','','

    The MODX community has created many add-ons which can be found in the Repository, from image galleries and e-commerce to smaller utilities.

    \n

    Template Variables with Bindings

    \n

    TVs - Template Variables - are powerful extra fields that you can use with your documents. As an example of an advanced template element that returns a different thing dependent on code or data, we created an @BINDING for the name of the Login menu item. This changes the menu name from Login to Logout based on your logged in state. The @BINDING as follows was placed in the default value as: @EVAL if ($modx->getLoginUserID()) return \'Logout\'; else return \'Login\';

    \n

    Using jQuery-effects

    \n

    We used some simple effects to highlight various things on the front/home page to demonstrate how easy it is to create a useful way to draw attention to things. To see them in action on the home page, click the Integrated Site Search, Related Links or Newest Documents headers.

    \n

    Custom Forms

    \n

    To demonstrate how to link to custom forms, we customized the calls to the Webuser Registration system and the Login system.

    \n

    And more

    \n

    Rich Text Editor for blog entries. To make it easier to format blog posts with simple text formatting, we modified the blog to use a custom RTE-enabled Template Variable (TV).

    \n

    Smart-Summary logic. When splitting the full blog/news posts you simply insert a \"<!-- splitter -->\" where you want the break to occur. In addition, if that leaves any important tags open, it will try to match them and close them so it doesn\'t mess up your site layout with unclosed OL, UL or DIV tags.

    ','1','{BOOTSTRAP_SQL_ID}','4','1','1','2','1144904400','1','1159309971','0','0','0','0','0','Extendability','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('24','document','text/html','Extendable by design','Extendable by design','','extendable','','1','1159092732','0','15','0','','

    The MODX community has created many add-ons which can be found in the Repository, from image galleries and e-commerce to smaller utilities.

    \n

    Template Variables with Bindings

    \n

    TVs - Template Variables - are powerful extra fields that you can use with your documents. As an example of an advanced template element that returns a different thing dependent on code or data, we created an @BINDING for the name of the Login menu item. This changes the menu name from Login to Logout based on your logged in state. The @BINDING as follows was placed in the default value as: @EVAL if ($modx->getLoginUserID()) return \'Logout\'; else return \'Login\';

    \n

    Using jQuery-effects

    \n

    We used some simple effects to highlight various things on the front/home page to demonstrate how easy it is to create a useful way to draw attention to things. To see them in action on the home page, click the Integrated Site Search, Related Links or Newest Documents headers.

    \n

    Custom Forms

    \n

    To demonstrate how to link to custom forms, we customized the calls to the Webuser Registration system and the Login system.

    \n

    And more

    \n

    Rich Text Editor for blog entries. To make it easier to format blog posts with simple text formatting, we modified the blog to use a custom RTE-enabled Template Variable (TV).

    \n

    Smart-Summary logic. When splitting the full blog/news posts you simply insert a \"<!-- splitter -->\" where you want the break to occur. In addition, if that leaves any important tags open, it will try to match them and close them so it doesn\'t mess up your site layout with unclosed OL, UL or DIV tags.

    ','1','{BOOTSTRAP_SQL_ID}','4','1','1','2','1144904400','1','1159309971','0','0','0','0','0','Extendability','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('32','document','text/html','Design','Site Design','','design','','1','0','0','0','0','','

    Credits

    \n

    The MODX Starter-theme is based on Bootstrap 3.3.6 and made by graffx.nl and fuseit.de.

    ','1','{BOOTSTRAP_SQL_ID}','4','1','1','2','1144904400','1','1160112322','0','0','0','1144912754','1','Design','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('32','document','text/html','Design','Site Design','','design','','1','0','0','0','0','','

    Credits

    \n

    The MODX Starter-theme is based on Bootstrap 3.3.6 and made by graffx.nl and fuseit.de.

    ','1','{BOOTSTRAP_SQL_ID}','4','1','1','2','1144904400','1','1160112322','0','0','0','1144912754','1','Design','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('33','document','text/html','Getting Help','Getting Help with MODX','','getting-help','','1','0','0','0','0','','

    The team behind MODX strives to constantly add to and refine the documentation to help you get up to speed with MODX:

    \n
      \n
    • For basic instructions on integrating custom templates into MODX, please see the Designer\'s Guide.
    • \n
    • For an introduction to working in MODX from the content editors perspectve, see the Content Editor\'s Guide.
    • \n
    • For a detailed overview of the backend "manager" and setting up Users and Groups, please peruse the Administration Guide.
    • \n
    • For developers, architecture and API documentation can be found in the Developer\'s Guide.
    • \n
    • And if someone has installed this site for you, but you\'re curious as to the steps they went through, please see the Getting Started Guide.
    • \n
    \n\n

    And don\'t forget, you can always learn and ask questions at the MODX forums. \n','1','{BOOTSTRAP_SQL_ID}','3','1','1','2','1144904400','2','1144904400','0','0','0','0','0','Getting Help','0','0','0','0','0','0','0','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('33','document','text/html','Getting Help','Getting Help with MODX','','getting-help','','1','0','0','0','0','','

    The team behind MODX strives to constantly add to and refine the documentation to help you get up to speed with MODX:

    \n
      \n
    • For basic instructions on integrating custom templates into MODX, please see the Designer\'s Guide.
    • \n
    • For an introduction to working in MODX from the content editors perspectve, see the Content Editor\'s Guide.
    • \n
    • For a detailed overview of the backend "manager" and setting up Users and Groups, please peruse the Administration Guide.
    • \n
    • For developers, architecture and API documentation can be found in the Developer\'s Guide.
    • \n
    • And if someone has installed this site for you, but you\'re curious as to the steps they went through, please see the Getting Started Guide.
    • \n
    \n\n

    And don\'t forget, you can always learn and ask questions at the MODX forums. \n','1','{BOOTSTRAP_SQL_ID}','3','1','1','2','1144904400','2','1144904400','0','0','0','0','0','Getting Help','0','0','0','0','0','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('37','document','text/html','[*loginName*]','The page you\'re trying to reach requires a login','','blog-login','','1','0','0','0','0','','

    In order to add a blog entry, you must be logged in as a Site Admin webuser. Also, commenting on posts requires a login. Contact the site owner for permissions to create new post, or create a web user account to automatically receive commenting privileges. If you already have an account, please login below.

    \n\n[!WebLogin? &tpl=`WebLogin_tplForm` &loginhomeid=`3`!]','1','{BOOTSTRAP_SQL_ID}','8','0','0','1','1144904400','1','1158599931','0','0','0','0','0','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('37','document','text/html','[*loginName*]','The page you\'re trying to reach requires a login','','blog-login','','1','0','0','0','0','','

    In order to add a blog entry, you must be logged in as a Site Admin webuser. Also, commenting on posts requires a login. Contact the site owner for permissions to create new post, or create a web user account to automatically receive commenting privileges. If you already have an account, please login below.

    \n\n[!WebLogin? &tpl=`WebLogin_tplForm` &loginhomeid=`3`!]','1','{BOOTSTRAP_SQL_ID}','8','0','0','1','1144904400','1','1158599931','0','0','0','0','0','','0','0','0','0','1','1'); -REPLACE INTO `{PREFIX}site_content` VALUES ('46','document','text/html','Thank You','','','thank-you','','1','0','0','0','0','','

    Thank You!

    \n

    We do appreciate your feedback. Your comments have been submitted to our office and hopefully someone will bother to actually read it. You should also receive a copy of the message in your inbox.

    \n

    Please be assured that we will do our best not to ignore you, but if today is a Monday please try again in a few days.

    \n','1','{BOOTSTRAP_SQL_ID}','6','1','1','1','1159302141','1','1159302892','0','0','0','1159302182','1','','0','0','0','0','0','0','1','1'); +REPLACE INTO `{PREFIX}site_content` VALUES ('46','document','text/html','Thank You','','','thank-you','','1','0','0','0','0','','

    Thank You!

    \n

    We do appreciate your feedback. Your comments have been submitted to our office and hopefully someone will bother to actually read it. You should also receive a copy of the message in your inbox.

    \n

    Please be assured that we will do our best not to ignore you, but if today is a Monday please try again in a few days.

    \n','1','{BOOTSTRAP_SQL_ID}','6','1','1','1','1159302141','1','1159302892','0','0','0','1159302182','1','','0','0','0','0','1','1'); # From 3de4fda4ea2b9d0c14cf9c5fd844f209c3771e39 Mon Sep 17 00:00:00 2001 From: Pathologic Date: Tue, 1 Aug 2017 12:00:22 +0300 Subject: [PATCH 127/338] fix #127 --- assets/lib/Helpers/FS.php | 3 ++- install/config.inc.tpl | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/lib/Helpers/FS.php b/assets/lib/Helpers/FS.php index 73231c2749..745b11c508 100644 --- a/assets/lib/Helpers/FS.php +++ b/assets/lib/Helpers/FS.php @@ -290,8 +290,9 @@ public function relativePath($path, $owner = null) if (is_null($owner)) { $owner = MODX_BASE_PATH; } + $path = str_replace('\\', '/', $path); if (!(empty($path) || !is_scalar($path)) && !preg_match("/^http(s)?:\/\/\w+/", $path)) { - $path = trim(preg_replace("#^" . preg_quote($owner) . "#", '', $path), DIRECTORY_SEPARATOR); + $path = trim(preg_replace("#^" . preg_quote($owner) . "#", '', $path), '/'); } else { $path = ''; } diff --git a/install/config.inc.tpl b/install/config.inc.tpl index f2941180b7..c867092bca 100644 --- a/install/config.inc.tpl +++ b/install/config.inc.tpl @@ -46,7 +46,6 @@ if(empty($base_path)||empty($base_url)||$_REQUEST['base_path']||$_REQUEST['base_ unset ($a); $base_url= $url . (substr($url, -1) != '/' ? '/' : ''); $base_path= $pth . (substr($pth, -1) != '/' && substr($pth, -1) != '\\' ? '/' : ''); - $base_path = str_replace('/', DIRECTORY_SEPARATOR, $base_path); } // check for valid hostnames @@ -76,7 +75,7 @@ $site_url .= $base_url; if (!defined('MODX_BASE_PATH')) define('MODX_BASE_PATH', $base_path); if (!defined('MODX_BASE_URL')) define('MODX_BASE_URL', $base_url); if (!defined('MODX_SITE_URL')) define('MODX_SITE_URL', $site_url); -if (!defined('MODX_MANAGER_PATH')) define('MODX_MANAGER_PATH', $base_path.MGR_DIR.DIRECTORY_SEPARATOR); +if (!defined('MODX_MANAGER_PATH')) define('MODX_MANAGER_PATH', $base_path.MGR_DIR.'/'); if (!defined('MODX_MANAGER_URL')) define('MODX_MANAGER_URL', $site_url.MGR_DIR.'/'); // start cms session From 268da0f6de5357dce5e5a40e3d887e36e0a4a6df Mon Sep 17 00:00:00 2001 From: Pathologic Date: Tue, 1 Aug 2017 12:44:55 +0300 Subject: [PATCH 128/338] update install --- install/setup.data.sql | 18 +++++++++--------- install/setup.sql | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/install/setup.data.sql b/install/setup.data.sql index 48d2abd580..74f7a25edd 100644 --- a/install/setup.data.sql +++ b/install/setup.data.sql @@ -61,28 +61,28 @@ REPLACE INTO `{PREFIX}site_content` VALUES ('46','document','text/html','Thank Y # -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'FormSignup', 'For the weblogin signup', 0, 'none', 2, 0, ' \n\n
    \n\n

    User Details

    \n
    \n \n Items marked by * are required
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n\n
    \n

    Password

    \n \n \n
    \n
    \n \n \n
    \n \n
    \n

    Optional Account Profile Info

    \n \n \n
    \n \n
    \n

    Bot-Patrol

    \n

    Enter the word/number combination shown in the image below.

    \n

    If you have trouble reading the code, click on the code itself to generate a new random code.

    \n \n
    \n \n
    \n \n
    \n\n
    \n\n\n
    \n\n

    Signup completed successfully!
    \nYour account was created. A copy of your signup information was sent to your email address.

    \n', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'FormSignup', 'For the weblogin signup', 0, 'none', 2, 0, ' \n\n
    \n\n

    User Details

    \n
    \n \n Items marked by * are required
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n\n
    \n

    Password

    \n \n \n
    \n
    \n \n \n
    \n \n
    \n

    Optional Account Profile Info

    \n \n \n
    \n \n
    \n

    Bot-Patrol

    \n

    Enter the word/number combination shown in the image below.

    \n

    If you have trouble reading the code, click on the code itself to generate a new random code.

    \n \n
    \n \n
    \n \n
    \n\n
    \n\n\n
    \n\n

    Signup completed successfully!
    \nYour account was created. A copy of your signup information was sent to your email address.

    \n', 0, UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'nl_sidebar', 'Default Template TPL for Ditto', 0, 'none', 1, 0, '[+title+]
    \n[+longtitle+]

    ', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'nl_sidebar', 'Default Template TPL for Ditto', 0, 'none', 1, 0, '[+title+]
    \n[+longtitle+]

    ', 0, UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ditto_blog', 'Blog Template', 0, 'none', 1, 0, '
    \n \n \n \n \n

    [+title+]

    \n \n \n [+summary+]\n \n
    ','0'); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ditto_blog', 'Blog Template', 0, 'none', 1, 0, '
    \n \n \n \n \n

    [+title+]

    \n \n \n [+summary+]\n \n
    ','0', UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'Comments', 'Comments (Jot) showing beneath a blog entry.', 0, 'none', 1, 0, '
    \r\n[!Jot? &customfields=`name,email` &subscribe=`1` &pagination=`4` &badwords=`dotNet` &canmoderate=`Site Admins` &tplForm=`Comments_tplForm` &tplComments=`Comments_tplComments`!]\r\n
    ', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'Comments', 'Comments (Jot) showing beneath a blog entry.', 0, 'none', 1, 0, '
    \r\n[!Jot? &customfields=`name,email` &subscribe=`1` &pagination=`4` &badwords=`dotNet` &canmoderate=`Site Admins` &tplForm=`Comments_tplForm` &tplComments=`Comments_tplComments`!]\r\n
    ', 0, UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ContactForm', 'eForm-template for showing contact-form', 0, 'none', 1, 0, '
    \n \n \n \n \n \n
    \n \n \n
    \n
    \n \n \n
    \n \n
    \n \n \n
    \n \n
    \n \n \n
    \n \n \n
    \n
    \n
    \n verification code\n
    \n
    \n \n
    \n
    \n
    \n \n
    \n \n
    \n\n
    \n\n\n', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ContactForm', 'eForm-template for showing contact-form', 0, 'none', 1, 0, '
    \n \n \n \n \n \n
    \n \n \n
    \n
    \n \n \n
    \n \n
    \n \n \n
    \n \n
    \n \n \n
    \n \n \n
    \n
    \n
    \n verification code\n
    \n
    \n \n
    \n
    \n
    \n \n
    \n \n
    \n\n
    \n\n\n', 0, UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ContactFormReport', 'eForm-template for sending form-data by mail', 0, 'none', 1, 0, '

    This is a response sent by [+name+] using the feedback form on the website. The details of the message follow below:

    \r\n\r\n\r\n

    Name: [+name+]

    \r\n

    Email: [+email+]

    \r\n

    Regarding: [+subject+]

    \r\n

    comments:
    [+message+]

    \r\n\r\n

    You can use this link to reply: [+email+]

    \r\n', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ContactFormReport', 'eForm-template for sending form-data by mail', 0, 'none', 1, 0, '

    This is a response sent by [+name+] using the feedback form on the website. The details of the message follow below:

    \r\n\r\n\r\n

    Name: [+name+]

    \r\n

    Email: [+email+]

    \r\n

    Regarding: [+subject+]

    \r\n

    comments:
    [+message+]

    \r\n\r\n

    You can use this link to reply: [+email+]

    \r\n', 0, UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'reflect_month_tpl', 'For the yearly archive. Use with Ditto.', 0, 'none', 1, 0, '[+month+] [+year+]', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'reflect_month_tpl', 'For the yearly archive. Use with Ditto.', 0, 'none', 1, 0, '[+month+] [+year+]', 0, UNIX_TIMESTAMP(), 0, 0); -INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ContactStyles', 'Styles for form validation', 0, 'none', 1, 0, '', 0); +INSERT INTO `{PREFIX}site_htmlsnippets` VALUES (NULL, 'ContactStyles', 'Styles for form validation', 0, 'none', 1, 0, '', 0, UNIX_TIMESTAMP(), 0, 0); # # Dumping data for table `site_tmplvar_contentvalues` @@ -119,7 +119,7 @@ REPLACE INTO `{PREFIX}web_groups` VALUES ('1','1','1'); # -REPLACE INTO `{PREFIX}web_user_attributes` VALUES ('1','1','Site Admin','0','you@example.com','','','0','0','0','25','1129049624','1129063123','0','f426f3209310abfddf2ee00e929774b4','0','0','','','','','','','',''); +REPLACE INTO `{PREFIX}web_user_attributes` VALUES ('1','1','Site Admin','0','you@example.com','','','0','0','0','25','1129049624','1129063123','0','f426f3209310abfddf2ee00e929774b4','0','0','','','','','','','','', UNIX_TIMESTAMP(), 0); # diff --git a/install/setup.sql b/install/setup.sql index ad1e61ea45..65b8799451 100755 --- a/install/setup.sql +++ b/install/setup.sql @@ -876,7 +876,7 @@ REPLACE INTO `{PREFIX}site_templates` # Default Site Documents -REPLACE INTO `{PREFIX}site_content` VALUES (1,'document','text/html','Evolution CMS Install Success','Welcome to the EVO Content Management System','','minimal-base','',1,0,0,0,0,'','

    Install Successful!

    \r\n

    You have successfully installed Evolution CMS.

    \r\n\r\n

    Getting Help

    \r\n

    The EVO Community provides a great starting point to learn all things Evolution CMS, or you can also see some great learning resources (books, tutorials, blogs and screencasts).

    \r\n

    Welcome to EVO!

    \r\n',1,3,0,1,1,1,1130304721,1,1130304927,0,0,0,1130304721,1,'Base Install',0,0,0,0,0,0,0,1); +REPLACE INTO `{PREFIX}site_content` VALUES (1,'document','text/html','Evolution CMS Install Success','Welcome to the EVO Content Management System','','minimal-base','',1,0,0,0,0,'','

    Install Successful!

    \r\n

    You have successfully installed Evolution CMS.

    \r\n\r\n

    Getting Help

    \r\n

    The EVO Community provides a great starting point to learn all things Evolution CMS, or you can also see some great learning resources (books, tutorials, blogs and screencasts).

    \r\n

    Welcome to EVO!

    \r\n',1,3,0,1,1,1,1130304721,1,1130304927,0,0,0,1130304721,1,'Base Install',0,0,0,0,0,1); REPLACE INTO `{PREFIX}manager_users` From 60e644c64adebb13b78b610cfc502ea6db23ef7e Mon Sep 17 00:00:00 2001 From: Pathologic Date: Tue, 1 Aug 2017 12:49:55 +0300 Subject: [PATCH 129/338] fix redundant tag --- manager/actions/document_data.static.php | 1 - 1 file changed, 1 deletion(-) diff --git a/manager/actions/document_data.static.php b/manager/actions/document_data.static.php index cbfee5167a..35ef1ce659 100644 --- a/manager/actions/document_data.static.php +++ b/manager/actions/document_data.static.php @@ -303,7 +303,6 @@ class="' . $_style["icons_move_document"] . '">' . $icon_pub_unpub : '')
    : " . $_lang['not_set'] . ")" ?>
     
    ' . implode('', $title) . '
    ' . implode('', $title) . '
    ' . implode('', $result_value) . '
    ' . $result . '
    '; + $result .= ''; + $result = '' . $result . '
    '; } } @@ -350,27 +351,28 @@ function checked($cond)

    -
    +
    - +
    -

    ' . $_lang["bkmgr_run_sql_result"] . '

    ' . $result . '
    '; - } - ?> + + +
    +
    +
    +

    -
    +
    "snapshot_path={$modx->config['snapshot_path']}")) ?>
    @@ -381,12 +383,14 @@ function checked($cond)
    - +
    - +
    + +
    @@ -405,55 +409,69 @@ function checked($cond) 'Description' ); if (is_array($files) && 0 < $total) { - echo ''; - echo "\n"; - arsort($files); - $tpl = '' . "\n"; - while ($file = array_shift($files)) { - $filename = substr($file, strrpos($file, '/') + 1); - $filesize = $modx->nicesize(filesize($file)); - - $file = fopen($file, "r"); - $count = 0; - $details = array(); - while ($count < 11) { - $line = fgets($file); - foreach ($detailFields as $label) { - $fileLabel = '# ' . $label; - if (strpos($line, $fileLabel) !== false) { - $details[$label] = htmlentities(trim(str_replace(array( - $fileLabel, - ':', - '`' - ), '', $line)), ENT_QUOTES, $modx_manager_charset); + ?> +
    +
    +
    {$_lang["files_filename"]}{$_lang["files_filesize"]}{$_lang["description"]}{$_lang["modx_version"]}{$_lang["database_name"]}{$_lang["onlineusers_action"]}
    [+filename+][+filesize+][+filedesc+][+modx_version+][+database_name+]' . $_lang["bkmgr_restore_submit"] . '
    + + + + + + + + + + + + + nicesize(filesize($file)); + + $file = fopen($file, "r"); + $count = 0; + $details = array(); + while ($count < 11) { + $line = fgets($file); + foreach ($detailFields as $label) { + $fileLabel = '# ' . $label; + if (strpos($line, $fileLabel) !== false) { + $details[$label] = htmlentities(trim(str_replace(array( + $fileLabel, + ':', + '`' + ), '', $line)), ENT_QUOTES, $modx_manager_charset); + } + } + $count++; + }; + fclose($file); + + $tooltip = "Generation Time: " . $details["Generation Time"] . "\n"; + $tooltip .= "Server version: " . $details["Server version"] . "\n"; + $tooltip .= "PHP Version: " . $details["PHP Version"] . "\n"; + $tooltip .= "Host: " . $details["Host"] . "\n"; + ?> + + + + + + + + + + '; + ?> + +
    +
    +
    + Date: Wed, 2 Aug 2017 03:26:27 +0300 Subject: [PATCH 139/338] add css class tab-content --- manager/media/style/default/css/custom.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 455058b7b5..bc9aa1723c 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -1,8 +1,12 @@ /* [ COLS ] */ .row { margin-left: -1.3rem; margin-right: -1.3rem } .container { padding-left: 1.3rem; padding-right: 1.3rem; width: 100% } +/* :TODO .container-body need remove and replace .tab-content */ .container-body { padding: 1.3rem } .tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } +.tab-header { padding: .5rem 1.3rem; } +.tab-content { width: 100%; padding: 1.3rem; } +.tab-content::after { display: table; width: 100%; content: '' } /* [ FORMS ] */ .form-row { margin-bottom: 0.25rem; } .form-row.row { margin-left: 0; margin-right: -1rem } From 7f3a73f36fbe93f31365f148534dc879d8b9bd4c Mon Sep 17 00:00:00 2001 From: Pathologic Date: Wed, 2 Aug 2017 04:02:34 +0300 Subject: [PATCH 140/338] remove etomite "compatibility" --- index.php | 2 -- manager/includes/document.parser.class.inc.php | 7 ------- manager/includes/settings.inc.php | 2 -- manager/includes/tmplvars.commands.inc.php | 1 - manager/index.php | 3 --- manager/processors/execute_module.processor.php | 1 - manager/processors/login.processor.php | 1 - 7 files changed, 17 deletions(-) diff --git a/index.php b/index.php index bbdc63e953..f55531a249 100644 --- a/index.php +++ b/index.php @@ -82,7 +82,6 @@ * Function: This file loads and executes the parser. * */ -define("IN_ETOMITE_PARSER", "true"); // provides compatibility with etomite 0.6 and maybe later versions define("IN_PARSER_MODE", "true"); if (!defined('IN_MANAGER_MODE')) { define("IN_MANAGER_MODE", "false"); @@ -107,7 +106,6 @@ // initiate a new document parser include_once(MODX_MANAGER_PATH.'includes/document.parser.class.inc.php'); $modx = new DocumentParser; -$etomite = &$modx; // for backward compatibility // set some parser options $modx->minParserPasses = 1; // min number of parser recursive loops or passes diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 3beb08c9a9..7227a57b8b 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -320,9 +320,6 @@ function getSettings() { } } - // added for backwards compatibility - garry FS#104 - $this->config['etomite_charset'] = & $this->config['modx_charset']; - // setup default site id - new installation should generate a unique id for the site. if(!isset($this->config['site_id'])) $this->config['site_id'] = "MzGeQ2faT4Dw06+U49x3"; @@ -1357,7 +1354,6 @@ function detectError($error) { * @param array $params */ function evalPlugin($pluginCode, $params) { - $etomite = $modx = & $this; $modx->event->params = & $params; // store params inside event object if (is_array($params)) { extract($params, EXTR_SKIP); @@ -1401,7 +1397,6 @@ function evalPlugin($pluginCode, $params) { * @return string */ function evalSnippet($phpcode, $params) { - $etomite = $modx = & $this; /* if(isset($params) && is_array($params)) { foreach($params as $k=>$v) { @@ -1447,8 +1442,6 @@ function evalSnippets($content) { if(strpos($content,'[[')===false) return $content; - $etomite= & $this; - $matches = $this->getTagsFromContent($content,'[[',']]'); if(!$matches) return $content; diff --git a/manager/includes/settings.inc.php b/manager/includes/settings.inc.php index 01b96fffe8..8d22eef911 100755 --- a/manager/includes/settings.inc.php +++ b/manager/includes/settings.inc.php @@ -12,8 +12,6 @@ } extract($settings, EXTR_OVERWRITE); -// add for backwards compatibility - garryn FS#104 -$etomite_charset = & $modx_manager_charset; // setup default site id - new installation should generate a unique id for the site. if(!isset($site_id)) $site_id = "MzGeQ2faT4Dw06+U49x3"; diff --git a/manager/includes/tmplvars.commands.inc.php b/manager/includes/tmplvars.commands.inc.php index c76dc25aa7..52e9c1d4a1 100755 --- a/manager/includes/tmplvars.commands.inc.php +++ b/manager/includes/tmplvars.commands.inc.php @@ -16,7 +16,6 @@ function ProcessTVCommand($value, $name = '', $docid = '', $src='docform', $tvsArray = array()) { global $modx; - $etomite = & $modx; $docid = intval($docid) ? intval($docid) : $modx->documentIdentifier; $nvalue = trim($value); if (substr($nvalue, 0, 1) != '@') diff --git a/manager/index.php b/manager/index.php index 22a4944d37..faad818fd3 100644 --- a/manager/index.php +++ b/manager/index.php @@ -127,8 +127,6 @@ $_SERVER["DOCUMENT_ROOT"] = str_replace($_SERVER["PATH_INFO"], "", preg_replace("/\\\\/", "/", $_SERVER["PATH_TRANSLATED"]))."/"; } -define("IN_ETOMITE_SYSTEM", "true"); // for backward compatibility with 0.6 - // include_once config file $config_filename = "./includes/config.inc.php"; if (!file_exists($config_filename)) { @@ -145,7 +143,6 @@ $modx = new DocumentParser; $modx->loadExtension("ManagerAPI"); $modx->getSettings(); -$etomite = &$modx; // for backward compatibility $modx->tstart = $tstart; $modx->mstart = $mstart; diff --git a/manager/processors/execute_module.processor.php b/manager/processors/execute_module.processor.php index 79cf911237..248f6ec740 100644 --- a/manager/processors/execute_module.processor.php +++ b/manager/processors/execute_module.processor.php @@ -64,7 +64,6 @@ // evalModule function evalModule($moduleCode,$params){ global $modx; - $etomite = &$modx; $modx->event->params = &$params; // store params inside event object if(is_array($params)) { extract($params, EXTR_SKIP); diff --git a/manager/processors/login.processor.php b/manager/processors/login.processor.php index 95b1550ee5..fc540c2dfa 100755 --- a/manager/processors/login.processor.php +++ b/manager/processors/login.processor.php @@ -23,7 +23,6 @@ $modx->loadExtension('ManagerAPI'); $modx->loadExtension('phpass'); $modx->getSettings(); -$etomite = &$modx; // include_once the language file $_lang = array(); From 0fbb8c6b0990174ddb3a70b63a1f3b738a0766da Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 2 Aug 2017 10:16:49 +0900 Subject: [PATCH 141/338] Fix @LITERAL --- manager/includes/document.parser.class.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 63c1b36175..b08c5fb50e 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -1181,6 +1181,7 @@ function mergeChunkContent($content,$ph=false) { */ function mergePlaceholderContent($content,$ph=false) { + if(stripos($content,'<@LITERAL>')!==false) $content= $this->escapeLiteralTagsContent($content); if (strpos($content, '[+') === false) return $content; if(!$ph) $ph = $this->placeholders; From 26a9c185d0a33b7c21b8ca958fea051ef1388577 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 2 Aug 2017 10:18:47 +0900 Subject: [PATCH 142/338] Fix @7f3a73f --- manager/includes/document.parser.class.inc.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index b08c5fb50e..91f5851b5d 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -1369,6 +1369,7 @@ function detectError($error) { * @param array $params */ function evalPlugin($pluginCode, $params) { + $modx = & $this; $modx->event->params = & $params; // store params inside event object if (is_array($params)) { extract($params, EXTR_SKIP); @@ -1412,6 +1413,7 @@ function evalPlugin($pluginCode, $params) { * @return string */ function evalSnippet($phpcode, $params) { + $modx = & $this; /* if(isset($params) && is_array($params)) { foreach($params as $k=>$v) { From 396814fe8b556b90b914b335f29da3def23b10c1 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 2 Aug 2017 19:17:15 +0900 Subject: [PATCH 143/338] [F] #134 Fix bug Cross References https://github.com/evolution-cms/evolution/issues/134 --- manager/includes/document.parser.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 91f5851b5d..64ac8ef794 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -1001,7 +1001,7 @@ function mergeDocumentContent($content,$ph=false) { if(substr($key, 0, 1) == '#') $key = substr($key, 1); // remove # for QuickEdit format list($key,$modifiers) = $this->splitKeyAndFilter($key); - list($key,$context) = explode('@',$key . '@',2); + list($key,$context) = explode('@',$key,2); // if(!isset($ph[$key]) && !$context) continue; // #1218 TVs/PHs will not be rendered if custom_meta_title is not assigned to template like [*custom_meta_title:ne:then=`[*custom_meta_title*]`:else=`[*pagetitle*]`*] if($context) $value = $this->_contextValue("{$key}@{$context}"); From b45cc3a7a932f7ba3bc173991014475e188917aa Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 2 Aug 2017 19:21:09 +0900 Subject: [PATCH 144/338] [F] Cross References bug [*pagetitle@parent*] --- manager/includes/document.parser.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 64ac8ef794..14cad47d2d 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -1004,7 +1004,7 @@ function mergeDocumentContent($content,$ph=false) { list($key,$context) = explode('@',$key,2); // if(!isset($ph[$key]) && !$context) continue; // #1218 TVs/PHs will not be rendered if custom_meta_title is not assigned to template like [*custom_meta_title:ne:then=`[*custom_meta_title*]`:else=`[*pagetitle*]`*] - if($context) $value = $this->_contextValue("{$key}@{$context}"); + if($context) $value = $this->_contextValue("{$key}@{$context}",$this->documentObject['parent']); else $value = isset($ph[$key]) ? $ph[$key] : ''; if (is_array($value)) { From 2e81ff4b51204cb901682eb406559d21fd741065 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 2 Aug 2017 19:27:11 +0900 Subject: [PATCH 145/338] [Fix] Missing parse modifier --- manager/includes/extenders/modifiers.class.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manager/includes/extenders/modifiers.class.inc.php b/manager/includes/extenders/modifiers.class.inc.php index 41357d0e8d..6a4905f905 100644 --- a/manager/includes/extenders/modifiers.class.inc.php +++ b/manager/includes/extenders/modifiers.class.inc.php @@ -77,7 +77,7 @@ function _getOpt($mode,$delim,$modifiers) { function _getRemainModifiers($mode,$delim,$modifiers) { if($delim) { if($mode=='(') - return substr($modifiers,strpos($modifiers, $delim . ')' )+2); + return trim(substr($modifiers,strpos($modifiers, $delim . ')' )+2)); else { $modifiers = trim($modifiers); $modifiers = substr($modifiers,1); @@ -112,7 +112,7 @@ function splitEachModifiers($modifiers) { $delim = $this->_getDelim($c,$modifiers); $opt = $this->_getOpt($c,$delim,$modifiers); - $modifiers = $this->_getRemainModifiers($c,$delim,$modifiers); + $modifiers = trim($this->_getRemainModifiers($c,$delim,$modifiers)); $result[]=array('cmd'=>trim($match[1]),'opt'=>$opt,'debuginfo'=>$debuginfo); $cmd = ''; @@ -121,7 +121,7 @@ function splitEachModifiers($modifiers) { $modifiers = $m1 = trim($modifiers); $delim = $this->_getDelim($c,$modifiers); $opt = $this->_getOpt($c,$delim,$modifiers); - $modifiers = $this->_getRemainModifiers($c,$delim,$modifiers); + $modifiers = trim($this->_getRemainModifiers($c,$delim,$modifiers)); $debuginfo = "#i=1 #c=[{$c}] #delim=[{$delim}] #m1=[{$m1}] remainMdf=[{$modifiers}]"; $result[]=array('cmd'=>trim($cmd),'opt'=>$opt,'debuginfo'=>$debuginfo); From 40514b5cabfd587879ba1787d405da99befa5390 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Thu, 3 Aug 2017 00:01:00 +0900 Subject: [PATCH 146/338] Code cleanup (readable flow) --- .../includes/document.parser.class.inc.php | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 14cad47d2d..bf332ad1f2 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -608,57 +608,57 @@ function getDocumentObjectFromCache($id, $loading = false) { $cache_path = $this->getHashFile($key); - if (is_file($cache_path)) { - $content = file_get_contents($cache_path, false); - if(substr($content,0,5)==='')+2); // remove php header - $a= explode('', $content, 2); - if (count($a) == 1) - $result = $a[0]; // return only document content - else { - $docObj= unserialize($a[0]); // rebuild document object - // check page security - if ($docObj['privateweb'] && isset ($docObj['__MODxDocGroups__'])) { - $pass= false; - $usrGrps= $this->getUserDocGroups(); - $docGrps= explode(',', $docObj['__MODxDocGroups__']); - // check is user has access to doc groups - if (is_array($usrGrps)) { - foreach ($usrGrps as $k => $v) - if (in_array($v, $docGrps)) { - $pass= true; - break; - } + if (!is_file($cache_path)) { + $this->documentGenerated= 1; + return ''; + } + $content = file_get_contents($cache_path, false); + if(substr($content,0,5)==='')+2); // remove php header + $a= explode('', $content, 2); + if (count($a) == 1) + $result = $a[0]; // return only document content + else { + $docObj= unserialize($a[0]); // rebuild document object + // check page security + if ($docObj['privateweb'] && isset ($docObj['__MODxDocGroups__'])) { + $pass= false; + $usrGrps= $this->getUserDocGroups(); + $docGrps= explode(',', $docObj['__MODxDocGroups__']); + // check is user has access to doc groups + if (is_array($usrGrps)) { + foreach ($usrGrps as $k => $v) { + if (!in_array($v, $docGrps)) continue; + $pass= true; + break; } - // diplay error pages if user has no access to cached doc - if (!$pass) { - if ($this->config['unauthorized_page']) { - // check if file is not public - $rs= $this->db->select('count(id)', '[+prefix+]document_groups', "document='{$id}'", '', '1'); - $total= $this->db->getValue($rs); - } - else $total = 0; - - if ($total > 0) $this->sendUnauthorizedPage(); - else $this->sendErrorPage(); - - exit; // stop here + } + // diplay error pages if user has no access to cached doc + if (!$pass) { + if ($this->config['unauthorized_page']) { + // check if file is not public + $rs= $this->db->select('count(id)', '[+prefix+]document_groups', "document='{$id}'", '', '1'); + $total= $this->db->getValue($rs); } + else $total = 0; + + if ($total > 0) $this->sendUnauthorizedPage(); + else $this->sendErrorPage(); + + exit; // stop here } - // Grab the Scripts - if (isset($docObj['__MODxSJScripts__'])) $this->sjscripts = $docObj['__MODxSJScripts__']; - if (isset($docObj['__MODxJScripts__'])) $this->jscripts = $docObj['__MODxJScripts__']; + } + // Grab the Scripts + if (isset($docObj['__MODxSJScripts__'])) $this->sjscripts = $docObj['__MODxSJScripts__']; + if (isset($docObj['__MODxJScripts__'])) $this->jscripts = $docObj['__MODxJScripts__']; - // Remove intermediate variables - unset($docObj['__MODxDocGroups__'], $docObj['__MODxSJScripts__'], $docObj['__MODxJScripts__']); + // Remove intermediate variables + unset($docObj['__MODxDocGroups__'], $docObj['__MODxSJScripts__'], $docObj['__MODxJScripts__']); - $this->documentObject= $docObj; - - $result = $a[1]; // return document content - } - } else { - $this->documentGenerated= 1; - return ''; + $this->documentObject= $docObj; + + $result = $a[1]; // return document content } + $this->documentGenerated= 0; // invoke OnLoadWebPageCache event $this->documentContent = $result; From 7f986c7012a30cd806ceaa7389405a6f88c0a306 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Thu, 3 Aug 2017 00:09:23 +0900 Subject: [PATCH 147/338] [I] New - $modx->config['enable_cache'] Toggle cache enable / disable all page --- .../actions/mutate_settings/tab1_site_settings.inc.php | 9 +++++++++ manager/includes/default_config.php | 1 + manager/includes/document.parser.class.inc.php | 9 +++++++-- manager/includes/lang/english.inc.php | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/manager/actions/mutate_settings/tab1_site_settings.inc.php b/manager/actions/mutate_settings/tab1_site_settings.inc.php index 7b12b8f789..5ade04b0f6 100644 --- a/manager/actions/mutate_settings/tab1_site_settings.inc.php +++ b/manager/actions/mutate_settings/tab1_site_settings.inc.php @@ -215,6 +215,15 @@ + +
    [(enable_cache)] + +
    +
    + + + +
    [(cache_type)] diff --git a/manager/includes/default_config.php b/manager/includes/default_config.php index 5c58954028..cff20c36d6 100644 --- a/manager/includes/default_config.php +++ b/manager/includes/default_config.php @@ -95,6 +95,7 @@ $c['allow_duplicate_alias'] = '0'; $c['automatic_alias'] = '1'; $c['datetime_format'] = 'dd-mm-YYYY'; +$c['enable_cache'] = '1'; $c['cache_type'] = '1'; $c['server_protocol'] = 'http'; $c['settings_version'] = 0; diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index bf332ad1f2..51d4bcb7ba 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -878,7 +878,7 @@ function checkPublishStatus() { */ function postProcess() { // if the current document was generated, cache it! - if ($this->documentGenerated == 1 && $this->documentObject['cacheable'] == 1 && $this->documentObject['type'] == 'document' && $this->documentObject['published'] == 1) { + if ($this->config['enable_cache'] && $this->documentGenerated && $this->documentObject['cacheable'] && $this->documentObject['type'] == 'document' && $this->documentObject['published']) { // invoke OnBeforeSaveWebPageCache event $this->invokeEvent("OnBeforeSaveWebPageCache"); @@ -2292,7 +2292,12 @@ function setRequestQ($request_uri) { */ function prepareResponse() { // we now know the method and identifier, let's check the cache - $this->documentContent= $this->getDocumentObjectFromCache($this->documentIdentifier, true); + + if($this->config['enable_cache']==2 && $this->isLoggedIn()) $this->config['enable_cache'] = 0; + + if($this->config['enable_cache']) + $this->documentContent= $this->getDocumentObjectFromCache($this->documentIdentifier, true); + else $this->documentContent= ''; if ($this->documentContent == '') { // get document object from DB diff --git a/manager/includes/lang/english.inc.php b/manager/includes/lang/english.inc.php index f421062fec..c5f2570f0a 100644 --- a/manager/includes/lang/english.inc.php +++ b/manager/includes/lang/english.inc.php @@ -1277,6 +1277,9 @@ $_lang["docid_incrmnt_method_1"] = 'Minimum missed ID'; $_lang["docid_incrmnt_method_2"] = 'Maximal ID + 1'; +$_lang["enable_cache_title"] = 'Document caching'; +$_lang["disabled_at_login"] = 'Disabled at login'; + $_lang["cache_type_title"] = 'Document caching type'; $_lang["cache_type_1"] = 'Cache is based only on Resource ID (standard)'; $_lang["cache_type_2"] = 'Cache is based on Resource ID and $_GET parameters'; From fcd6b4eea70b1b3a1f69561b6e1496cf8b48cb6b Mon Sep 17 00:00:00 2001 From: yamamoto Date: Thu, 3 Aug 2017 00:14:05 +0900 Subject: [PATCH 148/338] Refactor - Use $_SERVER['REQUEST_TIME'] --- manager/includes/document.parser.class.inc.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 51d4bcb7ba..fc7155302d 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -103,7 +103,7 @@ function __construct() { $this->dumpPlugins = false; $this->stopOnNotice = false; $this->snipLapCount = 0; - $this->time = time(); // for having global timestamp + $this->time = $_SERVER['REQUEST_TIME']; // for having global timestamp $this->q = self::_getCleanQueryString(); } @@ -686,7 +686,7 @@ function outputContent($noEvent= false) { // check for non-cached snippet output if (strpos($this->documentOutput, '[!') > -1) { - $this->recentUpdate = time() + $this->config['server_offset_time']; + $this->recentUpdate = $_SERVER['REQUEST_TIME'] + $this->config['server_offset_time']; $this->documentOutput= str_replace('[!', '[[', $this->documentOutput); $this->documentOutput= str_replace('!]', ']]', $this->documentOutput); @@ -2821,7 +2821,7 @@ function logEvent($evtid, $type, $msg, $source= 'Parser') { $this->db->insert(array( 'eventid' => $evtid, 'type' =>$type, - 'createdon' => time() + $this->config['server_offset_time'], + 'createdon' => $_SERVER['REQUEST_TIME'] + $this->config['server_offset_time'], 'source' => $esc_source, 'description' => $msg, 'user' => $LoginUserID, @@ -4154,7 +4154,7 @@ function sendAlert($type, $to, $from, $subject, $msg, $private= 0) { 'sender' => $from, 'recipient' => $to, 'private' => $private, - 'postdate' => time() + $this->config['server_offset_time'], + 'postdate' => $_SERVER['REQUEST_TIME'] + $this->config['server_offset_time'], 'messageread' => 0, ), $this->getFullTableName('user_messages')); } @@ -5218,7 +5218,7 @@ function messageQuit($msg= 'unspecified error', $query= '', $is_error= true, $nr $table[] = array('Referer' , $referer); $table[] = array('User Agent' , $ua); $table[] = array('IP' , $_SERVER['REMOTE_ADDR']); - $table[] = array('Current time' , date("Y-m-d H:i:s", time() + $this->config['server_offset_time'])); + $table[] = array('Current time' , date("Y-m-d H:i:s", $_SERVER['REQUEST_TIME'] + $this->config['server_offset_time'])); $str .= $MakeTable->create($table, array('Basic info','')); $str .= "
    "; From f4d30ca73613f27925bed9be14f9d83612987a0f Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Wed, 2 Aug 2017 19:41:22 +0300 Subject: [PATCH 149/338] resolve #135 --- manager/actions/category_mgr/skin/add.tpl.phtml | 6 +++--- manager/actions/category_mgr/skin/categorize.tpl.phtml | 6 +++--- manager/actions/category_mgr/skin/edit.tpl.phtml | 6 +++--- manager/actions/category_mgr/skin/sort.tpl.phtml | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manager/actions/category_mgr/skin/add.tpl.phtml b/manager/actions/category_mgr/skin/add.tpl.phtml index c414e37413..1051ec9bc0 100644 --- a/manager/actions/category_mgr/skin/add.tpl.phtml +++ b/manager/actions/category_mgr/skin/add.tpl.phtml @@ -4,9 +4,9 @@
  • txt('cm_create_new_category'); ?>
  • - +

    + Add a new category to the Manager. +

    - +

    -
    - -
    + -
    -
    -
    -

    - - - - :
    -
    - -
    - - -

    +
    +
    +

    +
    + + + + +

    :

    + + +
    +
    From 65dfe495a37ddff8b0e6cac94e568c6213bdb850 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 00:09:27 +0300 Subject: [PATCH 152/338] update messages.static --- manager/actions/messages.static.php | 586 +++++++++++++--------------- 1 file changed, 279 insertions(+), 307 deletions(-) diff --git a/manager/actions/messages.static.php b/manager/actions/messages.static.php index 768efa5caf..19b077c501 100644 --- a/manager/actions/messages.static.php +++ b/manager/actions/messages.static.php @@ -1,324 +1,296 @@ INCLUDE_ORDERING_ERROR


    Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('messages')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('messages')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } ?>

    - +

    - -
    -
    -
    - db->select('*', $modx->getFullTableName('user_messages'), "id='" . (int) $_REQUEST['id'] . "'"); - $message = $modx->db->getRow($rs); - if(!$message) { - echo "Wrong number of messages returned!"; - } else { - if($message['recipient'] != $modx->getLoginUserID()) { - echo $_lang['messages_not_allowed_to_read']; - } else { - // output message! - // get the name of the sender - $sender = $message['sender']; - if($sender == 0) { - $sendername = $_lang['messages_system_user']; - } else { - $rs2 = $modx->db->select('username', $modx->getFullTableName('manager_users'), "id='{$sender}'"); - $sendername = $modx->db->getValue($rs2); - } - ?> - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
      -
    • - " /> -
    • -
    • - - " />
    • -
    • ">
    • - - - -
    -
     
    :
    :toDateFormat($message['postdate'] + $server_offset_time); ?>
    :
     
    - ", $message['message']); - $dashcount = substr_count($message, "-----"); - $message = str_replace("-----", "", $message); - for($i = 0; $i < $dashcount; $i++) { - $message .= ""; - } - - echo $message; - ?> - -
    - db->update(array('messageread' => 1), $modx->getFullTableName('user_messages'), "id='{$_REQUEST['id']}'"); - } - } - ?> -
    -
    + +
    +
    + + db->select('*', $modx->getFullTableName('user_messages'), "id='" . (int)$_REQUEST['id'] . "'"); + $message = $modx->db->getRow($rs); + if (!$message) { + echo "Wrong number of messages returned!"; + } else { + if ($message['recipient'] != $modx->getLoginUserID()) { + echo $_lang['messages_not_allowed_to_read']; + } else { + // output message! + // get the name of the sender + $sender = $message['sender']; + if ($sender == 0) { + $sendername = $_lang['messages_system_user']; + } else { + $rs2 = $modx->db->select('username', $modx->getFullTableName('manager_users'), "id='{$sender}'"); + $sendername = $modx->db->getValue($rs2); + } + ?> +
    + + + "> +
    +

    +
    +
    + + + + + + + + + + + + + + + + +
    : 
    : toDateFormat($message['postdate'] + $server_offset_time) ?>
    : 
    +
    + ', $message['message']); + $dashcount = substr_count($message, '-----'); + $message = str_replace('-----', '', $message); + for ($i = 0; $i < $dashcount; $i++) { + $message .= ''; + } + ?> +
    +
    + db->update(array('messageread' => 1), $modx->getFullTableName('user_messages'), "id='{$_REQUEST['id']}'"); + } + } + ?> +
    +
    +

    -
    -
    -
    - db->select('count(id)', $modx->getFullTableName('user_messages'), "recipient=" . $modx->getLoginUserID() . ""); - $num_rows = $modx->db->getValue($rs); - - // ============================================================== - // Exemple Usage - // Note: I make 2 query to the database for this exemple, it - // could (and should) be made with only one query... - // ============================================================== - - // If current position is not set, set it to zero - if(!isset($_REQUEST['int_cur_position']) || $_REQUEST['int_cur_position'] == 0) { - $int_cur_position = 0; - } else { - $int_cur_position = (int) $_REQUEST['int_cur_position']; - } +
    +
    +

    + db->select('count(id)', $modx->getFullTableName('user_messages'), "recipient=" . $modx->getLoginUserID() . ""); + $num_rows = $modx->db->getValue($rs); - // Number of result to display on the page, will be in the LIMIT of the sql query also - $int_num_result = $number_of_messages; + // ============================================================== + // Exemple Usage + // Note: I make 2 query to the database for this exemple, it + // could (and should) be made with only one query... + // ============================================================== + // If current position is not set, set it to zero + if (!isset($_REQUEST['int_cur_position']) || $_REQUEST['int_cur_position'] == 0) { + $int_cur_position = 0; + } else { + $int_cur_position = (int)$_REQUEST['int_cur_position']; + } - $extargv = "&a=10"; // extra argv here (could be anything depending on your page) + // Number of result to display on the page, will be in the LIMIT of the sql query also + $int_num_result = $number_of_messages; - include_once "paginate.inc.php"; - // New instance of the Paging class, you can modify the color and the width of the html table - $p = new Paging($num_rows, $int_cur_position, $int_num_result, $extargv); + $extargv = "&a=10"; // extra argv here (could be anything depending on your page) - // Load up the 2 array in order to display result - $array_paging = $p->getPagingArray(); - $array_row_paging = $p->getPagingRowArray(); + include_once "paginate.inc.php"; + // New instance of the Paging class, you can modify the color and the width of the html table + $p = new Paging($num_rows, $int_cur_position, $int_num_result, $extargv); - // Display the result as you like... - $pager .= $_lang['showing'] . " " . $array_paging['lower']; - $pager .= " " . $_lang['to'] . " " . $array_paging['upper']; - $pager .= " (" . $array_paging['total'] . " " . $_lang['total'] . ")"; - $pager .= "
    " . $array_paging['previous_link'] . "<<" . (isset($array_paging['previous_link']) ? " " : " "); - for($i = 0; $i < sizeof($array_row_paging); $i++) { - $pager .= $array_row_paging[$i] . " "; - } - $pager .= $array_paging['next_link'] . ">>" . (isset($array_paging['next_link']) ? "" : ""); + // Load up the 2 array in order to display result + $array_paging = $p->getPagingArray(); + $array_row_paging = $p->getPagingRowArray(); - // The above exemple print somethings like: - // Results 1 to 20 of 597 <<< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 >>> - // Of course you can now play with array_row_paging in order to print - // only the results you would like... + // Display the result as you like... + $pager .= $_lang['showing'] . " " . $array_paging['lower']; + $pager .= " " . $_lang['to'] . " " . $array_paging['upper']; + $pager .= " (" . $array_paging['total'] . " " . $_lang['total'] . ")"; + $pager .= "
    " . $array_paging['previous_link'] . "<<" . (isset($array_paging['previous_link']) ? " " : " "); + for ($i = 0; $i < sizeof($array_row_paging); $i++) { + $pager .= $array_row_paging[$i] . " "; + } + $pager .= $array_paging['next_link'] . ">>" . (isset($array_paging['next_link']) ? "" : ""); - $rs = $modx->db->select('*', $modx->getFullTableName('user_messages'), "recipient=" . $modx->getLoginUserID() . "", 'postdate DESC', "{$int_cur_position}, {$int_num_result}"); - $limit = $modx->db->getRecordCount($rs); - if($limit < 1) { - echo $_lang['messages_no_messages']; - } else { - echo $pager; - $dotablestuff = 1; - ?> - - - - - - - - - - - - - db->getRow($rs)) { - $sender = $message['sender']; - if($sender == 0) { - $sendername = "[System]"; - } else { - $rs2 = $modx->db->select('username', $modx->getFullTableName('manager_users'), "id='{$sender}'"); - $sendername = $modx->db->getValue($rs2); - } - $messagestyle = $message['messageread'] == 0 ? "messageUnread" : "messageRead"; - ?> - - - - - - - - >> + // Of course you can now play with array_row_paging in order to print + // only the results you would like... - if($dotablestuff == 1) { ?> - -
    " : ""; ?>toDateFormat($message['postdate'] + $server_offset_time); ?>
    - -
    + $rs = $modx->db->select('*', $modx->getFullTableName('user_messages'), "recipient=" . $modx->getLoginUserID() . "", 'postdate DESC', "{$int_cur_position}, {$int_num_result}"); + $limit = $modx->db->getRecordCount($rs); + if ($limit < 1) { + echo $_lang['messages_no_messages']; + } else { + $dotablestuff = 1; + ?> + + +
    +
    + + + + + + + + + + + + db->getRow($rs)) { + $sender = $message['sender']; + if ($sender == 0) { + $sendername = "[System]"; + } else { + $rs2 = $modx->db->select('username', $modx->getFullTableName('manager_users'), "id='{$sender}'"); + $sendername = $modx->db->getValue($rs2); + } + $messagestyle = $message['messageread'] == 0 ? "text-primary" : ""; + ?> + + + + + + + + + +
    ' : "" ?>toDateFormat($message['postdate'] + $server_offset_time) ?>
    +
    +
    + +
    -
    -
    -
    - db->select('*', $modx->getFullTableName('user_messages'), "id='" . $_REQUEST['id'] . "'"); - $message = $modx->db->getRow($rs); - if(!$message) { - echo "Wrong number of messages returned!"; - } else { - if($message['recipient'] != $modx->getLoginUserID()) { - echo $_lang['messages_not_allowed_to_read']; - } else { - // output message! - // get the name of the sender - $sender = $message['sender']; - if($sender == 0) { - $sendername = "[System]"; - } else { - $rs2 = $modx->db->select('username', $modx->getFullTableName('manager_users'), "id='{$sender}'"); - $sendername = $modx->db->getValue($rs2); - } - $subjecttext = $_REQUEST['m'] == 'rp' ? "Re: " : "Fwd: "; - $subjecttext .= $message['subject']; - $messagetext = "\n\n\n-----\n" . $_lang['messages_from'] . ": $sendername\n" . $_lang['messages_sent'] . ": " . $modx->toDateFormat($message['postdate'] + $server_offset_time) . "\n" . $_lang['messages_subject'] . ": " . $message['subject'] . "\n\n" . $message['message']; - if($_REQUEST['m'] == 'rp') { - $recipientindex = $message['sender']; - } - } - } - } - ?> - -
    -
    - : - - - - -
    -     -     - -
    :  - db->select('username, id', $modx->getFullTableName('manager_users')); - ?> - -
    - - -
    -
    +

    -

    +
    +
    +

    + db->select('*', $modx->getFullTableName('user_messages'), "id='" . $_REQUEST['id'] . "'"); + $message = $modx->db->getRow($rs); + if (!$message) { + echo "Wrong number of messages returned!"; + } else { + if ($message['recipient'] != $modx->getLoginUserID()) { + echo $_lang['messages_not_allowed_to_read']; + } else { + // output message! + // get the name of the sender + $sender = $message['sender']; + if ($sender == 0) { + $sendername = "[System]"; + } else { + $rs2 = $modx->db->select('username', $modx->getFullTableName('manager_users'), "id='{$sender}'"); + $sendername = $modx->db->getValue($rs2); + } + $subjecttext = $_REQUEST['m'] == 'rp' ? "Re: " : "Fwd: "; + $subjecttext .= $message['subject']; + $messagetext = "\n\n\n-----\n" . $_lang['messages_from'] . ": $sendername\n" . $_lang['messages_sent'] . ": " . $modx->toDateFormat($message['postdate'] + $server_offset_time) . "\n" . $_lang['messages_subject'] . ": " . $message['subject'] . "\n\n" . $message['message']; + if ($_REQUEST['m'] == 'rp') { + $recipientindex = $message['sender']; + } + } + } + } + ?> -
    - : - - - - - - - - - - - - - -
    :
    :
    - - - -
    - -
    + +
    + : +
    +
    +
    + + + +
    +
    +
    :  + db->select('username, id', $modx->getFullTableName('manager_users')); + ?> + +
    + + +
    +
    + : +
    +
    :
    +
    +
    +
    +
    :
    +
    +
    +
    + "> + "> +
    +
    hasPermission('messages'); ?> From 72fa475433a3ef0537dc0cfc9e002d30d805881e Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 00:46:12 +0300 Subject: [PATCH 153/338] update evo tooltip --- manager/includes/header.inc.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 7ae26c57b7..f70031d0f0 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -108,22 +108,21 @@ function document_onload() b.className = 'evo-tooltip'; let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); [].slice.call(a).forEach(function(f) { - f.addEventListener('mouseenter', function() { + f.addEventListener('mouseenter', function(e) { b.innerHTML = (this.dataset && this.dataset.tooltip ? this.dataset.tooltip : this.innerHTML); - this.position = this.getBoundingClientRect(); - if (this.position.left + b.offsetWidth > window.innerWidth) { - b.style.left = Math.round(this.position.left - b.offsetWidth - (c * 2)) + 'px'; + if (e.pageX + b.offsetWidth + (c * 2) > window.innerWidth) { + b.style.left = Math.round(e.pageX - b.offsetWidth - (c * 2)) + 'px'; b.classList.add('evo-tooltip-right'); } else { - b.style.left = Math.round(this.position.left + this.position.width) + 'px'; + b.style.left = Math.round(e.pageX) + 'px'; b.classList.add('evo-tooltip-left'); } - if (this.position.top - (b.offsetHeight / 2) - c < 0) { + if (e.pageY - (b.offsetHeight / 2) - c < 0) { b.style.top = 0; - } else if (this.position.top + (b.offsetHeight / 2) > window.innerHeight) { + } else if (e.pageY + (b.offsetHeight / 2) > window.innerHeight) { b.style.top = Math.round(window.innerHeight - b.offsetHeight) - (c * 2) + 'px'; } else { - b.style.top = Math.round(this.position.top - (b.offsetHeight / 2)) - c + 'px'; + b.style.top = Math.round(e.pageY - (b.offsetHeight / 2)) - c + 'px'; } b.classList.add('show'); }); From 9906b5a9ae28b9b449ef64b50465a46426ab11c5 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 01:52:04 +0300 Subject: [PATCH 154/338] update document.static --- manager/actions/document_data.static.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager/actions/document_data.static.php b/manager/actions/document_data.static.php index 35ef1ce659..130c968dd8 100644 --- a/manager/actions/document_data.static.php +++ b/manager/actions/document_data.static.php @@ -96,7 +96,7 @@ // $rowHeaderClass = 'gridHeader'; // $rowRegularClass = 'gridItem'; // $rowAlternateClass = 'gridAltItem'; - $tableClass = 'table data'; + $tableClass = 'table data nowrap'; $columnHeaderClass = array( 'text-center', 'text-left', @@ -188,7 +188,7 @@ //$class .= ($children['hidemenu'] ? ' text-muted' : ' text-primary'); //$class .= ($children['isfolder'] ? ' font-weight-bold' : ''); if($modx->hasPermission('edit_document')) { - $title = '' . $icon . '' . $children['pagetitle'] . ''; + $title = '' . $icon . '' . '' . $children['pagetitle'] . ''; } else { $title = '' . $icon . '' . $children['pagetitle'] . ''; } From 7df8acaf4d18ad8b1b468086b6d7563fff4170c8 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 02:44:28 +0300 Subject: [PATCH 155/338] update evo tooltip --- manager/includes/header.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index f70031d0f0..596549f39a 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -109,7 +109,7 @@ function document_onload() let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); [].slice.call(a).forEach(function(f) { f.addEventListener('mouseenter', function(e) { - b.innerHTML = (this.dataset && this.dataset.tooltip ? this.dataset.tooltip : this.innerHTML); + b.innerHTML = (this.dataset && this.dataset.tooltip ? (this.dataset.tooltip[0] === '#' ? document.querySelector(this.dataset.tooltip).innerHTML : this.dataset.tooltip) : this.innerHTML); if (e.pageX + b.offsetWidth + (c * 2) > window.innerWidth) { b.style.left = Math.round(e.pageX - b.offsetWidth - (c * 2)) + 'px'; b.classList.add('evo-tooltip-right'); From 48767ee7b8b20c6013a241b2839ca294a4eb36ed Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 02:47:08 +0300 Subject: [PATCH 156/338] update manager categories refactor code, replace jQuery, Mootools --- .../actions/category_mgr/skin/add.tpl.phtml | 47 +++---- .../category_mgr/skin/categorize.tpl.phtml | 49 +++----- .../edit/assigned_elements_collapse.tpl.phtml | 8 +- .../actions/category_mgr/skin/edit.tpl.phtml | 105 ++++++++-------- .../category_mgr/skin/js/categories.js | 34 ++--- .../actions/category_mgr/skin/main.tpl.phtml | 117 ++++++++++-------- .../actions/category_mgr/skin/sort.tpl.phtml | 76 ++++++------ 7 files changed, 213 insertions(+), 223 deletions(-) diff --git a/manager/actions/category_mgr/skin/add.tpl.phtml b/manager/actions/category_mgr/skin/add.tpl.phtml index 1051ec9bc0..c5b0e49afb 100644 --- a/manager/actions/category_mgr/skin/add.tpl.phtml +++ b/manager/actions/category_mgr/skin/add.tpl.phtml @@ -1,29 +1,20 @@
    - - -

    - Add a new category to the Manager. -

    - - - - - - - - - - - - - - -
    txt('cm_category_name'); ?>txt('cm_category_position'); ?>
    -
    \ No newline at end of file + + +

    + Add a new category to the Manager. +

    +
    +
    + + +
    +
    + + +
    +
    + diff --git a/manager/actions/category_mgr/skin/categorize.tpl.phtml b/manager/actions/category_mgr/skin/categorize.tpl.phtml index 1a529cfc5e..0c0041d902 100644 --- a/manager/actions/category_mgr/skin/categorize.tpl.phtml +++ b/manager/actions/category_mgr/skin/categorize.tpl.phtml @@ -1,30 +1,21 @@
    - - -

    - Categorize elements easily by dragging them into categories. -

    - -
    - renderView('chunks/categorize/elements_select'); ?> -
    - - - - - -
    \ No newline at end of file + + +

    + Categorize elements easily by dragging them into categories. +

    +
    + renderView('chunks/categorize/elements_select'); ?> +
    + + + diff --git a/manager/actions/category_mgr/skin/chunks/edit/assigned_elements_collapse.tpl.phtml b/manager/actions/category_mgr/skin/chunks/edit/assigned_elements_collapse.tpl.phtml index b1c9fc8deb..58eba8adc5 100644 --- a/manager/actions/category_mgr/skin/chunks/edit/assigned_elements_collapse.tpl.phtml +++ b/manager/actions/category_mgr/skin/chunks/edit/assigned_elements_collapse.tpl.phtml @@ -1,8 +1,8 @@ - +
    $items ) : ?> - + @@ -10,9 +10,9 @@ $items ) : ?> - + -
    txt( $element ); ?>txt( $element ); ?>

    txt( 'none' ); ?>

    txt( 'none' ); ?>

    +
    • diff --git a/manager/actions/category_mgr/skin/edit.tpl.phtml b/manager/actions/category_mgr/skin/edit.tpl.phtml index 5bb08d5015..7be26e7d9b 100644 --- a/manager/actions/category_mgr/skin/edit.tpl.phtml +++ b/manager/actions/category_mgr/skin/edit.tpl.phtml @@ -1,54 +1,53 @@
      - - -

      - Change category name or delete category from the Manager. -

      - - - - - - - - - - - - - - - - - - - - - - - -
      txt('cm_assigned_elements'); ?>txt('cm_edit_name'); ?>txt('cm_mark_for_deletion'); ?>txt('cm_delete_now'); ?>
      - -
      renderView('chunks/edit/assigned_elements', $view->getAllAssignedElements($category['id'])); ?>
      -
      - - - - - - - txt('delete'); ?> -
      - renderView('chunks/edit/assigned_elements_collapse', $view->getAllAssignedElements($category['id'])); ?> -
      -
      \ No newline at end of file + + +

      + Change category name or delete category from the Manager. +

      +
      +
      + + + + + + + + + + + + + + + + + + + + + + +
      txt('cm_assigned_elements'); ?>txt('cm_edit_name'); ?>txt('cm_mark_for_deletion'); ?>txt('cm_delete_now'); ?>
      + +
      renderView('chunks/edit/assigned_elements', $view->getAllAssignedElements($category['id'])); ?>
      +
      + + + + + + + txt('delete'); ?> +
      + renderView('chunks/edit/assigned_elements_collapse', $view->getAllAssignedElements($category['id'])); ?> +
      +
      +
      + diff --git a/manager/actions/category_mgr/skin/js/categories.js b/manager/actions/category_mgr/skin/js/categories.js index 6c4010ce84..4e82761675 100644 --- a/manager/actions/category_mgr/skin/js/categories.js +++ b/manager/actions/category_mgr/skin/js/categories.js @@ -4,16 +4,16 @@ /** * Tips */ -new Tips($$('.mootooltip'),{className:'custom'} ); -new MooTips($$('.mootooltip_dom'), { - className :'assigned', - showOnClick: true, - showOnMouseEnter: true, - showDelay: 200, - hideDelay: 200, - offsets: {'x': 20, 'y': 20}, - fixed: true -}); +//new Tips($$('.mootooltip'),{className:'custom'} ); +//new MooTips($$('.mootooltip_dom'), { +// className :'assigned', +// showOnClick: true, +// showOnMouseEnter: true, +// showDelay: 200, +// hideDelay: 200, +// offsets: {'x': 20, 'y': 20}, +// fixed: true +//}); /** * Sort Categories @@ -29,10 +29,10 @@ new Sortables($('categories-sort'), { this.list.getChildren().each(function(element, i){ element.getElement('input.sort').setProperty( 'value', (i+1) ); element.getElement('span.sort').setHTML( (i+1) ); - element.getElements('td').each(function(td){ - td.removeClass('gridItem').removeClass('gridAltItem'); - td.addClass( ( i%2===0 ) ? 'gridItem' : 'gridAltItem' ); - }); +// element.getElements('td').each(function(td){ +// td.removeClass('gridItem').removeClass('gridAltItem'); +// td.addClass( ( i%2===0 ) ? 'gridItem' : 'gridAltItem' ); +// }); }); } }); @@ -42,7 +42,7 @@ new Sortables($('categories-sort'), { */ var reset_position = function( drag ) { drag.setStyles({ left:0+"px", top:0+"px" }); -} +}; var optDrop = { over: function(drag) { @@ -58,7 +58,7 @@ var optDrop = { drag.injectInside(this); reset_position(drag); } -} +}; var optDrag = { onStart: function(drag) { @@ -68,7 +68,7 @@ var optDrag = { drag.setOpacity(1).setStyle('z-index', 1000); reset_position(drag); } -} +}; var init_drag = function() { diff --git a/manager/actions/category_mgr/skin/main.tpl.phtml b/manager/actions/category_mgr/skin/main.tpl.phtml index 6a37d13bd7..02dc743bef 100644 --- a/manager/actions/category_mgr/skin/main.tpl.phtml +++ b/manager/actions/category_mgr/skin/main.tpl.phtml @@ -1,77 +1,88 @@ - -js_output)) : ?> - + +js_output)) : ?> +

      - get('name') ?> + get('name') ?>

      -
      + + renderView('chunks/db_setup') ?> + - - renderView('chunks/db_setup') ?> - +
      - renderView('chunks/messages', $view->getMessages('global')) ?> +
      renderView('chunks/messages', $view->getMessages('global')) ?>
      -
      - +
      + -
      -

      txt('cm_add_new_category') ?>

      - - renderView('chunks/messages', $view->getMessages('add')) ?> - renderView('add') ?> -
      +
      +

      txt('cm_add_new_category') ?>

      + +
      + renderView('chunks/messages', $view->getMessages('add')) ?> + renderView('add') ?> +
      +
      - + -
      -

      txt('cm_edit_categories') ?>

      - - renderView('chunks/messages', $view->getMessages('edit')) ?> - renderView('edit', $data) ?> -
      +
      +

      txt('cm_edit_categories') ?>

      + +
      + renderView('chunks/messages', $view->getMessages('edit')) ?> + renderView('edit', $data) ?> +
      +
      -
      -

      txt('cm_sort_categories') ?>

      - - renderView('chunks/messages', $view->getMessages('sort')) ?> - renderView('sort', $data) ?> -
      +
      +

      txt('cm_sort_categories') ?>

      + +
      + renderView('chunks/messages', $view->getMessages('sort')) ?> + renderView('sort', $data) ?> +
      +
      -
      -

      txt('cm_categorize_elements') ?>

      - - renderView('chunks/messages', $view->getMessages('categorize')) ?> - renderView('categorize', $data) ?> -
      +
      +

      txt('cm_categorize_elements') ?>

      + +
      + renderView('chunks/messages', $view->getMessages('categorize')) ?> + renderView('categorize', $data) ?> +
      +
      - + - new_translations[$view->get('manager_language')] && !empty($view->new_translations[$view->get('manager_language')])) : ?> + new_translations[$view->get('manager_language')] && !empty($view->new_translations[$view->get('manager_language')])) : ?> -
      -

      txt('Translations') ?>

      - - renderView('chunks/messages', $view->getMessages('translate')) ?> - renderView('translate', $view->new_translations[$view->get('manager_language')]) ?> -
      +
      +

      txt('Translations') ?>

      + +
      + renderView('chunks/messages', $view->getMessages('translate')) ?> + renderView('translate', $view->new_translations[$view->get('manager_language')]) ?> +
      +
      - + -
      +
      - +
      + + -
      - - - - - - - - - - - - - - - -
      txt('category_heading') ?>txt('position') ?>
      - - - - - - - - -
      + + +

      + Drag category up or down to change its rank. Can be very useful when used with CategorizedTabs plugin to change tabs order. +

      +
      +
      + + + + + + + + + + + + + + + +
      txt('category_heading') ?>txt('position') ?>
      + + + + + + + +
      +
      +
      From 35070b9e1af60ee7b02c7c355eccf6ef1c4bb1fe Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 02:47:46 +0300 Subject: [PATCH 157/338] remove unused css files --- .../media/style/default/css/actionbuttons.css | 48 --------------- .../style/default/css/actionsbuttons.css | 48 --------------- manager/media/style/default/css/cols.css | 6 -- .../media/style/default/css/datepicker.css | 19 ------ manager/media/style/default/css/tables.css | 61 ------------------- manager/media/style/default/css/widgets.css | 25 -------- 6 files changed, 207 deletions(-) delete mode 100644 manager/media/style/default/css/actionbuttons.css delete mode 100644 manager/media/style/default/css/actionsbuttons.css delete mode 100644 manager/media/style/default/css/cols.css delete mode 100644 manager/media/style/default/css/datepicker.css delete mode 100644 manager/media/style/default/css/tables.css delete mode 100644 manager/media/style/default/css/widgets.css diff --git a/manager/media/style/default/css/actionbuttons.css b/manager/media/style/default/css/actionbuttons.css deleted file mode 100644 index 0418c5d1d2..0000000000 --- a/manager/media/style/default/css/actionbuttons.css +++ /dev/null @@ -1,48 +0,0 @@ -/* -------------------------[ Action Buttons ]--- */ -#actions { background: rgba(199, 199, 199, 0.25); padding: 0.5rem; position: fixed; top: 0; right: 1rem; text-align: right; z-index: 100; border-radius: 0 0 0.3rem 0.3rem; } -#actions .btn-group > .btn-group { display: block } -#actions .btn-group .btn { font-size: 0.675rem; height: 2.5em } -#actions .btn-group .btn .fa { display: none; width: 1em; font-size: 1em; text-align: center } -#actions .btn-group .btn-group #Button1 { min-width: 100%; text-align: left; } -#actions .btn-group .btn-group .btn-success { box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .07); } -#actions .btn-group .btn-group .btn-success:hover { box-shadow: none } -#actions .btn-group .plus { z-index: 2; float: right; margin: -2.5em 0 0 0; width: 2rem; padding-left: 0; padding-right: 0; text-align: center } -#actions .btn-group select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; margin: -100% 0 -2rem 0; font-size: 0.675rem; opacity: 0; visibility: hidden; } -#actions .btn-group .dropdown-menu { display: none; position: absolute; z-index: -1; left: auto; right: 0; top: 100%; width: 100%; min-width: 2rem; margin: -2px 0 0; padding: 2px 0 0; text-align: left; font-size: 0.675rem; border-top: none; border-radius: 0 0 0.1em 0.1em; overflow: hidden; } -#actions .btn-group .show > .dropdown-menu { display: block } -#actions .btn-group .dropdown-menu > span { display: block; margin: 0; text-align: left } -#actions .btn-group .dropdown-menu > span:hover { background-color: #e6e6e6; } -#actions .btn-group .dropdown-toggle::after { margin: 0; border-width: 0.4em; transition-duration: 0.25s } -#actions .btn-group .show .dropdown-toggle::after { transform: rotate(180deg) } -@media (max-width: 840px) { -#actions { right: 0 } -#actions .btn-group .btn span, #actions .btn-group select#stay { display: none } -#actions .btn-group .btn .fa { display: inline-block } -#actions .btn-group .dropdown-menu { width: 2rem } -#actions .btn-group .dropdown-menu span { padding-left: 0; padding-right: 0; text-align: center } -} -/* old style */ -#actions .actionButtons { float: left; min-height: 32px } -#actions .actionButtons li { position: relative; float: left; margin-right: 3px; border: none } -#actions .actionButtons li a, #actions .actionButtons .plus { float: left; padding: 0 10px !important; height: 32px; line-height: 30px; -webkit-user-select: none; user-select: none; } -#actions .actionButtons li:last-child { margin: 0 } -#actions .actionButtons #Button1 a { width: 100%; text-align: left; } -#actions .actionButtons .plus { overflow: hidden; float: right; margin: -32px 0 0 0; width: 35px; border-radius: 0 3px 3px 0 !important; text-align: center; cursor: default; font: normal normal normal 0/30px FontAwesome } -#actions .actionButtons .plus::before { content: "\f107"; font-size: 14px } -#actions .actionButtons .show .plus::before { content: "\f106"; } -#actions .actionButtons .dropdown-menu { display: none; position: absolute; z-index: -1; left: auto; right: 0; top: 100%; width: 100%; min-width: 35px; margin: -2px 0 0; padding: 2px 0 0; text-align: left; font-size: 1em; background-color: #fff; border: 1px solid #32ab9a; border-top: none; border-radius: 0 0 3px 3px; overflow: hidden; } -#actions .actionButtons .show > .dropdown-menu { display: block } -#actions .actionButtons .dropdown-menu > span { display: block; padding: 0 10px; height: 32px; line-height: 30px; border: none; border-top: 1px solid #f2f2f2; cursor: pointer; } -#actions .actionButtons .dropdown-menu > span:hover { background-color: #fbfbfb; } -#actions .actionButtons select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; padding: 0 10px; margin: -100% 0 -32px 0; font-size: 1em; opacity: 0; visibility: hidden; } -#actions .actionButtons #Button1 a, #actions .actionButtons .plus { color: #fff; border-color: #32AB9A; background: #32AB9A linear-gradient(#32AB9A, #00948E); } -#actions .actionButtons #Button1 a:hover, #actions .actionButtons .plus:hover { background: #2b9385 linear-gradient(#2b9385, #007571); border-color: #2b9385; } -#actions .actionButtons #Button1 a:active, #actions .actionButtons .plus:active { background: #32AB9A; border-color: #32AB9A; } -@media (max-width: 900px) { -#actions .actionButtons li a, #actions .actionButtons .dropdown-menu span { font-size: 0 } -#actions .actionButtons li a .fa, #actions .actionButtons .dropdown-menu span .fa { display: inline-block; font-size: 14px; line-height: 30px } -#actions .actionButtons .dropdown-menu { width: 35px } -#actions .actionButtons #Button1 a { margin: 0; width: auto } -#actions .actionButtons .plus { margin: 0 0 0 -2px } -#actions .actionButtons select#stay { display: none } -} diff --git a/manager/media/style/default/css/actionsbuttons.css b/manager/media/style/default/css/actionsbuttons.css deleted file mode 100644 index a8a1fdc31f..0000000000 --- a/manager/media/style/default/css/actionsbuttons.css +++ /dev/null @@ -1,48 +0,0 @@ -/* -------------------------[ Action Buttons ]--- */ -#actions { background: none repeat scroll 0 0 rgba(230, 230, 230, 0.8); padding: 8px; position: fixed; top: 0; right: 1rem; text-align: right; z-index: 100; -moz-border-radius: 0 0 5px 5px; -webkit-border-radius: 0 0 5px 5px; border-radius: 0 0 5px 5px; } -#actions .btn-group > .btn-group { display: block } -#actions .btn-group .btn { font-size: 0.675rem } -#actions .btn-group .btn .fa { display: none; width: 1em; font-size: 1em; text-align: center } -#actions .btn-group .btn-group #Button1 { min-width: 100%; text-align: left; } -#actions .btn-group .btn-group .btn-success { box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .07); } -#actions .btn-group .btn-group .btn-success:hover { box-shadow: none } -#actions .btn-group .plus { z-index: 2; float: right; margin: -1.65rem 0 0 0; width: 2rem; padding-left: 0; padding-right: 0; text-align: center } -#actions .btn-group select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; margin: -100% 0 -2rem 0; font-size: 0.675rem; opacity: 0; visibility: hidden; } -#actions .btn-group .dropdown-menu { display: none; position: absolute; z-index: -1; left: auto; right: 0; top: 100%; width: 100%; min-width: 2rem; margin: -2px 0 0; padding: 2px 0 0; text-align: left; font-size: 0.675rem; border-top: none; border-radius: 0 0 0.1em 0.1em; overflow: hidden; } -#actions .btn-group .show > .dropdown-menu { display: block } -#actions .btn-group .dropdown-menu > span { display: block; margin: 0; text-align: left } -#actions .btn-group .dropdown-menu > span:hover { background-color: #e6e6e6; } -#actions .btn-group .dropdown-toggle::after { margin: 0; border-width: 0.4em; transition-duration: 0.25s } -#actions .btn-group .show .dropdown-toggle::after { transform: rotate(180deg) } -@media (max-width: 840px) { -#actions { right: 0 } -#actions .btn-group .btn span, #actions .btn-group select#stay { display: none } -#actions .btn-group .btn .fa { display: inline-block } -#actions .btn-group .dropdown-menu { width: 2rem } -#actions .btn-group .dropdown-menu span { padding-left: 0; padding-right: 0; text-align: center } -} -/* old style */ -#actions .actionButtons { float: left; min-height: 32px } -#actions .actionButtons li { position: relative; float: left; margin-right: 3px; border: none } -#actions .actionButtons li a, #actions .actionButtons .plus { float: left; padding: 0 10px !important; height: 32px; line-height: 30px; -webkit-user-select: none; user-select: none; } -#actions .actionButtons li:last-child { margin: 0 } -#actions .actionButtons #Button1 a { width: 100%; text-align: left; } -#actions .actionButtons .plus { overflow: hidden; float: right; margin: -32px 0 0 0; width: 35px; border-radius: 0 3px 3px 0 !important; text-align: center; cursor: default; font: normal normal normal 0/30px FontAwesome } -#actions .actionButtons .plus::before { content: "\f107"; font-size: 14px } -#actions .actionButtons .show .plus::before { content: "\f106"; } -#actions .actionButtons .dropdown-menu { display: none; position: absolute; z-index: -1; left: auto; right: 0; top: 100%; width: 100%; min-width: 35px; margin: -2px 0 0; padding: 2px 0 0; text-align: left; font-size: 1em; background-color: #fff; border: 1px solid #32ab9a; border-top: none; border-radius: 0 0 3px 3px; overflow: hidden; } -#actions .actionButtons .show > .dropdown-menu { display: block } -#actions .actionButtons .dropdown-menu > span { display: block; padding: 0 10px; height: 32px; line-height: 30px; border: none; border-top: 1px solid #f2f2f2; cursor: pointer; } -#actions .actionButtons .dropdown-menu > span:hover { background-color: #fbfbfb; } -#actions .actionButtons select#stay { display: block; position: relative; z-index: -1; clear: both; width: auto; height: 0; padding: 0 10px; margin: -100% 0 -32px 0; font-size: 1em; opacity: 0; visibility: hidden; } -#actions .actionButtons #Button1 a, #actions .actionButtons .plus { color: #fff; border-color: #32AB9A; background: #32AB9A linear-gradient(#32AB9A, #00948E); } -#actions .actionButtons #Button1 a:hover, #actions .actionButtons .plus:hover { background: #2b9385 linear-gradient(#2b9385, #007571); border-color: #2b9385; } -#actions .actionButtons #Button1 a:active, #actions .actionButtons .plus:active { background: #32AB9A; border-color: #32AB9A; } -@media (max-width: 900px) { -#actions .actionButtons li a, #actions .actionButtons .dropdown-menu span { font-size: 0 } -#actions .actionButtons li a .fa, #actions .actionButtons .dropdown-menu span .fa { display: inline-block; font-size: 14px; line-height: 30px } -#actions .actionButtons .dropdown-menu { width: 35px } -#actions .actionButtons #Button1 a { margin: 0; width: auto } -#actions .actionButtons .plus { margin: 0 0 0 -2px } -#actions .actionButtons select#stay { display: none } -} \ No newline at end of file diff --git a/manager/media/style/default/css/cols.css b/manager/media/style/default/css/cols.css deleted file mode 100644 index 2cac490e01..0000000000 --- a/manager/media/style/default/css/cols.css +++ /dev/null @@ -1,6 +0,0 @@ -.container{position:relative;margin-left:auto;margin-right:auto;padding-right:1rem;padding-left:1rem}@media (min-width:576px){.container{padding-right:1rem;padding-left:1rem}}@media (min-width:768px){.container{padding-right:1rem;padding-left:1rem}}@media (min-width:992px){.container{padding-right:1rem;padding-left:1rem}}@media (min-width:1200px){.container{padding-right:1rem;padding-left:1rem}}@media (min-width:576px){.container{width:540px;max-width:100%}}@media (min-width:768px){.container{width:720px;max-width:100%}}@media (min-width:992px){.container{width:960px;max-width:100%}}@media (min-width:1200px){.container{width:1140px;max-width:100%}}.container-fluid{position:relative;margin-left:auto;margin-right:auto;padding-right:1rem;padding-left:1rem}@media (min-width:576px){.container-fluid{padding-right:1rem;padding-left:1rem}}@media (min-width:768px){.container-fluid{padding-right:1rem;padding-left:1rem}}@media (min-width:992px){.container-fluid{padding-right:1rem;padding-left:1rem}}@media (min-width:1200px){.container-fluid{padding-right:1rem;padding-left:1rem}}.row{margin-right:-1rem;margin-left:-1rem}@media (min-width:576px){.row{margin-right:-1rem;margin-left:-1rem}}@media (min-width:768px){.row{margin-right:-1rem;margin-left:-1rem}}@media (min-width:992px){.row{margin-right:-1rem;margin-left:-1rem}}@media (min-width:1200px){.row{margin-right:-1rem;margin-left:-1rem}}.no-gutters{margin-right:0;margin-left:0}.no-gutters > .col,.no-gutters > [class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{position:relative;width:100%;min-height:1px;padding-right:1rem;padding-left:1rem}@media (min-width:576px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:1rem;padding-left:1rem}}@media (min-width:768px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:1rem;padding-left:1rem}}@media (min-width:992px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:1rem;padding-left:1rem}}@media (min-width:1200px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:1rem;padding-left:1rem}}.col{max-width:100%}.col-auto{width:auto}.col-1{max-width:8.333333%}.col-2{max-width:16.666667%}.col-3{max-width:25%}.col-4{max-width:33.333333%}.col-5{max-width:41.666667%}.col-6{max-width:50%}.col-7{max-width:58.333333%}.col-8{max-width:66.666667%}.col-9{max-width:75%}.col-10{max-width:83.333333%}.col-11{max-width:91.666667%}.col-12{max-width:100%}.pull-0{right:auto}.pull-1{right:8.333333%}.pull-2{right:16.666667%}.pull-3{right:25%}.pull-4{right:33.333333%}.pull-5{right:41.666667%}.pull-6{right:50%}.pull-7{right:58.333333%}.pull-8{right:66.666667%}.pull-9{right:75%}.pull-10{right:83.333333%}.pull-11{right:91.666667%}.pull-12{right:100%}.push-0{left:auto}.push-1{left:8.333333%}.push-2{left:16.666667%}.push-3{left:25%}.push-4{left:33.333333%}.push-5{left:41.666667%}.push-6{left:50%}.push-7{left:58.333333%}.push-8{left:66.666667%}.push-9{left:75%}.push-10{left:83.333333%}.push-11{left:91.666667%}.push-12{left:100%}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{max-width:100%}.col-sm-auto{width:auto}.col-sm-1{max-width:8.333333%}.col-sm-2{max-width:16.666667%}.col-sm-3{max-width:25%}.col-sm-4{max-width:33.333333%}.col-sm-5{max-width:41.666667%}.col-sm-6{max-width:50%}.col-sm-7{max-width:58.333333%}.col-sm-8{max-width:66.666667%}.col-sm-9{max-width:75%}.col-sm-10{max-width:83.333333%}.col-sm-11{max-width:91.666667%}.col-sm-12{max-width:100%}.pull-sm-0{right:auto}.pull-sm-1{right:8.333333%}.pull-sm-2{right:16.666667%}.pull-sm-3{right:25%}.pull-sm-4{right:33.333333%}.pull-sm-5{right:41.666667%}.pull-sm-6{right:50%}.pull-sm-7{right:58.333333%}.pull-sm-8{right:66.666667%}.pull-sm-9{right:75%}.pull-sm-10{right:83.333333%}.pull-sm-11{right:91.666667%}.pull-sm-12{right:100%}.push-sm-0{left:auto}.push-sm-1{left:8.333333%}.push-sm-2{left:16.666667%}.push-sm-3{left:25%}.push-sm-4{left:33.333333%}.push-sm-5{left:41.666667%}.push-sm-6{left:50%}.push-sm-7{left:58.333333%}.push-sm-8{left:66.666667%}.push-sm-9{left:75%}.push-sm-10{left:83.333333%}.push-sm-11{left:91.666667%}.push-sm-12{left:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{max-width:100%}.col-md-auto{width:auto}.col-md-1{max-width:8.333333%}.col-md-2{max-width:16.666667%}.col-md-3{max-width:25%}.col-md-4{max-width:33.333333%}.col-md-5{max-width:41.666667%}.col-md-6{max-width:50%}.col-md-7{max-width:58.333333%}.col-md-8{max-width:66.666667%}.col-md-9{max-width:75%}.col-md-10{max-width:83.333333%}.col-md-11{max-width:91.666667%}.col-md-12{max-width:100%}.pull-md-0{right:auto}.pull-md-1{right:8.333333%}.pull-md-2{right:16.666667%}.pull-md-3{right:25%}.pull-md-4{right:33.333333%}.pull-md-5{right:41.666667%}.pull-md-6{right:50%}.pull-md-7{right:58.333333%}.pull-md-8{right:66.666667%}.pull-md-9{right:75%}.pull-md-10{right:83.333333%}.pull-md-11{right:91.666667%}.pull-md-12{right:100%}.push-md-0{left:auto}.push-md-1{left:8.333333%}.push-md-2{left:16.666667%}.push-md-3{left:25%}.push-md-4{left:33.333333%}.push-md-5{left:41.666667%}.push-md-6{left:50%}.push-md-7{left:58.333333%}.push-md-8{left:66.666667%}.push-md-9{left:75%}.push-md-10{left:83.333333%}.push-md-11{left:91.666667%}.push-md-12{left:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{max-width:100%}.col-lg-auto{width:auto}.col-lg-1{max-width:8.333333%}.col-lg-2{max-width:16.666667%}.col-lg-3{max-width:25%}.col-lg-4{max-width:33.333333%}.col-lg-5{max-width:41.666667%}.col-lg-6{max-width:50%}.col-lg-7{max-width:58.333333%}.col-lg-8{max-width:66.666667%}.col-lg-9{max-width:75%}.col-lg-10{max-width:83.333333%}.col-lg-11{max-width:91.666667%}.col-lg-12{max-width:100%}.pull-lg-0{right:auto}.pull-lg-1{right:8.333333%}.pull-lg-2{right:16.666667%}.pull-lg-3{right:25%}.pull-lg-4{right:33.333333%}.pull-lg-5{right:41.666667%}.pull-lg-6{right:50%}.pull-lg-7{right:58.333333%}.pull-lg-8{right:66.666667%}.pull-lg-9{right:75%}.pull-lg-10{right:83.333333%}.pull-lg-11{right:91.666667%}.pull-lg-12{right:100%}.push-lg-0{left:auto}.push-lg-1{left:8.333333%}.push-lg-2{left:16.666667%}.push-lg-3{left:25%}.push-lg-4{left:33.333333%}.push-lg-5{left:41.666667%}.push-lg-6{left:50%}.push-lg-7{left:58.333333%}.push-lg-8{left:66.666667%}.push-lg-9{left:75%}.push-lg-10{left:83.333333%}.push-lg-11{left:91.666667%}.push-lg-12{left:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{max-width:100%}.col-xl-auto{width:auto}.col-xl-1{max-width:8.333333%}.col-xl-2{max-width:16.666667%}.col-xl-3{max-width:25%}.col-xl-4{max-width:33.333333%}.col-xl-5{max-width:41.666667%}.col-xl-6{max-width:50%}.col-xl-7{max-width:58.333333%}.col-xl-8{max-width:66.666667%}.col-xl-9{max-width:75%}.col-xl-10{max-width:83.333333%}.col-xl-11{max-width:91.666667%}.col-xl-12{max-width:100%}.pull-xl-0{right:auto}.pull-xl-1{right:8.333333%}.pull-xl-2{right:16.666667%}.pull-xl-3{right:25%}.pull-xl-4{right:33.333333%}.pull-xl-5{right:41.666667%}.pull-xl-6{right:50%}.pull-xl-7{right:58.333333%}.pull-xl-8{right:66.666667%}.pull-xl-9{right:75%}.pull-xl-10{right:83.333333%}.pull-xl-11{right:91.666667%}.pull-xl-12{right:100%}.push-xl-0{left:auto}.push-xl-1{left:8.333333%}.push-xl-2{left:16.666667%}.push-xl-3{left:25%}.push-xl-4{left:33.333333%}.push-xl-5{left:41.666667%}.push-xl-6{left:50%}.push-xl-7{left:58.333333%}.push-xl-8{left:66.666667%}.push-xl-9{left:75%}.push-xl-10{left:83.333333%}.push-xl-11{left:91.666667%}.push-xl-12{left:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}} -/* custom */ -.row { margin-left: -1.3rem; margin-right: -1.3rem } -.container { padding-left: 1.3rem; padding-right: 1.3rem; width: 100% } -.container-body { padding:1.3rem } -.navbar.navbar-editor { padding: .5rem 1.3rem; border-radius: 0 } diff --git a/manager/media/style/default/css/datepicker.css b/manager/media/style/default/css/datepicker.css deleted file mode 100644 index b1bfb56503..0000000000 --- a/manager/media/style/default/css/datepicker.css +++ /dev/null @@ -1,19 +0,0 @@ -/* [ datepicker ] */ -.dp_container { position: absolute; z-index: 500; } -.dp_cal { overflow: hidden; width: 220px; margin: 0.25rem 0; background-color: #fff; -webkit-box-shadow: 0 0.3rem 1rem rgba(0, 0, 0, 0.3); box-shadow: 0 0.3rem 1rem rgba(0, 0, 0, 0.3); } -.dp_cal p { position: relative; margin: 10px; } -.dp_cal select { font-size: 1em; margin: 2px 3px; width: auto !important } -.dp_cal select option { padding: 1px 3px } -.dp_cal table { border-collapse: collapse; border-spacing: 0; width: 100% } -.dp_cal td.dp_roll { background-color: rgba(0, 0, 0, 0.1); color: #333 !important } -.dp_cal th, .dp_cal td { font-size: 1em; padding: 0.5em 0 !important; text-align: center !important; width: 14.2857%; cursor: default } -.dp_cal tbody th { background-color: #656d79; color: #fff; } -.dp_cal tbody td:nth-child(6), .dp_cal tbody td:nth-child(7) { color: indianred } -.dp_cal .dp_empty { background-color: #f9f9f9 } -.dp_cal .dp_hide { visibility: hidden } -.dp_cal .dp_today { background-color: #4caf50; color: #fff !important } -.dp_cal .dp_selected { background-color: #3189ba; color: #fff !important } -.dp_cal input { width: 68% !important } -.dp_cal button { position: absolute; top: 0; right: 0; margin: 0 !important; width: 30% !important } -/* datepicker icon clear */ -.clearDate { position: relative; margin: 0.5rem 0 0 -1.5rem; } diff --git a/manager/media/style/default/css/tables.css b/manager/media/style/default/css/tables.css deleted file mode 100644 index 1481313faa..0000000000 --- a/manager/media/style/default/css/tables.css +++ /dev/null @@ -1,61 +0,0 @@ -table { border-collapse: collapse; background-color: transparent } -caption { padding-top: .75rem; padding-bottom: .75rem; color: #636c72; text-align: left; caption-side: bottom } -th { text-align: left } -summary { display: list-item } -summary { display: list-item } -.table { width: 100%; max-width: 100%; margin-bottom: 1rem } -.table td, .table th { padding: .75rem; vertical-align: top; border-top: 1px solid #eceeef } -.table thead th { vertical-align: bottom; border-bottom: 2px solid #eceeef } -.table tbody + tbody { border-top: 2px solid #eceeef } -.table .table { background-color: #fff } -.table-sm td, .table-sm th { padding: .3rem } -.table-bordered { border: 1px solid #eceeef } -.table-bordered td, .table-bordered th { border: 1px solid #eceeef } -.table-bordered thead td, .table-bordered thead th { border-bottom-width: 2px } -.table-striped tbody tr:nth-of-type(odd) { background-color: rgba(0, 0, 0, .05) } -.table-hover tbody tr:hover { background-color: rgba(0, 0, 0, .075) } -.table-active, .table-active > td, .table-active > th { background-color: rgba(0, 0, 0, .075) } -.table-hover .table-active:hover { background-color: rgba(0, 0, 0, .075) } -.table-hover .table-active:hover > td, .table-hover .table-active:hover > th { background-color: rgba(0, 0, 0, .075) } -.table-success, .table-success > td, .table-success > th { background-color: #dff0d8 } -.table-hover .table-success:hover { background-color: #d0e9c6 } -.table-hover .table-success:hover > td, .table-hover .table-success:hover > th { background-color: #d0e9c6 } -.table-info, .table-info > td, .table-info > th { background-color: #d9edf7 } -.table-hover .table-info:hover { background-color: #c4e3f3 } -.table-hover .table-info:hover > td, .table-hover .table-info:hover > th { background-color: #c4e3f3 } -.table-warning, .table-warning > td, .table-warning > th { background-color: #fcf8e3 } -.table-hover .table-warning:hover { background-color: #faf2cc } -.table-hover .table-warning:hover > td, .table-hover .table-warning:hover > th { background-color: #faf2cc } -.table-danger, .table-danger > td, .table-danger > th { background-color: #f2dede } -.table-hover .table-danger:hover { background-color: #ebcccc } -.table-hover .table-danger:hover > td, .table-hover .table-danger:hover > th { background-color: #ebcccc } -.thead-inverse th { color: #fff; background-color: #292b2c } -.thead-default th { color: #464a4c; background-color: #eceeef } -.table-inverse { color: #fff; background-color: #292b2c } -.table-inverse td, .table-inverse th, .table-inverse thead th { border-color: #fff } -.table-inverse.table-bordered { border: 0 } -.table-responsive { display: block; width: 100%; overflow-x: auto; -ms-overflow-style: -ms-autohiding-scrollbar } -.table-responsive.table-bordered { border: 0 } -/* table-data */ -.table.data { width: 100%; max-width: 100%; margin-bottom: 0; border-bottom: 1px solid #eceeef } -.table.data th { padding: 0.75rem; text-transform: uppercase; white-space: nowrap; font-size: 0.675rem; color: #777 } -.table.data td { padding: 0.55rem 0.75rem; } -.table.data td, .table th { vertical-align: top; border-top: 1px solid #eceeef } -.table.data td:first-child, .table.data th:first-child { padding-left: 1.3rem } -.table.data td:last-child, .table.data th:last-child { padding-right: 1.3rem } -.table.data thead { background-color: #fff; } -.table.data > tbody > tr { background-color: #f9f9f9; transition-duration: .5s } -.table.data > tbody > tr:nth-child(2n) { background-color: #fff } -.table.data > tbody > tr:hover { cursor: default; background-color: rgba(93, 109, 202, 0.16); transition-duration: .05s } -.table.data a { color: #555 } -.table.data .actions { white-space: nowrap } -.table.data .actions a .fa { position: relative; margin: 0 0.4rem; font-size: 0.9rem; } -.table.data .actions a:hover .fa { color: #000; } -.table.data .actions a:hover .fa.fa-trash { color: #d80030 } -.table.data .actions a .fa::before { position: relative; z-index: 2; } -.table.data .actions a .fa::after { content: ""; position: absolute; z-index: 1; left: 50%; top: 50%; width: 1.5rem; height: 1.5rem; margin: -0.75rem 0 0 -0.75rem; border-radius: 50%; -webkit-transition: 0.15s; transition: 0.15s; } -.table.data .actions a:hover .fa::after { background-color: #fff } -/* table-data-docs */ -.table.data .doc-item .fa { width: 1.2em; font-size: 0.9rem; text-align: center; margin-right: 0.25rem } -.table.data .doc-item { text-decoration: none } -.table.data .doc-item:hover span { text-decoration: underline } diff --git a/manager/media/style/default/css/widgets.css b/manager/media/style/default/css/widgets.css deleted file mode 100644 index 73dbd3878c..0000000000 --- a/manager/media/style/default/css/widgets.css +++ /dev/null @@ -1,25 +0,0 @@ -/* widgets */ -.widgets .card { margin-bottom: .75rem; border: none; border-radius: 0.15rem; background-color: #fff; box-shadow: 0 0 0.1rem 0 rgba(0, 0, 0, 0.1), 0 0.1rem 0.3rem rgba(0, 0, 0, 0.05) } -.widgets .card-header { padding: .75rem 1rem; font-size: .675rem; color: #616a73; text-transform: uppercase; font-weight: 900; border: none; background-color: #f2f2f2; } -.widgets .card-header .fa { font-size: .9rem } -.widgets .card-block { padding: 0; } -.widgets .card-block .card-block p { padding: 0 1rem } -.widgets .card-block .card-body { padding: 1rem; } -.widgets .card-block .card-body + .card-body { padding-top: 0 } -.widgets .table { margin-bottom: 1rem } -.widgets .table:not(.data) tr th, .widgets .table:not(.data) tr td { padding: .15rem; } -.widgets .table tr th:first-child, .widgets .table tr td:first-child { padding-left: 1rem !important } -.widgets .table tr th:last-child, .widgets .table tr td:last-child { padding-right: 1rem !important } -.widgets .table .actions a .fa { margin: 0 .05rem; } -/* custom */ -.widgets #welcome .wm_buttons { text-align: center } -.widgets #welcome .wm_button { display: inline-block; margin: 0 .15rem .5rem; } -.widgets #welcome .wm_button a { display: inline-block; text-decoration: none; color: #646b7b; padding: .25rem; /*min-width: 6rem; background-color: #f9f9f9;*/ border-radius: 0.25rem; box-shadow: none; transition-duration: .5s } -.widgets #welcome .wm_button a:hover { color: #373b46; background-color: #f2f2f2 } -.widgets #welcome .wm_button a .fa { display: inline-block; } -.widgets #welcome .wm_button a .fa + span { display: block; font-size:.7rem; } -.widgets #modxrecent_widget .table.data tbody tr:not(:hover) { background-color: #fff } -.widgets #modxrecent_widget .table.data tbody tr:nth-child(4n+1):not(:hover) { background-color: #f6f8f8 } -.widgets #modxrecent_widget .table.data tbody tr:nth-child(2n) { background-color: #fff } -/* dark */ -/*.dark .widgets .card-header { color: #fff; background-color: #282c34 }*/ From 2fb69eab1d5c82bd9e5ff0ca12c772883ebd3caa Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Thu, 3 Aug 2017 02:48:26 +0300 Subject: [PATCH 158/338] update default style refactor --- manager/media/style/default/css/custom.css | 25 ++++++++++++----- manager/media/style/default/css/page.css | 2 +- manager/media/style/default/css/tabpane.css | 8 ++++++ manager/media/style/default/style.css | 30 +-------------------- 4 files changed, 29 insertions(+), 36 deletions(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index bc9aa1723c..15545d70e9 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -3,15 +3,11 @@ .container { padding-left: 1.3rem; padding-right: 1.3rem; width: 100% } /* :TODO .container-body need remove and replace .tab-content */ .container-body { padding: 1.3rem } -.tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } -.tab-header { padding: .5rem 1.3rem; } -.tab-content { width: 100%; padding: 1.3rem; } -.tab-content::after { display: table; width: 100%; content: '' } /* [ FORMS ] */ .form-row { margin-bottom: 0.25rem; } .form-row.row { margin-left: 0; margin-right: -1rem } .form-row label { margin-bottom: 0.15rem } -.form-row .col, .form-row .col-1, .form-row .col-10, .form-row .col-11, .form-row .col-12, .form-row .col-2, .form-row .col-3, .form-row .col-4, .form-row .col-5, .form-row .col-6, .form-row .col-7, .form-row .col-8, .form-row .col-9, .form-row .col-lg, .form-row .col-lg-1, .form-row .col-lg-10, .form-row .col-lg-11, .form-row .col-lg-12, .form-row .col-lg-2, .form-row .col-lg-3, .form-row .col-lg-4, .form-row .col-lg-5, .form-row .col-lg-6, .form-row .col-lg-7, .form-row .col-lg-8, .form-row .col-lg-9, .form-row .col-md, .form-row .col-md-1, .form-row .col-md-10, .form-row .col-md-11, .form-row .col-md-12, .form-row .col-md-2, .form-row .col-md-3, .form-row .col-md-4, .form-row .col-md-5, .form-row .col-md-6, .form-row .col-md-7, .form-row .col-md-8, .form-row .col-md-9, .form-row .col-sm, .form-row .col-sm-1, .form-row .col-sm-10, .form-row .col-sm-11, .form-row .col-sm-12, .form-row .col-sm-2, .form-row .col-sm-3, .form-row .col-sm-4, .form-row .col-sm-5, .form-row .col-sm-6, .form-row .col-sm-7, .form-row .col-sm-8, .form-row .col-sm-9, .form-row .col-xl, .form-row .col-xl-1, .form-row .col-xl-10, .form-row .col-xl-11, .form-row .col-xl-12, .form-row .col-xl-2, .form-row .col-xl-3, .form-row .col-xl-4, .form-row .col-xl-5, .form-row .col-xl-6, .form-row .col-xl-7, .form-row .col-xl-8, .form-row .col-xl-9 { padding-left: 0 } +.form-row .col, .form-row .col-1, .form-row .col-10, .form-row .col-11, .form-row .col-12, .form-row .col-2, .form-row .col-3, .form-row .col-4, .form-row .col-5, .form-row .col-6, .form-row .col-7, .form-row .col-8, .form-row .col-9, .form-row .col-lg, .form-row .col-lg-1, .form-row .col-lg-10, .form-row .col-lg-11, .form-row .col-lg-12, .form-row .col-lg-2, .form-row .col-lg-3, .form-row .col-lg-4, .form-row .col-lg-5, .form-row .col-lg-6, .form-row .col-lg-7, .form-row .col-lg-8, .form-row .col-lg-9, .form-row .col-md, .form-row .col-md-1, .form-row .col-md-10, .form-row .col-md-11, .form-row .col-md-12, .form-row .col-md-2, .form-row .col-md-3, .form-row .col-md-4, .form-row .col-md-5, .form-row .col-md-6, .form-row .col-md-7, .form-row .col-md-8, .form-row .col-md-9, .form-row .col-sm, .form-row .col-sm-1, .form-row .col-sm-10, .form-row .col-sm-11, .form-row .col-sm-12, .form-row .col-sm-2, .form-row .col-sm-3, .form-row .col-sm-4, .form-row .col-sm-5, .form-row .col-sm-6, .form-row .col-sm-7, .form-row .col-sm-8, .form-row .col-sm-9, .form-row .col-xl, .form-row .col-xl-1, .form-row .col-xl-10, .form-row .col-xl-11, .form-row .col-xl-12, .form-row .col-xl-2, .form-row .col-xl-3, .form-row .col-xl-4, .form-row .col-xl-5, .form-row .col-xl-6, .form-row .col-xl-7, .form-row .col-xl-8, .form-row .col-xl-9, .form-row .col-xs, .form-row .col-xs-1, .form-row .col-xs-10, .form-row .col-xs-11, .form-row .col-xs-12, .form-row .col-xs-2, .form-row .col-xs-3, .form-row .col-xs-4, .form-row .col-xs-5, .form-row .col-xs-6, .form-row .col-xs-7, .form-row .col-xs-8, .form-row .col-xs-9 { padding-left: 0 } .form-row .form-control { float: left; } .form-inline .form-row .form-control { float: none; } .container-body > .form-group:last-child, .container-body > .form-row:last-child, .container-body > p:last-child, .container-body > .form-group:last-child > p:last-child { margin-bottom: 0 } @@ -98,7 +94,7 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .table.data > tbody > tr:hover { cursor: default; background-color: rgba(93, 109, 202, 0.16); transition-duration: .05s } .table.data tr.unstyled:hover { background-color: inherit } .table.data .actions { white-space: nowrap } -.table.data .actions a, .table.data a .fa { color: #555 } +.table.data .actions a { color: #555 } .table.data .actions a .fa, .table.data .actions span .fa { position: relative; margin: 0 0.375rem; font-size: 0.9rem; color: #555 } .table.data .actions a:hover .fa { color: #000; } .table.data .actions a:hover .fa.fa-trash { color: #d80030 } @@ -120,11 +116,21 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan /* table-data-sm */ .table.data.table-sm td, .table.data.table-sm th { padding: .25rem .5rem; } .table.data.table-sm th, .table.data.table-sm thead td { font-size: 0.75rem; text-transform: none; } +/* table-data-even */ +.table.data.table-even > tbody > tr:not(:hover) { background-color: #fff } +.table.data.table-even > tbody > tr:nth-child(4n+1):not(:hover) { background-color: #f6f8f8 } +.table.data.table-even > tbody > tr:nth-child(2n) { background-color: #fff } /* table-data-docs */ .table.data .doc-item .fa { width: 1.2em; font-size: 0.9rem; text-align: center; margin-right: 0.25rem } .table.data .doc-item { text-decoration: none } .table.data .doc-item:hover span { text-decoration: underline } .table.data .doc-item.private .fa::after { position: relative; float: left; margin: .5em -1em 0 0; content: "\f023"; font-size: 0.75em; color: #d9534f; } +/* [ PAGINATION ] */ +#pagination { padding: 0 1.3rem; margin: .5rem 0 0; } +#pagination ul { margin: 0 0 0 .5rem; display: inline-block; } +#pagination li { list-style: none; display: inline-block; margin: 0 0 0 1px; } +#pagination li a { display: inline-block; padding: 0 .5rem; line-height: 1.7; border: 1px solid #ddd; text-decoration: none; color: #333; } +#pagination li.currentPage a, #pagination li a:hover { color: #555; border: 1px solid #555; } /* [ SEARCHBAR ] */ .searchbar input[type=text] { max-width: 10rem } /* [ WIDGETS ] */ @@ -184,6 +190,13 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan ul.sortableList { margin: 0; } ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: .5rem; margin: .0625rem 0; border: 1px solid #ccc; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0, 0.15); transition: color .3s, box-shadow .3s, transform 0s, z-index 0s; } +/* [ TOOLTIPS ] */ +.evo-tooltip, .custom-tip { position: fixed; z-index: 13000; width: 13rem; margin: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); -webkit-box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); } +.evo-tooltip { opacity: 0; content: attr(data-tooltip); } +.evo-tooltip.show { opacity: 1; visibility: visible; transform: translate3d(0, 0, 0); } +[data-tooltip] { cursor: help } +[data-tooltip].fa-question-circle { opacity: 0.15; } +[data-tooltip].fa-question-circle:hover { opacity: 1; } /* STYLES FOR HELP */ #helpPane h1 { border-bottom: 1px solid #888; margin-bottom: 1em; } #helpPane li:not(:first-child) > strong { margin-top: 1.4em; } diff --git a/manager/media/style/default/css/page.css b/manager/media/style/default/css/page.css index efbdbcb23e..dba31d8bb2 100644 --- a/manager/media/style/default/css/page.css +++ b/manager/media/style/default/css/page.css @@ -56,7 +56,7 @@ to { transform: rotate(360deg) } .ElementsInTree #tree .tab-page .panel-group { overflow: visible !important; max-height: none !important; box-sizing: border-box !important } .ElementsInTree #tree .tab-row { padding: 0; margin-bottom: -1px; } .ElementsInTree #tree .tab-row .tab { height: 2rem; line-height: 2rem; } -.ElementsInTree #tree .tab-page { background-color: #fff; border: 1px solid #ddd; } +.ElementsInTree #tree .tab-page { background-color: #fff; border: 1px solid #ddd; box-shadow: none } .ElementsInTree #tree .form-control { padding: 0.25rem; font-size: 0.8rem; } .ElementsInTree #tree .eltree { line-height: 1.5 } .ElementsInTree #tree .eltree img { width: 0.8em; height: 0.8em } diff --git a/manager/media/style/default/css/tabpane.css b/manager/media/style/default/css/tabpane.css index 4b512ccbec..ad0406297d 100644 --- a/manager/media/style/default/css/tabpane.css +++ b/manager/media/style/default/css/tabpane.css @@ -13,3 +13,11 @@ .tab-row-container > i.prev { left: 0; } .tab-row-container > i.next { right: 0; } .tab-row-container > i.disable { font-size: 0.8rem; color: rgba(0, 0, 0, 0.2); pointer-events: none } +/* tab-page */ +.tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } +.tab-header { padding: .5rem 1.3rem; } +.tab-content > .tab-header { padding-left: 0; padding-right: 0 } +.tab-content { width: 100%; padding: 1.3rem; } +.tab-page > .tab-header + .tab-content { padding-top: .5rem } +.tab-content::after { display: table; width: 100%; content: '' } +.tab-content > .form-group:last-child, .tab-content > .form-row:last-child, .tab-content > p:last-child, .tab-content > .form-group:last-child > p:last-child { margin-bottom: 0 } diff --git a/manager/media/style/default/style.css b/manager/media/style/default/style.css index b089d34a47..f50ad729e9 100644 --- a/manager/media/style/default/style.css +++ b/manager/media/style/default/style.css @@ -57,11 +57,6 @@ a.hometblink:hover { text-decoration: underline; color: Gray; }*/ .sortabletable th:active { background: #ccc; padding: 3px 4px 1px 6px; } /* -------------------------[ Pagination table ]--- */ #max-display-records { margin: 10px 0; } -#pagination { margin: 10px 0; } -#pagination ul { margin: 10px 0; display: inline; } -#pagination li { list-style: none; display: inline; width: 1rem; margin: 0 0 0 1px; } -#pagination li a { padding: 3px 8px; border: 1px solid #d9e7c2; text-decoration: none; color: #333; } -#pagination li.currentPage a, #pagination li a:hover { color: #060; border: 1px solid #060; } fieldset.tab-page { border: 1px solid #e4e4e4 !important; } h2#edit_document_title { font-size: 0.9rem; color: #f5f5f5; width: 100%; border-bottom: none; padding: 5px 10px; } fieldset#preview h2.tab { float: right; } @@ -107,14 +102,6 @@ form#mutate input.date, form#mutate input.tvdate { margin-right: 10px; } form#mutate fieldset#settings_page_settings input#pub_date, form#mutate fieldset#settings_page_settings input#unpub_date { width: 150px; } form#mutate fieldset#settings_page_settings select { width: 155px; } /* -* Individual Styles for fieldset#meta_keywords -*/ -form#mutate fieldset#meta_keywords select.inputBox { display: block; margin-bottom: 0; } -form#mutate fieldset#meta_keywords dl.keywords { float: left; margin-right: 30px; } -form#mutate fieldset#meta_keywords dl.metatags { float: left; } -form#mutate fieldset#meta_keywords dl dt label { width: 100px; } -form#mutate fieldset#meta_keywords dl dd { margin-left: 110px; } -/* * Individual Styles for fieldset#preview */ fieldset#preview iframe { width: 100%; margin: 0 auto; border: 1px solid #f5f5f5; } @@ -137,16 +124,6 @@ fieldset#settings_templvars dd.tvCheckBox label input, fieldset#settings_templva fieldset#settings_templvars .tv_date { width: 150px; } form#mutate select.tv_url_select { padding: 5px 3px; } /* ppb: -* Style mootools tooltips -*/ -.evo-tooltip, .custom-tip { position: fixed; z-index: 13000; width: 13rem; margin: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); -webkit-box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); } -.evo-tooltip { opacity: 0; content: attr(data-tooltip); } -.evo-tooltip.show { opacity: 1; visibility: visible; transform: translate3d(0, 0, 0); } -[data-tooltip] { cursor: help } -[data-tooltip].fa-question-circle { opacity: 0.15; } -[data-tooltip].fa-question-circle:hover { opacity: 1; } -th > [data-tooltip].fa-question-circle, td > [data-tooltip].fa-question-circle { float: right; } -/* ppb: * Some styling for legacy mode fieldsets */ fieldset.legacy { background: #fff; padding: 10px; margin: 10px 10px 35px; border: 1px solid #e4e4e4 !important; position: relative; } @@ -174,7 +151,6 @@ td#displayparams > table.displayparams { border: none; } /* replace warning red color in tabs */ strong[style*='color:#EF1D1D'] { color: yellow !important; } .selected strong[style*='color:#ffeb00'] { color: red !important; } -#tabEvents table, #tabEvents td { padding: 2px; } code { font-size: inherit; font-family: Consolas, 'Courier New', 'Courier', monospace; background-color: #eee; border: 1px solid #ccc; padding: 1px 2px; } #resourcesPane .disabledPlugin a:hover { color: #aaa; } /* breadcrumbs */ @@ -189,7 +165,7 @@ li.breadcrumbs__li_current { font-size: 12px; font-weight: 500; } #documentPane .tab-page > table > tr > td:first-child, #documentPane .tab-page > table > tbody > tr > td:first-child, #documentPane .tab-page .tmplvars > table > tbody > tr > td:first-child, #tmplvarsPane .tab-page > table > tbody > tr > td:first-child, #tmplvarsPane .tab-page > table > tbody > tr > th:first-child, #chunkPane .tab-page > table > tbody > tr > td:first-child, #chunkPane .tab-page > table > tbody > tr > th:first-child, #snipetPane .tab-page > table > tbody > tr > td:first-child, #snipetPane .tab-page > table > tbody > tr > th:first-child, #pluginPane .tab-page > table > tbody > tr > td:first-child, #pluginPane .tab-page > table > tbody > tr > th:first-child, #modulePane .tab-page > table > tbody > tr > td:first-child, #modulePane .tab-page > table > tbody > tr > th:first-child, #docManagerPane .tab-page #dates > table > tbody > tr > td:first-child { width: 200px } #documentPane .tab-page > table > tr > td:last-child, #documentPane .tab-page .tmplvars > table > tbody > tr > td:last-child { width: inherit !important } #documentPane .tab-page > table > tbody > tr > td:first-child > .warning { display: inline-block; width: calc(100% - 1rem); } -#documentPane .tab-page > table > tbody > tr > td:first-child > [data-tooltip].fa-question-circle { margin-top: 0.3rem; } +#documentPane .tab-page > table > tbody > tr > td:first-child > [data-tooltip] { float: right; margin-top: 0.3rem; } .table--edit { margin-bottom: 1rem; } .table th, .table td { text-align: left; vertical-align: middle; } table th { font-weight: 500; } @@ -296,8 +272,6 @@ ul.elements_buttonbar .fa { font-size: 0.875rem; padding: 1px 1px 0; } table.actionButtons { margin-top: 1rem; margin-bottom: 10px; } table.actionButtons img { display: inline-block; } table.actionButtons .searchtext { padding: 5px; height: 24px; width: 150px; } -/* backup */ -#tabBackup p.actionButtons { margin-top: 20px; margin-bottom: 1rem; } /* filter elements */ .filterElements-form { margin-bottom: 10px; margin-top: 5px; } .actionButtons .filterElements-form { margin-top: 0; margin-bottom: 0; } @@ -317,8 +291,6 @@ tr.userIdle td strong:before { font-family: "FontAwesome"; font-style: normal; f #modxonline_widget td strong.userMultipleSessions:before { color: #bf4949; content: '\f2bd'; } #modxonline_widget tr.userIdle td strong.userMultipleSessions:before { color: #bf4949; content: '\f017'; } /*responsive buttons*/ -.filterButtons .input-group .form-control { width: auto; } -.filterButtons .input-group .input-group-btn { float: left; } .actionButtons .fa { display: none; text-align: center; font-size: 1em; line-height: 1em; width: 1.1em; vertical-align: initial } .sectionBody .actionButtons .fa, .actionButtons--eit .fa { display: inline-block; } .optionsTitle .fa { display: inline-block; } From f8e41287f4603c65f88dc29ee2f6bf8ccb886cdc Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:49:53 +0200 Subject: [PATCH 159/338] moved help templates to manager/actions --- assets/templates/help/01Documentation.php | 16 -- assets/templates/help/02Version_Notices.php | 21 --- assets/templates/help/03Changelog.php | 12 -- assets/templates/help/04About_MODX.php | 64 ------- assets/templates/help/version_notices/1.1.php | 8 - .../templates/help/version_notices/1.2.1.php | 21 --- .../templates/help/version_notices/1.2.2.php | 17 -- assets/templates/help/version_notices/1.2.php | 167 ------------------ 8 files changed, 326 deletions(-) delete mode 100644 assets/templates/help/01Documentation.php delete mode 100644 assets/templates/help/02Version_Notices.php delete mode 100644 assets/templates/help/03Changelog.php delete mode 100644 assets/templates/help/04About_MODX.php delete mode 100644 assets/templates/help/version_notices/1.1.php delete mode 100644 assets/templates/help/version_notices/1.2.1.php delete mode 100644 assets/templates/help/version_notices/1.2.2.php delete mode 100644 assets/templates/help/version_notices/1.2.php diff --git a/assets/templates/help/01Documentation.php b/assets/templates/help/01Documentation.php deleted file mode 100644 index 1e2bc8be04..0000000000 --- a/assets/templates/help/01Documentation.php +++ /dev/null @@ -1,16 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); -?> - -
      - - - - - - - - -
      What is MODX?Official 1.0 documentation
      MODX.comHome of MODX
      MODX ForumsGeneral support & discussions
      docs.evolution-cms.comGoogle TranslateFurther documentation
      API ReferenceGoogle TranslateFurther documentation
      MODX.imGoogle TranslateMODX by community
      MODX.com.uaGoogle TranslateFurther documentation
      -
      - diff --git a/assets/templates/help/02Version_Notices.php b/assets/templates/help/02Version_Notices.php deleted file mode 100644 index b5ed1d9433..0000000000 --- a/assets/templates/help/02Version_Notices.php +++ /dev/null @@ -1,21 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); - - if ($handle = opendir(MODX_BASE_PATH . 'assets/templates/help/version_notices')) { - while (false !== ($file = readdir($handle))) { - if ($file != "." && $file != ".." && $file != ".svn" && is_readable(MODX_BASE_PATH . "assets/templates/help/version_notices/{$file}")) { - $notices[] = str_replace('.php', '', $file); - } - } - closedir($handle); - } - - usort($notices, 'version_compare'); - $notices = array_reverse($notices); - - foreach($notices as $v) { - echo '
      MODX v'.$v.'
      '; - include(MODX_BASE_PATH . "assets/templates/help/version_notices/{$v}.php"); - echo '

      '; - } -?> \ No newline at end of file diff --git a/assets/templates/help/03Changelog.php b/assets/templates/help/03Changelog.php deleted file mode 100644 index 73fcd748e3..0000000000 --- a/assets/templates/help/03Changelog.php +++ /dev/null @@ -1,12 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); -?> - -
      Changelog
      -
      -',file_get_contents($changeLog)); -?> -
      \ No newline at end of file diff --git a/assets/templates/help/04About_MODX.php b/assets/templates/help/04About_MODX.php deleted file mode 100644 index 6b2746a66a..0000000000 --- a/assets/templates/help/04About_MODX.php +++ /dev/null @@ -1,64 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); - -$downloadLinks = array( - 0=>array('title'=>$_lang["information"],'link'=>'https://modx.com/community/modx-evolution'), - 1=>array('title'=>$_lang["download"],'link'=>'https://modx.com/download/evolution/'), - 2=>array('title'=>$_lang["previous_releases"],'link'=>'https://modx.com/download/evolution/previous-releases.html'), - 3=>array('title'=>$_lang["extras"],'link'=>array( - 'https://modx.com/extras/?product=evolution', - 'http://extras.evolution-cms.com/', - 'https://github.com/extras-evolution' - )), -); - -$translationLinks = array( - 0=>array('title'=>'MODX Evolution','link'=>'https://www.transifex.com/modx/modx-evolution/'), - 1=>array('title'=>$_lang["extras"],'link'=>'https://www.transifex.com/modx/modx-evolution-extras/'), -); - -function createList($sectionHeader, $linkArr) { - $output = '
      '.$sectionHeader.'
      '."\n"; - $output .= ''."\n"; - $links = ''; - foreach($linkArr as $row) { - if (!is_array($row['link'])) $row['link'] = array($row['link']); - foreach ($row['link'] as $link) { - $links .= $links != '' ? '
      ' : ''; - $links .= '' . $link . ''; - } - $output .= ' - - - - '; - $links = ''; - } - $output .= '
      ' . $row["title"] . '' . $links . '
      '."\n"; - return $output; -} - -echo createList($_lang['evo_downloads_title'], $downloadLinks); -echo createList($_lang['help_translating_title'], $translationLinks); - -?> - -
      - -
      - -
      - -
      - -
      - - - - - - - -
      -
      - diff --git a/assets/templates/help/version_notices/1.1.php b/assets/templates/help/version_notices/1.1.php deleted file mode 100644 index c5e94763c2..0000000000 --- a/assets/templates/help/version_notices/1.1.php +++ /dev/null @@ -1,8 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); -?> -

      -

      Configuration

      -
        -
      • New setting "AliasListing"Can be set on/off in settings (in "Friendly URL" tab) to extend the 10.000 resources limit by creating a much smaller siteCache.idx.php (30.000 resources = ~400kb). Tested with 1.000.000 resources.
      • -
      \ No newline at end of file diff --git a/assets/templates/help/version_notices/1.2.1.php b/assets/templates/help/version_notices/1.2.1.php deleted file mode 100644 index 7e81574759..0000000000 --- a/assets/templates/help/version_notices/1.2.1.php +++ /dev/null @@ -1,21 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); -?> -

      -

      New Plugin-Event

      -
        -
      • OnBeforeParseParams -

        Will get invoked before parsing a snippet-params string like &param1=`value` to allow replacing custom-placeholders like EvoBabel´s [%ph%] before parsing a params-string. Example:

        [[Wayfinder? &startId=`[%lang%]` ..]]

        -
      • -
      -

      Debug-Infos

      -
        -
      • Improved Debug-Infos for $modx->dumpSnippets and $modx->dumpPlugins -

        To display infos for plugins/snippets create a plugin with the following code and activate event "OnWebPageInit":

        -
        $e = & $modx->Event;
        -if ( $e->name == "OnWebPageInit" ) {
        -	$modx->dumpSnippets=true;
        -	$modx->dumpPlugins=true;
        -}
        -
      • -
      \ No newline at end of file diff --git a/assets/templates/help/version_notices/1.2.2.php b/assets/templates/help/version_notices/1.2.2.php deleted file mode 100644 index a3de907928..0000000000 --- a/assets/templates/help/version_notices/1.2.2.php +++ /dev/null @@ -1,17 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); -?> -

      -

      TinyMCE4

      -
        -
      • New checkbox "Use the global setting" -

        There were issues setting "Custom Plugins", "Custom Buttons" and "Block Formats" via MODX-configuration globally for all users. Therefore a new checkbox has been added, which active by default.

        -
      • -
      - -

      Developer-Infos

      -
        -
      • New $modx->configGlobal -

        Params from MODX-configuration which get overwritten by user-specific settings will be stored inside $modx->configGlobal to be available as fallback.

        -
      • -
      \ No newline at end of file diff --git a/assets/templates/help/version_notices/1.2.php b/assets/templates/help/version_notices/1.2.php deleted file mode 100644 index 09bf3f3d71..0000000000 --- a/assets/templates/help/version_notices/1.2.php +++ /dev/null @@ -1,167 +0,0 @@ -INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); -?> -

      -

      Resource-Tree

      -
        -
      • Moved "Sort menuindex" from DocManager to Resource-tree (#618, #636) -

        Sort Resources in Root: Click Button "Sort menu index" on top of resource-tree
        - Sort Resources of Parent Resource: Right mouse-click on parent, then choose "Sort menu index" -

        -
      • -
      • New "Manage Elements" Buttons (#669) -

        You can quick-access elements, files and images now directly from ressource-tree. Use Shift-Mouseclick to open multiple windows/elements. Permission is granted using new roles "assets_images" and "assets_files".

        -
      • -
      • Remember last sort-options (#618, #636) -

        The ressource-tree stores now the last set sort-options per user to database (Sort by, Asc/Desc, Display-Name). At manager log-in, last settings of each user get restored.

        -
      • -
      • New plugin "ElementsInTree" v1.2.0 (github.com/pmfx) -

        This plugin has been added to default installation. Use Shift-Mouseclick to collapse/expand all categories. Collapsed states per category will be remembered via browser´s localStorage.

        -
      • -
      - -

      MODX Tags

      -
        -
      • New Modifiers/Filters in Core (PHx) -

        Can be disabled in MODX-configuration. More infos at #623

        -
      • -
      • Snippet - Shortcut param = true -

        [[snippetName?param1&param2]] will automatically be handled as [[snippetName?param1=`1`&param2=`1`]] while param=`` will still be handled as empty value.

        -
      • -
      • Output value of $_GET, $_POST, $_COOKIE, $_SERVER, $_SESSION -
        [!$_SERVER['REQUEST_TIME']:dateFormat='Y'!]
        -
      • -
      • New Conditional Tags <@IF> <@ELSEIF> <@ELSE> <@ENDIF> and Modifiers -

        Can be enabled/disabled via Configuration -> "Enable Filters". More examples at #622 and #623.
        - Performance is good because it does not parse the block which is judged false.
        - Example:

        -
        [*longtitle:ifempty=[*pagetitle*]*]
        -
        <@IF:[*id:is('[(site_start)]')*]>
        -Top page
        -<@ELSE>
        -Sub page
        -<@ENDIF>
        -

        In combination with $_GET :

        -
        <@IF:[!$_GET['value']:preg('/^[0-9]+$/')!]>
        -Value is numeric.
        -<@ELSE>
        -Value is not numeric.
        -<@ENDIF>
        -

        UltimateParent

        -
        [[UltimateParent:is=`8`:then=`8`:else=`11`]]
        -<@IF:[[UltimateParent:is=8]]>
        -8
        -<@ELSE>
        -11
        -<@ENDIF>
        - -

        Combination with Cross-references (modxcms/evolution@956c9ae)

        -
        <@IF:[*id@ultimateparent:is=8*]>
        -8
        -<@ELSE>
        -11
        -<@ENDIF>
        -
      • - -
      • New Comment Tag -

        Comment-Tags will be completely removed from output. More infos at #680. Example:

        -
        <!--@- This is a comment -@-->
        -
        <!--@- Or HTML-Code / Snippets etc you want to disable temporarily -@-->
        -
      • - -
      • New Chunk Parameters -

        It is possible to pass properties/values to a chunk. More infos at #625. Example:

        - Chunk: -
        -<h1>[+title+]</h1>
        -<p>[+body+]</p>
        - Call: -
        {{chunkName? &title='First post' &body='Hello World!'}}
        -
      • - -
      • File-binded Templates via @INCLUDE -

        Templates can be included via @INCLUDE using external PHP- & HTML-files. More infos at #627. Examples:

        -

        HTML Template:

        -
        @INCLUDE:assets/templates/mydesign/template.html
        -

        PHP Template:

        -
        @INCLUDE:assets/templates/mydesign/template.inc.php
        -

        template.inc.php :

        -
        switch($modx->documentIdentifier) {
        -    case $modx->config['site_start']:
        -        return file_get_contents('assets/templates/mydesign/top.html');
        -    default:
        -        return file_get_contents('assets/templates/mydesign/page.html');
        -}
        -
      • -
      • Snippet-calls improved and supporting Modifiers -
        [[snippetName]]
        -[[snippet Name]]
        -[[snippetName?param=`value`]]
        -[[snippet Name?param=`value`]]
        -[[snippetName? &param=`value`]]
        -[[snippetName ? &param=`value`]]
        -[[snippetName &param=`value`]]
        -[[snippetName?
        -    &param=`value`
        -]]
        -[[snippetName
        -    &param=`value`
        -]]
        -[[snippet Name?
        -    &param=`value`
        -]]
        -[[snippetName?param]]
        -
        -[[snippetName:modifier]]
        -[[snippetName:modifier?param=`value`]]
        -[[snippetName:modifier ?
        -    &param=`value`
        -]]
        -[[snippetName:modifier
        -    &param=`value`
        -]]
        -[[snippetName:modifier=`option`
        -    &param=`value`
        -]]
        -[[snippetName:modifier(option)
        -    &param=`value`
        -]]
        -[[snippetName:modifier('option')
        -    &param=`value`
        -]]
        -[[snippetName:modifier("option")
        -    &param=`value`
        -]]
        -[[snippetName:modifier(`option`)
        -    &param=`value`
        -]]
        -
      • -
      • Wayfinder Debug-Mode -

        More infos at #719

        -
        [[Wayfinder?debug]]
        -
      • -
      - -

      New Manager Roles

      -
        -
      • change_resourcetype -

        A user with this permission can change resource-type (webpage/weblink). More infos at #531

        -
      • -
      • assets_images, assets_files -

        Controls the display of 2 new buttons in resource-tree and grants/blocks access to KCFinder. More infos at #681

        -
      • -
      - -

      Template-Variables

      -
        -
      • @BINDINGS providing TV-values -

        [*tv_name*] will be replaced by its value taken from actual resource. Beware of SQL-Errors in case no or wrong value is given (set a reasonable default-value to avoid errors). More infos at #699. Example:

        -
        @SELECT name,value FROM xxx WHERE yyy = [*tv_name*]
        -
      • -
      - -

      Other Important Details for Developers

      -
        -
      • jQuery updated to v3.1 and loaded into manager by default.Known issues: MultiTV 2.0.8 has problems with row-reordering and requires an update. Meanwhile a workaround can be found here.
      • -
      • Language OverridesCan be implemented by adding files to /manager/includes/lang/override/. Files in this directory will never get altered by future updates.
      • -
      \ No newline at end of file From 36e4bc09ae3be9ec80c2d5ab456a81549474eaab Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:50:27 +0200 Subject: [PATCH 160/338] updated help templates path --- manager/actions/help.static.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager/actions/help.static.php b/manager/actions/help.static.php index 48b1df1ca4..36ffc4100f 100644 --- a/manager/actions/help.static.php +++ b/manager/actions/help.static.php @@ -2,7 +2,7 @@ if(IN_MANAGER_MODE != "true") { die("INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); } -$helpBasePath = MODX_BASE_PATH . "assets/templates/help/"; +$helpBasePath = "actions/help/"; ?>

      @@ -16,7 +16,7 @@ Date: Thu, 3 Aug 2017 13:51:04 +0200 Subject: [PATCH 161/338] updated about tab for Evo --- manager/actions/help/01About_EVO.php | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 manager/actions/help/01About_EVO.php diff --git a/manager/actions/help/01About_EVO.php b/manager/actions/help/01About_EVO.php new file mode 100644 index 0000000000..0c4cb0d393 --- /dev/null +++ b/manager/actions/help/01About_EVO.php @@ -0,0 +1,54 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +$logo= ''; +$downloadLinks = array( + 0=>array('title'=>$_lang["information"],'link'=>'https://evo.im/'), + 1=>array('title'=>$_lang["download"],'link'=>'https://github.com/evolution-cms/evolution/releases'), + 2=>array('title'=>$_lang["previous_releases"],'link'=>'https://modx.com/download/evolution/previous-releases.html'), + 3=>array('title'=>$_lang["extras"],'link'=>array( + 'http://extras.evolution-cms.com/', + 'https://github.com/extras-evolution' + )), +); + +$translationLinks = array( + 0=>array('title'=>'Evolution CMS','link'=>'https://www.transifex.com/evolutioncms/evolution/'), + 1=>array('title'=>$_lang["extras"],'link'=>'https://www.transifex.com/evolutioncms/extras/'), +); + +function createList($sectionHeader, $linkArr) { + $output = '
      '.$sectionHeader.'
      '."\n"; + $output .= ''."\n"; + $links = ''; + foreach($linkArr as $row) { + if (!is_array($row['link'])) $row['link'] = array($row['link']); + foreach ($row['link'] as $link) { + $links .= $links != '' ? '
      ' : ''; + $links .= '' . $link . ''; + } + $output .= ' + + + + '; + $links = ''; + } + $output .= '
      ' . $row["title"] . '' . $links . '
      '."\n"; + return $output; +} +echo $logo; +echo createList($_lang['evo_downloads_title'], $downloadLinks); +echo createList($_lang['help_translating_title'], $translationLinks); + +?> + +
      + +
      + +
      + +
      + + + From 9d64b02f689f0b08dba9d5d1277879ebd2663f07 Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:51:32 +0200 Subject: [PATCH 162/338] updated help documentation tab for evo --- manager/actions/help/02Documentation.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 manager/actions/help/02Documentation.php diff --git a/manager/actions/help/02Documentation.php b/manager/actions/help/02Documentation.php new file mode 100644 index 0000000000..17fc14d367 --- /dev/null +++ b/manager/actions/help/02Documentation.php @@ -0,0 +1,15 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> + +
      + + + + + + + +
      What is EVO?Official EVO 3.0 documentation
      evo.imHome of EVO
      EVO ForumsGeneral support & discussions
      docs.evolution-cms.comGoogle TranslateFurther documentation
      API ReferenceGoogle TranslateFurther documentation
      MODX.imGoogle TranslateRussian community
      +
      + From 7ab5558c1c7a3b18fc03e2fe6e0e9ae5cea28b39 Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:51:46 +0200 Subject: [PATCH 163/338] updated help logs tab for evo --- manager/actions/help/04Changelog.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 manager/actions/help/04Changelog.php diff --git a/manager/actions/help/04Changelog.php b/manager/actions/help/04Changelog.php new file mode 100644 index 0000000000..73fcd748e3 --- /dev/null +++ b/manager/actions/help/04Changelog.php @@ -0,0 +1,12 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> + +
      Changelog
      +
      +',file_get_contents($changeLog)); +?> +
      \ No newline at end of file From 8745f3076ffd148c6d42fcb5bb3974541f0e7cf1 Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:53:12 +0200 Subject: [PATCH 164/338] added support for both (modx and evo) cms name in version noticies if ($v >= '1.3.0') { $cms = 'EVO'; } else { $cms = 'MODX EVO'; } :D :D --- manager/actions/help/03Version_Notices.php | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 manager/actions/help/03Version_Notices.php diff --git a/manager/actions/help/03Version_Notices.php b/manager/actions/help/03Version_Notices.php new file mode 100644 index 0000000000..07dc4f1576 --- /dev/null +++ b/manager/actions/help/03Version_Notices.php @@ -0,0 +1,28 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); + + if ($handle = opendir('actions/help/version_notices')) { + while (false !== ($file = readdir($handle))) { + if ($file != "." && $file != ".." && $file != ".svn" && is_readable("actions/help/version_notices/{$file}")) { + $notices[] = str_replace('.php', '', $file); + } + } + closedir($handle); + } + + usort($notices, 'version_compare'); + $notices = array_reverse($notices); + + foreach($notices as $v) { + if ($v >= '1.3.0') { + $cms = 'EVO'; + } + else { + $cms = 'MODX EVO'; + } + echo '
      '.$cms.' '.$v.'
      '; + include("actions/help/version_notices/{$v}.php"); + echo '

      '; + + } +?> \ No newline at end of file From 581cd64bcc6d5e94bb7060cbf1971b6fb53714ba Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:53:44 +0200 Subject: [PATCH 165/338] modx evo version noticies --- .../actions/help/version_notices/1.1.1.php | 89 ++++++++++ manager/actions/help/version_notices/1.1.php | 8 + .../actions/help/version_notices/1.2.1.php | 27 +++ .../actions/help/version_notices/1.2.2.php | 17 ++ manager/actions/help/version_notices/1.2.php | 167 ++++++++++++++++++ 5 files changed, 308 insertions(+) create mode 100644 manager/actions/help/version_notices/1.1.1.php create mode 100644 manager/actions/help/version_notices/1.1.php create mode 100644 manager/actions/help/version_notices/1.2.1.php create mode 100644 manager/actions/help/version_notices/1.2.2.php create mode 100644 manager/actions/help/version_notices/1.2.php diff --git a/manager/actions/help/version_notices/1.1.1.php b/manager/actions/help/version_notices/1.1.1.php new file mode 100644 index 0000000000..aa9868f421 --- /dev/null +++ b/manager/actions/help/version_notices/1.1.1.php @@ -0,0 +1,89 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +

      Resource-Tree

      +
        +
      • Moved "Sort menuindex" from DocManager to Resource-tree (#618, #636) +

        Sort Resources in Root: Click Button "Sort menu index" on top of resource-tree
        + Sort Resources of Parent Resource: Right mouse-click on parent, then choose "Sort menu index" +

        +
      • +
      • New "Manage Elements" Buttons (#669) +

        You can quick-access elements, files and images now directly from ressource-tree. Use Shift-Mouseclick to open multiple windows/elements.

        +
      • +
      • Remember last sort-options (#618, #636) +

        The ressource-tree stores now the last set sort-options per user to database (Sort by, Asc/Desc, Display-Name). At manager log-in, last settings of each user get restored.

        +
      • +
      + +

      MODX Tags

      +
        +
      • New Modifiers/Filters in Core (PHx) +

        Can be disabled in MODX-configuration. More infos at #623

        +
      • +
      • Snippet - Shortcut param = true +

        [[snippetName?param1&param2]] will automatically be handled as [[snippetName?param1=`1`&param2=`1`]] while param=`` will still be handled as empty value.

        +
      • +
      • New Conditional Tags / Modifiers +

        Can be enabled/disabled via Configuration -> "Enable Filters". More examples at #622 and #623. Example:

        +
        [*longtitle:ifempty=[*pagetitle*]*]
        +
        <!--@IF:[*id:is('[(site_start)]')*]>
        +Top page
        +<@ELSE>
        +Sub page
        +<@ENDIF-->
        +
      • + +
      • New Comment Tag +

        Comment-Tags will be completely removed from output. More infos at #680. Example:

        +
        <!--@- This is a comment -@-->
        +
        <!--@- Or HTML-Code / Snippets etc you want to disable temporarily -@-->
        +
      • + +
      • New Chunk Parameters +

        It is possible to pass properties/values to a chunk. More infos at #625. Example:

        + Chunk: +
        +<h1>[+title+]</h1>
        +<p>[+body+]</p>
        + Call: +
        {{chunkName? &title='First post' &body='Hello World!'}}
        +
      • + +
      • File-binded Templates via @INCLUDE +

        Templates can be included via @INCLUDE using external PHP- & HTML-files. More infos at #627. Example:

        +

        MODX-Template:

        +
        @INCLUDE:assets/templates/mydesign/template.inc.php
        +

        template.inc.php :

        +
        switch($modx->documentIdentifier) {
        +    case $modx->config['site_start']:
        +        return file_get_contents('assets/templates/mydesign/top.html');
        +    default:
        +        return file_get_contents('assets/templates/mydesign/page.html');
        +}
        +
      • +
      + +

      New Manager Roles

      +
        +
      • change_resourcetype +

        A user with this permission can change resource-type (webpage/weblink). More infos at #531

        +
      • +
      • assets_images, assets_files +

        Controls the display of 2 new buttons in resource-tree and grants/blocks access to KCFinder. More infos at #681

        +
      • +
      + +

      Template-Variables

      +
        +
      • @BINDINGS providing TV-values +

        [*tv_name*] will be replaced by its value taken from actual resource. Beware of SQL-Errors in case no or wrong value is given (set a reasonable default-value to avoid errors). More infos at #699. Example:

        +
        @SELECT name,value FROM xxx WHERE yyy = [*tv_name*]
        +
      • +
      + +

      Important Details for Developers

      +
        +
      • jQuery updated to v3.1 and loaded into manager by default.
        Known issues: MultiTV 2.0.8 has problems with row-reordering and requires an update.
      • +
      \ No newline at end of file diff --git a/manager/actions/help/version_notices/1.1.php b/manager/actions/help/version_notices/1.1.php new file mode 100644 index 0000000000..c5e94763c2 --- /dev/null +++ b/manager/actions/help/version_notices/1.1.php @@ -0,0 +1,8 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +

      Configuration

      +
        +
      • New setting "AliasListing"Can be set on/off in settings (in "Friendly URL" tab) to extend the 10.000 resources limit by creating a much smaller siteCache.idx.php (30.000 resources = ~400kb). Tested with 1.000.000 resources.
      • +
      \ No newline at end of file diff --git a/manager/actions/help/version_notices/1.2.1.php b/manager/actions/help/version_notices/1.2.1.php new file mode 100644 index 0000000000..e47150e79f --- /dev/null +++ b/manager/actions/help/version_notices/1.2.1.php @@ -0,0 +1,27 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +

      Server-Configuration

      +
        +
      • Turn off PHP directive "register_globals" +

        In case your server has "register_globals" set to ON for whatever reason, protect.inc.php will stop further script execution.

        +
      • +
      +

      New Plugin-Event

      +
        +
      • OnBeforeParseParams +

        Will get invoked before parsing a snippet-params string like &param1=`value` to allow replacing custom-placeholders like EvoBabel´s [%ph%] before parsing a params-string. Example:

        [[Wayfinder? &startId=`[%lang%]` ..]]

        +
      • +
      +

      Debug-Infos

      +
        +
      • Improved Debug-Infos for $modx->dumpSnippets and $modx->dumpPlugins +

        To display infos for plugins/snippets create a plugin with the following code and activate event "OnWebPageInit":

        +
        $e = & $modx->Event;
        +if ( $e->name == "OnWebPageInit" ) {
        +	$modx->dumpSnippets=true;
        +	$modx->dumpPlugins=true;
        +}
        +
      • +
      \ No newline at end of file diff --git a/manager/actions/help/version_notices/1.2.2.php b/manager/actions/help/version_notices/1.2.2.php new file mode 100644 index 0000000000..a3de907928 --- /dev/null +++ b/manager/actions/help/version_notices/1.2.2.php @@ -0,0 +1,17 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +

      TinyMCE4

      +
        +
      • New checkbox "Use the global setting" +

        There were issues setting "Custom Plugins", "Custom Buttons" and "Block Formats" via MODX-configuration globally for all users. Therefore a new checkbox has been added, which active by default.

        +
      • +
      + +

      Developer-Infos

      +
        +
      • New $modx->configGlobal +

        Params from MODX-configuration which get overwritten by user-specific settings will be stored inside $modx->configGlobal to be available as fallback.

        +
      • +
      \ No newline at end of file diff --git a/manager/actions/help/version_notices/1.2.php b/manager/actions/help/version_notices/1.2.php new file mode 100644 index 0000000000..09bf3f3d71 --- /dev/null +++ b/manager/actions/help/version_notices/1.2.php @@ -0,0 +1,167 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +

      Resource-Tree

      +
        +
      • Moved "Sort menuindex" from DocManager to Resource-tree (#618, #636) +

        Sort Resources in Root: Click Button "Sort menu index" on top of resource-tree
        + Sort Resources of Parent Resource: Right mouse-click on parent, then choose "Sort menu index" +

        +
      • +
      • New "Manage Elements" Buttons (#669) +

        You can quick-access elements, files and images now directly from ressource-tree. Use Shift-Mouseclick to open multiple windows/elements. Permission is granted using new roles "assets_images" and "assets_files".

        +
      • +
      • Remember last sort-options (#618, #636) +

        The ressource-tree stores now the last set sort-options per user to database (Sort by, Asc/Desc, Display-Name). At manager log-in, last settings of each user get restored.

        +
      • +
      • New plugin "ElementsInTree" v1.2.0 (github.com/pmfx) +

        This plugin has been added to default installation. Use Shift-Mouseclick to collapse/expand all categories. Collapsed states per category will be remembered via browser´s localStorage.

        +
      • +
      + +

      MODX Tags

      +
        +
      • New Modifiers/Filters in Core (PHx) +

        Can be disabled in MODX-configuration. More infos at #623

        +
      • +
      • Snippet - Shortcut param = true +

        [[snippetName?param1&param2]] will automatically be handled as [[snippetName?param1=`1`&param2=`1`]] while param=`` will still be handled as empty value.

        +
      • +
      • Output value of $_GET, $_POST, $_COOKIE, $_SERVER, $_SESSION +
        [!$_SERVER['REQUEST_TIME']:dateFormat='Y'!]
        +
      • +
      • New Conditional Tags <@IF> <@ELSEIF> <@ELSE> <@ENDIF> and Modifiers +

        Can be enabled/disabled via Configuration -> "Enable Filters". More examples at #622 and #623.
        + Performance is good because it does not parse the block which is judged false.
        + Example:

        +
        [*longtitle:ifempty=[*pagetitle*]*]
        +
        <@IF:[*id:is('[(site_start)]')*]>
        +Top page
        +<@ELSE>
        +Sub page
        +<@ENDIF>
        +

        In combination with $_GET :

        +
        <@IF:[!$_GET['value']:preg('/^[0-9]+$/')!]>
        +Value is numeric.
        +<@ELSE>
        +Value is not numeric.
        +<@ENDIF>
        +

        UltimateParent

        +
        [[UltimateParent:is=`8`:then=`8`:else=`11`]]
        +<@IF:[[UltimateParent:is=8]]>
        +8
        +<@ELSE>
        +11
        +<@ENDIF>
        + +

        Combination with Cross-references (modxcms/evolution@956c9ae)

        +
        <@IF:[*id@ultimateparent:is=8*]>
        +8
        +<@ELSE>
        +11
        +<@ENDIF>
        +
      • + +
      • New Comment Tag +

        Comment-Tags will be completely removed from output. More infos at #680. Example:

        +
        <!--@- This is a comment -@-->
        +
        <!--@- Or HTML-Code / Snippets etc you want to disable temporarily -@-->
        +
      • + +
      • New Chunk Parameters +

        It is possible to pass properties/values to a chunk. More infos at #625. Example:

        + Chunk: +
        +<h1>[+title+]</h1>
        +<p>[+body+]</p>
        + Call: +
        {{chunkName? &title='First post' &body='Hello World!'}}
        +
      • + +
      • File-binded Templates via @INCLUDE +

        Templates can be included via @INCLUDE using external PHP- & HTML-files. More infos at #627. Examples:

        +

        HTML Template:

        +
        @INCLUDE:assets/templates/mydesign/template.html
        +

        PHP Template:

        +
        @INCLUDE:assets/templates/mydesign/template.inc.php
        +

        template.inc.php :

        +
        switch($modx->documentIdentifier) {
        +    case $modx->config['site_start']:
        +        return file_get_contents('assets/templates/mydesign/top.html');
        +    default:
        +        return file_get_contents('assets/templates/mydesign/page.html');
        +}
        +
      • +
      • Snippet-calls improved and supporting Modifiers +
        [[snippetName]]
        +[[snippet Name]]
        +[[snippetName?param=`value`]]
        +[[snippet Name?param=`value`]]
        +[[snippetName? &param=`value`]]
        +[[snippetName ? &param=`value`]]
        +[[snippetName &param=`value`]]
        +[[snippetName?
        +    &param=`value`
        +]]
        +[[snippetName
        +    &param=`value`
        +]]
        +[[snippet Name?
        +    &param=`value`
        +]]
        +[[snippetName?param]]
        +
        +[[snippetName:modifier]]
        +[[snippetName:modifier?param=`value`]]
        +[[snippetName:modifier ?
        +    &param=`value`
        +]]
        +[[snippetName:modifier
        +    &param=`value`
        +]]
        +[[snippetName:modifier=`option`
        +    &param=`value`
        +]]
        +[[snippetName:modifier(option)
        +    &param=`value`
        +]]
        +[[snippetName:modifier('option')
        +    &param=`value`
        +]]
        +[[snippetName:modifier("option")
        +    &param=`value`
        +]]
        +[[snippetName:modifier(`option`)
        +    &param=`value`
        +]]
        +
      • +
      • Wayfinder Debug-Mode +

        More infos at #719

        +
        [[Wayfinder?debug]]
        +
      • +
      + +

      New Manager Roles

      +
        +
      • change_resourcetype +

        A user with this permission can change resource-type (webpage/weblink). More infos at #531

        +
      • +
      • assets_images, assets_files +

        Controls the display of 2 new buttons in resource-tree and grants/blocks access to KCFinder. More infos at #681

        +
      • +
      + +

      Template-Variables

      +
        +
      • @BINDINGS providing TV-values +

        [*tv_name*] will be replaced by its value taken from actual resource. Beware of SQL-Errors in case no or wrong value is given (set a reasonable default-value to avoid errors). More infos at #699. Example:

        +
        @SELECT name,value FROM xxx WHERE yyy = [*tv_name*]
        +
      • +
      + +

      Other Important Details for Developers

      +
        +
      • jQuery updated to v3.1 and loaded into manager by default.Known issues: MultiTV 2.0.8 has problems with row-reordering and requires an update. Meanwhile a workaround can be found here.
      • +
      • Language OverridesCan be implemented by adding files to /manager/includes/lang/override/. Files in this directory will never get altered by future updates.
      • +
      \ No newline at end of file From 8219b64f23cbcbf60109637acbce6f12931f27bf Mon Sep 17 00:00:00 2001 From: Nicola Date: Thu, 3 Aug 2017 13:54:34 +0200 Subject: [PATCH 166/338] 1.3x version noticies draft --- .../actions/help/version_notices/1.3.0.php | 45 +++++++++++++++++++ .../actions/help/version_notices/1.3.1.php | 8 ++++ .../actions/help/version_notices/1.3.2.php | 8 ++++ .../actions/help/version_notices/1.3.3.php | 8 ++++ 4 files changed, 69 insertions(+) create mode 100644 manager/actions/help/version_notices/1.3.0.php create mode 100644 manager/actions/help/version_notices/1.3.1.php create mode 100644 manager/actions/help/version_notices/1.3.2.php create mode 100644 manager/actions/help/version_notices/1.3.3.php diff --git a/manager/actions/help/version_notices/1.3.0.php b/manager/actions/help/version_notices/1.3.0.php new file mode 100644 index 0000000000..feb4066f3a --- /dev/null +++ b/manager/actions/help/version_notices/1.3.0.php @@ -0,0 +1,45 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +

      EVOLUTION CMS 1.3.0

      +
        +
      • The new release of EVO 1.3.0 runs under the name EVOLUTION CMS +

        Now updates will be released more often. About once a month there will be a fresh release instead of 1 release at half a year..

        +
      • +
      + +

      What's new in 1.3.0:

      +
        +
      • New name and logo +
      • +
      • New admin panel theme with a lot of innovations +
      • +
      • Correction of errors and stability +
      • +
      • Widgets for the main page (OnManagerWelcomeHome) +
      • +
      • Change the top menu (OnManagerMenuPrerender) +
      • +
      • Document tree changes (OnManagerNodePrerender) +
      • +
      +

      The New admin panel theme

      +
        +
      • Drag & drop in the document tree +
      • +
      • Dark style, quickly switching the appearance of the admin system +
      • +
      • Easier and faster +
      • +
      • Context menu for elements +
      • +
      • Ajax search in the admin area +
      • +
      • Remembering paths in admin panel +
      • +
      • 3 Level menu items with search and the ability to create a new item +
      • +
      • Support for mobile devices, although there is still some work in progress +
      • +
      \ No newline at end of file diff --git a/manager/actions/help/version_notices/1.3.1.php b/manager/actions/help/version_notices/1.3.1.php new file mode 100644 index 0000000000..cb5767676a --- /dev/null +++ b/manager/actions/help/version_notices/1.3.1.php @@ -0,0 +1,8 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +
        +
      • fix minor issues +
      • +
      diff --git a/manager/actions/help/version_notices/1.3.2.php b/manager/actions/help/version_notices/1.3.2.php new file mode 100644 index 0000000000..cb5767676a --- /dev/null +++ b/manager/actions/help/version_notices/1.3.2.php @@ -0,0 +1,8 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +
        +
      • fix minor issues +
      • +
      diff --git a/manager/actions/help/version_notices/1.3.3.php b/manager/actions/help/version_notices/1.3.3.php new file mode 100644 index 0000000000..cb5767676a --- /dev/null +++ b/manager/actions/help/version_notices/1.3.3.php @@ -0,0 +1,8 @@ +INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +?> +

      +
        +
      • fix minor issues +
      • +
      From 01d6301473c12f3657e6e50fdb7edb378253cef0 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Fri, 4 Aug 2017 07:14:25 +0900 Subject: [PATCH 167/338] Fix @396814f#commitcomment-23456321 https://github.com/evolution-cms/evolution/commit/396814fe8b556b90b914b335f29da3def23b10c1#commitcomment-23456321 --- manager/includes/document.parser.class.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index fc7155302d..b99471d7d3 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -1001,7 +1001,8 @@ function mergeDocumentContent($content,$ph=false) { if(substr($key, 0, 1) == '#') $key = substr($key, 1); // remove # for QuickEdit format list($key,$modifiers) = $this->splitKeyAndFilter($key); - list($key,$context) = explode('@',$key,2); + if(strpos($key,'@')!==false) list($key,$context) = explode('@',$key,2); + else $context = false; // if(!isset($ph[$key]) && !$context) continue; // #1218 TVs/PHs will not be rendered if custom_meta_title is not assigned to template like [*custom_meta_title:ne:then=`[*custom_meta_title*]`:else=`[*pagetitle*]`*] if($context) $value = $this->_contextValue("{$key}@{$context}",$this->documentObject['parent']); From 452d879b9c5edb3315e515dea32461e9663844f5 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 4 Aug 2017 01:48:26 +0300 Subject: [PATCH 168/338] add evoSortable in header.php refactor code --- .../actions/mutate_menuindex_sort.dynamic.php | 292 ++++++++---------- .../mutate_plugin_priority.dynamic.php | 179 +++++------ .../mutate_template_tv_rank.dynamic.php | 272 ++++++++-------- manager/actions/mutate_tv_rank.dynamic.php | 272 ++++++++-------- manager/includes/header.inc.php | 131 +++++--- manager/media/style/default/css/custom.css | 2 + 6 files changed, 556 insertions(+), 592 deletions(-) diff --git a/manager/actions/mutate_menuindex_sort.dynamic.php b/manager/actions/mutate_menuindex_sort.dynamic.php index 4cba33dd34..fed6a80053 100644 --- a/manager/actions/mutate_menuindex_sort.dynamic.php +++ b/manager/actions/mutate_menuindex_sort.dynamic.php @@ -1,12 +1,12 @@ INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('edit_document')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('edit_document')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } -$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : NULL; +$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null; $reset = isset($_POST['reset']) && $_POST['reset'] == 'true' ? 1 : 0; $items = isset($_POST['list']) ? $_POST['list'] : ''; $ressourcelist = ''; @@ -19,46 +19,46 @@ $udperms->document = $id; $udperms->role = $_SESSION['mgrRole']; -if(!$udperms->checkPermissions()) { - $modx->webAlertAndQuit($_lang["access_permission_denied"]); +if (!$udperms->checkPermissions()) { + $modx->webAlertAndQuit($_lang["access_permission_denied"]); } -if(isset($_POST['listSubmitted'])) { - $updateMsg .= '
      ' . $_lang['sort_updated'] . '
      '; - if(strlen($items) > 0) { - $items = explode(';', $items); - foreach($items as $key => $value) { - $docid = ltrim($value, 'item_'); - $key = $reset ? 0 : $key; - if(is_numeric($docid)) { - $modx->db->update(array('menuindex' => $key), $modx->getFullTableName('site_content'), "id='{$docid}'"); - } - } - } +if (isset($_POST['listSubmitted'])) { + $updateMsg .= '
      ' . $_lang['sort_updated'] . '
      '; + if (strlen($items) > 0) { + $items = explode(';', $items); + foreach ($items as $key => $value) { + $docid = ltrim($value, 'item_'); + $key = $reset ? 0 : $key; + if (is_numeric($docid)) { + $modx->db->update(array('menuindex' => $key), $modx->getFullTableName('site_content'), "id='{$docid}'"); + } + } + } } $disabled = 'true'; $pagetitle = ''; $ressourcelist = ''; -if($id !== NULL) { - $rs = $modx->db->select('pagetitle', $modx->getFullTableName('site_content'), "id='{$id}'"); - $pagetitle = $modx->db->getValue($rs); - - $rs = $modx->db->select('id, pagetitle, parent, menuindex, published, hidemenu, deleted, isfolder', $modx->getFullTableName('site_content'), "parent='{$id}'", 'menuindex ASC'); - if($modx->db->getRecordCount($rs)) { - $ressourcelist .= '
        '; - while($row = $modx->db->getRow($rs)) { - $classes = ''; - $classes .= ($row['hidemenu']) ? ' notInMenuNode ' : ' inMenuNode'; - $classes .= ($row['published']) ? ' publishedNode ' : ' unpublishedNode '; - $classes = ($row['deleted']) ? ' deletedNode ' : $classes; - $icon = $row['isfolder'] ? ' ' : ' '; - $ressourcelist .= '
      • ' . $icon . $row['pagetitle'] . ' (' . $row['id'] . ')
      • '; - } - $ressourcelist .= '
      '; - } else { - $updateMsg = '

      ' . $_lang['sort_nochildren'] . '

      '; - } +if ($id !== null) { + $rs = $modx->db->select('pagetitle', $modx->getFullTableName('site_content'), "id='{$id}'"); + $pagetitle = $modx->db->getValue($rs); + + $rs = $modx->db->select('id, pagetitle, parent, menuindex, published, hidemenu, deleted, isfolder', $modx->getFullTableName('site_content'), "parent='{$id}'", 'menuindex ASC'); + if ($modx->db->getRecordCount($rs)) { + $ressourcelist .= '
        '; + while ($row = $modx->db->getRow($rs)) { + $classes = ''; + $classes .= ($row['hidemenu']) ? ' notInMenuNode ' : ' inMenuNode'; + $classes .= ($row['published']) ? ' publishedNode ' : ' unpublishedNode '; + $classes = ($row['deleted']) ? ' deletedNode ' : $classes; + $icon = $row['isfolder'] ? ' ' : ' '; + $ressourcelist .= '
      • ' . $icon . $row['pagetitle'] . ' (' . $row['id'] . ')
      • '; + } + $ressourcelist .= '
      '; + } else { + $updateMsg = '

      ' . $_lang['sort_nochildren'] . '

      '; + } } $pagetitle = $id == 0 ? $site_name : $pagetitle; @@ -66,140 +66,118 @@

      - +

      -
      - () - -

      -

      - - -

      - - - - -
      +
      + () + +

      +

      + + +

      + + + + +
      - - + +
      diff --git a/manager/actions/mutate_plugin_priority.dynamic.php b/manager/actions/mutate_plugin_priority.dynamic.php index 040bd6d23d..97adb32cd3 100644 --- a/manager/actions/mutate_plugin_priority.dynamic.php +++ b/manager/actions/mutate_plugin_priority.dynamic.php @@ -1,37 +1,37 @@ INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

      Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('save_plugin')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('save_plugin')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } $siteURL = $modx->config['site_url']; $updateMsg = ''; -if(isset($_POST['listSubmitted'])) { - $updateMsg .= '' . $_lang['sort_updated'] . ''; - $tbl = $modx->getFullTableName('site_plugin_events'); - - foreach($_POST as $listName => $listValue) { - if($listName == 'listSubmitted') { - continue; - } - $orderArray = explode(',', $listValue); - $listName = ltrim($listName, 'list_'); - if(count($orderArray) > 0) { - foreach($orderArray as $key => $item) { - if($item == '') { - continue; - } - $pluginId = ltrim($item, 'item_'); - $modx->db->update(array('priority' => $key), $tbl, "pluginid='{$pluginId}' AND evtid='{$listName}'"); - } - } - } - // empty cache - $modx->clearCache('full'); +if (isset($_POST['listSubmitted'])) { + $updateMsg .= '' . $_lang['sort_updated'] . ''; + $tbl = $modx->getFullTableName('site_plugin_events'); + + foreach ($_POST as $listName => $listValue) { + if ($listName == 'listSubmitted') { + continue; + } + $orderArray = explode(',', $listValue); + $listName = ltrim($listName, 'list_'); + if (count($orderArray) > 0) { + foreach ($orderArray as $key => $item) { + if ($item == '') { + continue; + } + $pluginId = ltrim($item, 'item_'); + $modx->db->update(array('priority' => $key), $tbl, "pluginid='{$pluginId}' AND evtid='{$listName}'"); + } + } + } + // empty cache + $modx->clearCache('full'); } $rs = $modx->db->select("sysevt.name as evtname, sysevt.id as evtid, pe.pluginid, plugs.name, pe.priority, plugs.disabled", $modx->getFullTableName('system_eventnames') . " sysevt @@ -43,18 +43,18 @@ $sortableList = ''; $sortables = array(); -while($plugins = $modx->db->getRow($rs)) { - if($preEvt !== $plugins['evtid']) { - $sortables[] = $plugins['evtid']; - $sortableList .= $insideUl ? '

    ' : ''; - $sortableList .= '
    ' . $plugins['evtname'] . '
      '; - $insideUl = 1; - } - $sortableList .= '
    • ' . $plugins['name'] . ($plugins['disabled'] ? ' (hide)' : '') . '
    • '; - $preEvt = $plugins['evtid']; +while ($plugins = $modx->db->getRow($rs)) { + if ($preEvt !== $plugins['evtid']) { + $sortables[] = $plugins['evtid']; + $sortableList .= $insideUl ? '
    ' : ''; + $sortableList .= '
    ' . $plugins['evtname'] . '
      '; + $insideUl = 1; + } + $sortableList .= '
    • ' . $plugins['name'] . ($plugins['disabled'] ? ' (hide)' : '') . '
    • '; + $preEvt = $plugins['evtid']; } -if($insideUl) { - $sortableList .= '
    '; +if ($insideUl) { + $sortableList .= ''; } require_once(MODX_MANAGER_PATH . 'includes/header.inc.php'); @@ -62,89 +62,64 @@

    - +

    -
    - -

    +
    + +

    - + - + - -
    + +
    - - - - + + + +
    diff --git a/manager/actions/mutate_template_tv_rank.dynamic.php b/manager/actions/mutate_template_tv_rank.dynamic.php index 5d9997eb6f..78a80dd768 100644 --- a/manager/actions/mutate_template_tv_rank.dynamic.php +++ b/manager/actions/mutate_template_tv_rank.dynamic.php @@ -1,9 +1,9 @@ INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('save_template')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('save_template')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } $id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0; @@ -17,175 +17,153 @@ $updateMsg = ''; -if(isset($_POST['listSubmitted'])) { - $updateMsg .= '
    ' . $_lang['sort_updated'] . '
    '; - foreach($_POST as $listName => $listValue) { - if($listName == 'listSubmitted' || $listName == 'reset') { - continue; - } - $orderArray = explode(';', rtrim($listValue, ';')); - foreach($orderArray as $key => $item) { - if(strlen($item) == 0) { - continue; - } - $key = $reset ? 0 : $key; - $tmplvar = ltrim($item, 'item_'); - $modx->db->update(array('rank' => $key), $tbl_site_tmplvar_templates, "tmplvarid='{$tmplvar}' AND templateid='{$id}'"); - } - } - // empty cache - $modx->clearCache('full'); +if (isset($_POST['listSubmitted'])) { + $updateMsg .= '
    ' . $_lang['sort_updated'] . '
    '; + foreach ($_POST as $listName => $listValue) { + if ($listName == 'listSubmitted' || $listName == 'reset') { + continue; + } + $orderArray = explode(';', rtrim($listValue, ';')); + foreach ($orderArray as $key => $item) { + if (strlen($item) == 0) { + continue; + } + $key = $reset ? 0 : $key; + $tmplvar = ltrim($item, 'item_'); + $modx->db->update(array('rank' => $key), $tbl_site_tmplvar_templates, "tmplvarid='{$tmplvar}' AND templateid='{$id}'"); + } + } + // empty cache + $modx->clearCache('full'); } $rs = $modx->db->select("tv.name AS name, tv.caption AS caption, tv.id AS id, tr.templateid, tr.rank, tm.templatename", "{$tbl_site_tmplvar_templates} AS tr INNER JOIN {$tbl_site_tmplvars} AS tv ON tv.id = tr.tmplvarid INNER JOIN {$tbl_site_templates} AS tm ON tr.templateid = tm.id", "tr.templateid='{$id}'", "tr.rank ASC, tv.rank ASC, tv.id ASC"); -if($modx->db->getRecordCount($rs)) { - $sortableList = '
    ' . $row['templatename'] . '
      '; - while($row = $modx->db->getRow($rs)) { - $caption = $row['caption'] != '' ? $row['caption'] : $row['name']; - $sortableList .= '
    • ' . $caption . ' [*' . $row['name'] . '*]
    • '; - } - $sortableList .= '
    '; +if ($modx->db->getRecordCount($rs)) { + $sortableList = '
    ' . $row['templatename'] . '
      '; + while ($row = $modx->db->getRow($rs)) { + $caption = $row['caption'] != '' ? $row['caption'] : $row['name']; + $sortableList .= '
    • ' . $caption . ' [*' . $row['name'] . '*]
    • '; + } + $sortableList .= '
    '; } else { - $updateMsg = '

    ' . $_lang['tmplvars_novars'] . '

    '; + $updateMsg = '

    ' . $_lang['tmplvars_novars'] . '

    '; } ?>

    - +

    -
    - - -

    -

    - - -

    - - - - -
    +
    + + +

    +

    + + +

    + + + + +
    - - + +
    diff --git a/manager/actions/mutate_tv_rank.dynamic.php b/manager/actions/mutate_tv_rank.dynamic.php index 303bb35c5d..9fcbcc79ba 100644 --- a/manager/actions/mutate_tv_rank.dynamic.php +++ b/manager/actions/mutate_tv_rank.dynamic.php @@ -1,9 +1,9 @@ INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +if (IN_MANAGER_MODE != "true") { + die("INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); } -if(!$modx->hasPermission('save_template')) { - $modx->webAlertAndQuit($_lang["error_no_privileges"]); +if (!$modx->hasPermission('save_template')) { + $modx->webAlertAndQuit($_lang["error_no_privileges"]); } $reset = isset($_POST['reset']) && $_POST['reset'] == 'true' ? 1 : 0; @@ -14,173 +14,151 @@ $updateMsg = ''; -if(isset($_POST['listSubmitted'])) { - $updateMsg .= '' . $_lang['sort_updated'] . ''; - foreach($_POST as $listName => $listValue) { - if($listName == 'listSubmitted' || $listName == 'reset') { - continue; - } - $orderArray = explode(';', rtrim($listValue, ';')); - foreach($orderArray as $key => $item) { - if(strlen($item) == 0) { - continue; - } - $key = $reset ? 0 : $key; - $id = ltrim($item, 'item_'); - $modx->db->update(array('rank' => $key), $tbl_site_tmplvars, "id='{$id}'"); - } - } - // empty cache - $modx->clearCache('full'); +if (isset($_POST['listSubmitted'])) { + $updateMsg .= '' . $_lang['sort_updated'] . ''; + foreach ($_POST as $listName => $listValue) { + if ($listName == 'listSubmitted' || $listName == 'reset') { + continue; + } + $orderArray = explode(';', rtrim($listValue, ';')); + foreach ($orderArray as $key => $item) { + if (strlen($item) == 0) { + continue; + } + $key = $reset ? 0 : $key; + $id = ltrim($item, 'item_'); + $modx->db->update(array('rank' => $key), $tbl_site_tmplvars, "id='{$id}'"); + } + } + // empty cache + $modx->clearCache('full'); } $rs = $modx->db->select("name, caption, id, rank", $tbl_site_tmplvars, "", "rank ASC, id ASC"); -if($modx->db->getRecordCount($rs)) { - $sortableList = '
    ' . $row['templatename'] . '
      '; - while($row = $modx->db->getRow($rs)) { - $caption = $row['caption'] != '' ? $row['caption'] : $row['name']; - $sortableList .= '
    • ' . $caption . ' [*' . $row['name'] . '*]
    • '; - } - $sortableList .= '
    '; +if ($modx->db->getRecordCount($rs)) { + $sortableList = '
    ' . $row['templatename'] . '
      '; + while ($row = $modx->db->getRow($rs)) { + $caption = $row['caption'] != '' ? $row['caption'] : $row['name']; + $sortableList .= '
    • ' . $caption . ' [*' . $row['name'] . '*]
    • '; + } + $sortableList .= '
    '; } else { - $updateMsg = '

    ' . $_lang['tmplvars_novars'] . '

    '; + $updateMsg = '

    ' . $_lang['tmplvars_novars'] . '

    '; } ?>

    - +

    -
    - - -

    -

    - - -

    - - - - -
    +
    + + +

    +

    + + +

    + + + + +
    - - + +
    diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 596549f39a..ccf6b30fb6 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -35,8 +35,8 @@ - - + + @@ -49,6 +49,96 @@ evo = {}; } + // evoTooltips + evo.tooltips = function(a) { + if (!a) { + return; + } + let b = document.querySelector('.evo-tooltip'); + if (!b) { + b = document.createElement('div'); + } + document.body.appendChild(b); + b.className = 'evo-tooltip'; + let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); + [].slice.call(a).forEach(function(f) { + f.addEventListener('mouseenter', function(e) { + b.innerHTML = (this.dataset && this.dataset.tooltip ? (this.dataset.tooltip[0] === '#' ? document.querySelector(this.dataset.tooltip).innerHTML : this.dataset.tooltip) : this.innerHTML); + if (e.pageX + b.offsetWidth + (c * 2) > window.innerWidth) { + b.style.left = Math.round(e.pageX - b.offsetWidth - (c * 2)) + 'px'; + b.classList.add('evo-tooltip-right'); + } else { + b.style.left = Math.round(e.pageX) + 'px'; + b.classList.add('evo-tooltip-left'); + } + if (e.pageY - (b.offsetHeight / 2) - c < 0) { + b.style.top = 0; + } else if (e.pageY + (b.offsetHeight / 2) > window.innerHeight) { + b.style.top = Math.round(window.innerHeight - b.offsetHeight) - (c * 2) + 'px'; + } else { + b.style.top = Math.round(e.pageY - (b.offsetHeight / 2)) - c + 'px'; + } + b.classList.add('show'); + }); + f.addEventListener('mouseleave', function() { + b.className = 'evo-tooltip'; + }); + }); + }; + + // evoSortable + evo.sortable = function(a, b) { + if (!a && 'string' !== typeof a) { + return; + } + let h = { + handleClass: b.handleClass || 'ghost', complete: function(a) { + if ('function' === typeof b.complete) { + b.complete(a); + } + }, enter: function(a) { + if ('function' === typeof b.enter) { + b.enter(a); + } + }, + }; + [].slice.call(document.querySelectorAll(a)).forEach(function(c) { + c.onmousedown = function(e) { + let d = e.pageY, f, g = parseFloat(getComputedStyle(c).marginTop) + parseFloat(getComputedStyle(c).marginBottom); + c.classList.add(h.handleClass); + document.onselectstart = function(e) { + e.preventDefault(); + }; + document.onmousemove = function(e) { + f = (e.pageY - d); + if (f >= c.offsetHeight && c.nextElementSibling) { + d += c.offsetHeight + g; + c.parentNode.insertBefore(c, c.nextElementSibling.nextElementSibling); + h.enter(document.querySelectorAll(a)); + f = 0; + } else if (f <= -c.offsetHeight && c.previousElementSibling) { + d -= c.offsetHeight + g; + c.parentNode.insertBefore(c, c.previousElementSibling); + h.enter(document.querySelectorAll(a)); + f = 0; + } else if (!c.previousElementSibling && f < 0 || !c.nextElementSibling && f > 0) { + f = 0; + } + c.style.webkitTransform = 'translateY(' + f + 'px)'; + c.style.transform = 'translateY(' + f + 'px)'; + }; + document.onmouseup = function() { + c.style.webkitTransform = ''; + c.style.transform = ''; + c.classList.remove(h.handleClass); + document.onmousemove = null; + document.onselectstart = null; + h.complete(c, document.querySelectorAll(a)); + }; + }; + }); + }; + function document_onload() { stopWorker(); @@ -94,43 +184,6 @@ function document_onload() this.parentNode.classList.toggle('show'); }; } - - // evoTooltips - evo.tooltips = function(a) { - if (!a) { - return; - } - let b = document.querySelector('.evo-tooltip'); - if (!b) { - b = document.createElement('div'); - } - document.body.appendChild(b); - b.className = 'evo-tooltip'; - let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); - [].slice.call(a).forEach(function(f) { - f.addEventListener('mouseenter', function(e) { - b.innerHTML = (this.dataset && this.dataset.tooltip ? (this.dataset.tooltip[0] === '#' ? document.querySelector(this.dataset.tooltip).innerHTML : this.dataset.tooltip) : this.innerHTML); - if (e.pageX + b.offsetWidth + (c * 2) > window.innerWidth) { - b.style.left = Math.round(e.pageX - b.offsetWidth - (c * 2)) + 'px'; - b.classList.add('evo-tooltip-right'); - } else { - b.style.left = Math.round(e.pageX) + 'px'; - b.classList.add('evo-tooltip-left'); - } - if (e.pageY - (b.offsetHeight / 2) - c < 0) { - b.style.top = 0; - } else if (e.pageY + (b.offsetHeight / 2) > window.innerHeight) { - b.style.top = Math.round(window.innerHeight - b.offsetHeight) - (c * 2) + 'px'; - } else { - b.style.top = Math.round(e.pageY - (b.offsetHeight / 2)) - c + 'px'; - } - b.classList.add('show'); - }); - f.addEventListener('mouseleave', function() { - b.className = 'evo-tooltip'; - }); - }); - }; evo.tooltips(document.querySelectorAll('[data-tooltip]')); } diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 15545d70e9..a8f1a0eb50 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -113,6 +113,8 @@ input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !importan .table.data thead .sortable:hover a::after, .table.data thead .sortable-text:hover a::after, .table.data thead .sortable-numeric:hover a::after, .table.data thead .sortable-date:hover a::after { opacity: 1 } .table.data thead .sortable, .table.data thead .sortable-text, .table.data thead .sortable-numeric, .table.data thead .sortable-date { cursor: pointer } .table.data thead .sortable-text span, .table.data thead .sortable-numeric span, .table.data thead .sortable-date span { display: none } +.table.data.table-sortable > tbody > tr { cursor: move; transition-duration: .5s } +.table.data.table-sortable > tbody > tr.ghost { background-color: rgba(93, 109, 202, 0.16); color: #d9534f !important; transition: background-color .5s, color .5s, transform 0s } /* table-data-sm */ .table.data.table-sm td, .table.data.table-sm th { padding: .25rem .5rem; } .table.data.table-sm th, .table.data.table-sm thead td { font-size: 0.75rem; text-transform: none; } From 053269bec762d6ae7cf544a03de7e1160d51cb40 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 4 Aug 2017 08:30:58 +0300 Subject: [PATCH 169/338] update manager categories remove mootools sortable, replace evoSortable --- .../category_mgr/skin/js/categories.js | 23 ++++------ .../actions/category_mgr/skin/sort.tpl.phtml | 42 +++++++++---------- 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/manager/actions/category_mgr/skin/js/categories.js b/manager/actions/category_mgr/skin/js/categories.js index 4e82761675..850b69877f 100644 --- a/manager/actions/category_mgr/skin/js/categories.js +++ b/manager/actions/category_mgr/skin/js/categories.js @@ -18,22 +18,13 @@ /** * Sort Categories */ -new Sortables($('categories-sort'), { - //handles:'span.handle', - onStart: function(element){ - element.toggleClass('move'); - }, - onComplete: function(element){ - element.toggleClass('move'); - // reorder the indexes - this.list.getChildren().each(function(element, i){ - element.getElement('input.sort').setProperty( 'value', (i+1) ); - element.getElement('span.sort').setHTML( (i+1) ); -// element.getElements('td').each(function(td){ -// td.removeClass('gridItem').removeClass('gridAltItem'); -// td.addClass( ( i%2===0 ) ? 'gridItem' : 'gridAltItem' ); -// }); - }); +evo.sortable('.table-sortable tbody > tr', { + complete: function(a, b) { + for(let i = 0; i < b.length; i++) { + let item = b[i].querySelector('input.sort'); + b[i].querySelector('input.sort').value = i + 1; + b[i].querySelector('span.sort').innerHTML = i + 1 + } } }); diff --git a/manager/actions/category_mgr/skin/sort.tpl.phtml b/manager/actions/category_mgr/skin/sort.tpl.phtml index 9cc49e77bc..0552acf2cb 100644 --- a/manager/actions/category_mgr/skin/sort.tpl.phtml +++ b/manager/actions/category_mgr/skin/sort.tpl.phtml @@ -1,37 +1,37 @@ -
    - + +

    Drag category up or down to change its rank. Can be very useful when used with CategorizedTabs plugin to change tabs order.

    - +
    - - + + - - - - - + + + + - +
    txt('category_heading') ?>txt('position') ?>txt('category_heading') ?>txt('position') ?>
    - - - - - - - +
    + + + +
    From 3cc61fad4f8ed4ff1a83dc1430b676d130433967 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 4 Aug 2017 08:44:29 +0300 Subject: [PATCH 170/338] update evoSortable in header.php --- manager/includes/header.inc.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index ccf6b30fb6..e54e635f1e 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -92,13 +92,13 @@ return; } let h = { - handleClass: b.handleClass || 'ghost', complete: function(a) { + handleClass: b.handleClass || 'ghost', complete: function(a, j) { if ('function' === typeof b.complete) { - b.complete(a); + b.complete(a, j); } - }, enter: function(a) { + }, enter: function(a, j) { if ('function' === typeof b.enter) { - b.enter(a); + b.enter(a, j); } }, }; @@ -114,12 +114,12 @@ if (f >= c.offsetHeight && c.nextElementSibling) { d += c.offsetHeight + g; c.parentNode.insertBefore(c, c.nextElementSibling.nextElementSibling); - h.enter(document.querySelectorAll(a)); + h.enter(c, document.querySelectorAll(a)); f = 0; } else if (f <= -c.offsetHeight && c.previousElementSibling) { d -= c.offsetHeight + g; c.parentNode.insertBefore(c, c.previousElementSibling); - h.enter(document.querySelectorAll(a)); + h.enter(c, document.querySelectorAll(a)); f = 0; } else if (!c.previousElementSibling && f < 0 || !c.nextElementSibling && f > 0) { f = 0; From f7ea5e483e50fe997045b87921eb1477a2fa0a7e Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 4 Aug 2017 08:59:25 +0300 Subject: [PATCH 171/338] update evoSortable in header.php --- manager/includes/header.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index e54e635f1e..1c2e4fbdf6 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -88,7 +88,7 @@ // evoSortable evo.sortable = function(a, b) { - if (!a && 'string' !== typeof a) { + if (!a || 'string' !== typeof a) { return; } let h = { From 58d75d20c06460869312357fbe3e3893fc70d49a Mon Sep 17 00:00:00 2001 From: yamamoto Date: Fri, 4 Aug 2017 15:54:30 +0900 Subject: [PATCH 172/338] Update .gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 0fd30f6a6c..9173642252 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,10 @@ # and the config file /manager/includes/config.inc.php +# Windows and Mac +Thumbs.db +Desktop.ini +.DS_Store + # except do not ignore .gitignore !.gitignore From 389480ed0d1258ce04a2a3f4d2bab35e657726ee Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 4 Aug 2017 10:47:46 +0300 Subject: [PATCH 173/338] Update categories.js --- manager/actions/category_mgr/skin/js/categories.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/manager/actions/category_mgr/skin/js/categories.js b/manager/actions/category_mgr/skin/js/categories.js index 850b69877f..731f3ae71b 100644 --- a/manager/actions/category_mgr/skin/js/categories.js +++ b/manager/actions/category_mgr/skin/js/categories.js @@ -19,11 +19,11 @@ * Sort Categories */ evo.sortable('.table-sortable tbody > tr', { - complete: function(a, b) { - for(let i = 0; i < b.length; i++) { - let item = b[i].querySelector('input.sort'); - b[i].querySelector('input.sort').value = i + 1; - b[i].querySelector('span.sort').innerHTML = i + 1 + complete: function() { + let els = document.querySelectorAll('.table-sortable tbody > tr'); + for(let i = 0; i < els.length; i++) { + els[i].querySelector('input.sort').value = i + 1; + els[i].querySelector('span.sort').innerHTML = i + 1 } } }); From 805667dce30877c7d56bb6145daa00d177a31a9d Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 4 Aug 2017 10:58:23 +0300 Subject: [PATCH 174/338] refactor evoSortable in header.php --- manager/includes/header.inc.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 1c2e4fbdf6..f427d51612 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -88,21 +88,22 @@ // evoSortable evo.sortable = function(a, b) { - if (!a || 'string' !== typeof a) { + if (!a) { return; } let h = { - handleClass: b.handleClass || 'ghost', complete: function(a, j) { + handleClass: b.handleClass || 'ghost', complete: function() { if ('function' === typeof b.complete) { - b.complete(a, j); + b.complete(); } - }, enter: function(a, j) { - if ('function' === typeof b.enter) { - b.enter(a, j); + }, change: function() { + if ('function' === typeof b.change) { + b.change(); } }, }; - [].slice.call(document.querySelectorAll(a)).forEach(function(c) { + a = 'string' === typeof a ? document.querySelectorAll(a) : a; + [].slice.call(a).forEach(function(c) { c.onmousedown = function(e) { let d = e.pageY, f, g = parseFloat(getComputedStyle(c).marginTop) + parseFloat(getComputedStyle(c).marginBottom); c.classList.add(h.handleClass); @@ -114,12 +115,12 @@ if (f >= c.offsetHeight && c.nextElementSibling) { d += c.offsetHeight + g; c.parentNode.insertBefore(c, c.nextElementSibling.nextElementSibling); - h.enter(c, document.querySelectorAll(a)); + h.change(); f = 0; } else if (f <= -c.offsetHeight && c.previousElementSibling) { d -= c.offsetHeight + g; c.parentNode.insertBefore(c, c.previousElementSibling); - h.enter(c, document.querySelectorAll(a)); + h.change(); f = 0; } else if (!c.previousElementSibling && f < 0 || !c.nextElementSibling && f > 0) { f = 0; @@ -133,7 +134,7 @@ c.classList.remove(h.handleClass); document.onmousemove = null; document.onselectstart = null; - h.complete(c, document.querySelectorAll(a)); + h.complete(); }; }; }); From 4edf578dbd4d26496900f632f9d68e92d49a66cd Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 4 Aug 2017 11:06:34 +0300 Subject: [PATCH 175/338] update evoTooltips in header.php --- manager/includes/header.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index f427d51612..9af1e26eb1 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -61,6 +61,7 @@ document.body.appendChild(b); b.className = 'evo-tooltip'; let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); + a = 'string' === typeof a ? document.querySelectorAll(a) : a; [].slice.call(a).forEach(function(f) { f.addEventListener('mouseenter', function(e) { b.innerHTML = (this.dataset && this.dataset.tooltip ? (this.dataset.tooltip[0] === '#' ? document.querySelector(this.dataset.tooltip).innerHTML : this.dataset.tooltip) : this.innerHTML); From 8c123fc5ae28bb6bfd13fc383e948c1fc22a730d Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 4 Aug 2017 11:11:11 +0300 Subject: [PATCH 176/338] refactor evoTooltips in header.php --- manager/includes/header.inc.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 9af1e26eb1..7146d6a917 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -54,10 +54,7 @@ if (!a) { return; } - let b = document.querySelector('.evo-tooltip'); - if (!b) { - b = document.createElement('div'); - } + let b = document.querySelector('.evo-tooltip') || document.createElement('div'); document.body.appendChild(b); b.className = 'evo-tooltip'; let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); From c7fef5a3416b8c0229d5bcc6c5031a7b2d36c1c7 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 4 Aug 2017 11:32:08 +0300 Subject: [PATCH 177/338] no message --- ...21\202\320\265\320\273\320\265\320\271.md" | 145 ------------------ 1 file changed, 145 deletions(-) delete mode 100644 "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" deleted file mode 100644 index 04c410ea91..0000000000 --- "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" +++ /dev/null @@ -1,145 +0,0 @@ -## Авторизация пользователей - -Авторизация пользователей в `FormLister` осуществляется с использованием контроллера `Login`. - -Авторизация может проходить по id, имени (username), email средствами класса modUsers; другому полю из учетной записи (с помощью плагина для события OnWebAuthentication). Поле задается в параметре `loginField` и должно быть **уникальным** для каждого веб-пользователя. Обычно для авторизации используются поля `username` или `email`. - -Дополнительное использование плагина [userHelper](https://github.com/evolution-cms/evolution/blob/develop/assets/snippets/FormLister/plugin.userHelper.php) позволяет: - -* вести учет количества логинов; -* определить время последней авторизации; -* реализовать автологин и выход из учетной записи; -* блокировать пользователей после определенного количества неудачных попыток авторизации. - -Перед использованием плагина `userHelper` убедитесь что он включен: - -![Не забудьте включить userHelper](https://habrastorage.org/web/dbc/1e2/abd/dbc1e2abd8664a548f4eca254187fb60.png) - -## Параметры контроллера - -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### loginField -Поле, содержащее имя пользователя. - -Возможные значения - имя поля. - -Значение по умолчанию - username. - -### passwordField -Поле, содержащее пароль пользователя. - -Возможные значения - имя поля. - -Значение по умолчанию - password. - -### rememberField -Поле для запоминания пользователя. Если значение поля приводится к true, то при успешной авторизации будет установлена кука с параметрами автологина. Имя куки и ее время жизни задаются параметрами cookieName и cookieLifetime. - -Можно также задать поле rememberme в параметре defaults, чтобы запоминание происходило без участия пользователя: -``` -&defaults=`{"rememberme":1}` -``` - -Возможные значения - имя поля. - -Значение по умолчанию - rememberme. - -### checkActivation -Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). - -Возможные значения - 0 или 1. - -Значение по умолчанию - 1. - -### context -Контекст авторизации. - -Возможные значения - mgr или web. - -Значение по умолчанию - web. - -### cookieName -Имя куки для хранения параметров автологина. - -Значение по умолчанию - WebLoginPE. - -### cookieLifetime -Время жизни вышеуказанной куки. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 157680000 (5 лет). - -### redirectTo -Перенаправляет пользователя на страницу c указанным id после авторизации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет уже авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной авторизации. В шаблоне можно использовать данные пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Login с ключом [+login.default_successTpl+] - -### skipTpl -Шаблон сообщения о том, что пользователь уже авторизован. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Login с ключом [+login.default_skipTpl+] - -## Параметры плагина userHelper -### logoutKey -Имя GET-параметра для запуска выхода из учетной записи. Если в ссылке на страницу сайта указан параметр с соответствующим именем (например, http://sitename.ru/page.html?logout), будет произведен выход из учетной записи. - -Значение по умолчанию - logout. - -### cookieName -Имя куки для хранения параметров автологина. - -Значение по умолчанию - WebLoginPE. - -### cookieLifetime -Время жизни вышеуказанной куки. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 157680000 (5 лет). - -### maxFails -Количество попыток для ввода учетных данных. - -Возможные значения - число больше 0. - -Значение по умолчанию - 3. - -### blockTime -Время блокировки пользователя. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 3600 (1 час). - From 3c862c2108748b6495a34023deec1e7091ff66fe Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 4 Aug 2017 11:33:38 +0300 Subject: [PATCH 178/338] no message --- ...21\202\320\265\320\273\320\265\320\271.md" | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" new file mode 100644 index 0000000000..04c410ea91 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" @@ -0,0 +1,145 @@ +## Авторизация пользователей + +Авторизация пользователей в `FormLister` осуществляется с использованием контроллера `Login`. + +Авторизация может проходить по id, имени (username), email средствами класса modUsers; другому полю из учетной записи (с помощью плагина для события OnWebAuthentication). Поле задается в параметре `loginField` и должно быть **уникальным** для каждого веб-пользователя. Обычно для авторизации используются поля `username` или `email`. + +Дополнительное использование плагина [userHelper](https://github.com/evolution-cms/evolution/blob/develop/assets/snippets/FormLister/plugin.userHelper.php) позволяет: + +* вести учет количества логинов; +* определить время последней авторизации; +* реализовать автологин и выход из учетной записи; +* блокировать пользователей после определенного количества неудачных попыток авторизации. + +Перед использованием плагина `userHelper` убедитесь что он включен: + +![Не забудьте включить userHelper](https://habrastorage.org/web/dbc/1e2/abd/dbc1e2abd8664a548f4eca254187fb60.png) + +## Параметры контроллера + +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### loginField +Поле, содержащее имя пользователя. + +Возможные значения - имя поля. + +Значение по умолчанию - username. + +### passwordField +Поле, содержащее пароль пользователя. + +Возможные значения - имя поля. + +Значение по умолчанию - password. + +### rememberField +Поле для запоминания пользователя. Если значение поля приводится к true, то при успешной авторизации будет установлена кука с параметрами автологина. Имя куки и ее время жизни задаются параметрами cookieName и cookieLifetime. + +Можно также задать поле rememberme в параметре defaults, чтобы запоминание происходило без участия пользователя: +``` +&defaults=`{"rememberme":1}` +``` + +Возможные значения - имя поля. + +Значение по умолчанию - rememberme. + +### checkActivation +Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). + +Возможные значения - 0 или 1. + +Значение по умолчанию - 1. + +### context +Контекст авторизации. + +Возможные значения - mgr или web. + +Значение по умолчанию - web. + +### cookieName +Имя куки для хранения параметров автологина. + +Значение по умолчанию - WebLoginPE. + +### cookieLifetime +Время жизни вышеуказанной куки. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 157680000 (5 лет). + +### redirectTo +Перенаправляет пользователя на страницу c указанным id после авторизации. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### exitTo +Перенаправляет уже авторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### successTpl +Шаблон сообщения об успешной авторизации. В шаблоне можно использовать данные пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Login с ключом [+login.default_successTpl+] + +### skipTpl +Шаблон сообщения о том, что пользователь уже авторизован. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Login с ключом [+login.default_skipTpl+] + +## Параметры плагина userHelper +### logoutKey +Имя GET-параметра для запуска выхода из учетной записи. Если в ссылке на страницу сайта указан параметр с соответствующим именем (например, http://sitename.ru/page.html?logout), будет произведен выход из учетной записи. + +Значение по умолчанию - logout. + +### cookieName +Имя куки для хранения параметров автологина. + +Значение по умолчанию - WebLoginPE. + +### cookieLifetime +Время жизни вышеуказанной куки. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 157680000 (5 лет). + +### maxFails +Количество попыток для ввода учетных данных. + +Возможные значения - число больше 0. + +Значение по умолчанию - 3. + +### blockTime +Время блокировки пользователя. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 3600 (1 час). + From b7a8e801176c9500e672537d3bf7ad3ba7e5bc85 Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 4 Aug 2017 11:36:29 +0300 Subject: [PATCH 179/338] refactor evoTooltips in header.php --- manager/includes/header.inc.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 7146d6a917..57810c7de3 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -54,10 +54,13 @@ if (!a) { return; } - let b = document.querySelector('.evo-tooltip') || document.createElement('div'); - document.body.appendChild(b); - b.className = 'evo-tooltip'; - let c = parseInt(window.getComputedStyle(b, null).getPropertyValue('margin-top')); + let b = document.querySelector('.evo-tooltip'); + if (!b) { + b = document.createElement('div'); + document.body.appendChild(b); + b.className = 'evo-tooltip'; + } + let c = parseInt(window.getComputedStyle(b).getPropertyValue('margin-top')); a = 'string' === typeof a ? document.querySelectorAll(a) : a; [].slice.call(a).forEach(function(f) { f.addEventListener('mouseenter', function(e) { From eaba6e8e7edd39d5222316cd03154a59d1d29cff Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 4 Aug 2017 11:43:23 +0300 Subject: [PATCH 180/338] fix trouble with my local git --- assets/snippets/FormLister/docs/history.md | 135 -------- ...20\273\320\273\320\265\321\200\321\213.md" | 50 --- ...20\274\320\265\321\202\321\200\321\213.md" | 291 ------------------ ...20\260\320\275\320\275\321\213\321\205.md" | 132 -------- ...20\272\320\260\320\277\321\207\320\270.md" | 175 ----------- ...20\260\320\275\320\275\321\213\321\205.md" | 40 --- ...20\277\320\270\321\201\320\265\320\274.md" | 216 ------------- ...21\202\320\265\320\273\320\265\320\271.md" | 145 --------- ...21\202\320\265\320\273\320\265\320\271.md" | 137 --------- ...20\277\320\270\321\201\320\265\320\271.md" | 84 ----- ...20\260\321\202\320\265\320\273\321\217.md" | 99 ------ ...20\260\321\202\320\265\320\273\321\217.md" | 50 --- ...20\265\320\273\321\217\320\274\320\270.md" | 143 --------- ...20\265\320\273\321\217\320\274\320\270.md" | 166 ---------- ...20\265\320\273\321\217\320\274\320\270.md" | 97 ------ ...20\270\320\272\320\276\320\275\321\213.md" | 18 -- 16 files changed, 1978 deletions(-) delete mode 100644 assets/snippets/FormLister/docs/history.md delete mode 100644 "assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" delete mode 100644 "assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" diff --git a/assets/snippets/FormLister/docs/history.md b/assets/snippets/FormLister/docs/history.md deleted file mode 100644 index 7bca858b2d..0000000000 --- a/assets/snippets/FormLister/docs/history.md +++ /dev/null @@ -1,135 +0,0 @@ -## History -### 1.7.7 -* [Enhancement] Возможность указывать разный subject для разных типов писем (Form). - -### 1.7.6 -* [Fix] Исправления ошибок. - -### 1.7.5 -* [Fix] $this->modx вместо $modx в сниппете. - -### 1.7.4 -* [Fix] Ошибка в лексиконе (Form). -* [Refactor] Версии PHP ниже 5.6 не поддерживаются (Core). - -### 1.7.3 -* [Refactor] Подключать __autoload.php, если не задан другой загрузчик. -* [Fix] Ошибка в обработке параметра редиректа (Core). - -### 1.7.2 -* [Enhancement] Параметр &context в контроллере Login для поддержки модели modManagers (Login). -* [Fix] Ошибка в обработке параметра редиректа (Core). - -### 1.7.1 -* [Enhancement] Сниппет записывает в лог, если не задан параметр formid или не удалось загрузить класс контроллера. -* [Refactor] Плагин userHelper по умолчанию отключен. -* [Refactor] По умолчанию загружается лексикон english. -* [Fix] Ошибка в формате даты для лексикона english/form. - -### 1.7.0 -* [Refactor] Изменен метод loadModel, добавлена возможность указывать параметры, передаваемые в конструктор модели (Core). -* [Fix] Ошибка в лексиконе контроллера DeleteContent. -* [Fix] Создание записей анонимными пользователями если &onlyUsers=`0` (Content). -* [Refactor] Убраны include/require, для загрузки классов подключается файл assets/snippets/FormLister/__autoload.php. Модели MODxAPI загружаются этим же загрузчиком. -* [Refactor] Создание записи в логе, если не удалось сохранить данные (Content). -* [Refactor] Изменена обработка поля для запоминания авторизации: теперь время для автологина задается в параметре cookieLifetime (по умолчанию 5 лет, в секундах), а не значением поля (Login). -* [Refactor] Имя куки для автологина можно задать с помощью параметра cookieName, по умолчанию WebLoginPE (Login). -* [Refactor] В контроллере Login сначала проверяется, активирована ли учетная запись, а потом уже возможность авторизации (Login). -* [Enhancement] Блокировка пользователей после определенного числа неудачных попыток авторизации в плагине userHelper. - -### 1.6.2 -* [Fix] Неверное объявление метода в классах капчи. - -### 1.6.1 -* [Refactor] Переделан автологин в плагине userHelper. - -### 1.6.0 -* [Enhancement] Параметр rewriteUrls для обработки ссылок в шаблонах. Игнорируется, если задан параметр parseDocumentSource (Core). -* [Enhancement] Если страница с вызовом контроллера Login указана в конфигурации, как страница "Доступ запрещен", то после успешной авторизации будет произведен редирект на запрашиваемую страницу (Login). -* [Enhancement] Новый параметр ignoreMailerResult (Form). -* [Fix] Неправильная проверка уникальности username в контроллере Profile. -* [Refactor] Для добавления пользователей в группы используется метод из modUsers (Register). -* [Refactor] Введенный пользователем пароль сохраняется в поле user.password (Register). -* [Refactor] Контроллеры Register, Profile и Content загружают данные из моделей после успешного выполнения; после этого можно выполнить сниппеты из параметра preparePostProcess. Сделано это потому что плагины на сохранение или сами модели могут менять данные. -* [Enhancement] Восстановление данных, испорченных в protect.inc.php. Если параметр removeGpc равен 1, то очищены будут все входящие поля. Можно указать в параметре имена полей через запятую. При выводе обработанных полей будут экранироваться тэги MODX (Core). -* [Refactor] В prepare-сниппеты передается переменная name с названием параметра в котором задан сниппет. Можно использовать один сниппет для всех случаев (Core). -* [Enhancement] Контроллер DeleteUser для удаления пользователей c запросом пароля. -* [Enhancement] Контроллер DeleteContent для удаления записей MODxAPI. -* [Enhancement] Контроллер Activate для активации учетных записей. -* [Enhancement] Контроллеры Register и Login могут работать с активацией учетных записей. -* [Enhancement] Вывод параметров data-badge и data-callback для рекапчи (ReCaptchaWrapper). -* [Enhancement] Параметр deleteAttachments для удаления файлов после отправки письма (Form). -* [Enhancement] Сохранение имен файлов в поля формы (Form). -* [Enhancement] Отправка файлов не из формы. Список файлов задается массивом в параметре attachFiles: {"field":{"filepath":"assets/images/logo.png","filename":"logo.png"}} (Form). -* [Refactor] Можно не задавать параметр contentFields, в этом случае в модель будут переданы поля формы (Content). -* [Refactor] Корректная обработка полей lastlogin и thislogin в плагине userHelper. -* [Fix] Неверно выбирался шаблон при восстановлении паролей (Reminder). -* [Enhancement] Дополнительная обработка чанков парсером MODX c помощью параметра parseDocumentSource (Core). -* [Enhancement] Возможность вырезать необработанные плейсхолдеры из чанков с помощью параметра removeEmptyPlaceholders (Core). -* [Enhancement] Параметр removeEmptyPlaceholders для удаления необработанных плейсхолдеров из чанков (возможные значения 0,1; по умолчанию - 0) (Core). -* [Fix] Из-за неправильной обработки параметра defaultsSources не загружались поля в контроллере Profile (Core). -* [Fix] Метод filterFields не учитывал значение параметра allowEmptyFields (Core). - -### 1.5.1 -Исправления ошибок. - -###1.5.0 -* [Refactor] Переделана загрузка внешних параметров с учетом того, что не все источники могут содержать массив: добавлен источник aplh для загрузки массива значений из плейсхолдера MODX, в источнике cookie можно указать несколько имен кук через запятую. Добавлен источник user для загрузки данных авторизованного веб-пользователя (user:web) или менеджера (user:mgr) (Core). Добавлен источник document для загрузки данных текущего или указанного документа. -* [Refactor] Валидация капчи вынесена в класс капчи (Core). -* [Refactor] Параметры капчи задаются массивом, там же указываются сообщения об ошибках (Core). -* [Refactor] Валидация капчи происходит в классе капчи. (Core). -* [Enhancement] reCaptcha2. -* [Enhancement] smsCaptcha. -* [Enhancement] Поддержка Twig: в шаблон передаются переменные FormLister, data, errors, messages. Добавлен метод getErrorMessage для получения в шаблоне сообщений об ошибках для указанного поля (Core). -* [Enhancement] Параметры редиректа можно задавать в виде массива с ключами page (id страницы), query (массив параметров запроса) и header (заголовок) (Core). -* [Enhancement] Если задан параметр redirectTo и параметр editAfterCreate равен 1, то в параметры редиректа будет добавлен идентификатор созданного документа (Core, Content). -* [Fix] Плагин userHelper теперь перенаправляет пользователя на текущую страницу без ?logout в ссылке. -* [Fix] Сопоставление имен полей формы и модели в параметре contentFields неправильно работало в режиме редактирования, если имена различались (Content). -* [Refactor] Пользовательские функции валидации могут вместо false возвращать сообщение об ошибке (Core). - -### 1.4.1 -* [Refactor] Больше рандома в modxCaptcha. - -### 1.4.0 -* [Refactor] Класс modxCaptchaWrapper больше не привязан к FormLister (Core, modxCaptchaWrapper). -* [Enhancement] Убрано принудительное отключение параметров submitLimit и protectSubmit (Content). -* [Refactor] Изменен алгоритм загрузки пользовательских лексиконов. Теперь в параметре lexicon можно указывать как имя файла, так и сразу массив c языковыми записями (Core, Lexicon). -* [Refactor] Загрузка полей отправленной формы происходит не из $_REQUEST, а согласно параметру formMethod (значение по умолчанию - 'post') (Core). -* [Enhancement] Метод loadArray можно использовать для обработки строк с разделителем (по умолчанию - ',') (Config). -* [Enhancement] Если значение параметра submitLimit меньше 60, то оно не пересчитывается в минуты (Form). - -### 1.3.0 -* [Enhancement] Поддержка события OnBeforeWebLogin. В плагине можно реализовать процедуру авторизации независимую от модели; установку полей и шаблона сообщения об успешной авторизации нужно также производить в плагине. Плагин должен вернуть true в случае успешной авторизации, иначе будет выполнена авторизация методами модели (Login). - -### 1.2.1 -* [Refactor] Метод isArray теперь protected (FileValidator). - -### 1.2.0 -* [Refactor] Переделан пропуск полей при преобразовании в плейсхолдеры. Теперь плейсхолдеры отделены от полей формы, для работы с ними следует использовать методы setPlaceholder и getPlaceholder. Выводятся через [+placeholder+]. -* [Bug] Сниппеты, указанные в prepareProcess, выполнялись независимо от результатов валидации. -* [Refactor] Изменена логика обработки правил валидации. Теперь все правила, которых нет в валидаторе, обрабатываются как custom. Это позволяет применять сразу несколько таких правил. -* [Enhancement] Возможность применять правила валидации только для заполненных полей. -* [Refactor] Информация о файлах размещается в массиве formData c помощью метода setFiles (Core, Form). -* [Refactor] Объект FS теперь публичный. -* [Refactor] Контроллер Profile наследуется от Form, а не от Core. - -### 1.1.0 -* [Refactor] Метод filesToArray перемещен в Core. -* [Enhancement] Возможность загрузки произвольных моделей в контроллерах, которые используют MODxAPI. Новые параметры - model и modelPath. -* [Refactor] Метод для загрузки моделей MODxAPI. -* [Enhancement] Возможность загружать произвольные модели MODxAPI в контроллерах. -* [Enhancement] Новое правило валидации - date, проверяет является ли значение поля датой в указанном формате (Validator). -* [Enhancement] Возможность пропускать поля при преобразовании в плейсхолдеры (Core). - -### 1.0.2 -* [Enhancement] Убрано значение по умолчанию свойства allowedFields в контроллерах Register и Profile. - -### 1.0.1 -* [Enhancement] Новое правило валидации файлов - optional, аналог правила required но выполняется также, если файл не загружен пользователем (FileValidator). -* [Enhancement] Правила валидации файлов allowed, minSize, sizeBetween считаются выполненными, если файл не загружен пользователем (код ошибки 4). Решает проблему с файловыми полями, для которых не задано правило required (FileValidator). -* [Bug] К письму прикреплялись не загруженные пользователем файлы, теперь прикрепляются только успешно загруженные (код ошибки 0) (Form). -* [Fix] Параметры из файлов перезаписывали параметры сниппета (Core). -* [Bug] Конфиг из файла не добавлялся в общий массив настроек (Helpers/Config). - -### 1.0.0 -Public release. diff --git "a/assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" "b/assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" deleted file mode 100644 index e566b9dae2..0000000000 --- "a/assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" +++ /dev/null @@ -1,50 +0,0 @@ -## Контроллеры -Контроллер представляет собой класс, унаследованный от базового класса \FormLister\Core, который реализует: - -- загрузку классов для валидации и генерации капчи; -- работу с данными (под данными здесь и далее подразумеваются значения свойства formData, то есть не только значения массива $_REQUEST); -- работу с шаблоном формы и шаблоном успешной обработки. - -Схема работы: - -1. Загрузка данных из формы -2. Загрузка данных из внешних источников -3. Вызов сниппетов для обработки данных. -4. Валидация данных - если получены данные из формы; -3. Вызов сниппетов для обработки данных. -6. Итоговая обработка - если получены данные из формы и пройдена валидация. -7. Вывод. - -Итоговая обработка формы происходит в методе process() контроллера. После успешной обработки необходимо установить флаг результа обработки формы с помощью метода setFormStatus(), а также и указать в свойстве renderTpl шаблон для вывода информации с результатами обработки. - -Ниже перечислены базовые контроллеры. - -### Контроллер Form -Отправляет письма с данными формы. - -### Контроллер Login -Авторизует пользователя в контексте web. - -### Контроллер Register -Создает web-пользователя и отправляет соответствующие письма. - -### Контроллер Activate -Обрабатывает ссылку из письма с подтверждением регистрации или отправляет такое письмо. - -### Контроллер DeleteUser -Позволяет пользователям удалять свои учетные записи. Для подтверждения запрашивает пароль. - -### Контроллер Profile -Предназначен для редактирования данных web-пользователя. - -### Контроллер Reminder -Предназначен для восстановления паролей web-пользователями. - -### Контроллер Content -Позволяет создавать и изменять записи с помощью классов MODxAPI. - -### Контроллер DeleteContent -Позволяет пользователям удалять созданные ими записи. - -### Контроллер MailChimp -Добавляет пользователей в список рассылки сервиса MailChimp. Добавлен как пример расширения базового класса \FormLister\Core. diff --git "a/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" "b/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" deleted file mode 100644 index e0046780fa..0000000000 --- "a/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" +++ /dev/null @@ -1,291 +0,0 @@ -## Общие параметры - -Эти параметры обрабатываются базовым классом FormLister. В контроллерах некоторые общие параметры могут иметь другое назначение. - -## Настройки -### controller -Задает класс для обработки данных. - -Возможные значения - имя php-файла с классом без расширения. - -Значение по умолчанию - Form. - -### dir -Папка в которой находится класс контроллера. - -Значение по умолчанию - assets/snippets/FormLister/core/controller/ - -### formid -Имя формы, обязательный параметр. - -В шаблоне формы обязательно должно быть скрытое поле с именем formid и значением, указанным в параметре. Форма считается отправленной, если в массиве $_REQUEST присутствует ключ с именем параметра, а его значение соответствует значению параметра. - -### formMethod -Возможные значения - post, get или request. - -Значение по умолчанию - post. - -### config -Загрузка параметров в формате json из файла. - -Возможные значения - имяфайла:папка, несколько значений разделяются точкой с запятой. - -#### Пример -myparams:core - загрузить параметры из файла assets/snippets/FormLister/config/core/myparams.json; myparams - загрузить параметры из файла assets/snippets/FormLister/config/custom/myparams.json; myparams:/assets/myfolder - загрузить параметры из файла assets/myfolder/myparams.json. - -Значение по умолчанию - пусто. - -### api -Определяет, в каком виде будут выводиться данные. - -Возможные значения: - -- 0: только html; -- 1: json-массив с данными формы; -- 2: json-массив с данными формы и html. - -### debug -Режим отладки. Вывод записывается в лог MODX. - -Возможные значения - 0, 1. - -Значение по умолчанию - 0. - -### saveObject -Сохраняет объект класса FormLister в плейсхолдер, который можно использовать в других сниппетах. Объект сохраняется только при успешной обработке формы. - -Возможные значения - имя плейсхолдера. - -Значение по умолчанию - пусто. - -### removeGpc -Убирает экранирование данных, которое выполняет MODX для символов {{, [[ и т.д. При этом экранируются тэги MODX при выводе. - -Возножные значения - 0, 1 или имена полей через запятую. - -Значение по умолчанию - 0. - -## Источники данных -### defaultsSources -Позволяет загружать дополнительные данные из внешних источников, например, для предварительного заполнения полей формы. По умолчанию внешние данные загружаются только при начальном выводе формы и не загружаются после отправки формы Это поведение может быть изменено с помощью параметра keepDefaults. - -Возможные значения: список источников, разделенных точкой с запятой. Загрузка данных производится в том порядке, в котором они указаны в списке. - -Источник может задаваться в формате "имя:ключ:префикс". Префикс, если указан, добавляется c точкой к имени поля - например, config.site_name. - -Возможные значения: - -- array: json или php-массив, значения задаются параметром defaults; -- param:имя параметра:префикс - значения задаются значением параметра из вызова сниппета (аналогично array, только значение задается не параметром defaults, а произвольным, также можно указать префикс); -- session:ключ массива:префикс - значения загружаются из массива $_SESSION; -- plh:ключи через запятую:префикс - загружаются значения из массива $modx->placeholders; -- aplh:имя плейсхолдера:префикс - загружаются значения из плейсхолдера, содержащего массив; -- config:префикс - загружаются значения из конфигурации MODX; -- cookie:ключи через запятую:префикс - загружаются значения из массива $_COOKIE; -- имя класса MODxAPI:ключ:префикс - ключ является аргументом метода edit(), класс должен быть заранее загружен; -- document:префикс - загружает данные из модели modResource для документа, в котором вызван сниппет. Ключ не указывается; -- user:ключ:префикс - загружает данные из модели modUsers для авторизованного пользователя. Тип пользователя уточняется в ключе (web или mgr). - -Значение по умолчанию - array. - -### defaults -Данные для источника array. - -Возможные значения: массив значений по умолчанию, в формате json или php. - -### keepDefaults -Позволяет повторно загружать данные из внешних источников после отправки формы. Если в параметре указан список полей, то загружены будут только указанные поля. - -Возможные значения: 1, 0, имена полей, разделенные запятой. - -Значение по умолчанию - 0. - -### allowEmptyFields -Разрешает задавать поля с пустыми значениями. - -Возможные значения - 0 или 1. - -Значение по умолчанию - 1. - -## Элементы управления -### formControls -Список полей с управляющими элементами формы (списки, чекбоксы, радио-кнопки). Необходимо для отслеживания состояния элементов. - -Возможные значения - имена полей, разделенные запятой. - -Значение по умолчанию - пусто. - -### emptyFormControls - -Этот параметр позволяет решить проблему неотмеченных чекбоксов, которые не включаются в массив полей при отправке формы: если в $_REQUEST отсутствует нужный элемент, то он создается согласно данному параметру. Необходимость в таком параметре возникла в связи с тем, что MODxAPI требует явно указывать изменяемые поля в методе fromArray(). Но можно использовать и в обычных формах, чтобы подставить в шаблон значение неотмеченного чекбокса. - -Возможные значения - массив: -``` -&emptyFormControls=`{ - "mycheckbox" : "Нет", - "published" : 0 -}` -``` - -## Обработка данных -### prepare, prepareProcess, prepareAfterProcess -Аналогично параметру prepare в DocLister. - -Сниппеты из параметра prepare выполняются после загрузки данных в форму, сниппеты из параметра prepareProcess - после прохождения валидации, сниппеты из параметра prepareAfterProcess - после успешного выполнения обработки. В сниппетах через переменную $FormLister доступен объект контроллера, а через массив $data - значения полей формы. Также доступна переменная $name, которая задержит имя параметра из которого взят сниппет (prepare, prepareProcess и т.д.); это позволяет использовать один и тот же сниппет для разных случаев. Для изменения данных следует использовать в prepare-сниппетах методы контроллера (setField, setFields и т.д.) - -Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. - -Значение по умолчанию - пусто. - -## Валидация -### validator -Имя класса для валидации данных. Класс должен быть предварительно загружен. - -Значение по умолчанию - \FormLister\Validator. - -### rules -Массив с правилами валидации. - -Значение по умолчанию - пусто. - -## Шаблоны -### formTpl -Шаблон формы. В шаблоне формы обязательно должно быть поле с именем formid и значением, указанным в параметре formid. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### arraySplitter - -Разделитель для преобразования массивов в строку. - -Значение по умолчанию - точка с запятой. - -### {field}.arraySplitter -Разделитель для преобразования массивов в строку, но для отдельного поля {field}. Например: groups.arraySplitter - разделитель для массива из поля groups. - -Если не задано, то используется значение параметра arraySplitter. - -### errorTpl -Шаблон для вывода сообщений валидатора. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию: -``` -@CODE:
    [+message+]
    -``` - -### requiredClass, errorClass -Имена классов для обозначения незаполненных (required) и неверно заполенных (error) полей. - -Значение по умолчанию - required и error соответственно. - -### {field}.requiredClass, {field}.errorClass -Позволяет задавать указанные выше классы для конкретных полей. - -По умолчанию используются значения параметров requiredClass и errorClass. - -### messagesTpl -Шаблон сообщений обработчика формы. В шаблоне выводятся группы сообщений (messages, required, error). - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию: -``` -@CODE:
    [+messages+]
    -``` - -### messagesOuterTpl -Шаблон-обертка для группы произвольных сообщений. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - -``` -@CODE: [+messages+] -``` - -### messagesRequiredOuterTpl -Шаблон-обертка для группы сообщений о незаполненных полях. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию: -``` -@CODE: [+messages+] -``` - -### messagesErrorOuterTpl -Шаблон-обертка для группы сообщений о неверно заполненных полях. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию: -``` -@CODE: [+messages+] -``` - -### messagesSplitter, messagesRequiredSplitter, messagesErrorSplitter -Разделитель сообщений в группе. - -Возможные значения - произвольная строка. - -Значение по умолчанию: -``` -
    -``` - -### removeEmptyPlaceholders -Удаляет из шаблонов незаполненные прейслхолдеры. - -Возможные значения - 0 или 1. - -Значение по умолчанию - 0. - -### parseDocumentSource -Обрабатывает чанки MODX-парсером. - -Возможные значения - 0 или 1. - -Значение по умолчанию - 0. - -### rewriteUrls -Если параметр parseDocumentSource отключен, то парсит ссылки в шаблонах. - -Возможные значения - 0 или 1. - -Значение по умолчанию - 0. - -### skipPrerender -Позволяет отключить предварительную обработку полей формы (экранирование значений, преобразование массивов в строки, установка сообщений об ошибках). Можно включить, если для вывода не используется парсер MODX. - -Возможные значения - 0 или 1. - -Значение по умолчанию - 0. - -### templatePath, templateExtension -Путь к папке с файлами шаблонов и расширение файлов шаблонов. Эти параметры необходимо задавать при использовании плагина EvoTwig. - -Значение по умолчанию - пусто. - -## Перенаправление после обработки -### redirectTo -Id страницы, на которую нужно выполнить перенаправление после успешной обработки формы. В api-режиме перенаправление не выполняется, но в массиве данных формы сохраняется абсолютная ссылка на целевую страницу (поле "redirectTo"). - -Вместо числа можно указывать массив: -``` -&redirectTo=`{ - "page":10, - "query":{ - "foo":"bar" - }, - "header":"HTTP/1.1 307 Temporary Redirect" -}` -``` -Ключ page задает id станицы, в массиве query можно передать дополнительные get-параметры, значением ключа header может быть текст заголовка для перенаправления. - -Возможные значения - число или массив. - -Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" "b/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" deleted file mode 100644 index 9efb7da81d..0000000000 --- "a/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" +++ /dev/null @@ -1,132 +0,0 @@ -## Валидация данных - -При валидации данных валидатор последовательно применяет к значению поля заданные правила, при возникновении ошибки в массив данных об ошибках добавляется запись и дальнейшая обработка формы прекращается. - -Валидация считается пройденной, если в массиве данных об ошибках отсутствуют записи. - -### Правила валидации -Список правил задается в виде массива. Ключом является имя поля, а значением - массив правил валидации. Правило валидации является методом класса-валидатора. В массиве правил ключом является имя правила (название метода валидации), значением может быть либо строка с сообщением об ошибке валидации правила, или же массив с описанием. В этом массиве в ключе params задаются необходимые для валидации значения, а в ключе message задается строка с сообщением об ошибке. - -Можно также использовать отрицание правил, если добавить перед именем правила восклицательный знак: "!numeric" - поле пройдет валидацию, если его значение не является числом. - -Если нужно реализовать проверку только заполненных полей, то перед именем поля в списке правил нужно добавить восклицательный знак. В этом случае если значение поля пустое, правила будут проигнорированы. - -``` -{ - "имя поля 1": { - "правило 1" : "сообщение об ошибке", - "правило 2" : "сообщение об ошибке" - }, - "имя поля 2": { - "правило 1" : "сообщение об ошибке", - "правило 2" : { - "params" : значение, - "message" : "сообщение об ошибке" - } - }, - "!имя поля 3":{ - "правило 1" : "сообщение об ошибке" - } -} -``` -Стандартным классом валидации (\FormLister\Validator) предусмотрены правила: - -- required: поле заполнено; -- date: значение поля является датой в заданном формате; -- min: значение поля больше заданного или равно ему; -- max: значение поля меньше заданного или равно ему; -- greater: значение поля строго меньше заданного; -- less: значение поля строго больше заданного; -- between: значение поля входит в диапазон; -- equals: значение поля равно заданному; -- in: значение поля входит в заданный массив значений; -- alpha: значение поля содержит только буквы; -- numeric: значение поля содержит только цифры; -- alphaNumeric: значение поля содержит только буквы и цифры; -- slug: значение поля является частью url; -- decimal: значение поля является десятичным числом; -- phone: значение поля является номером телефона; -- matches: значение поля удовлетворяет регулярному выражению; -- url: значение поля является ссылкой; -- email: значение поля является email-адресом; -- length: длина значения поля равна заданному; -- minLength: длина значения поля больше заданного или равна ему; -- maxLength: длина значения поля меньше заданного или равна ему; -- lengthBetween: длина значения поля входит в диапазон; -- minCount: размер массива больше заданного; -- maxCount: размер массива меньше заданного; -- countBetween: размер массива входит в диапазон. - -Если требуется задать два значения для правила, то их следует задавать как массив: -``` -&rules=`{ - "field" : { - "lengthBetween" : { - "params" : [10,20], - "message" : "Длина должна быть от 10 до 20" - } - } -}` -``` - -Для правила in (и других правил, использующих массив) массив значений следует задавать следующим образом: -``` -&rules=`{ - "field" : { - "in" : { - "params" : [ [10,20,30] ], - "message" : "Значение поля field должно быть равно 10, 20 или 30" - } - } -}` -``` - -Это нужно, чтобы массив был передан в функцию одним аргументом. - -Предусмотрена также возможность использовать для валидации функции или статические методы загруженного класса: -``` -&rules=`{ - "myfield":{ - "required":"Required field", - "custom":{ - "function":"\\Namespace\\Classname::myCustomRule", - "params":[10,20,30], - "message":"Custom check failed" - } - } -}` -``` - -Метод должен принимать первым аргументом экземпляр контроллера из которого вызывается правило, вторым аргументом - значение проверяемого поля, далее - параметры передаваемые в ключе описания params: -``` -public static function myCustomRule($fl,$value,$a,$b,$c) { - $result = $fl->getField('field1') == $a && $fl->getField('field2') == $b && $value == $c; - return $result; -} -``` -В примере правило будет пройдено, если значение поля field1 = 10, значение поля field2 = 20, а значение поля, к которму применяется правило, = 30. - -Метод должен вернуть true, false или текст сообщения об ошибке (в этом случае можно не указывать message в списке правил). - -В примере используется название правила "сustom", но можно использовать любое название правила, которого нет в классе валидации. Таким образом можно использовать несколько правил данного типа. - -### Результаты валидации -Данные об ошибках хранятся в виде массива и могут быть получены вызовом метода getFormData('errors'): -``` -{ - "имя поля 1": { - "имя нарушенного правила" : "сообщение об ошибке" - }, - "имя поля 2": { - "имя нарушенного правила" : "сообщение об ошибке" - } -} -``` -Для добавления данных в этот массив используется метод addError(имя поля, имя правила, сообщение об ошибке). Таким образом, можно влиять на итоговый результат валидации, вручную добавляя записи в этот массив. Можно также объявить валидацию непройденной по умолчанию, вызвав метод setValid(false). - -В шаблонах результаты валидации для каждого поля выводятся с помощью плейсхолдера [+имя поля.error+]. Общий результат может быть выведен в плейсхолдер [+form.messages+], который задается шаблоном messagesTpl. В свою очередь, в этом шаблоне можно использовать плейсхолдеры: - -- [+required+] - сообщения о незаполенных полях; -- [+errors+] - сообщения о неверно заполненных полях. - -Получить сообщения об ошибках для определенного поля можно с помощью метода getErrorMessage(имя поля). diff --git "a/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" "b/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" deleted file mode 100644 index 99f61a25bf..0000000000 --- "a/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" +++ /dev/null @@ -1,175 +0,0 @@ -## Использование капчи - -По умолчанию FormLister может использовать модицифированную капчу MODX и Google Recaptcha. Также в наличии SmsCaptcha - для отправки формы необходимо ввести код, полученный в смс-сообщении (отправку сообщения необходимо реализовывать отдельно). - -Для подключения необходимо указать имя папки с файлами капчи (папки находятся в assets/snippets/FormLister/lib/captcha/) в параметре &captcha. - -В параметре &captchaParams задаются в виде массива настройки капчи. Например: -``` -&captchaParams=`{ -"width":200, -"height":120 -}` -``` - -Имя поля, в которое пользователь вводит значение капчи, задается параметром captchaField (по умолчанию - vericode). Правило валидации для этого поля создается автоматически. - -Капча выводится в шаблоне формы с помощью плейсхолдера [+captcha+]. - -### modxCaptcha - -Модификация стандартной капчи MODX. - -Настройки: -* width и height - ширина и высота картинки с капчей (значение по умолчанию - 100 и 60); -* inline - формат вывода. Если значение параметра равно 1, то в плейсхолдер [+captcha+] выводится картинка в base64-формате. Если 0, то выводится ссылка на файл connector.php, генерирующий картинку. Значение по умолчанию - 1; -* connectorDir - путь к папке с файлом connector.php, если параметр inline равен 0. Значение по умолчанию - assets/snippets/FormLister/lib/captcha/modxCaptcha/; -* errorEmptyCode - текст сообщения об ошибке, если поле со значением капчи не заполнено. Значение по умолчанию - "Введите проверочный код"; -* errorCodeFailed - текст сообщения об ошибке, если введено неверное значение капчи. Значение по умолчанию - "Неверный проверочный код" - -### reCaptcha - -Капча Google reCAPTCHA V2. На странице с формой должен быть подключен скрипт: -``` - -``` - -Значение параметра captchaField должно быть "g-recaptcha-response" (см. [документацию](https://developers.google.com/recaptcha/docs/verify)). - -Настройки: -* secretKey, siteKey - ключи для доступа к api reCAPTCHA; -* size, theme, badge, callback, expired_callback, tabIndex, type - см. [документацию](https://developers.google.com/recaptcha/docs/display#render_param); -* errorCodeFailed - текст сообщения об ошибке, если пользователь не прошел проверку. Значение по умолчанию - "Вы не прошли проверку" - -### smsCaptcha - -Настройки: -* codeLifeTime - срок действия введенного кода, секунд. Если пользователь попытается ввести код до истечения срока, то будет выведено сообщение errorCodeUsed. Значение по умолчанию - 86400 (сутки); -* errorEmptyCode - сообщение об ошибке, если пользователь получил, но не ввел код. Значение по умолчанию - "Введите код авторизации"; -* errorCodeRequired - сообщение об ошибке, если пользователь не запросил код. Значение по умолчанию - "Получите код авторизации"; -* errorCodeFailed - сообщение об ошибке, если пользователь ввел неверный код авторизации. Значение по умолчанию - "Неверный код авторизации"; -* errorCodeExpired - сообщение об ошибке, если пользователь не ввел полученный код в течение заданного времени. Значение по умолчанию - "Код авторизации истек, получите новый"; -* errorCodeUsed - сообщение об ошибке, если пользователь уже вводил код для текущей формы. Значение по умолчанию - "Код авторизации уже использовался". - -Чтобы использовать эту капчу необходимо предварительно создать таблицу в базе данных: -``` -createTable(); -``` - -Для отправки кода необходимо создать отдельную форму и указать в параметре prepareProcess сниппет: - ``` -setValid(false); - $FormLister->addError('phone','phone','Неверный номер телефона'); -} else { - //загружаем класс для работы с таблицей - $sms = $FormLister->loadModel('SmsModel','assets/snippets/FormLister/lib/captcha/smsCaptcha/model.php'); - $flag = false; - //проверяем, есть ли в таблице запись для заданного номера и идентификатора формы - $data = $sms->getData('+'.$rawPhone,$formid); - if ($data->getID()) { - //если есть и код не истек - if ($sms->get('expires') > time()) { - //смотрим, использован ли код - if ($sms->get('active')) { - $FormLister->addMessage('Вы уже использовали код.'); - } else { - $FormLister->addMessage('Код уже был отправлен. Подождите несколько минут прежде чем запросить новый.'); - } - //если код истек, то удаляем запись и разрешаем выдать новый - } else { - $sms->delete($sms->getID()); - $flag = true; - } - } else { - $flag = true; - } - //если можно выдать новый код - if ($flag) { - $code = mt_rand(1000,9999); - - //здесь отправляется смс и результат помещается в переменную $result - /** - * - */ - $result = array('status'=>true); - - //проверяем отправлена ли смс - if (is_array($result) && $result['status']) { - //создаем запись в таблице, время жизни кода - 3 минуты - $result = $sms->create()->fromArray(array( - 'phone'=>('+'.$rawPhone), - 'formid'=>$formid, - 'expires'=>(time() + 60*3), - 'ip'=> \APIhelpers::getUserIP(), - 'code'=>$code - ))->save(); - //если получилось записать, то сохраняем в сессию номер телефона - if ($result) { - $_SESSION[$session_key] = '+'.$rawPhone; - } else { - $FormLister->setValid(false); - $FormLister->addMessage('Не удалось отправить смс'); - } - } else { - //если нельзя выдать код, то запрещаем дальнейшую обработку формы - $FormLister->setValid(false); - } -} -?> -``` - -Полностью вызов FormLister: -``` -[!FormLister? -&formid=`code` -&submitLimit=`0` -&protectSubmit=`0` -&rules=`{ -"phone":{ - "required":"Обязательно введите номер телефона", - "phone":"Введите номер правильно" -} -}` -&prepareProcess=`setSmsCaptcha` -&captcha=`modxCaptcha` -&formTpl=`@CODE: -
    -
    -
    - - - -
    - -
    - - [+phone.error+] -
    -
    -[+form.messages+] -
    -
    - -
    -
    - - - [+vericode.error+] - -
    -
    -
    ` -&successTpl=`@CODE:Код авторизации отправлен на номер [+phone.value+]. Срок действия кода - 3 минуты.` -!] -``` diff --git "a/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" "b/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" deleted file mode 100644 index 8dc1af8cf9..0000000000 --- "a/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" +++ /dev/null @@ -1,40 +0,0 @@ -## Вывод данных - -Для вывода в шаблоны данные экранируются, а массивы преобразовываются в строки. Кроме этого, для элементов управления устанавливаются специальные плейсхолдеры. - -Вывод неэкранированного значения поля: -[+имя поля+] - -Вывод значения поля: -``` -[+имя поля.value+] -``` - -Установка чекбокса: -``` -[+c.имя поля.значение поля+] -``` - -Установка выпадающего списка или радио-кнопки: -``` -[+s.имя поля.значение поля+] -``` - -Установка класса для незаполненного поля: -[+имя поля.requiredСlass+] - -Установка класса для неверно заполненного поля: -[+имя поля.errorClass+] - -Вывод сообщения об ошибке валидации: -[+имя поля.error+] - -Вывод сообщений обработчика: -[+form.messages+] - -В плейсхолдер [+form.messages+] могут выводиться три типа сообщений: нарушения правила required, нарушения остальных правил, произвольные сообщения, которые задаются методом addMessage. По умолчанию выводятся только последние, см. описание параметра messagesTpl. - -Вывод значений из лексиконов: -[%ключ лексикона%] - -При использовании плагина EvoTwig в шаблонах доступны переменные FormLister (объект контроллера), errors (массив formData['errors']), messages (массив formData['messages']). diff --git "a/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" "b/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" deleted file mode 100644 index f501b7d5d8..0000000000 --- "a/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" +++ /dev/null @@ -1,216 +0,0 @@ -## Отправка писем - -Контроллер Form позволяет отправлять данные формы в письме. - -## Параметры отправки почты -### isHtml -Разрешает отправлять письмо в формате html. Проверка корректности кода письма возлагается на разработчика. - -Возможные значения - 1, 0. - -Значение по умолчанию - 1. - -### to -Адрес получателя. Если не указан, то письмо не отправляется, но считается успешно отправленным. - -Возможные значения - email-адрес. - -Значение по умолчанию - пусто. - -### from -Возможные значения - email-адрес. - -Значение по умолчанию - параметр конфигурации emailsender. - -### fromName -Имя отправителя. - -Возможное значение - строка. - -Значение по умолчанию - параметр конфигурации site_name. - -### replyTo -Заголовок replyTo. - -Возможные значения - email-адрес. - -Значение по умолчанию - пусто. - -### cc -Заголовок сс. - -Возможные значения - email-адрес. - -Значение по умолчанию - пусто. - -### bcc -Заголовок bcc. - -Возможные значения - email-адрес. - -Значение по умолчанию - пусто. - -### noemail -Если параметр задан, то письмо не отправляется, но считается успешно отправленным. - -Возможные значения - 1, 0. - -Значение по умолчанию - 0. - -### ignoreMailerResult -Если параметр задан, то письмо отправляется, но результат отправки игнорируется. - -Возможные значения - 1, 0. - -Значение по умолчанию - 0. - -### subject, ccSubject, autoSubject -Тема письма. - -Возможные значения - строка. - -Значение по умолчанию - пусто. - -### subjectTpl, ccSubjectTpl, autoSubjectTpl -Шаблон темы письма. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - значение параметра subject (ccSubject, autoSubject). - -### autosender -Адрес на который отправляется дополнительное письмо. - -Возможные значения - email-адрес. - -Значение по умолчанию - пусто. - -### autosenderFromName -Имя отправителя дополнительного письма. - -Возможные значения - строка. - -Значение по умолчанию - параметр конфигурации site_name. - -### ccSender -Если параметр задан, то на адрес указанный в поле формы отправляется письмо. - -Возможные значения - 1, 0. - -Значение по умолчанию - 0. - -### ccSenderField -Имя поля, в котором хранится адрес получателя. - -Возможные значения - имя поля формы. - -Значение по умолчанию - email. - -### ccSenderFromName -Имя отправителя письма на заданный в поле формы адрес. - -Возможные значения - строка. - -Значение по умолчанию - не указано. - -## Защита от повторной отправки -### protectSubmit -Защита от повторной отправки письма. - -Возможные значения - 1, 0 или список полей, по которым определяется уникальность письма. Если список не задан, то используются поля, обязательные для заполнения. - -Значение по умолчанию - 1. - -### submitLimit -Защита от частой отправки писем. - -Значение - число секунд между повторной отправкой. - -Значение по умолчанию - 60. - -## Шаблоны -### reportTpl -Основной шаблон письма. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - список полей и их значений. - -### automessageTpl -Шаблон дополнительного письма. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### ccSenderTpl -Шаблон письма на заданный в поле формы адрес. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной отправке писем. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -## Отправка файлов -### attachments -Имена полей, в которых хранятся файлы. Поддерживаются только поля с одним файлом (name="field" type="file") и поля с одномерным массивом файлов (name="field[]" type="file" multiple). - -Значение по умолчанию - пусто. - -### attachFiles -Позволяет отправить произвольные файлы. - -Возможные значения - массив: -``` -&attachFiles=`{ -"имя поля1":{ - "filepath":"assets/images/logo.png", - "filename":"logo.png" -}, -"имя поля2":[ - { - "filepath":"assets/images/file1.jpg", - "filename":"отчет.jpg" - }, - { - "filepath":"assets/images/file2.jpg", - "filename":"отчет2.jpg" - } -] -}` -``` -### deleteAttachments -Позволяет удалить файлы вложений после успешной отправки. - -Возможные значения - 0 или 1. - -Значение по умолчанию - 0. - -### fileValidator -Имя класса для валидации файлов. Если задано, то класс должен быть загружен заранее. - -Значение по умолчанию - \FormLister\FileValidator - -### fileRules -Правила валидации (см. раздел "Валидация данных"). Стандартный валидатор поддерживает правила: - -- required: файлы успешно отправлены; -- optional: аналогично required, но выполняется и в том случае, если пользователь не загружал файлы (то есть поле с файлами не является обязательным); -- allowed: расширение файла входит в заданный массив; -- images: расширение файла jpg, jpeg, gif, png, bmp; -- minSize: размер файла в килобайтах больше заданного; -- maxSize: размер файла в килобайтах меньше заданного; -- sizeBetween: размер файла в килобайтах входит в диапазон; -- minCount: количество файлов больше заданного; -- maxCount: количество файлов меньше заданного; -- countBetween: количество файлов входит в диапазон. - -Использовать конструкцию "!имя поля" в правилах валидации файлов нет смысла, так как значение поля с файлом не будет пустым, даже если файл не загружен. Следует использовать правило optional. - -В шаблоне письма reportTpl доступен плейсхолдер [+attachments.value+] со списком всех приложенных к письму файлов. Можно также вывести по отдельности: [+имя поля.value+]. Файлы отправляются только в письме c шаблоном reportTpl. diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" deleted file mode 100644 index 04c410ea91..0000000000 --- "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" +++ /dev/null @@ -1,145 +0,0 @@ -## Авторизация пользователей - -Авторизация пользователей в `FormLister` осуществляется с использованием контроллера `Login`. - -Авторизация может проходить по id, имени (username), email средствами класса modUsers; другому полю из учетной записи (с помощью плагина для события OnWebAuthentication). Поле задается в параметре `loginField` и должно быть **уникальным** для каждого веб-пользователя. Обычно для авторизации используются поля `username` или `email`. - -Дополнительное использование плагина [userHelper](https://github.com/evolution-cms/evolution/blob/develop/assets/snippets/FormLister/plugin.userHelper.php) позволяет: - -* вести учет количества логинов; -* определить время последней авторизации; -* реализовать автологин и выход из учетной записи; -* блокировать пользователей после определенного количества неудачных попыток авторизации. - -Перед использованием плагина `userHelper` убедитесь что он включен: - -![Не забудьте включить userHelper](https://habrastorage.org/web/dbc/1e2/abd/dbc1e2abd8664a548f4eca254187fb60.png) - -## Параметры контроллера - -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### loginField -Поле, содержащее имя пользователя. - -Возможные значения - имя поля. - -Значение по умолчанию - username. - -### passwordField -Поле, содержащее пароль пользователя. - -Возможные значения - имя поля. - -Значение по умолчанию - password. - -### rememberField -Поле для запоминания пользователя. Если значение поля приводится к true, то при успешной авторизации будет установлена кука с параметрами автологина. Имя куки и ее время жизни задаются параметрами cookieName и cookieLifetime. - -Можно также задать поле rememberme в параметре defaults, чтобы запоминание происходило без участия пользователя: -``` -&defaults=`{"rememberme":1}` -``` - -Возможные значения - имя поля. - -Значение по умолчанию - rememberme. - -### checkActivation -Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). - -Возможные значения - 0 или 1. - -Значение по умолчанию - 1. - -### context -Контекст авторизации. - -Возможные значения - mgr или web. - -Значение по умолчанию - web. - -### cookieName -Имя куки для хранения параметров автологина. - -Значение по умолчанию - WebLoginPE. - -### cookieLifetime -Время жизни вышеуказанной куки. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 157680000 (5 лет). - -### redirectTo -Перенаправляет пользователя на страницу c указанным id после авторизации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет уже авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной авторизации. В шаблоне можно использовать данные пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Login с ключом [+login.default_successTpl+] - -### skipTpl -Шаблон сообщения о том, что пользователь уже авторизован. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Login с ключом [+login.default_skipTpl+] - -## Параметры плагина userHelper -### logoutKey -Имя GET-параметра для запуска выхода из учетной записи. Если в ссылке на страницу сайта указан параметр с соответствующим именем (например, http://sitename.ru/page.html?logout), будет произведен выход из учетной записи. - -Значение по умолчанию - logout. - -### cookieName -Имя куки для хранения параметров автологина. - -Значение по умолчанию - WebLoginPE. - -### cookieLifetime -Время жизни вышеуказанной куки. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 157680000 (5 лет). - -### maxFails -Количество попыток для ввода учетных данных. - -Возможные значения - число больше 0. - -Значение по умолчанию - 3. - -### blockTime -Время блокировки пользователя. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 3600 (1 час). - diff --git "a/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" deleted file mode 100644 index 58843c8e7a..0000000000 --- "a/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" +++ /dev/null @@ -1,137 +0,0 @@ -## Регистрация пользователей - -Контроллер Register позволяет регистрировать пользователей в заданные группы и отправлять уведомления о регистрации. Контроллер является расширением контроллера Form, соответственно можно использовать соответствующие параметры для отправки писем при регистрации. - -Имена полей в форме должны соответствовать полям модели [modUsers](http://docs.evolution-cms.com/Extras/Snippets/DocLister/MODxAPI). - -Если в форме не задано поле username, то ему присваивается значение поля email. Таким образом можно регистрировать пользователей только по email. - -Если в форме не задано поле password, то значение поля генерируется автоматически. То есть регистрацию пользователя можно свести к указанию email. - -При регистрации с паролем, в форме может присутствовать поле repeatPassword. Если заданы правила валидации для полей password и repeatPassword, то при наличии для поля repeatPassword правила equals, оно будет автоматически скорректировано для проверки равенства значений полей password и repeatPassword: -``` -"repeatPassword":{ - "required":"Введите пароль еще раз", - "equals":{ - "params" : "Этот ключ в описании правила можно не задавать, он будет сформирован контроллером автоматически", - "message":"Пароли не совпадают" - } -} -``` - -При регистрации следует проверять уникальность имени пользователя и email. В контроллере предусмотрены соответствующие правила: -``` -&rules=`{ - "username":{ - "required":"Введите имя пользователя", - "alphaNumeric":"Только буквы и цифры", - "custom":{ - "function":"\\FormLister\\Register::uniqueUsername", - "message":"Имя уже занято" - } - }, - "email":{ - "required":"Введите email", - "email":"Неверный email", - "custom":{ - "function":"\\FormLister\\Register::uniqueEmail", - "message":"Этот email уже использует другой пользователь" - } - } -}` -``` -В шаблонах доступны все поля модели для созданной записи. Дополнительно задается поле user.password с незашифрованным паролем. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### allowedFields -Разрешенные для обработки поля. Поля, не указанные в списке, игнорируются. Поля username, email и password всегда разрешены. - -Если не задано, то разрешены все поля. - -Возможные значения - имена полей формы, разделенные запятой. - -Значение по умолчанию - пусто. - -### forbiddenFields -Запрещенные для обработки поля. Поля, указанные в списке, игнорируются. Поля username, email и password удаляются из списка запрещенных. - -Возможные значения - имена полей формы, разделенные запятой. - -Значение по умолчанию - пусто. - -### userGroups -Добавляет зарегистрированного пользователя в указанные группы. - -Возможные значения - имена групп, разделенные запятой (если имена содержат запятую в названии, то можно задать значение параметра массивом). - -Значение по умолчанию - пусто. - -### checkActivation -Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). При этом после сохранения записи будет установлено поле activate.url, содержащее ссылку на страницу с вызовом сниппета для активации учетной записи. - -Возможные значения - 1 или 0. - -Значение по умолчанию - 0. - -### activateTo -Если включена проверка активации, то в этом параметре необходимо указать id страницы, на которой вызывается сниппет для активации. - -Возможные значения - id страницы. - -Значение по умолчанию - значение $modx->config['site_start']. - -### preparePostProcess -Позволяет выполнить обработку данных после сохранения. - -Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. - -Значение по умолчанию - пусто. - -### redirectTo -Перенаправляет пользователя на указанную страницу после регистрации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет уже авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для уже авторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Register с ключом [+register.default_skipTpl+] - -### successTpl -Шаблон сообщения об успешной регистрации. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Register с ключом [+register.default_successTpl+] - -### passwordLength -Длина пароля (если создается автоматически). - -Возможные значения - число символов больше 6. - -Значение по умолчанию - 6. diff --git "a/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" deleted file mode 100644 index ce0f37925c..0000000000 --- "a/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" +++ /dev/null @@ -1,84 +0,0 @@ -## Активация учетных записей - -Контроллер Activate реализует активацию учетных записей. Таким образом появляется возможность требовать у пользователя подтверждение учетной записи путем перехода по специальной ссылке из письма, отправленного при регистрации. - -Если по какой-то причине пользователь не получил письмо, то c помощью контроллера Activate он может запросить его повторную отправку. - -Учетная запись пользователя считается неактивированной если в поле logincount записано -1. - -В вызовах сниппета для регистрации и авторизации пользователей должен присутствовать параметр &checkActivation=`1`. - -Поэтому если при регистрации пользователь указывал пароль самостоятельно, то нужно запрашивать пароль для отправки письма со ссылкой для активации. Иначе будет генерироваться новый пароль, потому что раз пользователь запрашивает письмо для активации вручную, значит письмо после регистрации он не получил и не знает созданный при регистрации пароль. - -В шаблонах доступны все поля модели для обрабатываемой записи. В шаблоне reportTpl задается поле user.password с незашифрованным паролем и поле activate.url со ссылкой для активации. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### redirectTo -Перенаправляет пользователя на указанную страницу после активации. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для авторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Register с ключом [+register.default_skipTpl+] - -### reportTpl -Шаблон письма с информацией для активации учетной записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### reportTpl -Шаблон письма с информацией для активации учетной записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной отправке письма с данными для активации. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Activate с ключом [+activate.default_successTpl+] - -### activateSuccessTpl -Шаблон сообщения об успешной активации. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Activate с ключом [+activate.default_activateSuccessTpl+] - -### passwordLength -Длина создаваемого пароля. - -Возможные значения - число символов больше 6. - -Значение по умолчанию - 6. diff --git "a/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" "b/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" deleted file mode 100644 index 1a6d503c7d..0000000000 --- "a/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" +++ /dev/null @@ -1,99 +0,0 @@ -## Редактирование профиля пользователя - -Контроллер Profile позволяет авторизованным пользователям редактировать свои профили, в том числе менять пароль. - -При изменении профиля следует проверять уникальность email. В контроллере предусмотрено соответствующее правило: -``` -&rules=`{ - "email":{ - "required":"Введите email", - "email":"Неверный email", - "custom":{ - "function":"\\FormLister\\Profile::uniqueEmail", - "message":"Этот email уже использует другой пользователь" - } - } -}` -``` -Аналогично с полем username: -``` -&rules=`{ - "username":{ - "required":"Введите имя пользователя", - "alphaNumeric":"Только буквы и цифры", - "custom":{ - "function":"\\FormLister\\Profile::uniqueUsername", - "message":"Имя уже занято" - } - } -}` -``` - -Если поле с паролем пустое, то пароль остается прежний. После изменения пароля пользователь должен авторизоваться с новым паролем. Новый пароль сохраняется в поле user.password. - - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### allowedFields -Разрешенные для обработки поля. Поля, не указанные в списке, игнорируются. Если пользователь меняет пароль, то в разрешенные поля добавляется поле password. Если у пользователей совпадают поля e-mail и username, то при изменении e-mail будет изменено и поле username, если значение этого поля не задано. В этом случае поле username будет добавлено в список разрешенных. - -Если не задано, то разрешены все поля. - -Возможные значения - имена полей формы, разделенные запятой. - -Значение по умолчанию - пусто. - -### forbiddenFields -Запрещенные для обработки поля. Поля, указанные в списке, игнорируются. Поля password и username исключаются из списка по аналогии с allowedFields. - -Возможные значения - имена полей формы, разделенные запятой. - -Значение по умолчанию - пусто. - -### preparePostProcess -Позволяет выполнить обработку данных после сохранения. - -Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. - -Значение по умолчанию - пусто. - -### redirectTo -Перенаправляет пользователя на указанную страницу после сохранения профиля. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет неавторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для неавторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Profile с ключом [+profile.default_skipTpl+] - -### successTpl -Шаблон сообщения об успешном обновлении профиля. Если не задан, то генерируется сообщение об успешном сохранении формы. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" "b/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" deleted file mode 100644 index bfe4041476..0000000000 --- "a/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" +++ /dev/null @@ -1,50 +0,0 @@ -## Удаление профиля пользователя - -Контроллер DeleteUser позволяет авторизованным пользователям удалять свои профили. Для подтверждения действия пользователю необходимо ввести свой пароль. - -Расширяет Form. - -В шаблонах доступны поля модели для удаляемой записи. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### redirectTo -Перенаправляет пользователя на указанную страницу после сохранения профиля. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### exitTo -Перенаправляет неавторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для неавторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона deleteUser с ключом [+deleteUser.default_skipTpl+] - -### successTpl -Шаблон сообщения об успешном удалении профиля. Если не задан, то генерируется сообщение об успешном сохранении формы. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" deleted file mode 100644 index e9b507dd4f..0000000000 --- "a/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" +++ /dev/null @@ -1,143 +0,0 @@ -## Восстановление паролей пользователями - -Контроллер Reminder позволяет web-пользователям восстанавливать забытые пароли. Расширяет контроллер Form. - -Восстановление паролей происходит по следующей схеме: - -- пользователь вводит в форме свой идентификатор (им может быть имя пользователя или email); -- пользователь получает письмо, в котором содержится ссылка для восстановления; -- при переходе по ссылке пользователь получает возможность ввести новый пароль либо пароль будет сгенерирован автоматически; -- пользователю отправляется письмо с новым паролем и показыается сообщение (в сообщении можно также вывести новый пароль). - -Параметр to перезаписывается значением email пользователя. Обязательно должен быть задан параметр resetTo. - -## Параметры -### model -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### modelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### hashField -Имя поля для хранения хэша данных пользователя. - -Значение по умолчанию - hash. - -### userField -Имя поля для хранения идентификатора пользователя (имя пользователя или email). - -Значение по умолчанию - email. - -### uidField -Имя поля, которое используется для идентификации пользователя при переходе по ссылке. - -Значение по умолчанию - id. - -### exitTo -Перенаправляет авторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### resetTo -Страница, на которую будет указывать ссылка для восстановления паролей. Обязательный параметр. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - id документа, в котором вызван контроллер. - -### redirectTo -Перенаправляет на указанную страницу после успешного восстановления пароля. - -Возможные значения - id целевой страницы. - -Значение по умолчанию - пусто. - -### skipTpl -Шаблон сообщения для авторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_skipTpl+]. - -### formTpl -Шаблон формы для ввода идентификатора пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### resetTpl -Шаблон формы для ввода нового пароля. Если параметр не задан, то пароль будет сгенерирован автоматически. - -Поля для ввода паролей должны называться password и repeatPassword. В форме должны также присутствовать скрытые поля с именами из параметров uidField и hashField. Значение для поля hashField задается через плейсхолдер [+user.hash+]. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### successTpl -Шаблон сообщения об успешной отправке письма со ссылкой для восстановления пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.). - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_successTpl+]. - -### resetSuccessTpl -Шаблон сообщения об успешном восстановлении пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_resetSuccessTpl+]. - -### reportTpl -Шаблон письма со ссылкой для восстановления пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). Ссылка для восстановлени пароля в письме задается через плейсхолдер [+reset.url+] - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_reportTpl+].. - -### resetReportTpl -Шаблон письма об успешном восстановлении пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). Если не задан, то письмо пользователю отправляться не будет. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. - -### rules -Правила валидации для формы идентификации пользователя. - -Возможные значения - см. раздел "Валидация данных". - -Значение по умолчанию - пусто. - -### resetRules -Правила валидации для формы установки нового пароля. Если заданы правила валидации для полей password и repeatPassword, то при наличии для поля repeatPassword правила equals, оно будет автоматически скорректировано для проверки равенства значений полей password и repeatPassword: -``` -"repeatPassword":{ - "required":"Введите пароль еще раз", - "equals":{ - "params" : "Этот ключ в описании правила можно не задавать, он будет сформирован контроллером автоматически", - "message":"Пароли не совпадают" - } -} -``` -Возможные значения - см. раздел "Валидация данных". - -Значение по умолчанию - пусто. - -### passwordLength -Длина пароля (если создается автоматически). - -Возможные значения - число символов больше 6. - -Значение по умолчанию - 6. diff --git "a/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" deleted file mode 100644 index d383e93f47..0000000000 --- "a/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" +++ /dev/null @@ -1,166 +0,0 @@ -## Создание и редактирование документов пользователями - -Контроллер Content позволяет web-пользователям создавать и редактировать записи в таблицах MODxAPI. Расширяет контроллер Form, что позволяет отправлять письма после создания записи. При редактировании записей отправка почты отключена, при необходимости ее можно реализовать с помощью плагинов на событие сохранения (OnDocFormSave и т.п.). - -Данные формы передаются в объект MODxAPI как есть, соответственно разработчику нужно заботиться об их корректности самостоятельно. - -При редактировании записей можно запретить изменение отдельных полей, используя параметр keepDefaults. - -При создании новой записи вызывается событие OnMakeDocUrl, в которое передается id записи и массив data со значениями полей записи. Это позволяет вернуть ссылку на созданную запись, она будет доступна через плейсхолдер [+content.url+]. Ссылку можно использовать в письме c уведомлением о создании новой записи. - -Также можно использовать данные авторизованного пользователя, доступны через плейсхолдеры [+user.fullname+], [+user.email+] и т.д. - -## Параметры -### model -Класс MODxAPI. - -Возможные значения - имя класса MODxAPI. - -Значение по умолчанию - \modResource. - -### modelPath -Путь к файлу класса, если класс не загружается заранее. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modResource.php. - -### userModel -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### userModelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### onlyUsers -Разрешить добавление записей только для зарегистрированных пользователей. - -Возможные значения - 0, 1. - -Значение по умолчанию - 1. - -### userGroups -Группы пользователей, которым разрешено добавлять или изменять записи. - -Возможные значения - список групп через точку с запятой. - -Значение по умолчанию - пусто (разрешены любые группы). - -### onlyOwners -Разрешает редактирование записей только их авторами. Автор определяется по полю, указанному в параметре ownerField. - -Возможные значения - 0, 1. - -Значение по умолчанию - 1. - -### ownerField -Имя поля, определяющего владельца записи. Если работать с документами modResource, то это будет имя tv-параметра (в Evo не предусмотрено создание записей веб-пользователями). - -Возможные значения - имя поля. - -Значение по умолчанию - aid. - -### idField -Имя ключа массива $_REQUEST, по которому определяется id редактируемой записи. Если ключ не задан, то контроллер вызывается в режиме создания записей. Информацию о режиме контроллера можно получить с помощью метода getMode. - -В форме редактирования нужно предусмотреть скрытое поле с именем параметра, в котором будет сохраняться id записи. - -Значение по умолчанию - id. - -### contentFields -Задает сопоставление полей MODxAPI и полей формы. Можно не задавать, если имена полей совпадают. Если параметр не задан, то ограничить список передаваемых в модель полей можно с помощью параметров allowedFields и forbiddenFields. - -Возможные значения - массив вида: -``` -&contentFields=`{ - "поле MODxAPI":"поле формы", - "поле MODxAPI":"поле формы" -} -` -``` -Значение по умолчанию - пусто. - -### clearCache -Очищать кэш после сохранения записи. - -Возможные значения - 0, 1. - -Значение по умолчанию - 0. - -### redirectTo -Перенаправляет пользователя на указанную страницу после сохранения новой записи. В режиме редактирования не используется. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### editAfterCreate -Переправляет пользователя на страницу для редактирования созданной записи. Страница указывается в параметре redirectTo. - -Возможные значения - 1 или 0. - -Значение по умолчанию - 0. - -### editTpl -Шаблон формы для редактирования документа. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - значение параметра formTpl. - -### badOwnerTpl -Шаблон сообщения о том, что пользователь не является автором документа. Только режим редактирования. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Content с ключом [+edit.default_badOwnerTpl+]. - -### badGroupTpl, badGroupEditTpl -Шаблон сообщения о том, что пользователь не входит в группу пользователей которым разрешено создавать и редактировать документы. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Content с ключом -[+create.default_badGroupTpl+] или [+edit.default_badGroupTpl+]. - -### badRecordTpl -Шаблон сообщения о том, что пользователь не может редактировать запись: например, запись не существует. Только режим редактирования. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Content с ключом [+edit.default_badRecordTpl+]. - -### exitTo -Перенаправляет неавторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### skipTpl, skipEditTpl -Шаблон сообщения для неавторизованного пользователя. Для режима редактирования - skipEditTpl. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Content с ключом [+create.default_skipTpl+] (edit.default_skipEditTpl). - -### successTpl -Шаблон сообщения об успешном сохранении новой записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона Content с ключом [+create.default_successTpl+] - -### editSuccessTpl -Шаблон сообщения об успешном обновлении записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" deleted file mode 100644 index 7cddeb4ad3..0000000000 --- "a/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" +++ /dev/null @@ -1,97 +0,0 @@ -## Удаление профиля пользователя - -Контроллер DeleteContent позволяет авторизованным пользователям удалять созданные ими документы. - -Расширяет Form. - -В шаблонах доступны поля модели для удаляемой записи. Информация о пользователе доступна в полях с префиксом user (user.fullname, user.email и т.д.) - -## Параметры -### model -Класс MODxAPI. - -Возможные значения - имя класса MODxAPI. - -Значение по умолчанию - \modResource. - -### modelPath -Путь к файлу класса, если класс не загружается заранее. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modResource.php. - -### userModel -Класс для работы с пользователями. - -Возможные значения - имя класса. - -Значение по умолчанию - \modUsers - -### userModelPath -Путь к файлу класса для работы с пользователями. - -Возможные значения - относительный путь к файлу. - -Значение по умолчанию - assets/lib/MODxAPI/modUsers.php - -### ownerField -Имя поля, определяющего владельца записи. Если работать с документами modResource, то это будет имя tv-параметра (в Evo не предусмотрено создание записей веб-пользователями). - -Возможные значения - имя поля. - -Значение по умолчанию - aid. - -### idField -Имя ключа массива $_REQUEST, по которому определяется id удаляемой записи. - -Значение по умолчанию - id. - -### redirectTo -Перенаправляет пользователя на указанную страницу после удаления записи. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### badOwnerTpl -Шаблон сообщения о том, что пользователь не является автором документа. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_badOwnerTpl+]. - -### badRecordTpl -Шаблон сообщения о том, что пользователь не может удалить запись: например, запись не существует. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_badRecordTpl+]. - -### skipTpl -Шаблон сообщения для неавторизованного пользователя. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_skipTpl+]. - -### successTpl -Шаблон сообщения об успешном сохранении новой записи. - -Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. - -Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_successTpl+] - -### exitTo -Перенаправляет неавторизованного пользователя на указанную страницу. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. - -### badRecordTo -Перенаправление, если невозможно удалить запись. - -Возможные значения - id целевой страницы или массив. - -Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" "b/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" deleted file mode 100644 index dd64c0974b..0000000000 --- "a/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" +++ /dev/null @@ -1,18 +0,0 @@ -## Лексиконы - -Для использования лексиконов необходимо создать папку с полным названием языка (russian-UTF8, english и т.д.), в ней создать файл название_лексикона.inc.php: -``` - -``` -Для загрузки лексиконов при вызове сниппета следует указать параметры: - -* langDir - путь к папке с лексиконами; -* lang - язык лексикона (если не указано, то используется параметр конфигурации manager_language); -* lexicon - название лексикона, можно указать несколько названий через запятую. - -После этого в шаблонах можно использовать плейсхолдеры [%ключ%] для подстановки значений из загруженных языковых файлов. Кроме того поддерживаются лексиконы компонента EvoBabel. \ No newline at end of file From d8aabd61b35ded62e75271320d9be104c81d2caf Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 4 Aug 2017 11:44:40 +0300 Subject: [PATCH 181/338] fix my local --- assets/snippets/FormLister/docs/history.md | 135 ++++++++ ...20\273\320\273\320\265\321\200\321\213.md" | 50 +++ ...20\274\320\265\321\202\321\200\321\213.md" | 291 ++++++++++++++++++ ...20\260\320\275\320\275\321\213\321\205.md" | 132 ++++++++ ...20\272\320\260\320\277\321\207\320\270.md" | 175 +++++++++++ ...20\260\320\275\320\275\321\213\321\205.md" | 40 +++ ...20\277\320\270\321\201\320\265\320\274.md" | 216 +++++++++++++ ...21\202\320\265\320\273\320\265\320\271.md" | 145 +++++++++ ...21\202\320\265\320\273\320\265\320\271.md" | 137 +++++++++ ...20\277\320\270\321\201\320\265\320\271.md" | 84 +++++ ...20\260\321\202\320\265\320\273\321\217.md" | 99 ++++++ ...20\260\321\202\320\265\320\273\321\217.md" | 50 +++ ...20\265\320\273\321\217\320\274\320\270.md" | 143 +++++++++ ...20\265\320\273\321\217\320\274\320\270.md" | 166 ++++++++++ ...20\265\320\273\321\217\320\274\320\270.md" | 97 ++++++ ...20\270\320\272\320\276\320\275\321\213.md" | 18 ++ 16 files changed, 1978 insertions(+) create mode 100755 assets/snippets/FormLister/docs/history.md create mode 100755 "assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" create mode 100755 "assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" create mode 100755 "assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" create mode 100755 "assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" create mode 100755 "assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" create mode 100755 "assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" create mode 100755 "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" create mode 100755 "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" create mode 100755 "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" create mode 100755 "assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" create mode 100755 "assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" create mode 100755 "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" create mode 100755 "assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" create mode 100755 "assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" create mode 100755 "assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" diff --git a/assets/snippets/FormLister/docs/history.md b/assets/snippets/FormLister/docs/history.md new file mode 100755 index 0000000000..7bca858b2d --- /dev/null +++ b/assets/snippets/FormLister/docs/history.md @@ -0,0 +1,135 @@ +## History +### 1.7.7 +* [Enhancement] Возможность указывать разный subject для разных типов писем (Form). + +### 1.7.6 +* [Fix] Исправления ошибок. + +### 1.7.5 +* [Fix] $this->modx вместо $modx в сниппете. + +### 1.7.4 +* [Fix] Ошибка в лексиконе (Form). +* [Refactor] Версии PHP ниже 5.6 не поддерживаются (Core). + +### 1.7.3 +* [Refactor] Подключать __autoload.php, если не задан другой загрузчик. +* [Fix] Ошибка в обработке параметра редиректа (Core). + +### 1.7.2 +* [Enhancement] Параметр &context в контроллере Login для поддержки модели modManagers (Login). +* [Fix] Ошибка в обработке параметра редиректа (Core). + +### 1.7.1 +* [Enhancement] Сниппет записывает в лог, если не задан параметр formid или не удалось загрузить класс контроллера. +* [Refactor] Плагин userHelper по умолчанию отключен. +* [Refactor] По умолчанию загружается лексикон english. +* [Fix] Ошибка в формате даты для лексикона english/form. + +### 1.7.0 +* [Refactor] Изменен метод loadModel, добавлена возможность указывать параметры, передаваемые в конструктор модели (Core). +* [Fix] Ошибка в лексиконе контроллера DeleteContent. +* [Fix] Создание записей анонимными пользователями если &onlyUsers=`0` (Content). +* [Refactor] Убраны include/require, для загрузки классов подключается файл assets/snippets/FormLister/__autoload.php. Модели MODxAPI загружаются этим же загрузчиком. +* [Refactor] Создание записи в логе, если не удалось сохранить данные (Content). +* [Refactor] Изменена обработка поля для запоминания авторизации: теперь время для автологина задается в параметре cookieLifetime (по умолчанию 5 лет, в секундах), а не значением поля (Login). +* [Refactor] Имя куки для автологина можно задать с помощью параметра cookieName, по умолчанию WebLoginPE (Login). +* [Refactor] В контроллере Login сначала проверяется, активирована ли учетная запись, а потом уже возможность авторизации (Login). +* [Enhancement] Блокировка пользователей после определенного числа неудачных попыток авторизации в плагине userHelper. + +### 1.6.2 +* [Fix] Неверное объявление метода в классах капчи. + +### 1.6.1 +* [Refactor] Переделан автологин в плагине userHelper. + +### 1.6.0 +* [Enhancement] Параметр rewriteUrls для обработки ссылок в шаблонах. Игнорируется, если задан параметр parseDocumentSource (Core). +* [Enhancement] Если страница с вызовом контроллера Login указана в конфигурации, как страница "Доступ запрещен", то после успешной авторизации будет произведен редирект на запрашиваемую страницу (Login). +* [Enhancement] Новый параметр ignoreMailerResult (Form). +* [Fix] Неправильная проверка уникальности username в контроллере Profile. +* [Refactor] Для добавления пользователей в группы используется метод из modUsers (Register). +* [Refactor] Введенный пользователем пароль сохраняется в поле user.password (Register). +* [Refactor] Контроллеры Register, Profile и Content загружают данные из моделей после успешного выполнения; после этого можно выполнить сниппеты из параметра preparePostProcess. Сделано это потому что плагины на сохранение или сами модели могут менять данные. +* [Enhancement] Восстановление данных, испорченных в protect.inc.php. Если параметр removeGpc равен 1, то очищены будут все входящие поля. Можно указать в параметре имена полей через запятую. При выводе обработанных полей будут экранироваться тэги MODX (Core). +* [Refactor] В prepare-сниппеты передается переменная name с названием параметра в котором задан сниппет. Можно использовать один сниппет для всех случаев (Core). +* [Enhancement] Контроллер DeleteUser для удаления пользователей c запросом пароля. +* [Enhancement] Контроллер DeleteContent для удаления записей MODxAPI. +* [Enhancement] Контроллер Activate для активации учетных записей. +* [Enhancement] Контроллеры Register и Login могут работать с активацией учетных записей. +* [Enhancement] Вывод параметров data-badge и data-callback для рекапчи (ReCaptchaWrapper). +* [Enhancement] Параметр deleteAttachments для удаления файлов после отправки письма (Form). +* [Enhancement] Сохранение имен файлов в поля формы (Form). +* [Enhancement] Отправка файлов не из формы. Список файлов задается массивом в параметре attachFiles: {"field":{"filepath":"assets/images/logo.png","filename":"logo.png"}} (Form). +* [Refactor] Можно не задавать параметр contentFields, в этом случае в модель будут переданы поля формы (Content). +* [Refactor] Корректная обработка полей lastlogin и thislogin в плагине userHelper. +* [Fix] Неверно выбирался шаблон при восстановлении паролей (Reminder). +* [Enhancement] Дополнительная обработка чанков парсером MODX c помощью параметра parseDocumentSource (Core). +* [Enhancement] Возможность вырезать необработанные плейсхолдеры из чанков с помощью параметра removeEmptyPlaceholders (Core). +* [Enhancement] Параметр removeEmptyPlaceholders для удаления необработанных плейсхолдеров из чанков (возможные значения 0,1; по умолчанию - 0) (Core). +* [Fix] Из-за неправильной обработки параметра defaultsSources не загружались поля в контроллере Profile (Core). +* [Fix] Метод filterFields не учитывал значение параметра allowEmptyFields (Core). + +### 1.5.1 +Исправления ошибок. + +###1.5.0 +* [Refactor] Переделана загрузка внешних параметров с учетом того, что не все источники могут содержать массив: добавлен источник aplh для загрузки массива значений из плейсхолдера MODX, в источнике cookie можно указать несколько имен кук через запятую. Добавлен источник user для загрузки данных авторизованного веб-пользователя (user:web) или менеджера (user:mgr) (Core). Добавлен источник document для загрузки данных текущего или указанного документа. +* [Refactor] Валидация капчи вынесена в класс капчи (Core). +* [Refactor] Параметры капчи задаются массивом, там же указываются сообщения об ошибках (Core). +* [Refactor] Валидация капчи происходит в классе капчи. (Core). +* [Enhancement] reCaptcha2. +* [Enhancement] smsCaptcha. +* [Enhancement] Поддержка Twig: в шаблон передаются переменные FormLister, data, errors, messages. Добавлен метод getErrorMessage для получения в шаблоне сообщений об ошибках для указанного поля (Core). +* [Enhancement] Параметры редиректа можно задавать в виде массива с ключами page (id страницы), query (массив параметров запроса) и header (заголовок) (Core). +* [Enhancement] Если задан параметр redirectTo и параметр editAfterCreate равен 1, то в параметры редиректа будет добавлен идентификатор созданного документа (Core, Content). +* [Fix] Плагин userHelper теперь перенаправляет пользователя на текущую страницу без ?logout в ссылке. +* [Fix] Сопоставление имен полей формы и модели в параметре contentFields неправильно работало в режиме редактирования, если имена различались (Content). +* [Refactor] Пользовательские функции валидации могут вместо false возвращать сообщение об ошибке (Core). + +### 1.4.1 +* [Refactor] Больше рандома в modxCaptcha. + +### 1.4.0 +* [Refactor] Класс modxCaptchaWrapper больше не привязан к FormLister (Core, modxCaptchaWrapper). +* [Enhancement] Убрано принудительное отключение параметров submitLimit и protectSubmit (Content). +* [Refactor] Изменен алгоритм загрузки пользовательских лексиконов. Теперь в параметре lexicon можно указывать как имя файла, так и сразу массив c языковыми записями (Core, Lexicon). +* [Refactor] Загрузка полей отправленной формы происходит не из $_REQUEST, а согласно параметру formMethod (значение по умолчанию - 'post') (Core). +* [Enhancement] Метод loadArray можно использовать для обработки строк с разделителем (по умолчанию - ',') (Config). +* [Enhancement] Если значение параметра submitLimit меньше 60, то оно не пересчитывается в минуты (Form). + +### 1.3.0 +* [Enhancement] Поддержка события OnBeforeWebLogin. В плагине можно реализовать процедуру авторизации независимую от модели; установку полей и шаблона сообщения об успешной авторизации нужно также производить в плагине. Плагин должен вернуть true в случае успешной авторизации, иначе будет выполнена авторизация методами модели (Login). + +### 1.2.1 +* [Refactor] Метод isArray теперь protected (FileValidator). + +### 1.2.0 +* [Refactor] Переделан пропуск полей при преобразовании в плейсхолдеры. Теперь плейсхолдеры отделены от полей формы, для работы с ними следует использовать методы setPlaceholder и getPlaceholder. Выводятся через [+placeholder+]. +* [Bug] Сниппеты, указанные в prepareProcess, выполнялись независимо от результатов валидации. +* [Refactor] Изменена логика обработки правил валидации. Теперь все правила, которых нет в валидаторе, обрабатываются как custom. Это позволяет применять сразу несколько таких правил. +* [Enhancement] Возможность применять правила валидации только для заполненных полей. +* [Refactor] Информация о файлах размещается в массиве formData c помощью метода setFiles (Core, Form). +* [Refactor] Объект FS теперь публичный. +* [Refactor] Контроллер Profile наследуется от Form, а не от Core. + +### 1.1.0 +* [Refactor] Метод filesToArray перемещен в Core. +* [Enhancement] Возможность загрузки произвольных моделей в контроллерах, которые используют MODxAPI. Новые параметры - model и modelPath. +* [Refactor] Метод для загрузки моделей MODxAPI. +* [Enhancement] Возможность загружать произвольные модели MODxAPI в контроллерах. +* [Enhancement] Новое правило валидации - date, проверяет является ли значение поля датой в указанном формате (Validator). +* [Enhancement] Возможность пропускать поля при преобразовании в плейсхолдеры (Core). + +### 1.0.2 +* [Enhancement] Убрано значение по умолчанию свойства allowedFields в контроллерах Register и Profile. + +### 1.0.1 +* [Enhancement] Новое правило валидации файлов - optional, аналог правила required но выполняется также, если файл не загружен пользователем (FileValidator). +* [Enhancement] Правила валидации файлов allowed, minSize, sizeBetween считаются выполненными, если файл не загружен пользователем (код ошибки 4). Решает проблему с файловыми полями, для которых не задано правило required (FileValidator). +* [Bug] К письму прикреплялись не загруженные пользователем файлы, теперь прикрепляются только успешно загруженные (код ошибки 0) (Form). +* [Fix] Параметры из файлов перезаписывали параметры сниппета (Core). +* [Bug] Конфиг из файла не добавлялся в общий массив настроек (Helpers/Config). + +### 1.0.0 +Public release. diff --git "a/assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" "b/assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" new file mode 100755 index 0000000000..e566b9dae2 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/010_\320\232\320\276\320\275\321\202\321\200\320\276\320\273\320\273\320\265\321\200\321\213.md" @@ -0,0 +1,50 @@ +## Контроллеры +Контроллер представляет собой класс, унаследованный от базового класса \FormLister\Core, который реализует: + +- загрузку классов для валидации и генерации капчи; +- работу с данными (под данными здесь и далее подразумеваются значения свойства formData, то есть не только значения массива $_REQUEST); +- работу с шаблоном формы и шаблоном успешной обработки. + +Схема работы: + +1. Загрузка данных из формы +2. Загрузка данных из внешних источников +3. Вызов сниппетов для обработки данных. +4. Валидация данных - если получены данные из формы; +3. Вызов сниппетов для обработки данных. +6. Итоговая обработка - если получены данные из формы и пройдена валидация. +7. Вывод. + +Итоговая обработка формы происходит в методе process() контроллера. После успешной обработки необходимо установить флаг результа обработки формы с помощью метода setFormStatus(), а также и указать в свойстве renderTpl шаблон для вывода информации с результатами обработки. + +Ниже перечислены базовые контроллеры. + +### Контроллер Form +Отправляет письма с данными формы. + +### Контроллер Login +Авторизует пользователя в контексте web. + +### Контроллер Register +Создает web-пользователя и отправляет соответствующие письма. + +### Контроллер Activate +Обрабатывает ссылку из письма с подтверждением регистрации или отправляет такое письмо. + +### Контроллер DeleteUser +Позволяет пользователям удалять свои учетные записи. Для подтверждения запрашивает пароль. + +### Контроллер Profile +Предназначен для редактирования данных web-пользователя. + +### Контроллер Reminder +Предназначен для восстановления паролей web-пользователями. + +### Контроллер Content +Позволяет создавать и изменять записи с помощью классов MODxAPI. + +### Контроллер DeleteContent +Позволяет пользователям удалять созданные ими записи. + +### Контроллер MailChimp +Добавляет пользователей в список рассылки сервиса MailChimp. Добавлен как пример расширения базового класса \FormLister\Core. diff --git "a/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" "b/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" new file mode 100755 index 0000000000..e0046780fa --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" @@ -0,0 +1,291 @@ +## Общие параметры + +Эти параметры обрабатываются базовым классом FormLister. В контроллерах некоторые общие параметры могут иметь другое назначение. + +## Настройки +### controller +Задает класс для обработки данных. + +Возможные значения - имя php-файла с классом без расширения. + +Значение по умолчанию - Form. + +### dir +Папка в которой находится класс контроллера. + +Значение по умолчанию - assets/snippets/FormLister/core/controller/ + +### formid +Имя формы, обязательный параметр. + +В шаблоне формы обязательно должно быть скрытое поле с именем formid и значением, указанным в параметре. Форма считается отправленной, если в массиве $_REQUEST присутствует ключ с именем параметра, а его значение соответствует значению параметра. + +### formMethod +Возможные значения - post, get или request. + +Значение по умолчанию - post. + +### config +Загрузка параметров в формате json из файла. + +Возможные значения - имяфайла:папка, несколько значений разделяются точкой с запятой. + +#### Пример +myparams:core - загрузить параметры из файла assets/snippets/FormLister/config/core/myparams.json; myparams - загрузить параметры из файла assets/snippets/FormLister/config/custom/myparams.json; myparams:/assets/myfolder - загрузить параметры из файла assets/myfolder/myparams.json. + +Значение по умолчанию - пусто. + +### api +Определяет, в каком виде будут выводиться данные. + +Возможные значения: + +- 0: только html; +- 1: json-массив с данными формы; +- 2: json-массив с данными формы и html. + +### debug +Режим отладки. Вывод записывается в лог MODX. + +Возможные значения - 0, 1. + +Значение по умолчанию - 0. + +### saveObject +Сохраняет объект класса FormLister в плейсхолдер, который можно использовать в других сниппетах. Объект сохраняется только при успешной обработке формы. + +Возможные значения - имя плейсхолдера. + +Значение по умолчанию - пусто. + +### removeGpc +Убирает экранирование данных, которое выполняет MODX для символов {{, [[ и т.д. При этом экранируются тэги MODX при выводе. + +Возножные значения - 0, 1 или имена полей через запятую. + +Значение по умолчанию - 0. + +## Источники данных +### defaultsSources +Позволяет загружать дополнительные данные из внешних источников, например, для предварительного заполнения полей формы. По умолчанию внешние данные загружаются только при начальном выводе формы и не загружаются после отправки формы Это поведение может быть изменено с помощью параметра keepDefaults. + +Возможные значения: список источников, разделенных точкой с запятой. Загрузка данных производится в том порядке, в котором они указаны в списке. + +Источник может задаваться в формате "имя:ключ:префикс". Префикс, если указан, добавляется c точкой к имени поля - например, config.site_name. + +Возможные значения: + +- array: json или php-массив, значения задаются параметром defaults; +- param:имя параметра:префикс - значения задаются значением параметра из вызова сниппета (аналогично array, только значение задается не параметром defaults, а произвольным, также можно указать префикс); +- session:ключ массива:префикс - значения загружаются из массива $_SESSION; +- plh:ключи через запятую:префикс - загружаются значения из массива $modx->placeholders; +- aplh:имя плейсхолдера:префикс - загружаются значения из плейсхолдера, содержащего массив; +- config:префикс - загружаются значения из конфигурации MODX; +- cookie:ключи через запятую:префикс - загружаются значения из массива $_COOKIE; +- имя класса MODxAPI:ключ:префикс - ключ является аргументом метода edit(), класс должен быть заранее загружен; +- document:префикс - загружает данные из модели modResource для документа, в котором вызван сниппет. Ключ не указывается; +- user:ключ:префикс - загружает данные из модели modUsers для авторизованного пользователя. Тип пользователя уточняется в ключе (web или mgr). + +Значение по умолчанию - array. + +### defaults +Данные для источника array. + +Возможные значения: массив значений по умолчанию, в формате json или php. + +### keepDefaults +Позволяет повторно загружать данные из внешних источников после отправки формы. Если в параметре указан список полей, то загружены будут только указанные поля. + +Возможные значения: 1, 0, имена полей, разделенные запятой. + +Значение по умолчанию - 0. + +### allowEmptyFields +Разрешает задавать поля с пустыми значениями. + +Возможные значения - 0 или 1. + +Значение по умолчанию - 1. + +## Элементы управления +### formControls +Список полей с управляющими элементами формы (списки, чекбоксы, радио-кнопки). Необходимо для отслеживания состояния элементов. + +Возможные значения - имена полей, разделенные запятой. + +Значение по умолчанию - пусто. + +### emptyFormControls + +Этот параметр позволяет решить проблему неотмеченных чекбоксов, которые не включаются в массив полей при отправке формы: если в $_REQUEST отсутствует нужный элемент, то он создается согласно данному параметру. Необходимость в таком параметре возникла в связи с тем, что MODxAPI требует явно указывать изменяемые поля в методе fromArray(). Но можно использовать и в обычных формах, чтобы подставить в шаблон значение неотмеченного чекбокса. + +Возможные значения - массив: +``` +&emptyFormControls=`{ + "mycheckbox" : "Нет", + "published" : 0 +}` +``` + +## Обработка данных +### prepare, prepareProcess, prepareAfterProcess +Аналогично параметру prepare в DocLister. + +Сниппеты из параметра prepare выполняются после загрузки данных в форму, сниппеты из параметра prepareProcess - после прохождения валидации, сниппеты из параметра prepareAfterProcess - после успешного выполнения обработки. В сниппетах через переменную $FormLister доступен объект контроллера, а через массив $data - значения полей формы. Также доступна переменная $name, которая задержит имя параметра из которого взят сниппет (prepare, prepareProcess и т.д.); это позволяет использовать один и тот же сниппет для разных случаев. Для изменения данных следует использовать в prepare-сниппетах методы контроллера (setField, setFields и т.д.) + +Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. + +Значение по умолчанию - пусто. + +## Валидация +### validator +Имя класса для валидации данных. Класс должен быть предварительно загружен. + +Значение по умолчанию - \FormLister\Validator. + +### rules +Массив с правилами валидации. + +Значение по умолчанию - пусто. + +## Шаблоны +### formTpl +Шаблон формы. В шаблоне формы обязательно должно быть поле с именем formid и значением, указанным в параметре formid. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### arraySplitter + +Разделитель для преобразования массивов в строку. + +Значение по умолчанию - точка с запятой. + +### {field}.arraySplitter +Разделитель для преобразования массивов в строку, но для отдельного поля {field}. Например: groups.arraySplitter - разделитель для массива из поля groups. + +Если не задано, то используется значение параметра arraySplitter. + +### errorTpl +Шаблон для вывода сообщений валидатора. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию: +``` +@CODE:
    [+message+]
    +``` + +### requiredClass, errorClass +Имена классов для обозначения незаполненных (required) и неверно заполенных (error) полей. + +Значение по умолчанию - required и error соответственно. + +### {field}.requiredClass, {field}.errorClass +Позволяет задавать указанные выше классы для конкретных полей. + +По умолчанию используются значения параметров requiredClass и errorClass. + +### messagesTpl +Шаблон сообщений обработчика формы. В шаблоне выводятся группы сообщений (messages, required, error). + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию: +``` +@CODE:
    [+messages+]
    +``` + +### messagesOuterTpl +Шаблон-обертка для группы произвольных сообщений. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - +``` +@CODE: [+messages+] +``` + +### messagesRequiredOuterTpl +Шаблон-обертка для группы сообщений о незаполненных полях. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию: +``` +@CODE: [+messages+] +``` + +### messagesErrorOuterTpl +Шаблон-обертка для группы сообщений о неверно заполненных полях. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию: +``` +@CODE: [+messages+] +``` + +### messagesSplitter, messagesRequiredSplitter, messagesErrorSplitter +Разделитель сообщений в группе. + +Возможные значения - произвольная строка. + +Значение по умолчанию: +``` +
    +``` + +### removeEmptyPlaceholders +Удаляет из шаблонов незаполненные прейслхолдеры. + +Возможные значения - 0 или 1. + +Значение по умолчанию - 0. + +### parseDocumentSource +Обрабатывает чанки MODX-парсером. + +Возможные значения - 0 или 1. + +Значение по умолчанию - 0. + +### rewriteUrls +Если параметр parseDocumentSource отключен, то парсит ссылки в шаблонах. + +Возможные значения - 0 или 1. + +Значение по умолчанию - 0. + +### skipPrerender +Позволяет отключить предварительную обработку полей формы (экранирование значений, преобразование массивов в строки, установка сообщений об ошибках). Можно включить, если для вывода не используется парсер MODX. + +Возможные значения - 0 или 1. + +Значение по умолчанию - 0. + +### templatePath, templateExtension +Путь к папке с файлами шаблонов и расширение файлов шаблонов. Эти параметры необходимо задавать при использовании плагина EvoTwig. + +Значение по умолчанию - пусто. + +## Перенаправление после обработки +### redirectTo +Id страницы, на которую нужно выполнить перенаправление после успешной обработки формы. В api-режиме перенаправление не выполняется, но в массиве данных формы сохраняется абсолютная ссылка на целевую страницу (поле "redirectTo"). + +Вместо числа можно указывать массив: +``` +&redirectTo=`{ + "page":10, + "query":{ + "foo":"bar" + }, + "header":"HTTP/1.1 307 Temporary Redirect" +}` +``` +Ключ page задает id станицы, в массиве query можно передать дополнительные get-параметры, значением ключа header может быть текст заголовка для перенаправления. + +Возможные значения - число или массив. + +Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" "b/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" new file mode 100755 index 0000000000..9efb7da81d --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" @@ -0,0 +1,132 @@ +## Валидация данных + +При валидации данных валидатор последовательно применяет к значению поля заданные правила, при возникновении ошибки в массив данных об ошибках добавляется запись и дальнейшая обработка формы прекращается. + +Валидация считается пройденной, если в массиве данных об ошибках отсутствуют записи. + +### Правила валидации +Список правил задается в виде массива. Ключом является имя поля, а значением - массив правил валидации. Правило валидации является методом класса-валидатора. В массиве правил ключом является имя правила (название метода валидации), значением может быть либо строка с сообщением об ошибке валидации правила, или же массив с описанием. В этом массиве в ключе params задаются необходимые для валидации значения, а в ключе message задается строка с сообщением об ошибке. + +Можно также использовать отрицание правил, если добавить перед именем правила восклицательный знак: "!numeric" - поле пройдет валидацию, если его значение не является числом. + +Если нужно реализовать проверку только заполненных полей, то перед именем поля в списке правил нужно добавить восклицательный знак. В этом случае если значение поля пустое, правила будут проигнорированы. + +``` +{ + "имя поля 1": { + "правило 1" : "сообщение об ошибке", + "правило 2" : "сообщение об ошибке" + }, + "имя поля 2": { + "правило 1" : "сообщение об ошибке", + "правило 2" : { + "params" : значение, + "message" : "сообщение об ошибке" + } + }, + "!имя поля 3":{ + "правило 1" : "сообщение об ошибке" + } +} +``` +Стандартным классом валидации (\FormLister\Validator) предусмотрены правила: + +- required: поле заполнено; +- date: значение поля является датой в заданном формате; +- min: значение поля больше заданного или равно ему; +- max: значение поля меньше заданного или равно ему; +- greater: значение поля строго меньше заданного; +- less: значение поля строго больше заданного; +- between: значение поля входит в диапазон; +- equals: значение поля равно заданному; +- in: значение поля входит в заданный массив значений; +- alpha: значение поля содержит только буквы; +- numeric: значение поля содержит только цифры; +- alphaNumeric: значение поля содержит только буквы и цифры; +- slug: значение поля является частью url; +- decimal: значение поля является десятичным числом; +- phone: значение поля является номером телефона; +- matches: значение поля удовлетворяет регулярному выражению; +- url: значение поля является ссылкой; +- email: значение поля является email-адресом; +- length: длина значения поля равна заданному; +- minLength: длина значения поля больше заданного или равна ему; +- maxLength: длина значения поля меньше заданного или равна ему; +- lengthBetween: длина значения поля входит в диапазон; +- minCount: размер массива больше заданного; +- maxCount: размер массива меньше заданного; +- countBetween: размер массива входит в диапазон. + +Если требуется задать два значения для правила, то их следует задавать как массив: +``` +&rules=`{ + "field" : { + "lengthBetween" : { + "params" : [10,20], + "message" : "Длина должна быть от 10 до 20" + } + } +}` +``` + +Для правила in (и других правил, использующих массив) массив значений следует задавать следующим образом: +``` +&rules=`{ + "field" : { + "in" : { + "params" : [ [10,20,30] ], + "message" : "Значение поля field должно быть равно 10, 20 или 30" + } + } +}` +``` + +Это нужно, чтобы массив был передан в функцию одним аргументом. + +Предусмотрена также возможность использовать для валидации функции или статические методы загруженного класса: +``` +&rules=`{ + "myfield":{ + "required":"Required field", + "custom":{ + "function":"\\Namespace\\Classname::myCustomRule", + "params":[10,20,30], + "message":"Custom check failed" + } + } +}` +``` + +Метод должен принимать первым аргументом экземпляр контроллера из которого вызывается правило, вторым аргументом - значение проверяемого поля, далее - параметры передаваемые в ключе описания params: +``` +public static function myCustomRule($fl,$value,$a,$b,$c) { + $result = $fl->getField('field1') == $a && $fl->getField('field2') == $b && $value == $c; + return $result; +} +``` +В примере правило будет пройдено, если значение поля field1 = 10, значение поля field2 = 20, а значение поля, к которму применяется правило, = 30. + +Метод должен вернуть true, false или текст сообщения об ошибке (в этом случае можно не указывать message в списке правил). + +В примере используется название правила "сustom", но можно использовать любое название правила, которого нет в классе валидации. Таким образом можно использовать несколько правил данного типа. + +### Результаты валидации +Данные об ошибках хранятся в виде массива и могут быть получены вызовом метода getFormData('errors'): +``` +{ + "имя поля 1": { + "имя нарушенного правила" : "сообщение об ошибке" + }, + "имя поля 2": { + "имя нарушенного правила" : "сообщение об ошибке" + } +} +``` +Для добавления данных в этот массив используется метод addError(имя поля, имя правила, сообщение об ошибке). Таким образом, можно влиять на итоговый результат валидации, вручную добавляя записи в этот массив. Можно также объявить валидацию непройденной по умолчанию, вызвав метод setValid(false). + +В шаблонах результаты валидации для каждого поля выводятся с помощью плейсхолдера [+имя поля.error+]. Общий результат может быть выведен в плейсхолдер [+form.messages+], который задается шаблоном messagesTpl. В свою очередь, в этом шаблоне можно использовать плейсхолдеры: + +- [+required+] - сообщения о незаполенных полях; +- [+errors+] - сообщения о неверно заполненных полях. + +Получить сообщения об ошибках для определенного поля можно с помощью метода getErrorMessage(имя поля). diff --git "a/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" "b/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" new file mode 100755 index 0000000000..99f61a25bf --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" @@ -0,0 +1,175 @@ +## Использование капчи + +По умолчанию FormLister может использовать модицифированную капчу MODX и Google Recaptcha. Также в наличии SmsCaptcha - для отправки формы необходимо ввести код, полученный в смс-сообщении (отправку сообщения необходимо реализовывать отдельно). + +Для подключения необходимо указать имя папки с файлами капчи (папки находятся в assets/snippets/FormLister/lib/captcha/) в параметре &captcha. + +В параметре &captchaParams задаются в виде массива настройки капчи. Например: +``` +&captchaParams=`{ +"width":200, +"height":120 +}` +``` + +Имя поля, в которое пользователь вводит значение капчи, задается параметром captchaField (по умолчанию - vericode). Правило валидации для этого поля создается автоматически. + +Капча выводится в шаблоне формы с помощью плейсхолдера [+captcha+]. + +### modxCaptcha + +Модификация стандартной капчи MODX. + +Настройки: +* width и height - ширина и высота картинки с капчей (значение по умолчанию - 100 и 60); +* inline - формат вывода. Если значение параметра равно 1, то в плейсхолдер [+captcha+] выводится картинка в base64-формате. Если 0, то выводится ссылка на файл connector.php, генерирующий картинку. Значение по умолчанию - 1; +* connectorDir - путь к папке с файлом connector.php, если параметр inline равен 0. Значение по умолчанию - assets/snippets/FormLister/lib/captcha/modxCaptcha/; +* errorEmptyCode - текст сообщения об ошибке, если поле со значением капчи не заполнено. Значение по умолчанию - "Введите проверочный код"; +* errorCodeFailed - текст сообщения об ошибке, если введено неверное значение капчи. Значение по умолчанию - "Неверный проверочный код" + +### reCaptcha + +Капча Google reCAPTCHA V2. На странице с формой должен быть подключен скрипт: +``` + +``` + +Значение параметра captchaField должно быть "g-recaptcha-response" (см. [документацию](https://developers.google.com/recaptcha/docs/verify)). + +Настройки: +* secretKey, siteKey - ключи для доступа к api reCAPTCHA; +* size, theme, badge, callback, expired_callback, tabIndex, type - см. [документацию](https://developers.google.com/recaptcha/docs/display#render_param); +* errorCodeFailed - текст сообщения об ошибке, если пользователь не прошел проверку. Значение по умолчанию - "Вы не прошли проверку" + +### smsCaptcha + +Настройки: +* codeLifeTime - срок действия введенного кода, секунд. Если пользователь попытается ввести код до истечения срока, то будет выведено сообщение errorCodeUsed. Значение по умолчанию - 86400 (сутки); +* errorEmptyCode - сообщение об ошибке, если пользователь получил, но не ввел код. Значение по умолчанию - "Введите код авторизации"; +* errorCodeRequired - сообщение об ошибке, если пользователь не запросил код. Значение по умолчанию - "Получите код авторизации"; +* errorCodeFailed - сообщение об ошибке, если пользователь ввел неверный код авторизации. Значение по умолчанию - "Неверный код авторизации"; +* errorCodeExpired - сообщение об ошибке, если пользователь не ввел полученный код в течение заданного времени. Значение по умолчанию - "Код авторизации истек, получите новый"; +* errorCodeUsed - сообщение об ошибке, если пользователь уже вводил код для текущей формы. Значение по умолчанию - "Код авторизации уже использовался". + +Чтобы использовать эту капчу необходимо предварительно создать таблицу в базе данных: +``` +createTable(); +``` + +Для отправки кода необходимо создать отдельную форму и указать в параметре prepareProcess сниппет: + ``` +setValid(false); + $FormLister->addError('phone','phone','Неверный номер телефона'); +} else { + //загружаем класс для работы с таблицей + $sms = $FormLister->loadModel('SmsModel','assets/snippets/FormLister/lib/captcha/smsCaptcha/model.php'); + $flag = false; + //проверяем, есть ли в таблице запись для заданного номера и идентификатора формы + $data = $sms->getData('+'.$rawPhone,$formid); + if ($data->getID()) { + //если есть и код не истек + if ($sms->get('expires') > time()) { + //смотрим, использован ли код + if ($sms->get('active')) { + $FormLister->addMessage('Вы уже использовали код.'); + } else { + $FormLister->addMessage('Код уже был отправлен. Подождите несколько минут прежде чем запросить новый.'); + } + //если код истек, то удаляем запись и разрешаем выдать новый + } else { + $sms->delete($sms->getID()); + $flag = true; + } + } else { + $flag = true; + } + //если можно выдать новый код + if ($flag) { + $code = mt_rand(1000,9999); + + //здесь отправляется смс и результат помещается в переменную $result + /** + * + */ + $result = array('status'=>true); + + //проверяем отправлена ли смс + if (is_array($result) && $result['status']) { + //создаем запись в таблице, время жизни кода - 3 минуты + $result = $sms->create()->fromArray(array( + 'phone'=>('+'.$rawPhone), + 'formid'=>$formid, + 'expires'=>(time() + 60*3), + 'ip'=> \APIhelpers::getUserIP(), + 'code'=>$code + ))->save(); + //если получилось записать, то сохраняем в сессию номер телефона + if ($result) { + $_SESSION[$session_key] = '+'.$rawPhone; + } else { + $FormLister->setValid(false); + $FormLister->addMessage('Не удалось отправить смс'); + } + } else { + //если нельзя выдать код, то запрещаем дальнейшую обработку формы + $FormLister->setValid(false); + } +} +?> +``` + +Полностью вызов FormLister: +``` +[!FormLister? +&formid=`code` +&submitLimit=`0` +&protectSubmit=`0` +&rules=`{ +"phone":{ + "required":"Обязательно введите номер телефона", + "phone":"Введите номер правильно" +} +}` +&prepareProcess=`setSmsCaptcha` +&captcha=`modxCaptcha` +&formTpl=`@CODE: +
    +
    +
    +
    + + +
    + +
    + + [+phone.error+] +
    +
    +[+form.messages+] +
    +
    + +
    +
    + + + [+vericode.error+] +
    +
    +
    +
    ` +&successTpl=`@CODE:Код авторизации отправлен на номер [+phone.value+]. Срок действия кода - 3 минуты.` +!] +``` diff --git "a/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" "b/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" new file mode 100755 index 0000000000..8dc1af8cf9 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" @@ -0,0 +1,40 @@ +## Вывод данных + +Для вывода в шаблоны данные экранируются, а массивы преобразовываются в строки. Кроме этого, для элементов управления устанавливаются специальные плейсхолдеры. + +Вывод неэкранированного значения поля: +[+имя поля+] + +Вывод значения поля: +``` +[+имя поля.value+] +``` + +Установка чекбокса: +``` +[+c.имя поля.значение поля+] +``` + +Установка выпадающего списка или радио-кнопки: +``` +[+s.имя поля.значение поля+] +``` + +Установка класса для незаполненного поля: +[+имя поля.requiredСlass+] + +Установка класса для неверно заполненного поля: +[+имя поля.errorClass+] + +Вывод сообщения об ошибке валидации: +[+имя поля.error+] + +Вывод сообщений обработчика: +[+form.messages+] + +В плейсхолдер [+form.messages+] могут выводиться три типа сообщений: нарушения правила required, нарушения остальных правил, произвольные сообщения, которые задаются методом addMessage. По умолчанию выводятся только последние, см. описание параметра messagesTpl. + +Вывод значений из лексиконов: +[%ключ лексикона%] + +При использовании плагина EvoTwig в шаблонах доступны переменные FormLister (объект контроллера), errors (массив formData['errors']), messages (массив formData['messages']). diff --git "a/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" "b/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" new file mode 100755 index 0000000000..f501b7d5d8 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" @@ -0,0 +1,216 @@ +## Отправка писем + +Контроллер Form позволяет отправлять данные формы в письме. + +## Параметры отправки почты +### isHtml +Разрешает отправлять письмо в формате html. Проверка корректности кода письма возлагается на разработчика. + +Возможные значения - 1, 0. + +Значение по умолчанию - 1. + +### to +Адрес получателя. Если не указан, то письмо не отправляется, но считается успешно отправленным. + +Возможные значения - email-адрес. + +Значение по умолчанию - пусто. + +### from +Возможные значения - email-адрес. + +Значение по умолчанию - параметр конфигурации emailsender. + +### fromName +Имя отправителя. + +Возможное значение - строка. + +Значение по умолчанию - параметр конфигурации site_name. + +### replyTo +Заголовок replyTo. + +Возможные значения - email-адрес. + +Значение по умолчанию - пусто. + +### cc +Заголовок сс. + +Возможные значения - email-адрес. + +Значение по умолчанию - пусто. + +### bcc +Заголовок bcc. + +Возможные значения - email-адрес. + +Значение по умолчанию - пусто. + +### noemail +Если параметр задан, то письмо не отправляется, но считается успешно отправленным. + +Возможные значения - 1, 0. + +Значение по умолчанию - 0. + +### ignoreMailerResult +Если параметр задан, то письмо отправляется, но результат отправки игнорируется. + +Возможные значения - 1, 0. + +Значение по умолчанию - 0. + +### subject, ccSubject, autoSubject +Тема письма. + +Возможные значения - строка. + +Значение по умолчанию - пусто. + +### subjectTpl, ccSubjectTpl, autoSubjectTpl +Шаблон темы письма. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - значение параметра subject (ccSubject, autoSubject). + +### autosender +Адрес на который отправляется дополнительное письмо. + +Возможные значения - email-адрес. + +Значение по умолчанию - пусто. + +### autosenderFromName +Имя отправителя дополнительного письма. + +Возможные значения - строка. + +Значение по умолчанию - параметр конфигурации site_name. + +### ccSender +Если параметр задан, то на адрес указанный в поле формы отправляется письмо. + +Возможные значения - 1, 0. + +Значение по умолчанию - 0. + +### ccSenderField +Имя поля, в котором хранится адрес получателя. + +Возможные значения - имя поля формы. + +Значение по умолчанию - email. + +### ccSenderFromName +Имя отправителя письма на заданный в поле формы адрес. + +Возможные значения - строка. + +Значение по умолчанию - не указано. + +## Защита от повторной отправки +### protectSubmit +Защита от повторной отправки письма. + +Возможные значения - 1, 0 или список полей, по которым определяется уникальность письма. Если список не задан, то используются поля, обязательные для заполнения. + +Значение по умолчанию - 1. + +### submitLimit +Защита от частой отправки писем. + +Значение - число секунд между повторной отправкой. + +Значение по умолчанию - 60. + +## Шаблоны +### reportTpl +Основной шаблон письма. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - список полей и их значений. + +### automessageTpl +Шаблон дополнительного письма. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### ccSenderTpl +Шаблон письма на заданный в поле формы адрес. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### successTpl +Шаблон сообщения об успешной отправке писем. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +## Отправка файлов +### attachments +Имена полей, в которых хранятся файлы. Поддерживаются только поля с одним файлом (name="field" type="file") и поля с одномерным массивом файлов (name="field[]" type="file" multiple). + +Значение по умолчанию - пусто. + +### attachFiles +Позволяет отправить произвольные файлы. + +Возможные значения - массив: +``` +&attachFiles=`{ +"имя поля1":{ + "filepath":"assets/images/logo.png", + "filename":"logo.png" +}, +"имя поля2":[ + { + "filepath":"assets/images/file1.jpg", + "filename":"отчет.jpg" + }, + { + "filepath":"assets/images/file2.jpg", + "filename":"отчет2.jpg" + } +] +}` +``` +### deleteAttachments +Позволяет удалить файлы вложений после успешной отправки. + +Возможные значения - 0 или 1. + +Значение по умолчанию - 0. + +### fileValidator +Имя класса для валидации файлов. Если задано, то класс должен быть загружен заранее. + +Значение по умолчанию - \FormLister\FileValidator + +### fileRules +Правила валидации (см. раздел "Валидация данных"). Стандартный валидатор поддерживает правила: + +- required: файлы успешно отправлены; +- optional: аналогично required, но выполняется и в том случае, если пользователь не загружал файлы (то есть поле с файлами не является обязательным); +- allowed: расширение файла входит в заданный массив; +- images: расширение файла jpg, jpeg, gif, png, bmp; +- minSize: размер файла в килобайтах больше заданного; +- maxSize: размер файла в килобайтах меньше заданного; +- sizeBetween: размер файла в килобайтах входит в диапазон; +- minCount: количество файлов больше заданного; +- maxCount: количество файлов меньше заданного; +- countBetween: количество файлов входит в диапазон. + +Использовать конструкцию "!имя поля" в правилах валидации файлов нет смысла, так как значение поля с файлом не будет пустым, даже если файл не загружен. Следует использовать правило optional. + +В шаблоне письма reportTpl доступен плейсхолдер [+attachments.value+] со списком всех приложенных к письму файлов. Можно также вывести по отдельности: [+имя поля.value+]. Файлы отправляются только в письме c шаблоном reportTpl. diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" new file mode 100755 index 0000000000..04c410ea91 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" @@ -0,0 +1,145 @@ +## Авторизация пользователей + +Авторизация пользователей в `FormLister` осуществляется с использованием контроллера `Login`. + +Авторизация может проходить по id, имени (username), email средствами класса modUsers; другому полю из учетной записи (с помощью плагина для события OnWebAuthentication). Поле задается в параметре `loginField` и должно быть **уникальным** для каждого веб-пользователя. Обычно для авторизации используются поля `username` или `email`. + +Дополнительное использование плагина [userHelper](https://github.com/evolution-cms/evolution/blob/develop/assets/snippets/FormLister/plugin.userHelper.php) позволяет: + +* вести учет количества логинов; +* определить время последней авторизации; +* реализовать автологин и выход из учетной записи; +* блокировать пользователей после определенного количества неудачных попыток авторизации. + +Перед использованием плагина `userHelper` убедитесь что он включен: + +![Не забудьте включить userHelper](https://habrastorage.org/web/dbc/1e2/abd/dbc1e2abd8664a548f4eca254187fb60.png) + +## Параметры контроллера + +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### loginField +Поле, содержащее имя пользователя. + +Возможные значения - имя поля. + +Значение по умолчанию - username. + +### passwordField +Поле, содержащее пароль пользователя. + +Возможные значения - имя поля. + +Значение по умолчанию - password. + +### rememberField +Поле для запоминания пользователя. Если значение поля приводится к true, то при успешной авторизации будет установлена кука с параметрами автологина. Имя куки и ее время жизни задаются параметрами cookieName и cookieLifetime. + +Можно также задать поле rememberme в параметре defaults, чтобы запоминание происходило без участия пользователя: +``` +&defaults=`{"rememberme":1}` +``` + +Возможные значения - имя поля. + +Значение по умолчанию - rememberme. + +### checkActivation +Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). + +Возможные значения - 0 или 1. + +Значение по умолчанию - 1. + +### context +Контекст авторизации. + +Возможные значения - mgr или web. + +Значение по умолчанию - web. + +### cookieName +Имя куки для хранения параметров автологина. + +Значение по умолчанию - WebLoginPE. + +### cookieLifetime +Время жизни вышеуказанной куки. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 157680000 (5 лет). + +### redirectTo +Перенаправляет пользователя на страницу c указанным id после авторизации. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### exitTo +Перенаправляет уже авторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### successTpl +Шаблон сообщения об успешной авторизации. В шаблоне можно использовать данные пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Login с ключом [+login.default_successTpl+] + +### skipTpl +Шаблон сообщения о том, что пользователь уже авторизован. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Login с ключом [+login.default_skipTpl+] + +## Параметры плагина userHelper +### logoutKey +Имя GET-параметра для запуска выхода из учетной записи. Если в ссылке на страницу сайта указан параметр с соответствующим именем (например, http://sitename.ru/page.html?logout), будет произведен выход из учетной записи. + +Значение по умолчанию - logout. + +### cookieName +Имя куки для хранения параметров автологина. + +Значение по умолчанию - WebLoginPE. + +### cookieLifetime +Время жизни вышеуказанной куки. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 157680000 (5 лет). + +### maxFails +Количество попыток для ввода учетных данных. + +Возможные значения - число больше 0. + +Значение по умолчанию - 3. + +### blockTime +Время блокировки пользователя. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 3600 (1 час). + diff --git "a/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" new file mode 100755 index 0000000000..58843c8e7a --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" @@ -0,0 +1,137 @@ +## Регистрация пользователей + +Контроллер Register позволяет регистрировать пользователей в заданные группы и отправлять уведомления о регистрации. Контроллер является расширением контроллера Form, соответственно можно использовать соответствующие параметры для отправки писем при регистрации. + +Имена полей в форме должны соответствовать полям модели [modUsers](http://docs.evolution-cms.com/Extras/Snippets/DocLister/MODxAPI). + +Если в форме не задано поле username, то ему присваивается значение поля email. Таким образом можно регистрировать пользователей только по email. + +Если в форме не задано поле password, то значение поля генерируется автоматически. То есть регистрацию пользователя можно свести к указанию email. + +При регистрации с паролем, в форме может присутствовать поле repeatPassword. Если заданы правила валидации для полей password и repeatPassword, то при наличии для поля repeatPassword правила equals, оно будет автоматически скорректировано для проверки равенства значений полей password и repeatPassword: +``` +"repeatPassword":{ + "required":"Введите пароль еще раз", + "equals":{ + "params" : "Этот ключ в описании правила можно не задавать, он будет сформирован контроллером автоматически", + "message":"Пароли не совпадают" + } +} +``` + +При регистрации следует проверять уникальность имени пользователя и email. В контроллере предусмотрены соответствующие правила: +``` +&rules=`{ + "username":{ + "required":"Введите имя пользователя", + "alphaNumeric":"Только буквы и цифры", + "custom":{ + "function":"\\FormLister\\Register::uniqueUsername", + "message":"Имя уже занято" + } + }, + "email":{ + "required":"Введите email", + "email":"Неверный email", + "custom":{ + "function":"\\FormLister\\Register::uniqueEmail", + "message":"Этот email уже использует другой пользователь" + } + } +}` +``` +В шаблонах доступны все поля модели для созданной записи. Дополнительно задается поле user.password с незашифрованным паролем. + +## Параметры +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### allowedFields +Разрешенные для обработки поля. Поля, не указанные в списке, игнорируются. Поля username, email и password всегда разрешены. + +Если не задано, то разрешены все поля. + +Возможные значения - имена полей формы, разделенные запятой. + +Значение по умолчанию - пусто. + +### forbiddenFields +Запрещенные для обработки поля. Поля, указанные в списке, игнорируются. Поля username, email и password удаляются из списка запрещенных. + +Возможные значения - имена полей формы, разделенные запятой. + +Значение по умолчанию - пусто. + +### userGroups +Добавляет зарегистрированного пользователя в указанные группы. + +Возможные значения - имена групп, разделенные запятой (если имена содержат запятую в названии, то можно задать значение параметра массивом). + +Значение по умолчанию - пусто. + +### checkActivation +Включает проверку активации учетной записи пользователя (см. "Активация учетных записей"). При этом после сохранения записи будет установлено поле activate.url, содержащее ссылку на страницу с вызовом сниппета для активации учетной записи. + +Возможные значения - 1 или 0. + +Значение по умолчанию - 0. + +### activateTo +Если включена проверка активации, то в этом параметре необходимо указать id страницы, на которой вызывается сниппет для активации. + +Возможные значения - id страницы. + +Значение по умолчанию - значение $modx->config['site_start']. + +### preparePostProcess +Позволяет выполнить обработку данных после сохранения. + +Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. + +Значение по умолчанию - пусто. + +### redirectTo +Перенаправляет пользователя на указанную страницу после регистрации. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### exitTo +Перенаправляет уже авторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы. + +Значение по умолчанию - пусто. + +### skipTpl +Шаблон сообщения для уже авторизованного пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Register с ключом [+register.default_skipTpl+] + +### successTpl +Шаблон сообщения об успешной регистрации. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Register с ключом [+register.default_successTpl+] + +### passwordLength +Длина пароля (если создается автоматически). + +Возможные значения - число символов больше 6. + +Значение по умолчанию - 6. diff --git "a/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" new file mode 100755 index 0000000000..ce0f37925c --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" @@ -0,0 +1,84 @@ +## Активация учетных записей + +Контроллер Activate реализует активацию учетных записей. Таким образом появляется возможность требовать у пользователя подтверждение учетной записи путем перехода по специальной ссылке из письма, отправленного при регистрации. + +Если по какой-то причине пользователь не получил письмо, то c помощью контроллера Activate он может запросить его повторную отправку. + +Учетная запись пользователя считается неактивированной если в поле logincount записано -1. + +В вызовах сниппета для регистрации и авторизации пользователей должен присутствовать параметр &checkActivation=`1`. + +Поэтому если при регистрации пользователь указывал пароль самостоятельно, то нужно запрашивать пароль для отправки письма со ссылкой для активации. Иначе будет генерироваться новый пароль, потому что раз пользователь запрашивает письмо для активации вручную, значит письмо после регистрации он не получил и не знает созданный при регистрации пароль. + +В шаблонах доступны все поля модели для обрабатываемой записи. В шаблоне reportTpl задается поле user.password с незашифрованным паролем и поле activate.url со ссылкой для активации. + +## Параметры +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### redirectTo +Перенаправляет пользователя на указанную страницу после активации. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### exitTo +Перенаправляет авторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### skipTpl +Шаблон сообщения для авторизованного пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Register с ключом [+register.default_skipTpl+] + +### reportTpl +Шаблон письма с информацией для активации учетной записи. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### reportTpl +Шаблон письма с информацией для активации учетной записи. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### successTpl +Шаблон сообщения об успешной отправке письма с данными для активации. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Activate с ключом [+activate.default_successTpl+] + +### activateSuccessTpl +Шаблон сообщения об успешной активации. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Activate с ключом [+activate.default_activateSuccessTpl+] + +### passwordLength +Длина создаваемого пароля. + +Возможные значения - число символов больше 6. + +Значение по умолчанию - 6. diff --git "a/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" "b/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" new file mode 100755 index 0000000000..1a6d503c7d --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" @@ -0,0 +1,99 @@ +## Редактирование профиля пользователя + +Контроллер Profile позволяет авторизованным пользователям редактировать свои профили, в том числе менять пароль. + +При изменении профиля следует проверять уникальность email. В контроллере предусмотрено соответствующее правило: +``` +&rules=`{ + "email":{ + "required":"Введите email", + "email":"Неверный email", + "custom":{ + "function":"\\FormLister\\Profile::uniqueEmail", + "message":"Этот email уже использует другой пользователь" + } + } +}` +``` +Аналогично с полем username: +``` +&rules=`{ + "username":{ + "required":"Введите имя пользователя", + "alphaNumeric":"Только буквы и цифры", + "custom":{ + "function":"\\FormLister\\Profile::uniqueUsername", + "message":"Имя уже занято" + } + } +}` +``` + +Если поле с паролем пустое, то пароль остается прежний. После изменения пароля пользователь должен авторизоваться с новым паролем. Новый пароль сохраняется в поле user.password. + + +## Параметры +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### allowedFields +Разрешенные для обработки поля. Поля, не указанные в списке, игнорируются. Если пользователь меняет пароль, то в разрешенные поля добавляется поле password. Если у пользователей совпадают поля e-mail и username, то при изменении e-mail будет изменено и поле username, если значение этого поля не задано. В этом случае поле username будет добавлено в список разрешенных. + +Если не задано, то разрешены все поля. + +Возможные значения - имена полей формы, разделенные запятой. + +Значение по умолчанию - пусто. + +### forbiddenFields +Запрещенные для обработки поля. Поля, указанные в списке, игнорируются. Поля password и username исключаются из списка по аналогии с allowedFields. + +Возможные значения - имена полей формы, разделенные запятой. + +Значение по умолчанию - пусто. + +### preparePostProcess +Позволяет выполнить обработку данных после сохранения. + +Возможные значения - имена сниппетов, анонимные функции, статические методы загруженных классов. + +Значение по умолчанию - пусто. + +### redirectTo +Перенаправляет пользователя на указанную страницу после сохранения профиля. + +Возможные значения - id целевой страницы. + +Значение по умолчанию - пусто. + +### exitTo +Перенаправляет неавторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### skipTpl +Шаблон сообщения для неавторизованного пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Profile с ключом [+profile.default_skipTpl+] + +### successTpl +Шаблон сообщения об успешном обновлении профиля. Если не задан, то генерируется сообщение об успешном сохранении формы. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" "b/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" new file mode 100755 index 0000000000..bfe4041476 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" @@ -0,0 +1,50 @@ +## Удаление профиля пользователя + +Контроллер DeleteUser позволяет авторизованным пользователям удалять свои профили. Для подтверждения действия пользователю необходимо ввести свой пароль. + +Расширяет Form. + +В шаблонах доступны поля модели для удаляемой записи. + +## Параметры +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### redirectTo +Перенаправляет пользователя на указанную страницу после сохранения профиля. + +Возможные значения - id целевой страницы. + +Значение по умолчанию - пусто. + +### exitTo +Перенаправляет неавторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### skipTpl +Шаблон сообщения для неавторизованного пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона deleteUser с ключом [+deleteUser.default_skipTpl+] + +### successTpl +Шаблон сообщения об успешном удалении профиля. Если не задан, то генерируется сообщение об успешном сохранении формы. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" new file mode 100755 index 0000000000..e9b507dd4f --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" @@ -0,0 +1,143 @@ +## Восстановление паролей пользователями + +Контроллер Reminder позволяет web-пользователям восстанавливать забытые пароли. Расширяет контроллер Form. + +Восстановление паролей происходит по следующей схеме: + +- пользователь вводит в форме свой идентификатор (им может быть имя пользователя или email); +- пользователь получает письмо, в котором содержится ссылка для восстановления; +- при переходе по ссылке пользователь получает возможность ввести новый пароль либо пароль будет сгенерирован автоматически; +- пользователю отправляется письмо с новым паролем и показыается сообщение (в сообщении можно также вывести новый пароль). + +Параметр to перезаписывается значением email пользователя. Обязательно должен быть задан параметр resetTo. + +## Параметры +### model +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### modelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### hashField +Имя поля для хранения хэша данных пользователя. + +Значение по умолчанию - hash. + +### userField +Имя поля для хранения идентификатора пользователя (имя пользователя или email). + +Значение по умолчанию - email. + +### uidField +Имя поля, которое используется для идентификации пользователя при переходе по ссылке. + +Значение по умолчанию - id. + +### exitTo +Перенаправляет авторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы. + +Значение по умолчанию - пусто. + +### resetTo +Страница, на которую будет указывать ссылка для восстановления паролей. Обязательный параметр. + +Возможные значения - id целевой страницы. + +Значение по умолчанию - id документа, в котором вызван контроллер. + +### redirectTo +Перенаправляет на указанную страницу после успешного восстановления пароля. + +Возможные значения - id целевой страницы. + +Значение по умолчанию - пусто. + +### skipTpl +Шаблон сообщения для авторизованного пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_skipTpl+]. + +### formTpl +Шаблон формы для ввода идентификатора пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### resetTpl +Шаблон формы для ввода нового пароля. Если параметр не задан, то пароль будет сгенерирован автоматически. + +Поля для ввода паролей должны называться password и repeatPassword. В форме должны также присутствовать скрытые поля с именами из параметров uidField и hashField. Значение для поля hashField задается через плейсхолдер [+user.hash+]. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### successTpl +Шаблон сообщения об успешной отправке письма со ссылкой для восстановления пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.). + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_successTpl+]. + +### resetSuccessTpl +Шаблон сообщения об успешном восстановлении пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_resetSuccessTpl+]. + +### reportTpl +Шаблон письма со ссылкой для восстановления пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). Ссылка для восстановлени пароля в письме задается через плейсхолдер [+reset.url+] + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Reminder с ключом [+reminder.default_reportTpl+].. + +### resetReportTpl +Шаблон письма об успешном восстановлении пароля. В шаблоне можно выводить плейсхолдеры с данными пользователя (username, email и т.д.), а также новый пароль (newpassword). Если не задан, то письмо пользователю отправляться не будет. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. + +### rules +Правила валидации для формы идентификации пользователя. + +Возможные значения - см. раздел "Валидация данных". + +Значение по умолчанию - пусто. + +### resetRules +Правила валидации для формы установки нового пароля. Если заданы правила валидации для полей password и repeatPassword, то при наличии для поля repeatPassword правила equals, оно будет автоматически скорректировано для проверки равенства значений полей password и repeatPassword: +``` +"repeatPassword":{ + "required":"Введите пароль еще раз", + "equals":{ + "params" : "Этот ключ в описании правила можно не задавать, он будет сформирован контроллером автоматически", + "message":"Пароли не совпадают" + } +} +``` +Возможные значения - см. раздел "Валидация данных". + +Значение по умолчанию - пусто. + +### passwordLength +Длина пароля (если создается автоматически). + +Возможные значения - число символов больше 6. + +Значение по умолчанию - 6. diff --git "a/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" new file mode 100755 index 0000000000..d383e93f47 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" @@ -0,0 +1,166 @@ +## Создание и редактирование документов пользователями + +Контроллер Content позволяет web-пользователям создавать и редактировать записи в таблицах MODxAPI. Расширяет контроллер Form, что позволяет отправлять письма после создания записи. При редактировании записей отправка почты отключена, при необходимости ее можно реализовать с помощью плагинов на событие сохранения (OnDocFormSave и т.п.). + +Данные формы передаются в объект MODxAPI как есть, соответственно разработчику нужно заботиться об их корректности самостоятельно. + +При редактировании записей можно запретить изменение отдельных полей, используя параметр keepDefaults. + +При создании новой записи вызывается событие OnMakeDocUrl, в которое передается id записи и массив data со значениями полей записи. Это позволяет вернуть ссылку на созданную запись, она будет доступна через плейсхолдер [+content.url+]. Ссылку можно использовать в письме c уведомлением о создании новой записи. + +Также можно использовать данные авторизованного пользователя, доступны через плейсхолдеры [+user.fullname+], [+user.email+] и т.д. + +## Параметры +### model +Класс MODxAPI. + +Возможные значения - имя класса MODxAPI. + +Значение по умолчанию - \modResource. + +### modelPath +Путь к файлу класса, если класс не загружается заранее. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modResource.php. + +### userModel +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### userModelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### onlyUsers +Разрешить добавление записей только для зарегистрированных пользователей. + +Возможные значения - 0, 1. + +Значение по умолчанию - 1. + +### userGroups +Группы пользователей, которым разрешено добавлять или изменять записи. + +Возможные значения - список групп через точку с запятой. + +Значение по умолчанию - пусто (разрешены любые группы). + +### onlyOwners +Разрешает редактирование записей только их авторами. Автор определяется по полю, указанному в параметре ownerField. + +Возможные значения - 0, 1. + +Значение по умолчанию - 1. + +### ownerField +Имя поля, определяющего владельца записи. Если работать с документами modResource, то это будет имя tv-параметра (в Evo не предусмотрено создание записей веб-пользователями). + +Возможные значения - имя поля. + +Значение по умолчанию - aid. + +### idField +Имя ключа массива $_REQUEST, по которому определяется id редактируемой записи. Если ключ не задан, то контроллер вызывается в режиме создания записей. Информацию о режиме контроллера можно получить с помощью метода getMode. + +В форме редактирования нужно предусмотреть скрытое поле с именем параметра, в котором будет сохраняться id записи. + +Значение по умолчанию - id. + +### contentFields +Задает сопоставление полей MODxAPI и полей формы. Можно не задавать, если имена полей совпадают. Если параметр не задан, то ограничить список передаваемых в модель полей можно с помощью параметров allowedFields и forbiddenFields. + +Возможные значения - массив вида: +``` +&contentFields=`{ + "поле MODxAPI":"поле формы", + "поле MODxAPI":"поле формы" +} +` +``` +Значение по умолчанию - пусто. + +### clearCache +Очищать кэш после сохранения записи. + +Возможные значения - 0, 1. + +Значение по умолчанию - 0. + +### redirectTo +Перенаправляет пользователя на указанную страницу после сохранения новой записи. В режиме редактирования не используется. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### editAfterCreate +Переправляет пользователя на страницу для редактирования созданной записи. Страница указывается в параметре redirectTo. + +Возможные значения - 1 или 0. + +Значение по умолчанию - 0. + +### editTpl +Шаблон формы для редактирования документа. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - значение параметра formTpl. + +### badOwnerTpl +Шаблон сообщения о том, что пользователь не является автором документа. Только режим редактирования. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Content с ключом [+edit.default_badOwnerTpl+]. + +### badGroupTpl, badGroupEditTpl +Шаблон сообщения о том, что пользователь не входит в группу пользователей которым разрешено создавать и редактировать документы. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Content с ключом +[+create.default_badGroupTpl+] или [+edit.default_badGroupTpl+]. + +### badRecordTpl +Шаблон сообщения о том, что пользователь не может редактировать запись: например, запись не существует. Только режим редактирования. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Content с ключом [+edit.default_badRecordTpl+]. + +### exitTo +Перенаправляет неавторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### skipTpl, skipEditTpl +Шаблон сообщения для неавторизованного пользователя. Для режима редактирования - skipEditTpl. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Content с ключом [+create.default_skipTpl+] (edit.default_skipEditTpl). + +### successTpl +Шаблон сообщения об успешном сохранении новой записи. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона Content с ключом [+create.default_successTpl+] + +### editSuccessTpl +Шаблон сообщения об успешном обновлении записи. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" new file mode 100755 index 0000000000..7cddeb4ad3 --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" @@ -0,0 +1,97 @@ +## Удаление профиля пользователя + +Контроллер DeleteContent позволяет авторизованным пользователям удалять созданные ими документы. + +Расширяет Form. + +В шаблонах доступны поля модели для удаляемой записи. Информация о пользователе доступна в полях с префиксом user (user.fullname, user.email и т.д.) + +## Параметры +### model +Класс MODxAPI. + +Возможные значения - имя класса MODxAPI. + +Значение по умолчанию - \modResource. + +### modelPath +Путь к файлу класса, если класс не загружается заранее. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modResource.php. + +### userModel +Класс для работы с пользователями. + +Возможные значения - имя класса. + +Значение по умолчанию - \modUsers + +### userModelPath +Путь к файлу класса для работы с пользователями. + +Возможные значения - относительный путь к файлу. + +Значение по умолчанию - assets/lib/MODxAPI/modUsers.php + +### ownerField +Имя поля, определяющего владельца записи. Если работать с документами modResource, то это будет имя tv-параметра (в Evo не предусмотрено создание записей веб-пользователями). + +Возможные значения - имя поля. + +Значение по умолчанию - aid. + +### idField +Имя ключа массива $_REQUEST, по которому определяется id удаляемой записи. + +Значение по умолчанию - id. + +### redirectTo +Перенаправляет пользователя на указанную страницу после удаления записи. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### badOwnerTpl +Шаблон сообщения о том, что пользователь не является автором документа. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_badOwnerTpl+]. + +### badRecordTpl +Шаблон сообщения о том, что пользователь не может удалить запись: например, запись не существует. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_badRecordTpl+]. + +### skipTpl +Шаблон сообщения для неавторизованного пользователя. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_skipTpl+]. + +### successTpl +Шаблон сообщения об успешном сохранении новой записи. + +Возможные значения - имя шаблона, указанное по правилам задания шаблонов в DocLister. + +Значение по умолчанию - запись из лексикона deleteContent с ключом [+deleteContent.default_successTpl+] + +### exitTo +Перенаправляет неавторизованного пользователя на указанную страницу. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. + +### badRecordTo +Перенаправление, если невозможно удалить запись. + +Возможные значения - id целевой страницы или массив. + +Значение по умолчанию - пусто. diff --git "a/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" "b/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" new file mode 100755 index 0000000000..dd64c0974b --- /dev/null +++ "b/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" @@ -0,0 +1,18 @@ +## Лексиконы + +Для использования лексиконов необходимо создать папку с полным названием языка (russian-UTF8, english и т.д.), в ней создать файл название_лексикона.inc.php: +``` + +``` +Для загрузки лексиконов при вызове сниппета следует указать параметры: + +* langDir - путь к папке с лексиконами; +* lang - язык лексикона (если не указано, то используется параметр конфигурации manager_language); +* lexicon - название лексикона, можно указать несколько названий через запятую. + +После этого в шаблонах можно использовать плейсхолдеры [%ключ%] для подстановки значений из загруженных языковых файлов. Кроме того поддерживаются лексиконы компонента EvoBabel. \ No newline at end of file From c3d1109c2081baa35f6b0972d79380425dd65a8d Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 4 Aug 2017 11:52:37 +0300 Subject: [PATCH 182/338] fix file names --- ...20\260\320\275\320\275\321\213\321\205.md" | 0 ...20\272\320\260\320\277\321\207\320\270.md" | 0 ...20\260\320\275\320\275\321\213\321\205.md" | 0 ...20\277\320\270\321\201\320\265\320\274.md" | 0 ...21\202\320\265\320\273\320\265\320\271.md" | 30 +------------------ ...21\202\320\265\320\273\320\265\320\271.md" | 0 ...20\277\320\270\321\201\320\265\320\271.md" | 0 ...20\260\321\202\320\265\320\273\321\217.md" | 0 ...20\260\321\202\320\265\320\273\321\217.md" | 0 ...20\265\320\273\321\217\320\274\320\270.md" | 0 ...20\265\320\273\321\217\320\274\320\270.md" | 0 ...20\265\320\273\321\217\320\274\320\270.md" | 0 12 files changed, 1 insertion(+), 29 deletions(-) rename "assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" => "assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\320\264\320\260\320\275\320\275\321\213\321\205.md" (100%) rename "assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" => "assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\272\320\260\320\277\321\207\320\270.md" (100%) rename "assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" => "assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264_\320\264\320\260\320\275\320\275\321\213\321\205.md" (100%) rename "assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" => "assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\277\320\270\321\201\320\265\320\274.md" (100%) rename "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" => "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" (70%) mode change 100755 => 100644 rename "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" => "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" (100%) rename "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" => "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217_\321\203\321\207\320\265\321\202\320\275\321\213\321\205_\320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" (100%) rename "assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" => "assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\277\321\200\320\276\321\204\320\270\320\273\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" (100%) rename "assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" => "assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265_\320\277\321\200\320\276\321\204\320\270\320\273\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" (100%) rename "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" => "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265_\320\277\320\260\321\200\320\276\320\273\320\265\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" (100%) rename "assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" => "assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" (100%) rename "assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" => "assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" (100%) diff --git "a/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" "b/assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\320\264\320\260\320\275\320\275\321\213\321\205.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217 \320\264\320\260\320\275\320\275\321\213\321\205.md" rename to "assets/snippets/FormLister/docs/ru/030_\320\222\320\260\320\273\320\270\320\264\320\260\321\206\320\270\321\217_\320\264\320\260\320\275\320\275\321\213\321\205.md" diff --git "a/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" "b/assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\272\320\260\320\277\321\207\320\270.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265 \320\272\320\260\320\277\321\207\320\270.md" rename to "assets/snippets/FormLister/docs/ru/035_\320\230\321\201\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\320\275\320\270\320\265_\320\272\320\260\320\277\321\207\320\270.md" diff --git "a/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" "b/assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264_\320\264\320\260\320\275\320\275\321\213\321\205.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264 \320\264\320\260\320\275\320\275\321\213\321\205.md" rename to "assets/snippets/FormLister/docs/ru/040_\320\222\321\213\320\262\320\276\320\264_\320\264\320\260\320\275\320\275\321\213\321\205.md" diff --git "a/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" "b/assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\277\320\270\321\201\320\265\320\274.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260 \320\277\320\270\321\201\320\265\320\274.md" rename to "assets/snippets/FormLister/docs/ru/050_\320\236\321\202\320\277\321\200\320\260\320\262\320\272\320\260_\320\277\320\270\321\201\320\265\320\274.md" diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" old mode 100755 new mode 100644 similarity index 70% rename from "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" rename to "assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" index 04c410ea91..841e652207 --- "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" +++ "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" @@ -1,19 +1,6 @@ ## Авторизация пользователей -Авторизация пользователей в `FormLister` осуществляется с использованием контроллера `Login`. - -Авторизация может проходить по id, имени (username), email средствами класса modUsers; другому полю из учетной записи (с помощью плагина для события OnWebAuthentication). Поле задается в параметре `loginField` и должно быть **уникальным** для каждого веб-пользователя. Обычно для авторизации используются поля `username` или `email`. - -Дополнительное использование плагина [userHelper](https://github.com/evolution-cms/evolution/blob/develop/assets/snippets/FormLister/plugin.userHelper.php) позволяет: - -* вести учет количества логинов; -* определить время последней авторизации; -* реализовать автологин и выход из учетной записи; -* блокировать пользователей после определенного количества неудачных попыток авторизации. - -Перед использованием плагина `userHelper` убедитесь что он включен: - -![Не забудьте включить userHelper](https://habrastorage.org/web/dbc/1e2/abd/dbc1e2abd8664a548f4eca254187fb60.png) +Контроллер Login позволяет авторизировать пользователей как по имени, так и по email. Кроме этого, можно дополнительно использовать плагин userHelper, который ведет учет количества логинов и времени последнего логина, а также реализует автологин и выход из учетной записи. ## Параметры контроллера @@ -128,18 +115,3 @@ Возможные значения - число секунд с момента последнего логина. Значение по умолчанию - 157680000 (5 лет). - -### maxFails -Количество попыток для ввода учетных данных. - -Возможные значения - число больше 0. - -Значение по умолчанию - 3. - -### blockTime -Время блокировки пользователя. - -Возможные значения - число секунд с момента последнего логина. - -Значение по умолчанию - 3600 (1 час). - diff --git "a/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" rename to "assets/snippets/FormLister/docs/ru/070_\320\240\320\265\320\263\320\270\321\201\321\202\321\200\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" diff --git "a/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217_\321\203\321\207\320\265\321\202\320\275\321\213\321\205_\320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217 \321\203\321\207\320\265\321\202\320\275\321\213\321\205 \320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" rename to "assets/snippets/FormLister/docs/ru/075_\320\220\320\272\321\202\320\270\320\262\320\260\321\206\320\270\321\217_\321\203\321\207\320\265\321\202\320\275\321\213\321\205_\320\267\320\260\320\277\320\270\321\201\320\265\320\271.md" diff --git "a/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" "b/assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\277\321\200\320\276\321\204\320\270\320\273\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" rename to "assets/snippets/FormLister/docs/ru/080_\320\240\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\277\321\200\320\276\321\204\320\270\320\273\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" diff --git "a/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" "b/assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265_\320\277\321\200\320\276\321\204\320\270\320\273\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\277\321\200\320\276\321\204\320\270\320\273\321\217 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" rename to "assets/snippets/FormLister/docs/ru/085_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265_\320\277\321\200\320\276\321\204\320\270\320\273\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217.md" diff --git "a/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265_\320\277\320\260\321\200\320\276\320\273\320\265\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265 \320\277\320\260\321\200\320\276\320\273\320\265\320\271 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" rename to "assets/snippets/FormLister/docs/ru/090_\320\222\320\276\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265\320\275\320\270\320\265_\320\277\320\260\321\200\320\276\320\273\320\265\320\271_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" diff --git "a/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265 \320\270 \321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" rename to "assets/snippets/FormLister/docs/ru/100_\320\241\320\276\320\267\320\264\320\260\320\275\320\270\320\265_\320\270_\321\200\320\265\320\264\320\260\320\272\321\202\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" diff --git "a/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" "b/assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" similarity index 100% rename from "assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265 \320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262 \320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" rename to "assets/snippets/FormLister/docs/ru/105_\320\243\320\264\320\260\320\273\320\265\320\275\320\270\320\265_\320\264\320\276\320\272\321\203\320\274\320\265\320\275\321\202\320\276\320\262_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\321\217\320\274\320\270.md" From 10cb5dd8bee5feaa71d83d9dbe131d554af0b036 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 4 Aug 2017 12:05:05 +0300 Subject: [PATCH 183/338] [F] fix for check version in update with version_compare --- assets/plugins/updater/plugin.updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/plugins/updater/plugin.updater.php b/assets/plugins/updater/plugin.updater.php index 6e96f85e46..671b1b71cf 100644 --- a/assets/plugins/updater/plugin.updater.php +++ b/assets/plugins/updater/plugin.updater.php @@ -91,7 +91,7 @@ $_SESSION['updatelink'] = md5(time()); $_SESSION['updateversion'] = $git['version']; - if ($git['version'] != $currentVersion['version'] && $git['version'] != '') { + if (version_compare($git['version'], $currentVersion['version'],'>') && $git['version'] != '') { // get manager role $role = $_SESSION['mgrRole']; if(($role!=1) AND ($showButton == 'AdminOnly') OR ($showButton == 'hide') OR ($errors > 0)) { From f5728a10c079f96f9a156469711b3e01ed9da9f4 Mon Sep 17 00:00:00 2001 From: Pathologic Date: Fri, 4 Aug 2017 12:46:49 +0300 Subject: [PATCH 184/338] refactor getSettings --- manager/includes/document.parser.class.inc.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index b99471d7d3..0f6592f575 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -316,6 +316,13 @@ function getSettings() { while ($row= $this->db->getRow($result)) { $this->config[$row['setting_name']]= $row['setting_value']; } + if ($this->config['enable_filter']) { + $where = "plugincode LIKE '%phx.parser.class.inc.php%OnParseDocument();%' AND disabled != 1"; + $count = $this->db->getRecordCount($this->db->select('id', '[+prefix+]site_plugins', $where)); + if ($count) { + $this->config['enable_filter'] = '0'; + } + } } } } @@ -334,10 +341,6 @@ function getSettings() { $this->config['filemanager_path'] = str_replace('[(base_path)]',MODX_BASE_PATH,$this->config['filemanager_path']); $this->config['rb_base_dir'] = str_replace('[(base_path)]',MODX_BASE_PATH,$this->config['rb_base_dir']); - $where = "plugincode LIKE '%phx.parser.class.inc.php%OnParseDocument();%' AND disabled != 1"; - $count = $this->db->getRecordCount($this->db->select('id', '[+prefix+]site_plugins', $where)); - if($count) $this->config['enable_filter'] = '0'; - // now merge user settings into MODX-configuration $this->getUserSettings(); } From 9a081655b33acbd55e8868fdf19f8db5e5fbf010 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 4 Aug 2017 22:24:47 +0300 Subject: [PATCH 185/338] fix favicon form login --- manager/includes/accesscontrol.inc.php | 1 + manager/media/style/default/login.tpl | 2 +- manager/media/style/default/style.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/manager/includes/accesscontrol.inc.php b/manager/includes/accesscontrol.inc.php index 653500619d..daa6f1e0c3 100644 --- a/manager/includes/accesscontrol.inc.php +++ b/manager/includes/accesscontrol.inc.php @@ -69,6 +69,7 @@ $modx->setPlaceholder('modx_charset', $modx_manager_charset); $modx->setPlaceholder('theme', $manager_theme); + $modx->setPlaceholder('favicon', (file_exists(MODX_BASE_PATH . 'favicon.ico') ? MODX_SITE_URL . 'favicon.ico' : 'media/style/' . $modx->config['manager_theme'] . '/images/favicon.ico')); // invoke OnManagerLoginFormPrerender event $evtOut = $modx->invokeEvent('OnManagerLoginFormPrerender'); diff --git a/manager/media/style/default/login.tpl b/manager/media/style/default/login.tpl index 220c3db9ee..bd0b2a1646 100644 --- a/manager/media/style/default/login.tpl +++ b/manager/media/style/default/login.tpl @@ -5,7 +5,7 @@ - + - + [+lang.DM_update_title+] + + + + +

    [+lang.DM_module_title+]

    -
    -
    [+lang.DM_update_title+]
    -
    -

    [+update.message+]

    - -
    +
    +
    + [+lang.DM_update_title+] +

    [+update.message+]

    + +
    + \ No newline at end of file diff --git a/assets/modules/docmanager/tv.ajax.php b/assets/modules/docmanager/tv.ajax.php index a67d6e491c..4477a03ea7 100644 --- a/assets/modules/docmanager/tv.ajax.php +++ b/assets/modules/docmanager/tv.ajax.php @@ -15,9 +15,9 @@ $dm = new DocManager($modx); $dm->getLang(); $dm->getTheme(); - + $output = ''; - + if(isset($_POST['tplID']) && is_numeric($_POST['tplID'])) { $rs = $modx->db->select( '*', @@ -26,7 +26,7 @@ "tvt.templateid ='{$_POST['tplID']}'" ); $limit = $modx->db->getRecordCount($rs); - + if ($limit > 0) { require (MODX_MANAGER_PATH.'includes/tmplvars.commands.inc.php'); $output.= ""; @@ -35,7 +35,7 @@ while ($row = $modx->db->getRow($rs)) { if($i++>0) $output .= ''; - + $output.=''; + } + $output .= '
     '.$row['caption'].'
    '.$row['description'].' @@ -50,12 +50,12 @@ } else { print $dm->lang['DM_tv_no_tv']; } - + print $output; } else { print ''; } - + function renderFormElement($field_type, $field_id, $default_text, $field_elements, $field_value, $field_style='') { @@ -84,7 +84,7 @@ function renderFormElement($field_type, $field_id, $default_text, $field_element $field_html .= ''; break; case "date": - $field_id = str_replace(array('-', '.'),'_', urldecode($field_id)); + $field_id = str_replace(array('-', '.'),'_', urldecode($field_id)); if($field_value=='') $field_value=0; $field_html .= ''; $field_html .= ' No date'; @@ -102,7 +102,7 @@ function renderFormElement($field_type, $field_id, $default_text, $field_element $field_html .= ""; break; case "listbox": // handler for select boxes - $field_html .= ''; $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id)); while (list($item, $itemvalue) = each ($index_list)) { @@ -161,7 +161,7 @@ function renderFormElement($field_type, $field_id, $default_text, $field_element case "image": // handles image fields using htmlarea image manager global $ResourceManagerLoaded; global $content,$use_editor,$which_editor,$which_browser; - if (!$ResourceManagerLoaded && !(($content['richtext']==1 || $_GET['a']==4) && $use_editor==1 && $which_editor==3)){ + if (!$ResourceManagerLoaded && !(($content['richtext']==1 || $_GET['a']==4) && $use_editor==1 && $which_editor==3)){ $field_html .=" "; - $ResourceManagerLoaded = true; - } + $ResourceManagerLoaded = true; + } $field_html .=' '; break; case "file": // handles the input of file uploads @@ -215,7 +215,7 @@ function SetUrl(url, width, height, alt){ global $ResourceManagerLoaded; global $content,$use_editor,$which_editor; if (!$ResourceManagerLoaded && !(($content['richtext']==1 || $_GET['a']==4) && $use_editor==1 && $which_editor==3)){ - /* I didn't understand the meaning of the condition above, so I left it untouched ;-) */ + /* I didn't understand the meaning of the condition above, so I left it untouched ;-) */ $field_html .=" "; - $ResourceManagerLoaded = true; - } + $ResourceManagerLoaded = true; + } $field_html .=' '; - + break; default: // the default handler -- for errors, mostly $field_html .= ''; From f30fd5aa1e93820924f65b1ef6ce62263610efaf Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 18 Aug 2017 01:55:49 +0300 Subject: [PATCH 278/338] refactor css default theme --- manager/media/style/default/css/custom.css | 44 +++++++++++++- manager/media/style/default/css/tabpane.css | 18 +++++- manager/media/style/default/style.css | 67 +-------------------- 3 files changed, 60 insertions(+), 69 deletions(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index dcc4efac16..e938a6f498 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -23,8 +23,8 @@ input[name*=date]:not(.unstyled) + .input-group-addon { float: left; width: auto input[size="50"], select[size="50"] { width: 10rem !important } select[name=usergroup], select[name=docgroup] { margin: 0 0.5em; } select[name=docgroup] + input[type=submit] { float: none; margin: 0; } -#settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype], input[name=photo], #range input#pids, form#mutate input[type=text][name^=tv]:not(.DatePicker):not([class^=mtv]), form#mutate input[type=number][name^=tv] { border-top-right-radius: 0; border-bottom-right-radius: 0 } -#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], form#mutate input[name="ta"].inputBox + input[type=button], form#mutate input[name="ta"].inputBox + .CodeMirror + input[type=button], form#mutate input[name^=tv]:not([class^=mtv]) + input[type=button], form#mutate input[name^=tv].DatePicker + a { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } +#settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype] { border-top-right-radius: 0; border-bottom-right-radius: 0 } +#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], input[name^=tv]:not([class^=mtv]) + input[type=button], input[name^=tv].DatePicker + a { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } #settingsPane [name=site_name], #settingsPane [name=txt_custom_contenttype], #settingsPane [name=filemanager_path], #settingsPane [name=rb_base_dir], input[name=photo], #range input#pids, input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } #range::after { content: ""; display: table; width: 100% } /* [ Editor ] */ @@ -82,7 +82,43 @@ select[name=docgroup] + input[type=submit] { float: none; margin: 0; } #actions .actionButtons .plus { margin: 0 0 0 -2px } #actions .actionButtons select#stay { display: none } } +/* actionButtons in content ( old style ) */ +.actionButtons { margin: 0; padding: 0; background: none; width: auto; white-space: nowrap; } +.actionButtons li { float: left; margin: 0; padding: 0; list-style: none; } +.actionButtons li:before, .mmTagList li:before, .rTable li:before, .tab-pane ul li ul li:before, .dashboard li:before, div#idShowHideSocialBox.sectionBody > div.btn-group.ope > ul.dropdown-menu > li:before, .sectionBody .multitv .list li:before { display: none; content: ''; } +.actionButtons img { vertical-align: top; margin-top: 1px; filter: alpha(opacity=30); -moz-opacity: 0.3; opacity: 0.3; } +.actionButtons:hover img { filter: alpha(opacity=100); -moz-opacity: 1; opacity: 1; } +.actionButtons a:hover { border-color: #999; -moz-box-shadow: 1px 1px 2px #aaa; -webkit-box-shadow: 1px 1px 2px #aaa; box-shadow: 1px 1px 2px #aaa; -webkit-transition: all .3s ease; -moz-transition: all .3s ease; -o-transition: all .3s ease; transition: .3s ease; background: -moz-linear-gradient(#fff, #f5f5f5); background: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f5f5f5)); background: -o-linear-gradient(#fff, #f5f5f5); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#fff, endColorstr=#f5f5f5); +zoom: 1; text-decoration: none !important; } +.actionButtons a:active { background: #92aac4 bottom left; -webkit-box-shadow: 0 0 10px #b8c7d6; -moz-box-shadow: 0 0 10px #b8c7d6; box-shadow: 0 0 10px #b8c7d6; } +.actionButtons a { float: left; padding: 5px 10px; height: 32px; font-size: 13px; font-weight: 500; } +.actionButtons a, .actionButtons li.primary a, .actionButtons a.primary, .actionButtons a.default { text-shadow: none; background: #fff; color: #555; border: 1px solid #e4e4e4; border-radius: 3px; /*box-shadow: 0 0 0 1px #E4E4E4;*/ box-shadow: none; transition: none; } +.actionButtons a:hover { background: #1377c5; box-shadow: none; border-color: #1377c5; color: #fff !important; transition: none; } +.actionButtons a:active { background-color: #3189ba; border-color: #3189ba; } +.actionButtons li.primary a, .actionButtons a.primary { color: #fff; border-color: #32ab9a; background: #32ab9a linear-gradient(#32ab9a, #00948e); } +.actionButtons li.primary a:hover, .actionButtons a.primary:hover { background: #2b9385 linear-gradient(#2b9385, #007571); border-color: #2b9385; } +.actionButtons li.primary a:active, .actionButtons a.primary:active { background: #32ab9a; border-color: #32ab9a; } +.actionButtons img { display: none; } +#treePane .actionButtons img { display: inline; } +.actionButtons--tableheader .fa { font-size: 14px; } +.sectionBody .actionButtons { padding-top: 0; min-height: 40px; } +.sectionBody .actionButtons li { margin-right: 10px; } +.sectionBody .actionButtons a { display: inline-block; padding: 9px 10px; line-height: 1; } +table.actionButtons { margin-top: 1rem; margin-bottom: 10px; } +table.actionButtons img { display: inline-block; } +table.actionButtons .searchtext { padding: 5px; height: 24px; width: 150px; } +.actionButtons .fa { display: none; text-align: center; font-size: 1em; line-height: 1em; width: 1.1em; vertical-align: initial } +.actionButtons .fa, .actionButtons--eit .fa { display: inline-block; } +.optionsTitle .fa { display: inline-block; } +@media (max-width: 900px) { +.actionButtons a { display: inline-block; padding: 6px 10px } +.tab-page .actionButtons a { margin-top: 0 !important } +.actionButtons a span { display: none; } +.actionButtons a .fa { display: inline-block; } +} /* [ TABLES ] */ +/* table */ +.table th, .table td { padding: 0.15rem 0.25rem; } /* table-data */ .table.data { width: 100%; max-width: 100%; margin-bottom: 0; border-bottom: 1px solid #eceeef } .table.data th, .table.data thead td { padding: 0.75rem; text-transform: uppercase; white-space: nowrap; font-size: 0.675rem; color: #777; border-bottom: 2px solid #eceeef } @@ -244,7 +280,7 @@ ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0 /* ManagerManager */ .sectionHeader.minimizable { position: relative; z-index: 1; background-color: #fafafa; padding: 0.5rem; border: 1px solid rgba(0, 0, 0, 0.15); } .dark .sectionHeader.minimizable { background-color: #f2f2f2 } -form#mutate .imageField { min-width: 100% !important; width: 100% !important } +.imageField { min-width: 100% !important; width: 100% !important } ul.mmTagList { float: left; margin-top: .25rem !important } /* MCE */ .mce-container, .mce-container-body { box-sizing: border-box !important } @@ -259,6 +295,8 @@ ul.mmTagList { float: left; margin-top: .25rem !important } .CodeMirror pre { word-break: break-all !important; } .CodeMirror > div:first-child > textarea { /*opacity: 0;*/ z-index: -1; left: -9999rem; } div.CodeMirror-cursors { pointer-events: none; } +/* docFinder */ +form#docfinder div.tab-page { height: auto !important } /* SimpleGallery */ #SimpleGallery .pagination { display: block } #SimpleGallery .sg_image { width: auto } diff --git a/manager/media/style/default/css/tabpane.css b/manager/media/style/default/css/tabpane.css index 9c7c86fb69..0e3c3f254a 100644 --- a/manager/media/style/default/css/tabpane.css +++ b/manager/media/style/default/css/tabpane.css @@ -2,7 +2,7 @@ .tab-row { position: relative; z-index: 1; white-space: nowrap; padding: 0 1.5rem } .tab-row::after, .tab-row-container::after { content: ""; position: absolute; z-index: 1; left: 0; right: 0; bottom: 0; height: 1px; background-color: #ddd } .tab-row .tab { position: relative; display: inline-block; margin: 0; padding: 0 0.875rem; line-height: 2.7rem; height: 2.5rem; text-transform: uppercase; border: 1px solid rgba(0, 0, 0, 0); border-bottom: none; cursor: pointer; -webkit-user-select: none; user-select: none; } -.tab-row .tab { color: rgba(0, 0, 0, 0.6); font-size: 0.75rem } +.tab-row .tab, .tab-row .tab a { color: rgba(0, 0, 0, 0.6); font-size: 0.75rem } .tab-row .tab.selected { z-index: 2; border-color: #ddd; background-color: #fff; color: #444; font-weight: 700 } .tab-row .tab .fa { margin-right: 0.1em; font-size: 0.875rem } /* tabs-container */ @@ -41,3 +41,19 @@ .tab-page .tab-header[data-toggle="collapse"]::after { float: right; content: "\f107"; font-family: FontAwesome; font-size: 1rem; line-height: 1em; color: #777; cursor: pointer; transition-duration: .3s } .tab-page .tab-header[data-toggle="collapse"].collapsed::after { transform: rotate(180deg) } .tab-page .tab-header[data-toggle="collapse"]:hover::after { color: #333 } +/* old style */ +.sectionBody .tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } +.sectionBody > .tab-pane > .tab-page { padding: 1.25rem; } +.tab-page > table { width: 100%; border-collapse: collapse } +.sectionBody .displayparams, .sectionBody .permissiongroup { margin-bottom: 0.15rem; background-color: #eee; border-collapse: separate; border-spacing: 1px; } +.sectionBody .displayparams th, .sectionBody .displayparams td { padding: 4px 4px; } +.sectionBody .displayparams thead td, .sectionBody .permissiongroup thead td { border-top: none; } +.sectionBody fieldset { background: none repeat scroll 0 0 #fdfdfd; border: 1px solid #ccc; padding: 1rem !important; } +.sectionBody legend { font-weight: 500; padding: 5px 1rem; background: #fff; border: 1px solid #ccc; -moz-box-shadow: 1px 1px 3px #ccc; -webkit-box-shadow: 1px 1px 3px #ccc; box-shadow: 1px 1px 3px #ccc; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } +.sectionBody fieldset h3 { font-size: 14px; color: #789; font-weight: 500; padding-bottom: 0; margin-bottom: 0; } +.showHideVisible { color: #333; margin: 0 1rem; padding: 5px 3px 5px; zoom: 1; font-weight: 500; text-shadow: 0 1px 0 #fff; } +.showHideVisible + .sectionBody { margin-top: -1px !important } +.sectionBody, .layerVisible { position: relative; } +.sectionBody > p:first-child { margin-left: 1rem; margin-right: 1rem } +.showHideVisible, .layerVisible { margin: 0 10px 4px; } +.sectionBody td, .sectionBody th { padding: 0.15rem 0.25rem; vertical-align: top; } diff --git a/manager/media/style/default/style.css b/manager/media/style/default/style.css index 983e16d319..a33f13d084 100644 --- a/manager/media/style/default/style.css +++ b/manager/media/style/default/style.css @@ -6,14 +6,6 @@ @import "css/tabpane.css"; @import "css/contextmenu.css"; /* -------------------------[ Misc stuff ]--- */ -.sectionBody fieldset { background: none repeat scroll 0 0 #fdfdfd; border: 1px solid #ccc; padding: 1rem !important; } -.sectionBody legend { font-weight: 500; padding: 5px 1rem; background: #fff; border: 1px solid #ccc; -moz-box-shadow: 1px 1px 3px #ccc; -webkit-box-shadow: 1px 1px 3px #ccc; box-shadow: 1px 1px 3px #ccc; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } -.sectionBody fieldset h3 { font-size: 14px; color: #789; font-weight: 500; padding-bottom: 0; margin-bottom: 0; } -.showHideVisible { color: #333; margin: 0 1rem; padding: 5px 3px 5px; zoom: 1; font-weight: 500; text-shadow: 0 1px 0 #fff; } -.showHideVisible + .sectionBody { margin-top: -1px !important } -.sectionBody, .layerVisible { position: relative; } -.sectionBody > p:first-child { margin-left: 1rem; margin-right: 1rem } -.showHideVisible, .layerVisible { margin: 0 10px 4px; } .comment { font-size: 11px; color: #999; padding: 4px 0; } .screen { border: 1px solid #ddd; text-align: center; } .even { background: #d9e7c2; } @@ -34,10 +26,6 @@ a.hometblink:hover { text-decoration: underline; color: Gray; }*/ .notice { width: 100%; padding: 5px; border: 1px solid #eee; background-color: #f5f5f5; color: #707070; } /* -------------------------[ Settings Table ]--- */ .filelist td { border-bottom: 1px solid #c2c3cf; } -/* -------------------------[ Tabs ]--- */ -.sectionBody .tab-page { clear: both; width: 100%; background-color: #fff; padding: 0; border: 0; border-radius: 0; box-shadow: 0 0 0.3rem 0 rgba(0, 0, 0, .1) } -.sectionBody > .tab-pane > .tab-page { padding: 1.25rem; } -.tab-page > table { width: 100%; border-collapse: collapse } /* -------------------------[ Welcome Page ]--- */ /*#mainActionPages { background: #f5f5f5; }*/ /* -------------------------[ New sortable table class ]--- */ @@ -55,15 +43,6 @@ a.hometblink:hover { text-decoration: underline; color: Gray; }*/ fieldset.tab-page { border: 1px solid #e4e4e4 !important; } h2#edit_document_title { font-size: 0.9rem; color: #f5f5f5; width: 100%; border-bottom: none; padding: 5px 10px; } fieldset#preview h2.tab { float: right; } -/* -------------------------[ Action Buttons ]--- */ -.actionButtons { margin: 0; padding: 0; background: none; width: auto; white-space: nowrap; } -.actionButtons li { float: left; margin: 0; padding: 0; list-style: none; } -.actionButtons li:before, .mmTagList li:before, .rTable li:before, .tab-pane ul li ul li:before, .dashboard li:before, div#idShowHideSocialBox.sectionBody > div.btn-group.ope > ul.dropdown-menu > li:before, .sectionBody .multitv .list li:before { display: none; content: ''; } -.actionButtons img { vertical-align: top; margin-top: 1px; filter: alpha(opacity=30); -moz-opacity: 0.3; opacity: 0.3; } -.actionButtons:hover img { filter: alpha(opacity=100); -moz-opacity: 1; opacity: 1; } -.actionButtons a:hover { border-color: #999; -moz-box-shadow: 1px 1px 2px #aaa; -webkit-box-shadow: 1px 1px 2px #aaa; box-shadow: 1px 1px 2px #aaa; -webkit-transition: all .3s ease; -moz-transition: all .3s ease; -o-transition: all .3s ease; transition: .3s ease; background: -moz-linear-gradient(#fff, #f5f5f5); background: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f5f5f5)); background: -o-linear-gradient(#fff, #f5f5f5); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#fff, endColorstr=#f5f5f5); -zoom: 1; text-decoration: none !important; } -.actionButtons a:active { background: #92aac4 bottom left; -webkit-box-shadow: 0 0 10px #b8c7d6; -moz-box-shadow: 0 0 10px #b8c7d6; box-shadow: 0 0 10px #b8c7d6; } /* * Generic styles for all form elements */ @@ -77,8 +56,8 @@ form#mutate .imageField { width: 50%; min-width: 300px; } form#mutate input[name="menuindex"] { text-align: center; width: 80px; padding-left: 0; padding-right: 0; } form#mutate input[name="ta"].inputBox { padding-left: 30px } form#mutate input[name="ta"].inputBox:focus + input[type=button], form#mutate input[name="ta"].inputBox:focus + .CodeMirror + input[type=button] { border-color: #1377c5 #1377c5 #1377c5 #bbb; } -form#mutate input[name^=tv].DatePicker, form#mutate input[name*=date].DatePicker, form#mutate input[name=createdon].DatePicker, form#mutate input[name=editedon].DatePicker { float: left; width: auto; padding-right: 2em } -form#mutate input[name^=tv].DatePicker + a, form#mutate input[name*=date].DatePicker + a { position: relative; z-index: 5; margin-top: 0.5em; margin-left: -1.5em; float: left; } +input[name^=tv].DatePicker, input[name*=date].DatePicker, input[name=createdon].DatePicker, input[name=editedon].DatePicker { float: left; width: auto; padding-right: 2em } +input[name^=tv].DatePicker + a, input[name*=date].DatePicker + a { position: relative; z-index: 5; margin-top: 0.5em; margin-left: -1.5em; float: left; } form#mutate textarea.tv_textareamini { height: 100px; width: 300px; overflow-y: scroll; } form#mutate textarea.tv_textarea { height: 100px; width: 100%; overflow-y: scroll; } form#mutate #llock { position: relative; z-index: 5; float: left; width: 1.9rem; height: 1.9rem; margin: 0 -2rem 0 0; line-height: 2rem; cursor: pointer; text-align: center; } @@ -110,10 +89,6 @@ fieldset.legacy h2 { width: 100%; background: #f5f5f5; margin: -10px -10px 1rem .phptextarea { font-family: Consolas, 'Courier New', 'Courier', monospace; } /* Custom */ /* normalize some td paddings */ -#tabTemplate tbody td, .sectionBody td, .sectionBody th { padding: 1px 5px; text-align: left; vertical-align: top; } -.sectionBody .displayparams, .sectionBody .permissiongroup { margin-bottom: 0.15rem; background-color: #eee; border-collapse: separate; border-spacing: 1px; } -.sectionBody .displayparams th, .sectionBody .displayparams td { padding: 4px 4px; } -.sectionBody .displayparams thead td, .sectionBody .permissiongroup thead td { border-top: none; } #displayparams table { background: #fff; } #displayparams table tbody td { border-bottom: 1px dotted #d3d3d3; } .permissiongroups { margin: 0; } @@ -136,7 +111,6 @@ code { font-size: inherit; font-family: Consolas, 'Courier New', 'Courier', mono table th { font-weight: 500; } .table--edit th { width: 200px; color: #555; font-size: inherit; } .table--edit input[type="text"], .table--edit input[type="password"], .table--edit input[type="number"], .table--edit textarea, .table--edit select, .settings input[type="text"], .settings input[type="password"], .settings input[type="number"], .settings textarea, .settings select { width: 300px; } -.table th, .table td, .sectionBody td, .sectionBody th { padding: 0.15rem 0.25rem; } /* * MODxRE2 styles * css above is original MODxRE @@ -210,36 +184,12 @@ ul.elements_buttonbar .fa { font-size: 0.875rem; padding: 1px 1px 0; } .resourceTable.flex ul.elements { } .resourceTable.flex ul.elements > li { overflow: hidden; /* fix for Firefox */ break-inside: avoid-column; -webkit-column-break-inside: avoid; -moz-column-break-inside: avoid; -o-column-break-inside: avoid; -ms-column-break-inside: avoid; column-break-inside: avoid; page-break-inside: avoid } .resourceTable.flex .elements_descr { display: block; margin-left: 1.5em; } -/* action buttons */ -.actionButtons a { float: left; padding: 5px 10px; height: 32px; font-size: 13px; font-weight: 500; } -.actionButtons a, .actionButtons li.primary a, .actionButtons a.primary, .actionButtons a.default { text-shadow: none; background: #fff; color: #555; border: 1px solid #e4e4e4; border-radius: 3px; /*box-shadow: 0 0 0 1px #E4E4E4;*/ box-shadow: none; transition: none; } -.actionButtons a:hover { background: #1377c5; box-shadow: none; border-color: #1377c5; color: #fff !important; transition: none; } -.actionButtons a:active { background-color: #3189ba; border-color: #3189ba; } -.actionButtons li.primary a, .actionButtons a.primary { color: #fff; border-color: #32ab9a; background: #32ab9a linear-gradient(#32ab9a, #00948e); } -.actionButtons li.primary a:hover, .actionButtons a.primary:hover { background: #2b9385 linear-gradient(#2b9385, #007571); border-color: #2b9385; } -.actionButtons li.primary a:active, .actionButtons a.primary:active { background: #32ab9a; border-color: #32ab9a; } -.actionButtons img { display: none; } -#treePane .actionButtons img { display: inline; } -.actionButtons--tableheader .fa { font-size: 14px; } -.sectionBody .actionButtons { padding-top: 0; min-height: 40px; } -.sectionBody .actionButtons li { margin-right: 10px; } -.sectionBody .actionButtons a { display: inline-block; padding: 9px 10px; line-height: 1; } #content_body #which_editor { margin-top: 12px; } /* resource children list */ #tabChildren .grid th, #tabChildren .grid tr > td:nth-child(5), #tabChildren .grid tr > td:nth-child(6) { text-align: center; white-space: nowrap } #tabChildren .grid td { text-align: right; white-space: nowrap } #tabChildren .grid tr > th:nth-child(2), #tabChildren .grid tr > td:nth-child(2) { text-align: left; white-space: normal } #tabChildren .grid tr > td:nth-child(6) a { padding: 0 .2em; font-size: 0.9rem; color: #444; } -table.actionButtons { margin-top: 1rem; margin-bottom: 10px; } -table.actionButtons img { display: inline-block; } -table.actionButtons .searchtext { padding: 5px; height: 24px; width: 150px; } -/* filter elements */ -.filterElements-form { margin-bottom: 10px; margin-top: 5px; } -.actionButtons .filterElements-form { margin-top: 0; margin-bottom: 0; } -.filterElements-form .form-control { display: block; width: 100%; max-width: 500px; font-size: 13px; } -.actionButtons .filterElements-form .form-control { width: 200px; height: 33px; padding-left: 8px; box-sizing: border-box; } -/* pagetitle-icon */ -.pagetitle-icon { margin-right: 2px; color: #1377c5; } /* element-edit-message */ .msg-container { padding-bottom: 10px; border-bottom: 1px solid #ededed; margin-bottom: 1rem; color: #777; } .btn-small { padding: 2px 4px !important; font-size: 11px !important; } @@ -248,16 +198,3 @@ table.actionButtons .searchtext { padding: 5px; height: 24px; width: 150px; } .modx-alert.alert-error { background-color: #ffd0d0; border: 1px solid #f00; color: #000; } tr.userIdle td { color: #aaa; } tr.userIdle td strong:before { font-family: "FontAwesome"; font-style: normal; font-weight: normal; color: #aaa; padding: 0 5px 0 0; content: '\f017'; } -#modxonline_widget td strong:before { font-family: "FontAwesome"; font-style: normal; font-weight: normal; color: #3d5764; padding: 0 5px 0 0; content: '\f2be'; } -#modxonline_widget td strong.userMultipleSessions:before { color: #bf4949; content: '\f2bd'; } -#modxonline_widget tr.userIdle td strong.userMultipleSessions:before { color: #bf4949; content: '\f017'; } -/*responsive buttons*/ -.actionButtons .fa { display: none; text-align: center; font-size: 1em; line-height: 1em; width: 1.1em; vertical-align: initial } -.sectionBody .actionButtons .fa, .actionButtons--eit .fa { display: inline-block; } -.optionsTitle .fa { display: inline-block; } -@media (max-width: 900px) { -.actionButtons a { display: inline-block; padding: 6px 10px } -.tab-page .actionButtons a { margin-top: 0 !important } -.actionButtons a span { display: none; } -.actionButtons a .fa { display: inline-block; } -} From 9832bbd39fac343575d0adf3b32411a2f0f2c402 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 18 Aug 2017 01:58:06 +0300 Subject: [PATCH 279/338] fix quickly filter elements disabled press enter --- manager/actions/resources/tab1_templates.inc.php | 2 +- manager/actions/resources/tab2_templatevars.inc.php | 2 +- manager/actions/resources/tab3_chunks.inc.php | 2 +- manager/actions/resources/tab4_snippets.inc.php | 2 +- manager/actions/resources/tab5_plugins.inc.php | 2 +- manager/actions/resources/tab6_categoryview.inc.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/manager/actions/resources/tab1_templates.inc.php b/manager/actions/resources/tab1_templates.inc.php index 15f8a1eae2..d33561a715 100644 --- a/manager/actions/resources/tab1_templates.inc.php +++ b/manager/actions/resources/tab1_templates.inc.php @@ -16,7 +16,7 @@
    - +
    "> "> diff --git a/manager/actions/resources/tab2_templatevars.inc.php b/manager/actions/resources/tab2_templatevars.inc.php index 0ec45d3cc8..0af5a39c34 100644 --- a/manager/actions/resources/tab2_templatevars.inc.php +++ b/manager/actions/resources/tab2_templatevars.inc.php @@ -20,7 +20,7 @@
    - +
    "> "> diff --git a/manager/actions/resources/tab3_chunks.inc.php b/manager/actions/resources/tab3_chunks.inc.php index a64768faaf..c2aceaa276 100644 --- a/manager/actions/resources/tab3_chunks.inc.php +++ b/manager/actions/resources/tab3_chunks.inc.php @@ -17,7 +17,7 @@
    - +
    "> "> diff --git a/manager/actions/resources/tab4_snippets.inc.php b/manager/actions/resources/tab4_snippets.inc.php index 2fe8e1fab5..afee07b694 100644 --- a/manager/actions/resources/tab4_snippets.inc.php +++ b/manager/actions/resources/tab4_snippets.inc.php @@ -17,7 +17,7 @@
    - +
    "> "> diff --git a/manager/actions/resources/tab5_plugins.inc.php b/manager/actions/resources/tab5_plugins.inc.php index 3f445f92ae..1cc600a879 100644 --- a/manager/actions/resources/tab5_plugins.inc.php +++ b/manager/actions/resources/tab5_plugins.inc.php @@ -17,7 +17,7 @@
    - +
    hasPermission('new_plugin')) { ?> "> diff --git a/manager/actions/resources/tab6_categoryview.inc.php b/manager/actions/resources/tab6_categoryview.inc.php index 22f1c06cc5..94b0601ae1 100644 --- a/manager/actions/resources/tab6_categoryview.inc.php +++ b/manager/actions/resources/tab6_categoryview.inc.php @@ -15,7 +15,7 @@
    - +
    "> "> From 15346ef7b8606fa6f9fb73f22d15fcae34323b0d Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 18 Aug 2017 02:09:48 +0300 Subject: [PATCH 280/338] update css default theme --- manager/media/style/default/css/custom.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index e938a6f498..d675163803 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -24,9 +24,10 @@ input[size="50"], select[size="50"] { width: 10rem !important } select[name=usergroup], select[name=docgroup] { margin: 0 0.5em; } select[name=docgroup] + input[type=submit] { float: none; margin: 0; } #settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype] { border-top-right-radius: 0; border-bottom-right-radius: 0 } -#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], input[name^=tv]:not([class^=mtv]) + input[type=button], input[name^=tv].DatePicker + a { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } +#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], #documentPane input[name^=tv]:not([class^=mtv]) + input[type=button], #documentPane input[name^=tv].DatePicker + a { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } #settingsPane [name=site_name], #settingsPane [name=txt_custom_contenttype], #settingsPane [name=filemanager_path], #settingsPane [name=rb_base_dir], input[name=photo], #range input#pids, input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } #range::after { content: ""; display: table; width: 100% } + /* [ Editor ] */ .navbar.navbar-editor { padding: .5rem 1.25rem; border-radius: 0 } .navbar-editor > label { margin-bottom: 0 } From 6b0154002b2c712f75c962f5c4f181b82bd76d46 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Fri, 18 Aug 2017 03:14:58 +0300 Subject: [PATCH 281/338] fix DocManager which_browser for tvars add DatePicker format code --- assets/modules/docmanager/templates/main.tpl | 8 + assets/modules/docmanager/tv.ajax.php | 341 ++++++++++--------- 2 files changed, 184 insertions(+), 165 deletions(-) diff --git a/assets/modules/docmanager/templates/main.tpl b/assets/modules/docmanager/templates/main.tpl index ef039085cb..81d9b610cc 100644 --- a/assets/modules/docmanager/templates/main.tpl +++ b/assets/modules/docmanager/templates/main.tpl @@ -26,6 +26,14 @@ } document.getElementById('results').innerHTML = this.response; document.getElementById('tvloading').style.display = 'none'; + var DatePickers = document.querySelectorAll('input.DatePicker'); + if (DatePickers) { + for (var i = 0; i < DatePickers.length; i++) { + new DatePicker(DatePickers[i], { + yearOffset: dpOffset, format: dpformat, dayNames: dpdayNames, monthNames: dpmonthNames, startDay: dpstartDay, + }); + } + } } }; xhr.send('theme=[+theme+]&tplID=' + tplId); diff --git a/assets/modules/docmanager/tv.ajax.php b/assets/modules/docmanager/tv.ajax.php index 4477a03ea7..35ea6dd2ba 100644 --- a/assets/modules/docmanager/tv.ajax.php +++ b/assets/modules/docmanager/tv.ajax.php @@ -5,10 +5,10 @@ include_once("../../cache/siteManager.php"); -require_once '../../../'.MGR_DIR.'/includes/protect.inc.php'; -include_once ('../../../'.MGR_DIR.'/includes/config.inc.php'); -include_once (MODX_MANAGER_PATH.'includes/document.parser.class.inc.php'); -include_once (MODX_BASE_PATH.'assets/modules/docmanager/classes/docmanager.class.php'); +require_once '../../../' . MGR_DIR . '/includes/protect.inc.php'; +include_once('../../../' . MGR_DIR . '/includes/config.inc.php'); +include_once(MODX_MANAGER_PATH . 'includes/document.parser.class.inc.php'); +include_once(MODX_BASE_PATH . 'assets/modules/docmanager/classes/docmanager.class.php'); $modx = new DocumentParser; $modx->getSettings(); @@ -16,153 +16,161 @@ $dm->getLang(); $dm->getTheme(); - $output = ''; +$output = ''; - if(isset($_POST['tplID']) && is_numeric($_POST['tplID'])) { - $rs = $modx->db->select( - '*', - $modx->getFullTableName('site_tmplvars')." tv - LEFT JOIN ".$modx->getFullTableName('site_tmplvar_templates')." AS tvt ON tv.id = tvt.tmplvarid", - "tvt.templateid ='{$_POST['tplID']}'" - ); - $limit = $modx->db->getRecordCount($rs); +$which_browser = $modx->configGlobal['which_browser'] ? $modx->configGlobal['which_browser'] : $modx->config['which_browser']; - if ($limit > 0) { - require (MODX_MANAGER_PATH.'includes/tmplvars.commands.inc.php'); - $output.= ""; +if (isset($_POST['tplID']) && is_numeric($_POST['tplID'])) { + $rs = $modx->db->select('*', $modx->getFullTableName('site_tmplvars') . " tv + LEFT JOIN " . $modx->getFullTableName('site_tmplvar_templates') . " AS tvt ON tv.id = tvt.tmplvarid", "tvt.templateid ='{$_POST['tplID']}'"); + $limit = $modx->db->getRecordCount($rs); - $i = 0; - while ($row = $modx->db->getRow($rs)) { + if ($limit > 0) { + require(MODX_MANAGER_PATH . 'includes/tmplvars.commands.inc.php'); + $output .= "
    "; - if($i++>0) $output .= ''; + $i = 0; + while ($row = $modx->db->getRow($rs)) { - $output.=' + if ($i++ > 0) { + $output .= ''; + } + + $output .= ''; - } - $output.='
    -  '.$row['caption'].'
    '.$row['description'].' +  ' . $row['caption'] . '
    ' . $row['description'] . '
    '; - $base_url = str_replace("assets/modules/docmanager/", "", MODX_BASE_URL); - $output.= renderFormElement($row['type'], $row['id'], $row['default_text'], $row['elements'], $row['value'], ' style="width:300px;"'); - $output.= '
    '; - //$output.= '
    '.$dm->lang['DM_tv_ignore_tv'].' '; - } else { - print $dm->lang['DM_tv_no_tv']; - } - - print $output; - } else { - print ''; - } + $base_url = str_replace("assets/modules/docmanager/", "", MODX_BASE_URL); + $output .= renderFormElement($row['type'], $row['id'], $row['default_text'], $row['elements'], $row['value'], ' style="width:300px;"'); + $output .= '
    '; + //$output.= '
    '.$dm->lang['DM_tv_ignore_tv'].' '; + } else { + print $dm->lang['DM_tv_no_tv']; + } + print $output; +} else { + print ''; +} -function renderFormElement($field_type, $field_id, $default_text, $field_elements, $field_value, $field_style='') { - global $modx; - global $dm; - global $base_url; - global $rb_base_url; +function renderFormElement($field_type, $field_id, $default_text, $field_elements, $field_value, $field_style = '') +{ + global $modx; + global $dm; + global $base_url; + global $rb_base_url; - $field_html =''; - $field_value = ($field_value!="" ? $field_value : $default_text); + $field_html = ''; + $field_value = ($field_value != "" ? $field_value : $default_text); - switch ($field_type) { - case "text": // handler for regular text boxes - case "rawtext"; // non-htmlentity converted text boxes - case "email": // handles email input fields - case "number": // handles the input of numbers - $field_html .= ''; - break; - case "textareamini": // handler for textarea mini boxes - $field_html .= ''; - break; - case "textarea": // handler for textarea boxes - case "rawtextarea": // non-htmlentity convertex textarea boxes - case "htmlarea": // handler for textarea boxes (deprecated) - case "richtext": // handler for textarea boxes - $field_html .= ''; - break; - case "date": - $field_id = str_replace(array('-', '.'),'_', urldecode($field_id)); - if($field_value=='') $field_value=0; - $field_html .= ''; - $field_html .= ' No date'; + switch ($field_type) { + case "text": // handler for regular text boxes + case "rawtext"; // non-htmlentity converted text boxes + case "email": // handles email input fields + case "number": // handles the input of numbers + $field_html .= ''; + break; + case "textareamini": // handler for textarea mini boxes + $field_html .= ''; + break; + case "textarea": // handler for textarea boxes + case "rawtextarea": // non-htmlentity convertex textarea boxes + case "htmlarea": // handler for textarea boxes (deprecated) + case "richtext": // handler for textarea boxes + $field_html .= ''; + break; + case "date": + $field_id = str_replace(array('-', '.'), '_', urldecode($field_id)); + if ($field_value == '') { + $field_value = 0; + } + $field_html .= ''; + $field_html .= ' No date'; - break; - case "dropdown": // handler for select boxes - $field_html .= '"; - break; - case "listbox": // handler for select boxes - $field_html .= '"; - break; - case "listbox-multiple": // handler for select boxes where you can choose multiple items - $field_value = explode("||",$field_value); - $field_html .= '"; - break; - case "url": // handles url input fields - $urls= array(''=>'--', 'http://'=>'http://', 'https://'=>'https://', 'ftp://'=>'ftp://', 'mailto:'=>'mailto:'); - $field_html ='
    '; - $field_html .= '
    '; - break; - case "checkbox": // handles check boxes - $field_value = !is_array($field_value) ? explode("||",$field_value) : $field_value; - $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id)); - static $i=0; - while (list($item, $itemvalue) = each ($index_list)) - { - list($item,$itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==",$itemvalue); - if (strlen($itemvalue)==0) $itemvalue = $item; - $field_html .= '
    '; - $i++; - } - break; - case "option": // handles radio buttons - $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id)); - while (list($item, $itemvalue) = each ($index_list)) - { - list($item,$itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==",$itemvalue); - if (strlen($itemvalue)==0) $itemvalue = $item; - $field_html .= ''.$item.'
    '; - } - break; - case "image": // handles image fields using htmlarea image manager - global $ResourceManagerLoaded; - global $content,$use_editor,$which_editor,$which_browser; - if (!$ResourceManagerLoaded && !(($content['richtext']==1 || $_GET['a']==4) && $use_editor==1 && $which_editor==3)){ - $field_html .=" + break; + case "dropdown": // handler for select boxes + $field_html .= '"; + break; + case "listbox": // handler for select boxes + $field_html .= '"; + break; + case "listbox-multiple": // handler for select boxes where you can choose multiple items + $field_value = explode("||", $field_value); + $field_html .= '"; + break; + case "url": // handles url input fields + $urls = array('' => '--', 'http://' => 'http://', 'https://' => 'https://', 'ftp://' => 'ftp://', 'mailto:' => 'mailto:'); + $field_html = '
    '; + $field_html .= '
    '; + break; + case "checkbox": // handles check boxes + $field_value = !is_array($field_value) ? explode("||", $field_value) : $field_value; + $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id)); + static $i = 0; + while (list($item, $itemvalue) = each($index_list)) { + list($item, $itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==", $itemvalue); + if (strlen($itemvalue) == 0) { + $itemvalue = $item; + } + $field_html .= '
    '; + $i++; + } + break; + case "option": // handles radio buttons + $index_list = ParseIntputOptions(ProcessTVCommand($field_elements, $field_id)); + while (list($item, $itemvalue) = each($index_list)) { + list($item, $itemvalue) = (is_array($itemvalue)) ? $itemvalue : explode("==", $itemvalue); + if (strlen($itemvalue) == 0) { + $itemvalue = $item; + } + $field_html .= '' . $item . '
    '; + } + break; + case "image": // handles image fields using htmlarea image manager + global $ResourceManagerLoaded; + global $content, $use_editor, $which_editor, $which_browser; + if (!$ResourceManagerLoaded && !(($content['richtext'] == 1 || $_GET['a'] == 4) && $use_editor == 1 && $which_editor == 3)) { + $field_html .= " "; - $ResourceManagerLoaded = true; - } - $field_html .=' '; - break; - case "file": // handles the input of file uploads - /* Modified by Timon for use with resource browser */ - global $ResourceManagerLoaded; - global $content,$use_editor,$which_editor; - if (!$ResourceManagerLoaded && !(($content['richtext']==1 || $_GET['a']==4) && $use_editor==1 && $which_editor==3)){ - /* I didn't understand the meaning of the condition above, so I left it untouched ;-) */ - $field_html .=" + $ResourceManagerLoaded = true; + } + $field_html .= ' '; + break; + case "file": // handles the input of file uploads + /* Modified by Timon for use with resource browser */ + global $ResourceManagerLoaded; + global $content, $use_editor, $which_editor, $which_browser; + if (!$ResourceManagerLoaded && !(($content['richtext'] == 1 || $_GET['a'] == 4) && $use_editor == 1 && $which_editor == 3)) { + /* I didn't understand the meaning of the condition above, so I left it untouched ;-) */ + $field_html .= " "; - $ResourceManagerLoaded = true; - } - $field_html .=' '; + $ResourceManagerLoaded = true; + } + $field_html .= ' '; - break; - default: // the default handler -- for errors, mostly - $field_html .= ''; - } // end switch statement - return $field_html; + break; + default: // the default handler -- for errors, mostly + $field_html .= ''; + } // end switch statement + return $field_html; } // end renderFormElement function -function ParseIntputOptions($v) { - global $modx; - $a = array(); - if(is_array($v)) return $v; - else if($modx->db->isResult($v)) { - $a = $modx->db->makeArray($v); - } - else $a = explode("||", $v); - return $a; +function ParseIntputOptions($v) +{ + global $modx; + $a = array(); + if (is_array($v)) { + return $v; + } else if ($modx->db->isResult($v)) { + $a = $modx->db->makeArray($v); + } else { + $a = explode("||", $v); + } + return $a; } From 2e8a052d3005cf3773d4c6c3a64a974b3f4ffda3 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Fri, 18 Aug 2017 15:55:04 +0900 Subject: [PATCH 282/338] Fix - mm_widget_showimagetvs by https url https://example.com/image.jpg --- .../widgets/showimagetvs/jquery.ddMM.mm_widget_showimagetvs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/plugins/managermanager/widgets/showimagetvs/jquery.ddMM.mm_widget_showimagetvs.js b/assets/plugins/managermanager/widgets/showimagetvs/jquery.ddMM.mm_widget_showimagetvs.js index 691a15fbf6..b8332bb63e 100755 --- a/assets/plugins/managermanager/widgets/showimagetvs/jquery.ddMM.mm_widget_showimagetvs.js +++ b/assets/plugins/managermanager/widgets/showimagetvs/jquery.ddMM.mm_widget_showimagetvs.js @@ -67,7 +67,7 @@ $.fn.mm_widget_showimagetvs = function(params){ $this.data('lastvalue', url); - if (url.length > 0 && url.search(/http:\/\//i) == -1 && url.search(/\//) != 0){ + if (url.length > 0 && url.search(/https?:\/\//i) == -1 && url.search(/\//) != 0){ url = $.ddMM.config.site_url + url; } // If we have a PHPThumb URL From 0dc8d416b2acf96563586d985f9bed016ef5b558 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sat, 19 Aug 2017 20:58:54 +0300 Subject: [PATCH 283/338] update forms.css change color radio and checkbox --- manager/media/style/default/css/forms.css | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/manager/media/style/default/css/forms.css b/manager/media/style/default/css/forms.css index 5a3daa73e2..11020f1855 100644 --- a/manager/media/style/default/css/forms.css +++ b/manager/media/style/default/css/forms.css @@ -4,14 +4,14 @@ label { cursor: pointer; display: inline-block; margin-bottom: .5em } label:not([for]) { cursor: default } button, input { margin: 0; padding: 0; border: none; font: inherit; line-height: normal; } input[type=checkbox], input[type=radio] { width: 0.8125rem !important; height: 0.8125rem !important; margin-right: 0.25em; vertical-align: -0.15em; border-radius: .1rem; border: 1px solid #d4d4d4; background: #fff no-repeat center -1em; outline: none; transition: border-color .2s, background-position .1s; } -input[type=checkbox] { background: #fff url('data:image/svg+xml;utf8,%3Csvg width=".675em" height=".675em" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68z" fill="%23000"/%3E%3C/svg%3E') no-repeat center -1em; } -input[type=radio] { background: #fff url('data:image/svg+xml;utf8,%3Csvg width="0.538461em" height="0.538461em" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M1664 896q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z" fill="%23000"/%3E%3C/svg%3E') no-repeat center -1em; border-radius: 50% } +input[type=checkbox] { background: #fff url('data:image/svg+xml;utf8,%3Csvg width=".675em" height=".675em" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68z" fill="%23444"/%3E%3C/svg%3E') no-repeat center -1em; } +input[type=radio] { background: #fff url('data:image/svg+xml;utf8,%3Csvg width="0.538461em" height="0.538461em" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M1664 896q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z" fill="%23444"/%3E%3C/svg%3E') no-repeat center -1em; border-radius: 50% } input[type=checkbox]:hover, input[type=radio]:hover { border-color: #bcbcbc } input[type=checkbox]:active, input[type=radio]:active { background-color: #fafafa; } input[type=checkbox]:focus, input[type=radio]:focus { border-color: #4d8ef9 !important; box-shadow: 0 0 0 1px rgba(77, 142, 249, 0.5) } input[type=checkbox]:checked { background-position: center 0 } input[type=radio]:checked { background-position: center 0.06850975em } -button, input, optgroup, select, textarea { position: relative; font-family: sans-serif; font-size: 0.8125rem; line-height: 1.23076923; margin: 0; -webkit-appearance: none; -moz-appearance: none; -ms-appearance: none; appearance: none !important; } +button, input, optgroup, select, textarea { position: relative; font-family: sans-serif; font-size: 0.8125rem; line-height: 1.23076923; margin: 0; -webkit-appearance: none; -moz-appearance: none; } .form-control, input[type=text]:not(.form-control), input[type=password], input[type=number], input[type=email], input[type=date], input[type=url], input[type=search], select, textarea { display: inline-block; width: 100%; max-width: 100%; padding: 0.46153846em .5em; line-height: 1.23076923; vertical-align: inherit; font-size: 0.8125rem; color: #464a4c; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #d4d4d4; border-radius: .1em; -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .form-control:focus, input:not([type=radio]):not([type=checkbox]):focus, select:focus, textarea:focus, .btn.focus, .btn:focus { z-index: 3; outline-offset: -1px; outline: rgba(77, 142, 249, 0.5) solid 2px; border-color: #66afe9; } input:not([type=button]):not([type=submit]):hover:not(:focus), select:hover:not(:focus), textarea:hover:not(:focus) { border-color: #bbb; transition: border-color 0s, background-position .1s; } @@ -34,6 +34,8 @@ textarea, textarea.form-control { width: 100%; line-height: 1.5; overflow: auto; select:not([size]):not([multiple]), select[size="1"] { padding-right: 2em !important; background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMS41ZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMzk1IDczNnEwIDEzLTEwIDIzbC00NjYgNDY2cS0xMCAxMC0yMyAxMHQtMjMtMTBsLTQ2Ni00NjZxLTEwLTEwLTEwLTIzdDEwLTIzbDUwLTUwcTEwLTEwIDIzLTEwdDIzIDEwbDM5MyAzOTMgMzkzLTM5M3ExMC0xMCAyMy0xMHQyMyAxMGw1MCA1MHExMCAxMCAxMCAyM3oiLz48L3N2Zz4=') !important; background-repeat: no-repeat; background-position: right center; } optgroup { font-style: normal; font-weight: 500; background-color: #ddd; } optgroup option { font-weight: normal; background-color: #fff; } +input[type=color] { width: 2.308em; height: 2.308em; -webkit-appearance: menulist; -moz-appearance: menupopup } +input[type=range] { -webkit-appearance: slider-horizontal; -moz-appearance: initial; } .input-group-addon { padding: 0.46153846em .75em; font-size: 0.8125rem; border: 1px solid rgba(0, 0, 0, .15); border-radius: .1em; } .form-control.dropdown-item:focus, .form-control.dropdown-item:hover { background-color: inherit } ::-ms-value { border: none; margin: 0; padding: 0 0 1px; line-height: 1 } From afb7b0d76c9cf86b92867a0017e5a617eaa14e19 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sun, 20 Aug 2017 00:05:51 +0300 Subject: [PATCH 284/338] refactor datePicker javascript es2015 standard for job in IE11 --- manager/media/calendar/datepicker.js | 597 +++++++++++++++------------ 1 file changed, 341 insertions(+), 256 deletions(-) diff --git a/manager/media/calendar/datepicker.js b/manager/media/calendar/datepicker.js index 3c37abf0ee..b14690e860 100644 --- a/manager/media/calendar/datepicker.js +++ b/manager/media/calendar/datepicker.js @@ -1,125 +1,188 @@ 'use strict'; -class DatePicker -{ - constructor(dp, options) - { - let self = this; - this.dayChars = 1; - this.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; - this.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - this.format = 'dd-mm-yyyy hh:mm:00'; - this.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - this.startDay = 7; - this.yearOrder = 'asc'; - this.yearRange = 10; - this.yearStart = (new Date().getFullYear()); - this.yearOffset = -10; - this.error = ''; - options = options || []; - dp.options = { - monthNames: (options.monthNames && options.monthNames.length === 12 ? options.monthNames : this.monthNames) || this.monthNames, daysInMonth: (options.daysInMonth && options.daysInMonth.length === 12 ? options.daysInMonth : this.daysInMonth) || this.daysInMonth, dayNames: (options.dayNames && options.dayNames.length === 7 ? options.dayNames : this.dayNames) || this.dayNames, startDay: options.startDay || this.startDay, dayChars: options.dayChars || this.dayChars, format: options.format || this.format, yearStart: options.yearStart || this.yearStart, yearRange: options.yearRange || this.yearRange, yearOrder: options.yearOrder || this.yearOrder, yearOffset: options.yearOffset || this.yearOffset, - }; - dp.id = dp.name; - dp.autocomplete = 'off'; - dp = DatePicker.getValue(dp); - dp.lastValidDate = dp.value; - dp.oldYear = dp.year = dp.then.getFullYear(); - dp.oldMonth = dp.month = dp.then.getMonth(); - dp.oldDay = dp.then.getDate(); - dp.nowYear = dp.today.getFullYear(); - dp.nowMonth = dp.today.getMonth(); - dp.nowDay = dp.today.getDate(); - dp.container = false; - dp.calendar = false; - dp.interval = null; - dp.active = false; - dp.onclick = dp.onfocus = function() { - DatePicker.create(dp, self); - }; +var _createClass = function() { + function defineProperties(target, props) + { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) { + descriptor.writable = true; + } + Object.defineProperty(target, descriptor.key, descriptor); } + } - static getValue(dp) - { - if (dp.value !== '') { - if (dp.options.format === 'dd-mm-YYYY hh:mm:00' || dp.options.format === 'dd-mm-YYYY') { - let dateVals = dp.value.split(' '); - let dateParts = dateVals[0].split('-'); - dp.thenvalue = dateParts[1] + '/' + dateParts[0] + '/' + dateParts[2]; - if (dateVals[1]) { - dp.thenvalue = dp.thenvalue + ' ' + dateVals[1]; - } - } else { - dp.thenvalue = dp.value; - } - dp.then = new Date(dp.thenvalue); - dp.today = new Date(); - } else { - dp.thenvalue = dp.then = dp.today = new Date(); - dp.thenvalue = dp.then; - } - return dp; + return function(Constructor, protoProps, staticProps) { + if (protoProps) { + defineProperties(Constructor.prototype, protoProps); } + if (staticProps) { + defineProperties(Constructor, staticProps); + } + return Constructor; + }; +}(); - static updateValue(dp) - { - let el = document.querySelector('td.dp_selected'); - let ds; - if (el) { - ds = el.axis.split('|'); - let formatted = DatePicker.formatValue(dp, ds[0], ds[1], ds[2]); - if (formatted !== '') { - dp.value = formatted; - dp.lastValidDate = formatted; - } - this.dp.dirty = true; - } +var DatePicker = function() { + function DatePicker(dp, options) + { + if (!(this instanceof DatePicker)) { + throw new TypeError('Cannot call a class as a function'); } - static alertError(dp) + var self = this; + this.dayChars = 1; + this.dayNames = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; + this.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + this.format = 'dd-mm-yyyy hh:mm:00'; + this.monthNames = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ]; + this.startDay = 7; + this.yearOrder = 'asc'; + this.yearRange = 10; + this.yearStart = new Date().getFullYear(); + this.yearOffset = -10; + this.error = ''; + options = options || []; + dp.options = { + monthNames: (options.monthNames && options.monthNames.length === 12 + ? options.monthNames + : this.monthNames) || this.monthNames, + daysInMonth: (options.daysInMonth && options.daysInMonth.length === 12 + ? options.daysInMonth + : this.daysInMonth) || this.daysInMonth, + dayNames: (options.dayNames && options.dayNames.length === 7 + ? options.dayNames + : this.dayNames) || this.dayNames, + startDay: options.startDay || this.startDay, + dayChars: options.dayChars || this.dayChars, + format: options.format || this.format, + yearStart: options.yearStart || this.yearStart, + yearRange: options.yearRange || this.yearRange, + yearOrder: options.yearOrder || this.yearOrder, + yearOffset: options.yearOffset || this.yearOffset, + }; + dp.id = dp.name; + dp.autocomplete = 'off'; + dp = DatePicker.getValue(dp); + dp.lastValidDate = dp.value; + dp.oldYear = dp.year = dp.then.getFullYear(); + dp.oldMonth = dp.month = dp.then.getMonth(); + dp.oldDay = dp.then.getDate(); + dp.nowYear = dp.today.getFullYear(); + dp.nowMonth = dp.today.getMonth(); + dp.nowDay = dp.today.getDate(); + dp.container = false; + dp.calendar = false; + dp.interval = null; + dp.active = false; + dp.onclick = dp.onfocus = function() { + DatePicker.create(dp, self); + }; + } + + _createClass(DatePicker, null, [ { + key: 'getValue', value: function getValue(dp) { + if (dp.value !== '') { + if (dp.options.format === 'dd-mm-YYYY hh:mm:00' || + dp.options.format === 'dd-mm-YYYY') { + var dateVals = dp.value.split(' '); + var dateParts = dateVals[0].split('-'); + dp.thenvalue = dateParts[1] + '/' + dateParts[0] + '/' + dateParts[2]; + if (dateVals[1]) { + dp.thenvalue = dp.thenvalue + ' ' + dateVals[1]; + } + } else { + dp.thenvalue = dp.value; + } + dp.then = new Date(dp.thenvalue); + dp.today = new Date(); + } else { + dp.thenvalue = dp.then = dp.today = new Date(); + dp.thenvalue = dp.then; + } + return dp; + }, + }, { + key: 'updateValue', value: function updateValue(dp) { + var el = document.querySelector('td.dp_selected'); + var ds = void 0; + if (el) { + ds = el.axis.split('|'); + var formatted = DatePicker.formatValue(dp, ds[0], ds[1], ds[2]); + if (formatted !== '') { + dp.value = formatted; + dp.lastValidDate = formatted; + } + this.dp.dirty = true; + } + }, + }, { + key: 'alertError', value: function alertError(dp) { if (typeof dp.error !== 'undefined' && dp.error !== '') { - alert(dp.error); - dp.error = ''; + alert(dp.error); + dp.error = ''; } - } - - static hasChild(a, b) - { - let parent = a.parentNode; + }, + }, { + key: 'hasChild', value: function hasChild(a, b) { + var parent = a.parentNode; while (parent && parent !== document.body) { - if (parent === b) { - return parent; - } else { - parent = parent.parentNode; - } + if (parent === b) { + return parent; + } else { + parent = parent.parentNode; + } } return null; - } - - static close(e) - { + }, + }, { + key: 'close', value: function close(e) { if (!document.getElementById(this.dp.id + 'dp_container')) { - return; + return; } - let clickOutside = (e.target && e.target !== this.dp && e.target !== this.dp.container && !(DatePicker.hasChild(e.target, this.dp.container))); + var clickOutside = e.target && e.target !== this.dp && e.target !== + this.dp.container && + !DatePicker.hasChild(e.target, this.dp.container); if (clickOutside) { - if (this.dp.dirty) { - this.updateValue(this.dp); - DatePicker.alertError(this.dp); - } - DatePicker.remove(this.dp); + if (this.dp.dirty) { + this.updateValue(this.dp); + DatePicker.alertError(this.dp); + } + DatePicker.remove(this.dp); } - } - - static create(dp) - { - let y; - let self = this; + }, + }, { + key: 'create', value: function create(dp) { + var y = void 0; + var self = this; dp = DatePicker.getValue(dp); this.dp = dp; if (dp.calendar) { - return false; + return false; } this.dp.dirty = false; dp.container = document.createElement('div'); @@ -127,246 +190,268 @@ class DatePicker dp.container.id = dp.id + 'dp_container'; document.body.appendChild(dp.container); document.onmousedown = function(e) { - DatePicker.close(e); + DatePicker.close(e); }; document.onkeydown = function(e) { - if ((e.code === 9 && !e.shift) || e.code === 27 || e.code === 13) { - if (e.code === 13 && dp.container) { - e.preventDefault ? e.preventDefault() : (e.returnValue = false); - if (self.dp.dirty) { - self.updateValue(dp); - } - DatePicker.remove(self.dp); - DatePicker.alertError(self.dp); - } else { - DatePicker.remove(self.dp); - } + if (e.code === 9 && !e.shift || e.code === 27 || e.code === 13) { + if (e.code === 13 && dp.container) { + e.preventDefault ? e.preventDefault() : e.returnValue = false; + if (self.dp.dirty) { + self.updateValue(dp); + } + DatePicker.remove(self.dp); + DatePicker.alertError(self.dp); + } else { + DatePicker.remove(self.dp); } + } }; dp.calendar = document.createElement('div'); dp.calendar.className = 'dp_cal'; dp.container.appendChild(dp.calendar); - let date = new Date(); - if ((dp.month >= 0) && dp.year) { - date.setFullYear(dp.year, dp.month, 1); + var date = new Date(); + if (dp.month >= 0 && dp.year) { + date.setFullYear(dp.year, dp.month, 1); } else { - dp.month = parseInt(date.getMonth()); - dp.year = parseInt(date.getFullYear()); - date.setDate(1); + dp.month = parseInt(date.getMonth()); + dp.year = parseInt(date.getFullYear()); + date.setDate(1); } - dp.year % 4 === 0 ? dp.options.daysInMonth[1] = 29 : dp.options.daysInMonth[1] = 28; - let firstDay = (1 - (7 + date.getDay() - dp.options.startDay) % 7); - let monthSel = document.createElement('select'); + dp.year % 4 === 0 + ? dp.options.daysInMonth[1] = 29 + : dp.options.daysInMonth[1] = 28; + var firstDay = 1 - (7 + date.getDay() - dp.options.startDay) % 7; + var monthSel = document.createElement('select'); monthSel.id = dp.id + '_monthSelect'; - for (let m = 0; m < dp.options.monthNames.length; m++) { - monthSel.options[m] = new Option(dp.options.monthNames[m], m); - if (parseInt(dp.month) === m) { - monthSel.options[m].selected = true; - } + for (var m = 0; m < dp.options.monthNames.length; m++) { + monthSel.options[m] = new Option(dp.options.monthNames[m], m); + if (parseInt(dp.month) === m) { + monthSel.options[m].selected = true; + } } - let yearSel = document.createElement('select'); + var yearSel = document.createElement('select'); yearSel.id = dp.id + '_yearSelect'; - let i = 0; + var i = 0; if (!dp.options.yearStart) { - dp.options.yearStart = date.getFullYear(); + dp.options.yearStart = date.getFullYear(); } if (dp.options.yearOrder === 'desc') { - for (y = dp.options.yearStart - dp.options.yearOffset; y > (dp.options.yearStart - dp.options.yearRange - 1); y--) { - yearSel.options[i] = new Option(y, y); - if (parseInt(dp.year) === y) { - yearSel.options[i].selected = true; - } - i++; + for (y = dp.options.yearStart - dp.options.yearOffset; y > + dp.options.yearStart - dp.options.yearRange - 1; y--) { + yearSel.options[i] = new Option(y, y); + if (parseInt(dp.year) === y) { + yearSel.options[i].selected = true; } + i++; + } } else { - for (y = dp.options.yearStart + dp.options.yearOffset; y < (dp.options.yearStart + dp.options.yearRange + 1); y++) { - yearSel.options[i] = new Option(y, y); - if (parseInt(dp.year) === y) { - yearSel.options[i].selected = true; - } - i++; + for (y = dp.options.yearStart + dp.options.yearOffset; y < + dp.options.yearStart + dp.options.yearRange + 1; y++) { + yearSel.options[i] = new Option(y, y); + if (parseInt(dp.year) === y) { + yearSel.options[i].selected = true; } + i++; + } } - let time; + var time = void 0; if (!dp.time) { - let d = new Date(dp.thenvalue); - let minutes = d.getMinutes(); - if (minutes < 10) { - minutes = '0' + minutes; - } - time = d.getHours() + ':' + minutes; + var d = new Date(dp.thenvalue); + var minutes = d.getMinutes(); + if (minutes < 10) { + minutes = '0' + minutes; + } + time = d.getHours() + ':' + minutes; } else { - time = dp.time; + time = dp.time; } - let timeTextBox = document.createElement('input'); + var timeTextBox = document.createElement('input'); timeTextBox.id = dp.id + '_timeTextBox'; timeTextBox.className = 'cal_timeTextBox'; timeTextBox.type = 'text'; timeTextBox.value = time; - let submitButton = document.createElement('button'); + var submitButton = document.createElement('button'); submitButton.id = dp.id + '_submit'; submitButton.className = 'cal_submit btn btn-secondary'; submitButton.innerHTML = 'OK'; - let calTable = document.createElement('table'); - let calTableThead = document.createElement('thead'); - let calSelRow = document.createElement('tr'); - let calSelCell = document.createElement('th'); + var calTable = document.createElement('table'); + var calTableThead = document.createElement('thead'); + var calSelRow = document.createElement('tr'); + var calSelCell = document.createElement('th'); calSelCell.colSpan = 7; calSelCell.appendChild(monthSel); calSelCell.appendChild(yearSel); calSelRow.appendChild(calSelCell); calTableThead.appendChild(calSelRow); - let calTableTbody = document.createElement('tbody'); - let calDayNameRow = document.createElement('tr'); - let calDayNameCell; + var calTableTbody = document.createElement('tbody'); + var calDayNameRow = document.createElement('tr'); + var calDayNameCell = void 0; for (i = 0; i < dp.options.dayNames.length; i++) { - calDayNameCell = document.createElement('th'); - calDayNameCell.innerHTML = dp.options.dayNames[(dp.options.startDay + i) % 7].substr(0, dp.options.dayChars); - calDayNameRow.appendChild(calDayNameCell); + calDayNameCell = document.createElement('th'); + calDayNameCell.innerHTML = dp.options.dayNames[(dp.options.startDay + + i) % 7].substr(0, dp.options.dayChars); + calDayNameRow.appendChild(calDayNameCell); } calTableTbody.appendChild(calDayNameRow); - let calDayRow; - let calDayCell; + var calDayRow = void 0; + var calDayCell = void 0; while (firstDay <= dp.options.daysInMonth[dp.month]) { - calDayRow = document.createElement('tr'); - for (i = 0; i < 7; i++) { - calDayCell = document.createElement('td'); - if ((firstDay <= dp.options.daysInMonth[dp.month]) && (firstDay > 0)) { - calDayCell.className = dp.id + '_calDay'; - calDayCell.axis = dp.year + '|' + (parseInt(dp.month) + 1) + '|' + firstDay; - calDayCell.innerHTML = firstDay; - } else { - calDayCell.className = 'dp_empty'; - calDayCell.innerHTML = ' '; - } - calDayRow.appendChild(calDayCell); - if ((firstDay === parseInt(dp.oldDay)) && (dp.month === dp.oldMonth) && (dp.year === dp.oldYear)) { - calDayCell.classList.add('dp_selected'); - } - if ((firstDay === dp.nowDay) && (parseInt(dp.month) === dp.nowMonth) && (parseInt(dp.year) === dp.nowYear)) { - calDayCell.classList.add('dp_today'); - } - firstDay++; + calDayRow = document.createElement('tr'); + for (i = 0; i < 7; i++) { + calDayCell = document.createElement('td'); + if (firstDay <= dp.options.daysInMonth[dp.month] && firstDay > 0) { + calDayCell.className = dp.id + '_calDay'; + calDayCell.axis = dp.year + '|' + (parseInt(dp.month) + 1) + '|' + + firstDay; + calDayCell.innerHTML = firstDay; + } else { + calDayCell.className = 'dp_empty'; + calDayCell.innerHTML = ' '; } - calTableTbody.appendChild(calDayRow); + calDayRow.appendChild(calDayCell); + if (firstDay === parseInt(dp.oldDay) && dp.month === dp.oldMonth && + dp.year === dp.oldYear) { + calDayCell.classList.add('dp_selected'); + } + if (firstDay === dp.nowDay && parseInt(dp.month) === dp.nowMonth && + parseInt(dp.year) === dp.nowYear) { + calDayCell.classList.add('dp_today'); + } + firstDay++; + } + calTableTbody.appendChild(calDayRow); } calTable.appendChild(calTableThead); calTable.appendChild(calTableTbody); - let calTimePara = document.createElement('p'); + var calTimePara = document.createElement('p'); calTimePara.id = dp.id + '_calTime'; calTimePara.appendChild(timeTextBox); calTimePara.appendChild(submitButton); dp.calendar.appendChild(calTable); dp.calendar.appendChild(calTimePara); dp.position = dp.getBoundingClientRect(); - dp.container.style.left = (dp.position.left + window.scrollX) + 'px'; - if (dp.position.top + (dp.container.offsetHeight) > window.innerHeight) { - dp.container.style.top = (dp.position.top + window.scrollY) - dp.container.offsetHeight + 'px'; + dp.container.style.left = dp.position.left + window.pageXOffset + 'px'; + if (dp.position.top + dp.container.offsetHeight > window.innerHeight) { + dp.container.style.top = dp.position.top + window.pageYOffset - + dp.container.offsetHeight + 'px'; } else { - dp.container.style.top = (dp.position.top + dp.position.height + window.scrollY) + 'px'; + dp.container.style.top = dp.position.top + dp.position.height + + window.pageYOffset + 'px'; } - let calDays = document.querySelectorAll('td.' + dp.id + '_calDay'); + var calDays = document.querySelectorAll('td.' + dp.id + '_calDay'); for (i = 0; i < calDays.length; i++) { - calDays[i].onmouseover = function() { - this.classList.add('dp_roll'); - }; - calDays[i].onmouseout = function() { - this.classList.remove('dp_roll'); - }; - calDays[i].onclick = function() { - let el = document.querySelector('td.dp_selected'); - if (el) { - el.classList.remove('dp_selected'); - } - this.classList.add('dp_selected'); - self.updateValue(self.dp); - }; - calDays[i].ondblclick = function() { - let el = document.querySelector('td.dp_selected'); - if (el) { - el.classList.remove('dp_selected'); - } - this.classList.add('dp_selected'); - self.updateValue(self.dp); - DatePicker.remove(dp); - }; + calDays[i].onmouseover = function() { + this.classList.add('dp_roll'); + }; + calDays[i].onmouseout = function() { + this.classList.remove('dp_roll'); + }; + calDays[i].onclick = function() { + var el = document.querySelector('td.dp_selected'); + if (el) { + el.classList.remove('dp_selected'); + } + this.classList.add('dp_selected'); + self.updateValue(self.dp); + }; + calDays[i].ondblclick = function() { + var el = document.querySelector('td.dp_selected'); + if (el) { + el.classList.remove('dp_selected'); + } + this.classList.add('dp_selected'); + self.updateValue(self.dp); + DatePicker.remove(dp); + }; } monthSel.onfocus = function() { - dp.active = true; + dp.active = true; }; monthSel.onblur = function() { - dp.active = true; + dp.active = true; }; monthSel.onchange = function() { - dp.month = monthSel.value; - dp.year = yearSel.value; - DatePicker.remove(dp); - self.create(dp); + dp.month = monthSel.value; + dp.year = yearSel.value; + DatePicker.remove(dp); + self.create(dp); }; yearSel.onfocus = function() { - dp.active = true; + dp.active = true; }; yearSel.onblur = function() { - dp.active = true; + dp.active = true; }; yearSel.onchange = function() { - dp.month = monthSel.value; - dp.year = yearSel.value; - DatePicker.remove(dp); - self.create(dp); + dp.month = monthSel.value; + dp.year = yearSel.value; + DatePicker.remove(dp); + self.create(dp); }; timeTextBox.onfocus = function() { - dp.active = true; + dp.active = true; }; timeTextBox.onblur = function() { - self.updateValue(self.dp); - DatePicker.alertError(self.dp); + self.updateValue(self.dp); + DatePicker.alertError(self.dp); }; timeTextBox.onkeyup = function(e) { - self.dp.dirty = true; + self.dp.dirty = true; }; submitButton.onclick = function(e) { - if (self.dp.dirty) { - self.updateValue(self.dp); - DatePicker.alertError(self.dp); - } - DatePicker.remove(self.dp); - e.stopPropagation(); + if (self.dp.dirty) { + self.updateValue(self.dp); + DatePicker.alertError(self.dp); + } + DatePicker.remove(self.dp); + e.stopPropagation(); }; - } - - static formatValue(dp, year, month, day) - { - let time = document.getElementById(dp.id + '_timeTextBox').value.split(':'); + }, + }, { + key: 'formatValue', value: function formatValue(dp, year, month, day) { + var time = document.getElementById(dp.id + '_timeTextBox'). + value. + split(':'); if (!time[0] || time[0] === '' || time[0] < 0 || time[0] > 23) { - dp.error = 'Invalid hours value: ' + time[0] + '\nAllowed range is 00:23'; - return ''; + dp.error = 'Invalid hours value: ' + time[0] + + '\nAllowed range is 00:23'; + return ''; } - if (!time[1] || time[1] === '' || time[1] < 0 || time[1] > 59 || time[1].length !== 2) { - dp.error = 'Invalid minutes value: ' + time[1] + '\nAllowed range is 00:59'; - return ''; + if (!time[1] || time[1] === '' || time[1] < 0 || time[1] > 59 || + time[1].length !== 2) { + dp.error = 'Invalid minutes value: ' + time[1] + + '\nAllowed range is 00:59'; + return ''; } if (day < 10) { - day = '0' + day; + day = '0' + day; } if (month < 10) { - month = '0' + month; + month = '0' + month; } - let dateStr = dp.options.format.replace(/dd/i, day).replace(/mm/i, month).replace(/yyyy/i, year).replace(/hh/, time[0]).replace(/mm/, time[1]); + var dateStr = dp.options.format.replace(/dd/i, day). + replace(/mm/i, month). + replace(/yyyy/i, year). + replace(/hh/, time[0]). + replace(/mm/, time[1]); dp.month = dp.oldMonth = '' + (month - 1) + ''; dp.year = dp.oldYear = year; dp.oldDay = day; - this.dp.thenvalue = month + '/' + day + '/' + year + ' ' + time[0] + ':' + time[1] + ':00'; + this.dp.thenvalue = month + '/' + day + '/' + year + ' ' + time[0] + + ':' + time[1] + ':00'; return dateStr; - } - - static remove(dp) - { + }, + }, { + key: 'remove', value: function remove(dp) { dp.active = false; if (dp.container) { - dp.container.remove(); + dp.container.remove(); } dp.calendar = false; dp.container = false; - } -} + }, + }, + ]); + + return DatePicker; +}(); \ No newline at end of file From 0fc55da65ae4833e131412b50957a1e3f8a452b0 Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Sun, 20 Aug 2017 19:01:18 +0300 Subject: [PATCH 285/338] Update README.md --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 35bd14c3cc..11e87066f0 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,23 @@ Evolution CMS requires **PHP >= 5.4**, but snippet FormLister need **PHP >=5.6** ## What is EVO -EVO is an open source Content Management System and Application Framework. Initially inspired by Etomite 0.6, then it been MODX Evolution 0.7 - 1.0.8 is an ongoing project written by Raymond Irving and a core team of contributors MODX, and now its Evolution CMS maintained by Dmytro Lukianenko and a core team of contributors at the EVO Project. EVO is distributed under the GPL license and is now run by a professional team of developers from all over the world. Visit the Forums for more information. +EVO is an open source Content Management System and Application Framework. -EVO provides a fast, lightweight and powerful framework on which to deploy and secure your website and web applications. For example, it gives you a true system for registered web users and groups that is separate from administration users. You can grant some web users access to one page and others access to another page. For content management, you can easily duplicate documents, folders (and all their children!), chunks and snippets. Most significant, though, is EVO's ability to empower you to quickly and easily create and maintain a rich and dynamic website like never before. +Initially inspired by **Etomite 0.6**, then it been **MODX Evolution 0.7 - 1.0.8** is an ongoing project written by *Raymond Irving* and a core team of contributors **MODX**, and now its **Evolution CMS** maintained by *Dmytro Lukianenko* and a core team of contributors at the **EVO Project**. +**EVO** is distributed under the **GPL license** and is now run by a professional team of developers from all over the world. Visit the Forums for more information. +**EVO** provides a fast, lightweight and powerful framework on which to deploy and secure your website and web applications. -### Install -for easy and fast install you can use [Evo Installer](https://github.com/evolution-cms/installer) +For example, it gives you a true system for registered web users and groups that is separate from administration users. You can grant some web users access to one page and others access to another page. + +For content management, you can easily duplicate documents, folders (and all their children!), chunks and snippets. + +Most significant, though, is **EVO's** ability to empower you to quickly and easily create and maintain a rich and dynamic website like never before. + + +## Install +Just use [Evo Installer](https://github.com/evolution-cms/installer) ### Screenshots From 7ee2ef4d1c3ef74401046a6598b2c8a8d753f85b Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Sun, 20 Aug 2017 19:01:54 +0300 Subject: [PATCH 286/338] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 11e87066f0..f4d1a17051 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Evolution CMS requires **PHP >= 5.4**, but snippet FormLister need **PHP >=5.6** ## What is EVO -EVO is an open source Content Management System and Application Framework. +**EVO** is an open source Content Management System and Application Framework. Initially inspired by **Etomite 0.6**, then it been **MODX Evolution 0.7 - 1.0.8** is an ongoing project written by *Raymond Irving* and a core team of contributors **MODX**, and now its **Evolution CMS** maintained by *Dmytro Lukianenko* and a core team of contributors at the **EVO Project**. From c3e02422f13fc6adff960da07c996e0fadc7c02c Mon Sep 17 00:00:00 2001 From: Anton Kolesnikov Date: Sun, 20 Aug 2017 19:06:54 +0300 Subject: [PATCH 287/338] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f4d1a17051..fe19bb5334 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,16 @@ Evolution CMS requires **PHP >= 5.4**, but snippet FormLister need **PHP >=5.6** **EVO** is an open source Content Management System and Application Framework. +## History + Initially inspired by **Etomite 0.6**, then it been **MODX Evolution 0.7 - 1.0.8** is an ongoing project written by *Raymond Irving* and a core team of contributors **MODX**, and now its **Evolution CMS** maintained by *Dmytro Lukianenko* and a core team of contributors at the **EVO Project**. +## License + **EVO** is distributed under the **GPL license** and is now run by a professional team of developers from all over the world. Visit the Forums for more information. +## Features + **EVO** provides a fast, lightweight and powerful framework on which to deploy and secure your website and web applications. For example, it gives you a true system for registered web users and groups that is separate from administration users. You can grant some web users access to one page and others access to another page. From 139d0cc0787fd5dee9bdea46794ac5c2922bdc47 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Mon, 21 Aug 2017 02:58:03 +0300 Subject: [PATCH 288/338] update forms.css add style buttons --- manager/media/style/default/css/custom.css | 2 +- manager/media/style/default/css/forms.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index d675163803..84c40eb2cf 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -24,7 +24,7 @@ input[size="50"], select[size="50"] { width: 10rem !important } select[name=usergroup], select[name=docgroup] { margin: 0 0.5em; } select[name=docgroup] + input[type=submit] { float: none; margin: 0; } #settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype] { border-top-right-radius: 0; border-bottom-right-radius: 0 } -#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], #documentPane input[name^=tv]:not([class^=mtv]) + input[type=button], #documentPane input[name^=tv].DatePicker + a { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } +#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], #documentPane input[name^=tv]:not([class^=mtv]) + input[type=button] { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } #settingsPane [name=site_name], #settingsPane [name=txt_custom_contenttype], #settingsPane [name=filemanager_path], #settingsPane [name=rb_base_dir], input[name=photo], #range input#pids, input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } #range::after { content: ""; display: table; width: 100% } diff --git a/manager/media/style/default/css/forms.css b/manager/media/style/default/css/forms.css index 11020f1855..4aa91a8733 100644 --- a/manager/media/style/default/css/forms.css +++ b/manager/media/style/default/css/forms.css @@ -28,6 +28,10 @@ select:not([size]):not([multiple]), select.form-control:not([size]):not([multipl .btn-success:hover { color: #fff; background-color: #449d44; border-color: #419641 } .btn-danger { color: #fff; background-color: #d9534f; border-color: #d9534f } .btn-danger:hover { color: #fff; background-color: #c9302c; border-color: #c12e2a } +.btn-warning { color: #fff; background-color: #f0ad4e; border-color: #f0ad4e; } +.btn-warning:hover { color: #fff; background-color: #ec971f; border-color: #eb9316; } +.btn-info { color: #fff; background-color: #5bc0de; border-color: #5bc0de; } +.btn-info:hover { color: #fff; background-color: #31b0d5; border-color: #2aabd2; } .btn-default { color: #bbb; background-color: #202329; border-color: #202329 } .btn-default:hover { color: #fff; background-color: #1a1c21; border-color: #1a1c21 } textarea, textarea.form-control { width: 100%; line-height: 1.5; overflow: auto; resize: vertical } From 2c3785cada699625abcac4a409932cb34711b4b7 Mon Sep 17 00:00:00 2001 From: Nicola Date: Mon, 21 Aug 2017 18:28:51 +0200 Subject: [PATCH 289/338] [E] Quick Manager : New "Load Font Awesome css in front-end" plugin setting New "Load Font Awesome css in front-end" (true/false) plugin setting to avoid styles conflicts and duplicate Font Awesome css loading when is already used in frontend template. --- assets/plugins/qm/qm.inc.php | 15 +++++++++++---- install/assets/plugins/qm.tpl | 8 ++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/assets/plugins/qm/qm.inc.php b/assets/plugins/qm/qm.inc.php index 846205b4c6..dd276f9a46 100755 --- a/assets/plugins/qm/qm.inc.php +++ b/assets/plugins/qm/qm.inc.php @@ -4,7 +4,7 @@ * * @author Mikko Lammi, www.maagit.fi, updated by Dmi3yy and Nicola1971 * @license GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html - * @version 1.5.7 updated 21/01/2017 + * @version 1.5.8 updated 21/08/2017 */ if(!class_exists('Qm')) { @@ -13,7 +13,7 @@ class Qm { var $modx; //_______________________________________________________ - function __construct(&$modx, $jqpath='', $loadmanagerjq='', $loadfrontendjq='', $noconflictjq='', $loadtb='', $tbwidth='', $tbheight='', $hidefields='', $hidetabs='', $hidesections='', $addbutton='', $tpltype='', $tplid='', $custombutton='', $managerbutton='', $logout='', $autohide='', $position='', $editbuttons='', $editbclass='', $newbuttons='', $newbclass='', $tvbuttons='', $tvbclass='', $buttonStyle='', $removeBg='') { + function __construct(&$modx, $jqpath='', $loadmanagerjq='', $loadfrontendjq='', $noconflictjq='', $loadfa='', $loadtb='', $tbwidth='', $tbheight='', $hidefields='', $hidetabs='', $hidesections='', $addbutton='', $tpltype='', $tplid='', $custombutton='', $managerbutton='', $logout='', $autohide='', $position='', $editbuttons='', $editbclass='', $newbuttons='', $newbclass='', $tvbuttons='', $tvbclass='', $buttonStyle='', $removeBg='') { $this->modx = $modx; // Get plugin parameters @@ -21,6 +21,7 @@ function __construct(&$modx, $jqpath='', $loadmanagerjq='', $loadfrontendjq='', $this->loadmanagerjq = $loadmanagerjq; $this->loadfrontendjq = $loadfrontendjq; $this->noconflictjq = $noconflictjq; + $this->loadfa = $loadfa; $this->loadtb = $loadtb; $this->tbwidth = $tbwidth; $this->tbheight = $tbheight; @@ -481,11 +482,17 @@ function Run() { $MGR_DIR = $this->modx->getManagerPath( ); $css = ' '; - + $css .= ' - '; + + // font-awesome + if ($this->loadfa == 'true') { + $css .= ' + + '; + } // Buttons Styles if ($this->buttonStyle == 'actionButtons') { $css .= ' diff --git a/install/assets/plugins/qm.tpl b/install/assets/plugins/qm.tpl index 2ec520d45c..546e08963d 100644 --- a/install/assets/plugins/qm.tpl +++ b/install/assets/plugins/qm.tpl @@ -5,9 +5,9 @@ * Enables QuickManager+ front end content editing support * * @category plugin - * @version 1.5.7 + * @version 1.5.8 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL v3) - * @internal @properties &jqpath=Path to jQuery;text;assets/js/jquery.min.js &loadmanagerjq=Load jQuery in manager;list;true,false;false &loadfrontendjq=Load jQuery in front-end;list;true,false;true &noconflictjq=jQuery noConflict mode in front-end;list;true,false;true &loadtb=Load modal box in front-end;list;true,false;true &tbwidth=Modal box window width;text;80% &tbheight=Modal box window height;text;90% &hidefields=Hide document fields from front-end editors;text;parent &hidetabs=Hide document tabs from front-end editors;text; &hidesections=Hide document sections from front-end editors;text; &addbutton=Show add document here button;list;true,false;true &tpltype=New document template type;list;parent,id,selected;parent &tplid=New document template id;int;3 &custombutton=Custom buttons;textarea; &managerbutton=Show go to manager button;list;true,false;true &logout=Logout to;list;manager,front-end;manager &disabled=Plugin disabled on documents;text; &autohide=Autohide toolbar;list;true,false;true &position= Toolbar position;list;top,right,bottom,left,before;top &editbuttons=Inline edit buttons;list;true,false;false &editbclass=Edit button CSS class;text;qm-edit &newbuttons=Inline new resource buttons;list;true,false;false &newbclass=New resource button CSS class;text;qm-new &tvbuttons=Inline template variable buttons;list;true,false;false &tvbclass=Template variable button CSS class;text;qm-tv &removeBg=Remove toolbar background;list;yes,no;no &buttonStyle=QuickManager buttons CSS stylesheet;list;actionButtons,navButtons;actionButtons + * @internal @properties &jqpath=Path to jQuery;text;assets/js/jquery.min.js &loadmanagerjq=Load jQuery in manager;list;true,false;false &loadfrontendjq=Load jQuery in front-end;list;true,false;true &noconflictjq=jQuery noConflict mode in front-end;list;true,false;true &loadfa=Load Font Awesome css in front-end;list;true,false;true &loadtb=Load modal box in front-end;list;true,false;true &tbwidth=Modal box window width;text;80% &tbheight=Modal box window height;text;90% &hidefields=Hide document fields from front-end editors;text;parent &hidetabs=Hide document tabs from front-end editors;text; &hidesections=Hide document sections from front-end editors;text; &addbutton=Show add document here button;list;true,false;true &tpltype=New document template type;list;parent,id,selected;parent &tplid=New document template id;int;3 &custombutton=Custom buttons;textarea; &managerbutton=Show go to manager button;list;true,false;true &logout=Logout to;list;manager,front-end;manager &disabled=Plugin disabled on documents;text; &autohide=Autohide toolbar;list;true,false;true &position= Toolbar position;list;top,right,bottom,left,before;top &editbuttons=Inline edit buttons;list;true,false;false &editbclass=Edit button CSS class;text;qm-edit &newbuttons=Inline new resource buttons;list;true,false;false &newbclass=New resource button CSS class;text;qm-new &tvbuttons=Inline template variable buttons;list;true,false;false &tvbclass=Template variable button CSS class;text;qm-tv &removeBg=Remove toolbar background;list;yes,no;no &buttonStyle=QuickManager buttons CSS stylesheet;list;actionButtons,navButtons;actionButtons * @internal @events OnParseDocument,OnWebPagePrerender,OnDocFormPrerender,OnDocFormSave,OnManagerLogout * @internal @modx_category Manager and Admin * @internal @legacy_names QM+,QuickEdit @@ -18,7 +18,7 @@ * @link http://www.maagit.fi/modx/quickmanager-plus * @author Mikko Lammi * @author Since 2011: yama, dmi3yy, segr, Nicola1971. - * @lastupdate 23/01/2017 + * @lastupdate 21/08/2017 */ // In manager @@ -43,5 +43,5 @@ if ($show) { } } include_once($modx->config['base_path'].'assets/plugins/qm/qm.inc.php'); - $qm = new Qm($modx, $jqpath, $loadmanagerjq, $loadfrontendjq, $noconflictjq, $loadtb, $tbwidth, $tbheight, $hidefields, $hidetabs, $hidesections, $addbutton, $tpltype, $tplid, $custombutton, $managerbutton, $logout, $autohide, $position, $editbuttons, $editbclass, $newbuttons, $newbclass, $tvbuttons, $tvbclass, $buttonStyle, $removeBg); + $qm = new Qm($modx, $jqpath, $loadmanagerjq, $loadfrontendjq, $noconflictjq, $loadfa, $loadtb, $tbwidth, $tbheight, $hidefields, $hidetabs, $hidesections, $addbutton, $tpltype, $tplid, $custombutton, $managerbutton, $logout, $autohide, $position, $editbuttons, $editbclass, $newbuttons, $newbclass, $tvbuttons, $tvbclass, $buttonStyle, $removeBg); } From ee3128ac56e2053c7289b89bd3057e27f63d137f Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Mon, 21 Aug 2017 21:27:21 +0300 Subject: [PATCH 290/338] update style buttons in manage elements add margin --- manager/media/style/default/css/custom.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 84c40eb2cf..14725aad56 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -27,7 +27,6 @@ select[name=docgroup] + input[type=submit] { float: none; margin: 0; } #settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], #documentPane input[name^=tv]:not([class^=mtv]) + input[type=button] { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } #settingsPane [name=site_name], #settingsPane [name=txt_custom_contenttype], #settingsPane [name=filemanager_path], #settingsPane [name=rb_base_dir], input[name=photo], #range input#pids, input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } #range::after { content: ""; display: table; width: 100% } - /* [ Editor ] */ .navbar.navbar-editor { padding: .5rem 1.25rem; border-radius: 0 } .navbar-editor > label { margin-bottom: 0 } @@ -51,12 +50,18 @@ select[name=docgroup] + input[type=submit] { float: none; margin: 0; } #actions .btn-group .dropdown-menu > span:hover { background-color: #e6e6e6; } #actions .btn-group .dropdown-toggle::after { margin: 0; border-width: 0.4em; transition-duration: 0.25s } #actions .btn-group .show .dropdown-toggle::after { transform: rotate(180deg) } +#_actions .btn-group .input-group-btn .btn { margin-left: .1875rem } +#_actions .btn-group .form-control, #_actions .btn-group .btn { border-radius: .1rem } @media (max-width: 840px) { #actions { right: 0 } #actions .btn-group .btn span, #actions .btn-group select#stay, #_actions .btn-group .btn span { display: none } #actions .btn-group .btn .fa, #_actions .btn-group .btn .fa { display: inline-block } #actions .btn-group .dropdown-menu { width: 2rem } #actions .btn-group .dropdown-menu span { padding-left: 0; padding-right: 0; text-align: center } +#_actions .btn-group .input-group-btn .btn { margin-left: -1px } +#_actions .btn-group .form-control, #_actions .btn-group .btn { border-radius: 0 } +#_actions .btn-group .form-control:first-child { border-top-left-radius: .1rem; border-bottom-left-radius: .1rem; } +#_actions .btn-group .btn:last-child { border-top-right-radius: .1rem; border-bottom-right-radius: .1rem; } } /* old style */ #actions .actionButtons { float: left; min-height: 32px } From 460740338c09ed59a173c3a018a18c60e7a08593 Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Thu, 24 Aug 2017 11:39:19 +0300 Subject: [PATCH 291/338] correct #184 --- manager/media/style/default/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 14725aad56..f6b9ed06ac 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -24,7 +24,7 @@ input[size="50"], select[size="50"] { width: 10rem !important } select[name=usergroup], select[name=docgroup] { margin: 0 0.5em; } select[name=docgroup] + input[type=submit] { float: none; margin: 0; } #settingsPane #filemanager_path, #settingsPane #rb_base_dir, #settingsPane input[name=txt_custom_contenttype] { border-top-right-radius: 0; border-bottom-right-radius: 0 } -#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], #documentPane input[name^=tv]:not([class^=mtv]) + input[type=button] { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } +#settingsPane #filemanager_path + input[name=reset_filemanager_path], #settingsPane #rb_base_dir + input[name=reset_rb_base_dir], #settingsPane input[name=txt_custom_contenttype] + input[type=button], input[name=photo] + input[type=button], #range input#pids + input[name=fsubmit], input[name="ta"].inputBox + input[type=button], input[name="ta"].inputBox + .CodeMirror + input[type=button], #documentPane input[name^=tv]:not([class*=mtv]) + input[type=button] { z-index: 5; float: right; margin-top: -2.30769em; width: auto !important; border-top-left-radius: 0; border-bottom-left-radius: 0 } #settingsPane [name=site_name], #settingsPane [name=txt_custom_contenttype], #settingsPane [name=filemanager_path], #settingsPane [name=rb_base_dir], input[name=photo], #range input#pids, input[maxlength="350"], textarea.mce, #editorRow_TinyMCE { width: 100% !important } #range::after { content: ""; display: table; width: 100% } /* [ Editor ] */ From e3c58c4066c87c2712e8959311af3f961ee2f540 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 24 Aug 2017 12:20:51 +0300 Subject: [PATCH 292/338] fix Ditto sorting by pub_date leads to no results #179 --- assets/snippets/ditto/classes/ditto.class.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index c9de16fa07..023bccc4ad 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -639,9 +639,9 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, $customReset = $this->customReset; if ($this->debug) {$this->addField("pagetitle","backend","db");} - $limitSearch=$limit; - if (count($customReset) > 0) {$this->addField("createdon","backend","db"); $limitSearch=0;} - $resource = $this->getDocuments($documentIDs,$this->fields["backend"]["db"],$TVs,$orderBy,$showPublishedOnly,0,$hidePrivate,$where,$limitSearch,$randomize,$dateSource); + + if (count($customReset) > 0) {$this->addField("createdon","backend","db");} + $resource = $this->getDocuments($documentIDs,$this->fields["backend"]["db"],$TVs,$orderBy,$showPublishedOnly,0,$hidePrivate,$where,$limit,$randomize,$dateSource); // EPO - End of change (then see line 692 - if ($limit) array_slice($resource, 0, $limit); ) From 6061996046a2eee1aa1fe3e2a7a285e9c9230a1d Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 24 Aug 2017 12:57:18 +0300 Subject: [PATCH 293/338] update DocLister --- assets/lib/Helpers/Config.php | 9 +- assets/lib/Helpers/FS.php | 2 +- assets/lib/Helpers/Mailer.php | 134 ++++++++++++++++-- assets/lib/MODxAPI/MODx.php | 19 +++ assets/lib/MODxAPI/modManagers.php | 51 ++++--- assets/lib/MODxAPI/modResource.php | 19 --- assets/lib/MODxAPI/modUsers.php | 72 ++++++---- .../DocLister/core/DocLister.abstract.php | 16 +++ .../core/controller/site_content.php | 22 ++- .../core/extender/jotcount.extender.inc | 29 ++-- .../DocLister/lib/DLTemplate.class.php | 17 +-- install/assets/snippets/DocLister.tpl | 2 +- 12 files changed, 271 insertions(+), 121 deletions(-) mode change 100755 => 100644 assets/lib/Helpers/Config.php mode change 100755 => 100644 assets/lib/Helpers/Mailer.php mode change 100755 => 100644 assets/snippets/DocLister/core/extender/jotcount.extender.inc mode change 100755 => 100644 assets/snippets/DocLister/lib/DLTemplate.class.php diff --git a/assets/lib/Helpers/Config.php b/assets/lib/Helpers/Config.php old mode 100755 new mode 100644 index b0c9667590..4500ca7ad5 --- a/assets/lib/Helpers/Config.php +++ b/assets/lib/Helpers/Config.php @@ -86,10 +86,10 @@ public function getConfig() * @param array $cfg массив настроек * @return int результат сохранения настроек */ - public function setConfig($cfg) + public function setConfig($cfg, $overwrite = false) { if (is_array($cfg)) { - $this->_cfg = array_merge($this->_cfg, $cfg); + $this->_cfg = $overwrite ? $cfg : array_merge($this->_cfg, $cfg); $ret = count($this->_cfg); } else { $ret = false; @@ -98,6 +98,11 @@ public function setConfig($cfg) return $ret; } + /** + * @param $name + * @param null $def + * @return mixed + */ public function getCFGDef($name, $def = null) { return \APIhelpers::getkey($this->_cfg, $name, $def); diff --git a/assets/lib/Helpers/FS.php b/assets/lib/Helpers/FS.php index 745b11c508..2694f40ae4 100644 --- a/assets/lib/Helpers/FS.php +++ b/assets/lib/Helpers/FS.php @@ -292,7 +292,7 @@ public function relativePath($path, $owner = null) } $path = str_replace('\\', '/', $path); if (!(empty($path) || !is_scalar($path)) && !preg_match("/^http(s)?:\/\/\w+/", $path)) { - $path = trim(preg_replace("#^" . preg_quote($owner) . "#", '', $path), '/'); + $path = trim(preg_replace("#^" . preg_quote($owner) . "#", '', $path), DIRECTORY_SEPARATOR); } else { $path = ''; } diff --git a/assets/lib/Helpers/Mailer.php b/assets/lib/Helpers/Mailer.php old mode 100755 new mode 100644 index b60d77f9f4..e64c466dcf --- a/assets/lib/Helpers/Mailer.php +++ b/assets/lib/Helpers/Mailer.php @@ -1,6 +1,7 @@ modx = $modx; - $modx->loadExtension('MODxMailer'); - $this->mail = $modx->mail; + $this->mail = new \MODxMailer(); + $this->mail->init($modx); $this->config = $cfg; $this->debug = $debug; + $this->applyMailConfig(); } /** @@ -88,15 +90,7 @@ public function send($report) return false; } - $this->mail->IsHTML($this->getCFGDef('isHtml', 1)); - $this->mail->From = $this->getCFGDef('from', $this->modx->config['site_name']); - $this->mail->FromName = $this->getCFGDef('fromName', $this->modx->config['emailsender']); - $this->mail->Subject = $this->getCFGDef('subject'); $this->mail->Body = $report; - $this->addAddressToMailer("replyTo", $this->getCFGDef('replyTo')); - $this->addAddressToMailer("to", $this->getCFGDef('to')); - $this->addAddressToMailer("cc", $this->getCFGDef('cc')); - $this->addAddressToMailer("bcc", $this->getCFGDef('bcc')); $result = $this->mail->send(); if ($result) { @@ -107,6 +101,124 @@ public function send($report) return $result; } + /** + * @param $report + * @return bool + */ + public function toQueue($report) + { + //если отправлять некуда или незачем, то делаем вид, что отправили + if (!$this->getCFGDef('to') || $this->getCFGDef('noemail')) { + return true; + } elseif (empty($report)) { + return false; + } + + $this->mail->Body = $report; + + $this->Body = $this->modx->removeSanitizeSeed($this->mail->Body); + $this->Subject = $this->modx->removeSanitizeSeed($this->mail->Subject); + try { + $result = $this->mail->preSend() && $this->saveMessage(); + } catch (\phpmailerException $e) { + $this->mail->SetError($e->getMessage()); + + $result = false; + } + + if ($result) { + $this->mail->ClearAllRecipients(); + $this->mail->ClearAttachments(); + $result = $this->getFileName(); + } + + return $result; + } + + /** + * @param string $path + * @return bool + */ + public function setQueuePath($path = '') { + if (!empty($path)) { + $this->queuePath = $path; + return true; + } else { + return false; + } + } + + /** + * @return mixed + */ + protected function saveMessage() + { + $data = serialize(array( + "header" => $this->mail->getMIMEHeader(), + "body" => $this->mail->getMIMEBody(), + "config" => $this->config + )); + $file = $this->getFileName(); + $dir = MODX_BASE_PATH . $this->queuePath; + if (!is_dir($dir)) { + @mkdir($dir); + } + $result = @file_put_contents($dir . $file, $data) !== false; + if ($result) { + $result = $file; + } + + return $result; + } + + /** + * @return string + */ + protected function getFileName() { + return $this->mail->getMessageID() . '.eml'; + } + + /** + * @param $file + * @return bool + */ + public function fromQueue($file) + { + $result = false; + $dir = MODX_BASE_PATH . $this->queuePath; + if (file_exists($dir . $file) && is_readable($dir . $file)) { + $message = unserialize(file_get_contents($dir . $file)); + $this->config = $message['config']; + $this->applyMailConfig(); + $this->mail->setMIMEHeader($message['header'])->setMIMEBody($message['body']); + unset($message); + $result = $this->mail->postSend(); + if ($result) { + $this->mail->setMIMEBody()->setMIMEHeader(); + @unlink($dir . $file); + } + } + + return $result; + } + + /** + * @return $this + */ + protected function applyMailConfig() + { + $this->mail->IsHTML($this->getCFGDef('isHtml', 1)); + $this->mail->From = $this->getCFGDef('from', $this->modx->config['emailsender']); + $this->mail->FromName = $this->getCFGDef('fromName', $this->modx->config['site_name']); + $this->mail->Subject = $this->getCFGDef('subject'); + $this->addAddressToMailer("replyTo", $this->getCFGDef('replyTo')); + $this->addAddressToMailer("to", $this->getCFGDef('to')); + $this->addAddressToMailer("cc", $this->getCFGDef('cc')); + $this->addAddressToMailer("bcc", $this->getCFGDef('bcc')); + + return $this; + } + /** * @param string $param * @param mixed $default diff --git a/assets/lib/MODxAPI/MODx.php b/assets/lib/MODxAPI/MODx.php index 96b21682f6..dd7507e793 100644 --- a/assets/lib/MODxAPI/MODx.php +++ b/assets/lib/MODxAPI/MODx.php @@ -186,6 +186,25 @@ public function getDefaultFields() return $this->default_field; } + /** + * @param $value + * @return int|mixed|string + */ + protected function getTime($value) + { + $value = trim($value); + if (!empty($value)) { + if (!is_numeric($value)) { + $value = (int)strtotime($value); + } + if (!empty($value)) { + $value += $this->modxConfig('server_offset_time'); + } + } + + return $value; + } + /** * @param string $name * @param null $default diff --git a/assets/lib/MODxAPI/modManagers.php b/assets/lib/MODxAPI/modManagers.php index 80346e64e1..f9d722bbf7 100644 --- a/assets/lib/MODxAPI/modManagers.php +++ b/assets/lib/MODxAPI/modManagers.php @@ -11,15 +11,15 @@ class modManagers extends MODxAPI */ protected $default_field = array( 'user' => array( - 'username' => "", - 'password' => "", + 'username' => '', + 'password' => '', ), 'attribute' => array( - 'fullname' => "", + 'fullname' => '', 'role' => 0, - 'email' => "", - 'phone' => "", - 'mobilephone' => "", + 'email' => '', + 'phone' => '', + 'mobilephone' => '', 'blocked' => 0, 'blockeduntil' => 0, 'blockedafter' => 0, @@ -27,17 +27,19 @@ class modManagers extends MODxAPI 'lastlogin' => 0, 'thislogin' => 0, 'failedlogincount' => 0, - 'sessionid' => "", + 'sessionid' => '', 'dob' => 0, - 'gender' => "", - 'country' => "", - 'state' => "", - 'city' => "", - 'street' => "", - 'zip' => "", - 'fax' => "", - 'photo' => "", - 'comment' => "" + 'gender' => 0, + 'country' => '', + 'state' => '', + 'city' => '', + 'street' => '', + 'zip' => '', + 'fax' => '', + 'photo' => '', + 'comment' => '', + 'createdon' => 0, + 'editedon' => 0 ), 'hidden' => array( 'internalKey' @@ -97,6 +99,18 @@ protected function findUser($data) return $find; } + /** + * @param array $data + * @return $this + */ + public function create($data = array()) + { + parent::create($data); + $this->set('createdon', time()); + + return $this; + } + /** * @param $id * @return $this @@ -111,6 +125,7 @@ public function edit($id) if (!$find = $this->findUser($id)) { $this->id = null; } else { + $this->set('editedon', time()); $result = $this->query(" SELECT * from {$this->makeTable('user_attributes')} as attribute LEFT JOIN {$this->makeTable('manager_users')} as user ON user.id=attribute.internalKey @@ -149,6 +164,10 @@ public function set($key, $value) session_regenerate_id(false); $value = session_id(); break; + case 'editedon': + case 'createdon': + $value = $this->getTime($value); + break; } $this->field[$key] = $value; } diff --git a/assets/lib/MODxAPI/modResource.php b/assets/lib/MODxAPI/modResource.php index dcdc227016..63bfed59c6 100644 --- a/assets/lib/MODxAPI/modResource.php +++ b/assets/lib/MODxAPI/modResource.php @@ -434,25 +434,6 @@ protected function findUserBy($data) return $find; } - /** - * @param $value - * @return int|mixed|string - */ - protected function getTime($value) - { - $value = trim($value); - if (!empty($value)) { - if (!is_numeric($value)) { - $value = (int)strtotime($value); - } - if (!empty($value)) { - $value += $this->modxConfig('server_offset_time'); - } - } - - return $value; - } - /** * @param array $data * @return $this diff --git a/assets/lib/MODxAPI/modUsers.php b/assets/lib/MODxAPI/modUsers.php index bd1eebea91..1089dfd41d 100644 --- a/assets/lib/MODxAPI/modUsers.php +++ b/assets/lib/MODxAPI/modUsers.php @@ -11,34 +11,36 @@ class modUsers extends MODxAPI */ protected $default_field = array( 'user' => array( - 'username' => null, - 'password' => null, - 'cachepwd' => null + 'username' => '', + 'password' => '', + 'cachepwd' => '' ), 'attribute' => array( - 'fullname' => null, - 'role' => null, - 'email' => null, - 'phone' => null, - 'mobilephone' => null, - 'blocked' => null, - 'blockeduntil' => null, - 'blockedafter' => null, - 'logincount' => null, - 'lastlogin' => null, - 'thislogin' => null, - 'failedlogincount' => null, - 'sessionid' => null, - 'dob' => null, - 'gender' => null, - 'country' => null, - 'state' => null, - 'city' => null, - 'street' => null, - 'zip' => null, - 'fax' => null, - 'photo' => null, - 'comment' => null + 'fullname' => '', + 'role' => '', + 'email' => '', + 'phone' => '', + 'mobilephone' => '', + 'blocked' => 0, + 'blockeduntil' => 0, + 'blockedafter' => 0, + 'logincount' => 0, + 'lastlogin' => 0, + 'thislogin' => 0, + 'failedlogincount' => 0, + 'sessionid' => '', + 'dob' => 0, + 'gender' => 0, + 'country' => '', + 'state' => '', + 'city' => '', + 'street' => '', + 'zip' => '', + 'fax' => '', + 'photo' => '', + 'comment' => '', + 'createdon' => 0, + 'editedon' => 0 ), 'hidden' => array( 'internalKey' @@ -84,6 +86,18 @@ protected function findUser($data) return $find; } + /** + * @param array $data + * @return $this + */ + public function create($data = array()) + { + parent::create($data); + $this->set('createdon', time()); + + return $this; + } + /** * @param $id * @return $this @@ -98,6 +112,7 @@ public function edit($id) if (!$find = $this->findUser($id)) { $this->id = null; } else { + $this->set('editedon', time()); $result = $this->query(" SELECT * from {$this->makeTable('web_user_attributes')} as attribute LEFT JOIN {$this->makeTable('web_users')} as user ON user.id=attribute.internalKey @@ -132,6 +147,10 @@ public function set($key, $value) session_regenerate_id(false); $value = session_id(); break; + case 'editedon': + case 'createdon': + $value = $this->getTime($value); + break; } $this->field[$key] = $value; } @@ -174,6 +193,7 @@ public function save($fire_events = false, $clearCache = false) return false; } + $time = $this->set('sessionid', ''); $fld = $this->toArray(); foreach ($this->default_field['user'] as $key => $value) { diff --git a/assets/snippets/DocLister/core/DocLister.abstract.php b/assets/snippets/DocLister/core/DocLister.abstract.php index be1aca0892..ae939f9672 100644 --- a/assets/snippets/DocLister/core/DocLister.abstract.php +++ b/assets/snippets/DocLister/core/DocLister.abstract.php @@ -1640,6 +1640,22 @@ public function filtersJoin() return APIHelpers::getkey($this->_filters, 'join', ''); } + /** + * @param string $join + * @return $this + */ + public function setFiltersJoin($join = '') { + if (!empty($join)) { + if (!empty($this->_filters['join'])) { + $this->_filters['join'] .= ' ' . $join; + } else { + $this->_filters['join'] = $join; + } + } + + return $this; + } + /** * Приведение типа поля * diff --git a/assets/snippets/DocLister/core/controller/site_content.php b/assets/snippets/DocLister/core/controller/site_content.php index 6771e62531..1e76d834a5 100644 --- a/assets/snippets/DocLister/core/controller/site_content.php +++ b/assets/snippets/DocLister/core/controller/site_content.php @@ -49,6 +49,15 @@ public function getDocs($tvlist = '') $this->extTV->getAllTV_Name(); + /** + * @var $extJotCount jotcount_DL_Extender + */ + $extJotCount = $this->getCFGdef('jotcount', 0) ? $this->getExtender('jotcount', true) : null; + + if ($extJotCount) { + $extJotCount->init($this); + } + if ($this->extPaginate = $this->getExtender('paginate')) { $this->extPaginate->init($this); } else { @@ -111,15 +120,6 @@ public function _render($tpl = '') */ $extPrepare = $this->getExtender('prepare'); - /** - * @var $extJotCount jotcount_DL_Extender - */ - $extJotCount = $this->getCFGdef('jotcount', 0) ? $this->getExtender('jotcount', true) : null; - - if ($extJotCount) { - $comments = $extJotCount->countComments(array_keys($this->_docs)); - } - $this->skippedDocs = 0; foreach ($this->_docs as $item) { $this->renderTPL = $tpl; @@ -129,10 +129,6 @@ public function _render($tpl = '') $item['summary'] = $extSummary ? $this->getSummary($item, $extSummary, 'introtext', 'content') : ''; - if ($extJotCount) { - $item['jotcount'] = APIHelpers::getkey($comments, $item['id'], 0); - } - $item = array_merge($item, $sysPlh); //inside the chunks available all placeholders set via $modx->toPlaceholders with prefix id, and with prefix sysKey $item['iteration'] = $i; //[+iteration+] - Number element. Starting from zero diff --git a/assets/snippets/DocLister/core/extender/jotcount.extender.inc b/assets/snippets/DocLister/core/extender/jotcount.extender.inc old mode 100755 new mode 100644 index 7fc620d24c..cc2a3a6b95 --- a/assets/snippets/DocLister/core/extender/jotcount.extender.inc +++ b/assets/snippets/DocLister/core/extender/jotcount.extender.inc @@ -17,26 +17,13 @@ class jotcount_DL_Extender extends extDocLister */ protected function run() { - return true; - } - - /** - * @param $docs - * @return array - */ - public function countComments($docs) - { - $comments = array(); - if (count($docs)) { - $from = $this->DocLister->getTable('jot_content'); - $rs = $this->DocLister->dbQuery("SELECT uparent, COUNT(*) as total FROM {$from} WHERE uparent IN (" . implode(',', - $docs) . ") AND published=1 AND deleted=0 GROUP BY uparent"); - $counts = $this->modx->db->makeArray($rs); - foreach ($counts as $v) { - $comments[$v['uparent']] = $v['total']; - } - } + $join = "LEFT JOIN (SELECT `uparent`, COUNT(`id`) AS `jotcount` FROM {$this->DocLister->getTable('jot_content')} WHERE `published`=1 AND `deleted`=0 GROUP BY `uparent`) `jc` ON `jc`.`uparent` = {$this->DocLister->getPK()}"; + $this->DocLister->setFiltersJoin($join); + $fields = $this->DocLister->getCFGDef('selectFields', 'c.*'); + $this->DocLister->config->setConfig(array( + "selectFields" => $fields . ",IFNULL(`jc`.`jotcount`,0) AS `jotcount`" + )); - return $comments; + return true; } -} \ No newline at end of file +} diff --git a/assets/snippets/DocLister/lib/DLTemplate.class.php b/assets/snippets/DocLister/lib/DLTemplate.class.php old mode 100755 new mode 100644 index 71bbf6644f..b0f576307d --- a/assets/snippets/DocLister/lib/DLTemplate.class.php +++ b/assets/snippets/DocLister/lib/DLTemplate.class.php @@ -330,18 +330,13 @@ public function parseChunk($name, $data, $parseDocumentSource = false) $out = str_replace(array_keys($item), array_values($item), $out); } if (preg_match("/:([^:=]+)(?:=`(.*?)`(?=:[^:=]+|$))?/is", $out)) { - if($this->modx->config['enable_filter']) { - $out = $this->modx->parseText($out,$data); - } - else { - if (is_null($this->phx) || !($this->phx instanceof DLphx)) { - $this->phx = $this->createPHx(0, 1000); - } - $this->phx->placeholders = array(); - $this->setPHxPlaceholders($data); - $out = $this->phx->Parse($out); - $out = $this->cleanPHx($out); + if (is_null($this->phx) || !($this->phx instanceof DLphx)) { + $this->phx = $this->createPHx(0, 1000); } + $this->phx->placeholders = array(); + $this->setPHxPlaceholders($data); + $out = $this->phx->Parse($out); + $out = $this->cleanPHx($out); } } } diff --git a/install/assets/snippets/DocLister.tpl b/install/assets/snippets/DocLister.tpl index 58d8a9f3b8..eb5be9f604 100644 --- a/install/assets/snippets/DocLister.tpl +++ b/install/assets/snippets/DocLister.tpl @@ -5,7 +5,7 @@ * Snippet to display the information of the tables by the description rules. The main goal - replacing Ditto and CatalogView * * @category snippet - * @version 2.3.10 + * @version 2.3.11 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL) * @internal @properties * @internal @modx_category Content From ec2c7f23143b7b5a3889554122475d706c281a35 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 24 Aug 2017 13:00:31 +0300 Subject: [PATCH 294/338] update FormLister to 1.7.8 --- .../FormLister/core/FormLister.abstract.php | 35 +++++--- assets/snippets/FormLister/docs/history.md | 8 ++ ...20\274\320\265\321\202\321\200\321\213.md" | 2 +- ...21\202\320\265\320\273\320\265\320\271.md" | 89 ++++++++++++++++++- ...20\270\320\272\320\276\320\275\321\213.md" | 16 +++- assets/snippets/FormLister/lib/Lexicon.php | 8 +- install/assets/plugins/userHelper.tpl | 2 +- install/assets/snippets/FormLister.tpl | 2 +- 8 files changed, 140 insertions(+), 22 deletions(-) mode change 100755 => 100644 assets/snippets/FormLister/docs/history.md mode change 100755 => 100644 "assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" mode change 100755 => 100644 "assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" diff --git a/assets/snippets/FormLister/core/FormLister.abstract.php b/assets/snippets/FormLister/core/FormLister.abstract.php index 6960d74441..7479555045 100644 --- a/assets/snippets/FormLister/core/FormLister.abstract.php +++ b/assets/snippets/FormLister/core/FormLister.abstract.php @@ -118,7 +118,8 @@ public function __construct(\DocumentParser $modx, $cfg = array()) )); } $this->lexicon = new Lexicon($modx, array( - 'langDir' => 'assets/snippets/FormLister/core/lang/' + 'langDir' => 'assets/snippets/FormLister/core/lang/', + 'lang' => $this->getCFGDef('lang', $this->modx->config['manager_language']) )); $this->formid = $this->getCFGDef('formid'); switch (strtolower($this->getCFGDef('formMethod', 'post'))) { @@ -146,14 +147,15 @@ public function initForm() $lexicon = $this->getCFGDef('lexicon'); if ($lexicon) { $_lexicon = $this->config->loadArray($lexicon); - if (is_array($_lexicon)) { - $lang = $this->lexicon->fromArray($_lexicon); + if (isset($_lexicon[0])) { + $lang = $this->lexicon->loadLang($_lexicon); } else { - $lang = $this->lexicon->loadLang($lexicon, $this->getCFGDef('lang'), - $this->getCFGDef('langDir')); + $lang = $this->lexicon->fromArray($_lexicon); } - if ($lang) { + if (!empty($lang)) { $this->log('Custom lexicon loaded', array('lexicon' => $lang)); + } else { + $this->log('Failed to load lexicon', array('lexicon' => $_lexicon)); } } $this->allowedFields = array_merge($this->allowedFields, @@ -478,7 +480,7 @@ public function setFields($fields = array(), $prefix = '') public function validateForm() { $validator = $this->getCFGDef('validator', '\FormLister\Validator'); - $validator = $this->loadModel($validator , '', array()); + $validator = $this->loadModel($validator, '', array()); $fields = $this->getFormData('fields'); $rules = $this->getValidationRules(); $this->rules = array_merge($this->rules, $rules); @@ -738,10 +740,14 @@ public function errorsToPlaceholders() foreach ($this->getFormData('errors') as $field => $error) { foreach ($error as $type => $message) { $classType = ($type == 'required') ? 'required' : 'error'; - $plh[$field . '.error'] = $this->parseChunk($this->getCFGDef('errorTpl', - '@CODE:
    [+message+]
    '), array('message' => $message)); + if (!empty($message)) { + $plh[$field . '.error'] = $this->parseChunk($this->getCFGDef('errorTpl', + '@CODE:
    [+message+]
    '), array('message' => $message)); + } $plh[$field . '.' . $classType . 'Class'] = $this->getCFGDef($field . '.' . $classType . 'Class', $this->getCFGDef($classType . 'Class', $classType)); + $plh[$field . '.class'] = "class=\"{$plh[$field . '.' . $classType . 'Class']}\""; + $plh[$field . '.classname'] = "{$plh[$field . '.' . $classType . 'Class']}"; } } @@ -859,7 +865,7 @@ public function renderMessagesGroup($messages, $wrapper, $splitter) public function parseChunk($name, $data, $parseDocumentSource = false) { $parseDocumentSource = $parseDocumentSource || $this->getCFGDef('parseDocumentSource', 0); - $rewriteUrls = $this->getCFGDef('rewriteUrls', 0); + $rewriteUrls = $this->getCFGDef('rewriteUrls', 1); $DLTemplate = \DLTemplate::getInstance($this->modx) ->setTemplatePath($this->getCFGDef('templatePath')) ->setTemplateExtension($this->getCFGDef('templateExtension')) @@ -877,7 +883,7 @@ public function parseChunk($name, $data, $parseDocumentSource = false) if (!$parseDocumentSource && $rewriteUrls) { $out = $this->modx->rewriteUrls($out); } - if ($this->getCFGDef('removeEmptyPlaceholders', 0)) { + if ($this->getCFGDef('removeEmptyPlaceholders', 1)) { preg_match_all('~\[(\+|\*|\(|%)([^:\+\[\]]+)([^\[\]]*?)(\1|\)|%)\]~s', $out, $matches); if ($matches[0]) { $out = str_replace($matches[0], '', $out); @@ -897,7 +903,9 @@ public function initCaptcha() $className = ucfirst($captcha . 'Wrapper'); $cfg = $this->config->loadArray($this->getCFGDef('captchaParams', array())); $cfg['id'] = $this->getFormId(); - $captcha = $this->loadModel($className, MODX_BASE_PATH . "assets/snippets/FormLister/lib/captcha/{$captcha}/wrapper.php",array($this->modx, $cfg)); + $captcha = $this->loadModel($className, + MODX_BASE_PATH . "assets/snippets/FormLister/lib/captcha/{$captcha}/wrapper.php", + array($this->modx, $cfg)); if (!is_null($captcha) && $captcha instanceof CaptchaInterface) { $captcha->init(); @@ -1023,7 +1031,8 @@ public function redirect($param = 'redirectTo', $_query = array()) * @param $url * @param $header */ - public function sendRedirect($url, $header = 'HTTP/1.1 307 Temporary Redirect') { + public function sendRedirect($url, $header = 'HTTP/1.1 307 Temporary Redirect') + { if (!$this->getCFGDef('api', 0)) { $header = $header ? $header : 'HTTP/1.1 307 Temporary Redirect'; $this->modx->sendRedirect($url, 0, 'REDIRECT_HEADER', $header); diff --git a/assets/snippets/FormLister/docs/history.md b/assets/snippets/FormLister/docs/history.md old mode 100755 new mode 100644 index 7bca858b2d..a11937a365 --- a/assets/snippets/FormLister/docs/history.md +++ b/assets/snippets/FormLister/docs/history.md @@ -1,4 +1,12 @@ ## History +### 1.7.8 +* [Refactor] Переименованы файлы документации. +* [Refactor] Параметр removeEmptyPlaceholders по умолчанию включен (Core). +* [Refactor] Параметр rewriteUrls по умолчанию включен (Core). +* [Refactor] Плейсхолдеры ошибок [+field.error+] не устанавливаются, если нет сообщения об ошибке (Core). +* [Enhancement] Плейсхолдеры [+field.class+] (включает class="") и [+field.classname+] (не включает class="") (Core). +* [Refactor] Параметр lexicon может содержать или имена файлов (без расширения) через запятую или массив с языковыми строками (Lexicon). + ### 1.7.7 * [Enhancement] Возможность указывать разный subject для разных типов писем (Form). diff --git "a/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" "b/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" old mode 100755 new mode 100644 index e0046780fa..1cb9acd0bd --- "a/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" +++ "b/assets/snippets/FormLister/docs/ru/020_\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213.md" @@ -242,7 +242,7 @@ myparams:core - загрузить параметры из файла assets/sni Возможные значения - 0 или 1. -Значение по умолчанию - 0. +Значение по умолчанию - 1. ### parseDocumentSource Обрабатывает чанки MODX-парсером. diff --git "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" index 841e652207..8a1203405e 100644 --- "a/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" +++ "b/assets/snippets/FormLister/docs/ru/060_\320\220\320\262\321\202\320\276\321\200\320\270\320\267\320\260\321\206\320\270\321\217_\320\277\320\276\320\273\321\214\320\267\320\276\320\262\320\260\321\202\320\265\320\273\320\265\320\271.md" @@ -1,6 +1,78 @@ ## Авторизация пользователей -Контроллер Login позволяет авторизировать пользователей как по имени, так и по email. Кроме этого, можно дополнительно использовать плагин userHelper, который ведет учет количества логинов и времени последнего логина, а также реализует автологин и выход из учетной записи. +Авторизация пользователей в `FormLister` осуществляется с использованием контроллера `Login`. + +### Выбор поля для авторизации + +Поле для авторизации задается в параметре `loginField` и должно быть **уникальным** для каждого веб-пользователя. + +Авторизация может осуществляться: +* по **базовым** полям средствами класса `modUsers`: `id`, `username` и `email` +* по любому **другому полю** из учетной записи (с помощью плагина для события `OnWebAuthentication`) + + +Дополнительное использование плагина [userHelper](https://github.com/evolution-cms/evolution/blob/develop/assets/snippets/FormLister/plugin.userHelper.php) позволяет: + +* вести учет количества логинов +* определить время последней авторизации +* реализовать автологин и выход из учетной записи +* блокировать пользователей после определенного количества неудачных попыток авторизации + +Перед использованием плагина `userHelper` убедитесь что он включен: + +![Не забудьте включить userHelper](https://habrastorage.org/web/dbc/1e2/abd/dbc1e2abd8664a548f4eca254187fb60.png) + +## Пример вызова FormLister для авторизации веб-пользователей + +```javascript +[!FormLister? +&formid=`login` +&controller=`Login` +&loginField=`email` +&passwordField=`password` +&rules=`{ + "email":{ + "required":"Обязательно введите email" + } + }, + "password":{ + "required":"Обязательно введите пароль", + "minLength":{ + "params":6, + "message":"В пароле должно быть больше 6 символов" + } + }, +}` +&allowedFields=`email,password` +&formTpl=`@CODE: +
    + + +
    + + + [+email.error+] +
    +
    + + + [+password.error+] +
    + [+form.messages+] +
    + +
    + +
    +` +&messagesOuterTpl=`@CODE:` +&successTpl=`@CODE:
    Поздравляем с успешной авторизацией, [+fullname.value+]!
    ` +&errorTpl=`@CODE:
    [+message+]
    ` +&requiredClass=` has-error` +&errorClass=` has-error` +&requiredClass=` has-error` +!] +``` ## Параметры контроллера @@ -115,3 +187,18 @@ Возможные значения - число секунд с момента последнего логина. Значение по умолчанию - 157680000 (5 лет). + +### maxFails +Количество попыток для ввода учетных данных. + +Возможные значения - число больше 0. + +Значение по умолчанию - 3. + +### blockTime +Время блокировки пользователя. + +Возможные значения - число секунд с момента последнего логина. + +Значение по умолчанию - 3600 (1 час). + diff --git "a/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" "b/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" old mode 100755 new mode 100644 index dd64c0974b..c9edeba8bc --- "a/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" +++ "b/assets/snippets/FormLister/docs/ru/110_\320\233\320\265\320\272\321\201\320\270\320\272\320\276\320\275\321\213.md" @@ -13,6 +13,20 @@ return $lang; * langDir - путь к папке с лексиконами; * lang - язык лексикона (если не указано, то используется параметр конфигурации manager_language); -* lexicon - название лексикона, можно указать несколько названий через запятую. +* lexicon - название лексикона, можно указать несколько названий через запятую. Также можно задать значения непосредственно в параметре: +``` +&lexicon=`{ + "english":{ + "test":"Test lexicon value", + "foo":"Another lexicon value", + "bar":"And one more value" + }, + "russian-UTF8":{ + "test":"Проверка", + "foo":"Еще проверка", + "bar":"И еще" + } +}` +``` После этого в шаблонах можно использовать плейсхолдеры [%ключ%] для подстановки значений из загруженных языковых файлов. Кроме того поддерживаются лексиконы компонента EvoBabel. \ No newline at end of file diff --git a/assets/snippets/FormLister/lib/Lexicon.php b/assets/snippets/FormLister/lib/Lexicon.php index a855a01c82..b6c1ad383a 100644 --- a/assets/snippets/FormLister/lib/Lexicon.php +++ b/assets/snippets/FormLister/lib/Lexicon.php @@ -39,9 +39,8 @@ public function loadLang($name = 'core', $lang = '', $langDir = '') if (is_scalar($name) && !empty($name)) { $name = array($name); - } else { - return $this->_lang; } + foreach ($name as $n) { if ($lang != 'english') { $this->loadLangFile($n, 'english', $langDir); @@ -71,8 +70,9 @@ private function loadLangFile($name = 'core', $lang = '', $langDir = '') */ public function fromArray($lang) { - if (is_array($lang) && $lang) { - $this->_lang = array_merge($this->_lang, $lang); + $language = \APIhelpers::getkey($this->cfg, 'lang', $this->modx->config['manager_language']); + if (is_array($lang) && isset($lang[$language])) { + $this->_lang = array_merge($this->_lang, $lang[$language]); } return $this->_lang; diff --git a/install/assets/plugins/userHelper.tpl b/install/assets/plugins/userHelper.tpl index 1dbaa56754..527dbcd9a1 100644 --- a/install/assets/plugins/userHelper.tpl +++ b/install/assets/plugins/userHelper.tpl @@ -5,7 +5,7 @@ * addition to FormLister * * @category plugin - * @version 1.7.7 + * @version 1.7.8 * @internal @properties &logoutKey=Request key;text;logout &cookieName=Cookie Name;text;WebLoginPE &cookieLifetime=Cookie Lifetime, seconds;text;157680000 &maxFails=Max failed logins;text;3 &blockTime=Block for, seconds;text;3600 * @internal @events OnWebPageInit,OnPageNotFound,OnWebLogin * @internal @disabled 1 diff --git a/install/assets/snippets/FormLister.tpl b/install/assets/snippets/FormLister.tpl index afc8e3b70a..204dac4b2a 100644 --- a/install/assets/snippets/FormLister.tpl +++ b/install/assets/snippets/FormLister.tpl @@ -5,7 +5,7 @@ * Form processor * * @category snippet - * @version 1.7.7 + * @version 1.7.8 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL) * @internal @modx_category Content * @internal @installset base, sample From d03412a74ff6208c1cabab3cf306d9d8b02cc151 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 24 Aug 2017 13:04:21 +0300 Subject: [PATCH 295/338] Updater one more check for use from manager only --- assets/plugins/updater/plugin.updater.php | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/plugins/updater/plugin.updater.php b/assets/plugins/updater/plugin.updater.php index 671b1b71cf..aa9d3020ea 100644 --- a/assets/plugins/updater/plugin.updater.php +++ b/assets/plugins/updater/plugin.updater.php @@ -7,6 +7,7 @@ */ if(!defined('MODX_BASE_PATH')){die('What are you doing? Get out of here!');} +if (empty($_SESSION['mgrInternalKey'])) return; $version = 'evolution-cms/evolution'; $type = isset($type) ? $type: 'tags'; From 30e0efc9a772e305c07a983469219daf9d240703 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 24 Aug 2017 13:05:21 +0300 Subject: [PATCH 296/338] fix version --- manager/includes/version.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager/includes/version.inc.php b/manager/includes/version.inc.php index 1f8bf98260..e9301eeb5d 100755 --- a/manager/includes/version.inc.php +++ b/manager/includes/version.inc.php @@ -1,5 +1,5 @@ Date: Thu, 24 Aug 2017 13:48:40 +0300 Subject: [PATCH 297/338] 1.3.4 --- assets/docs/changelog.txt | 303 ++++++++++++++++++ install/assets/snippets/DDocInfo.tpl | 29 -- install/assets/snippets/DLBeforeAfter.tpl | 15 - install/assets/snippets/DLBuildMenu.tpl | 15 - install/assets/snippets/DLFirstChar.tpl | 23 -- install/assets/snippets/DLPrevNext.tpl | 15 - install/assets/snippets/DLReflect.tpl | 15 - install/assets/snippets/DLReflectFilter.tpl | 15 - install/assets/snippets/DLTemplate.tpl | 15 - install/assets/snippets/DLglossary.tpl | 15 - install/assets/snippets/DLvaluelist.tpl | 15 - .../actions/help/version_notices/1.3.4.php | 8 + 12 files changed, 311 insertions(+), 172 deletions(-) delete mode 100644 install/assets/snippets/DDocInfo.tpl delete mode 100644 install/assets/snippets/DLBeforeAfter.tpl delete mode 100644 install/assets/snippets/DLBuildMenu.tpl delete mode 100644 install/assets/snippets/DLFirstChar.tpl delete mode 100644 install/assets/snippets/DLPrevNext.tpl delete mode 100644 install/assets/snippets/DLReflect.tpl delete mode 100644 install/assets/snippets/DLReflectFilter.tpl delete mode 100644 install/assets/snippets/DLTemplate.tpl delete mode 100644 install/assets/snippets/DLglossary.tpl delete mode 100644 install/assets/snippets/DLvaluelist.tpl create mode 100644 manager/actions/help/version_notices/1.3.4.php diff --git a/assets/docs/changelog.txt b/assets/docs/changelog.txt index ece45ca885..8ff983a17d 100644 --- a/assets/docs/changelog.txt +++ b/assets/docs/changelog.txt @@ -1,6 +1,309 @@ This file shows the changes in recent releases of Evolution CMS. The most current release is usually the development release, and is only shown to give an idea of what's currently in the pipeline. +Evolution CMS 1.3.4 (Aug 24, 2017) +* [GitHub:#d03412a7] - Updater one more check for use from manager only (dmi3yy) +* [GitHub:#ec2c7f23] - update FormLister to 1.7.8 (dmi3yy) +* [GitHub:#60619960] - update DocLister 1.3.11 (dmi3yy) +* [GitHub:#e3c58c40] - [F] fix Ditto sorting by pub_date leads to no results #179 (dmi3yy) +* [GitHub:#46074033] - [F] correct #184 (Serg) +* [GitHub:#ee3128ac] - [F] update style buttons in manage elements add margin (64j) +* [GitHub:#2c3785ca] - [I] Quick Manager : New "Load Font Awesome css in front-end" plugin setting (Nicola) +* [GitHub:#afb7b0d7] - [R] refactor datePicker javascript es2015 standard for job in IE11 (64j) +* [GitHub:#0dc8d416] - update forms.css change color radio and checkbox (64j) +* [GitHub:#2e8a052d] - [F] Fix - mm_widget_showimagetvs by https url (yamamoto) +* [GitHub:#6b015400] - fix DocManager which_browser for tvars add DatePicker format code (64j) +* [GitHub:#9832bbd3] - fix quickly filter elements disabled press enter (64j) +* [GitHub:#54b89c95] - refactor Document Manager remove mootools (64j) +* [GitHub:#ac62798a] - remove unused DBAPI methods (Pathologic) +* [GitHub:#05a7b383] - fix #24 (Pathologic) +* [GitHub:#2139dcb5] - fix #23 (Pathologic) +* [GitHub:#74fc4606] - refactor Manage Gategories deleted mootools (64j) +* [GitHub:#51993f44] - update header.php add evo.draggable (64j) +* [GitHub:#84cfb156] - fix (Pathologic) +* [GitHub:#eb7956c8] - fix warning tabPage in FF (64j) +* [GitHub:#d9f95baf] - fix #38 (Pathologic) +* [GitHub:#d541bcc7] - fix inputs and buttons padding, width (64j) +* [GitHub:#c59efff4] - fix (Pathologic) +* [GitHub:#f52a6e96] - Remove Japanese comment (yamamoto) +* [GitHub:#8370c6b4] - New - [*value:makeUrl*] modifier (yamamoto) +* [GitHub:#616cfb17] - New - Core modifier math (yamamoto) +* [GitHub:#b00cd21b] - Refactor (yamamoto) +* [GitHub:#6573becd] - Code cleanup (yamamoto) +* [GitHub:#e8bb914b] - Code cleanup (yamamoto) +* [GitHub:#25117c60] - Fix - :id modifier (yamamoto) +* [GitHub:#ec6168a3] - Fix - typo (yamamoto) +* [GitHub:#f3c5a4b8] - Code cleanup (yamamoto) +* [GitHub:#cfcff99d] - [F] #173 Wayfinder [+wf.level+] no output any more (yamamoto) +* [GitHub:#4889cf8f] - Ditto - Code clean up (yamamoto) +* [GitHub:#abc194e2] - refactor MODxMailer (Pathologic) +:...skipping... +* [GitHub:#30e0efc9] - fix version (dmi3yy) +* [GitHub:#d03412a7] - Updater one more check for use from manager only (dmi3yy) +* [GitHub:#ec2c7f23] - update FormLister to 1.7.8 (dmi3yy) +* [GitHub:#60619960] - update DocLister (dmi3yy) +* [GitHub:#e3c58c40] - fix Ditto sorting by pub_date leads to no results #179 (dmi3yy) +* [GitHub:#46074033] - correct #184 (Serg) +* [GitHub:#ee3128ac] - update style buttons in manage elements add margin (64j) +* [GitHub:#2c3785ca] - [E] Quick Manager : New "Load Font Awesome css in front-end" plugin setting (Nicola) +* [GitHub:#139d0cc0] - update forms.css add style buttons (64j) +* [GitHub:#c3e02422] - Update README.md (Anton Kolesnikov) +* [GitHub:#7ee2ef4d] - Update README.md (Anton Kolesnikov) +* [GitHub:#0fc55da6] - Update README.md (Anton Kolesnikov) +* [GitHub:#afb7b0d7] - refactor datePicker javascript es2015 standard for job in IE11 (64j) +* [GitHub:#0dc8d416] - update forms.css change color radio and checkbox (64j) +* [GitHub:#2e8a052d] - Fix - mm_widget_showimagetvs by https url (yamamoto) +* [GitHub:#6b015400] - fix DocManager which_browser for tvars add DatePicker format code (64j) +* [GitHub:#15346ef7] - update css default theme (64j) +* [GitHub:#9832bbd3] - fix quickly filter elements disabled press enter (64j) +* [GitHub:#f30fd5aa] - refactor css default theme (64j) +* [GitHub:#54b89c95] - refactor Document Manager remove mootools (64j) +* [GitHub:#ac62798a] - remove unused DBAPI methods (Pathologic) +* [GitHub:#05a7b383] - fix #24 (Pathologic) +* [GitHub:#2139dcb5] - fix #23 (Pathologic) +* [GitHub:#74fc4606] - refactor Manage Gategories deleted mootools (64j) +* [GitHub:#51993f44] - update header.php add evo.draggable (64j) +* [GitHub:#84cfb156] - fix (Pathologic) +* [GitHub:#eb7956c8] - fix warning tabPage in FF (64j) +* [GitHub:#d9f95baf] - fix #38 (Pathologic) +* [GitHub:#d541bcc7] - fix inputs and buttons padding, width (64j) +* [GitHub:#c59efff4] - fix (Pathologic) +* [GitHub:#f52a6e96] - Remove Japanese comment (yamamoto) +* [GitHub:#8370c6b4] - New - [*value:makeUrl*] modifier (yamamoto) +* [GitHub:#616cfb17] - New - Core modifier math (yamamoto) +* [GitHub:#b00cd21b] - Refactor (yamamoto) +* [GitHub:#6573becd] - Code cleanup (yamamoto) +* [GitHub:#e8bb914b] - Code cleanup (yamamoto) +* [GitHub:#25117c60] - Fix - :id modifier (yamamoto) +* [GitHub:#ec6168a3] - Fix - typo (yamamoto) +* [GitHub:#f3c5a4b8] - Code cleanup (yamamoto) +* [GitHub:#cfcff99d] - [F] #173 Wayfinder [+wf.level+] no output any more (yamamoto) +* [GitHub:#4889cf8f] - Ditto - Code clean up (yamamoto) +* [GitHub:#abc194e2] - refactor MODxMailer (Pathologic) +* [GitHub:#48c5e2fa] - [F] #143 Fix sorting of items in element-listings (Deesen) +* [GitHub:#11318883] - Fix #168 Ditto sees single Resources as Folders (yamamoto) +* [GitHub:#a376de86] - Minor fix (yamamoto) +* [GitHub:#ea15209e] - [DocListre] $modx->config['enable_filter'] (yamamoto) +* [GitHub:#a4f60166] - Fix #127 (yamamoto) +* [GitHub:#72f160f0] - fix bug tree sorting (Serg) +* [GitHub:#243d0cbd] - DocLister 2.3.10 (Pathologic) +* [GitHub:#ad493fc5] - DocLister 2.3.10 (Pathologic) +* [GitHub:#eca89655] - update transition inputs radio and checkbox (64j) +* [GitHub:#47ddae9b] - Refactor (yamamoto) +* [GitHub:#7028c2d3] - Code cleanup - DBAPI (yamamoto) +* [GitHub:#241ba661] - Fix DBAPI (yamamoto) +* [GitHub:#5026cbd4] - Fix - Related @d723915 (yamamoto) +* [GitHub:#14ea7e3f] - update style checkboxes and radio buttons (64j) +* [GitHub:#d7239159] - fix #167 (Pathologic) +* [GitHub:#9e576658] - fix #149 (Pathologic) +* [GitHub:#3c80664d] - remove transition blur text when hovering (Serg) +* [GitHub:#e618355b] - fix padding input-group-addon class (Serg) +* [GitHub:#e99a030d] - normalize style inputs, buttons, list select (64j) +* [GitHub:#3ab388c6] - normalize style inputs, buttons, list select in FF (64j) +* [GitHub:#1ac70c76] - fix #158 (64j) +* [GitHub:#ec8f7ee0] - normalize style inputs, buttons, list select added cross browser style for check boxes, radio buttons, list select (64j) +* [GitHub:#16403889] - Refactor (yamamoto) +* [GitHub:#b58b87a7] - Refactor cache_sync (yamamoto) +* [GitHub:#36e2ab81] - Refactor $modx->checkPublishStatus() (yamamoto) +* [GitHub:#35625fa3] - Update english.inc.php (Mr B) +* [GitHub:#360678b0] - Refactor - Remove $modx->getDocumentMethod() (yamamoto) +* [GitHub:#2c190f2d] - Refactor - $modx->_IIS_furl_fix() (yamamoto) +* [GitHub:#2d4571cf] - Refactor - $modx->postProcess() (yamamoto) +* [GitHub:#5ebcada9] - Refactor - $modx->checkPublishStatus() (yamamoto) +* [GitHub:#a06aecd6] - Remove $modx->setRequestQ() (yamamoto) +* [GitHub:#7b38336d] - Update changelog.txt (Mr B) +* [GitHub:#26ac6b39] - Update 01About_EVO.php (Mr B) +* [GitHub:#10d5ce61] - fix css line-height for textarea (64j) +* [GitHub:#4520b3f9] - fix index name (Pathologic) +* [GitHub:#6d20167f] - Update 02Documentation.php (Mr B) +* [GitHub:#a247e118] - fix #155 (Pathologic) +* [GitHub:#2c40a6d0] - add unique index to document_groups and site_tmplvar_contentvalues (Pathologic) +* [GitHub:#6b99aab8] - normalize vertical inputs and buttons (64j) +* [GitHub:#ed0c10c4] - resolve #148 (64j) +* [GitHub:#8b441bcb] - update css class sectionBody, sectionHeader (64j) +* [GitHub:#9072e966] - Change class styles and new layout of sections (64j) +* [GitHub:#0de44795] - Update 02Documentation.php (Mr B) +* [GitHub:#5d8b5ad9] - [I] #147 $modx->sendForward() (yamamoto) +* [GitHub:#d1d74e85] - resolve issue #151 (64j) +* [GitHub:#dbd67dce] - [F] #151 Errors saving system configuration (yamamoto) +* [GitHub:#413f6bd6] - add evo.collapse (64j) +* [GitHub:#0d7a7319] - Fix (yamamoto) +* [GitHub:#f5092ab1] - Refactor - $modx->db->select() (yamamoto) +* [GitHub:#87df7125] - removing deprecated css classes (64j) +* [GitHub:#c88ac9b1] - fix codemirror border in one-dark theme (64j) +* [GitHub:#3368e8fc] - fix min-height input search in top menu (64j) +* [GitHub:#21e57787] - fix css image height (64j) +* [GitHub:#1ef08655] - [I] array data into $modx->db->query() (yamamoto) +* [GitHub:#d2feee38] - Translate ru to english (yamamoto) +* [GitHub:#92fc062a] - [I] #116 For vue.js (yamamoto) +* [GitHub:#8f23175e] - Fix (yamamoto) +* [GitHub:#02943e4a] - DIRECTORY_SEPARATOR (yamamoto) +* [GitHub:#640dd225] - [R] $ditto->fetch() (yamamoto) +* [GitHub:#3f108c9b] - [I] DocLister - Using Core modifiers (yamamoto) +* [GitHub:#1c6ac02e] - fix btn-sm padding (64j) +* [GitHub:#cc091b53] - update check mail ajax (64j) +* [GitHub:#f4514b99] - update check conection to server (64j) +* [GitHub:#c181c71a] - no message (64j) +* [GitHub:#eade0468] - added lang error_internet_connection english russian (64j) +* [GitHub:#b37ed9e8] - remove style button format code (64j) +* [GitHub:#23b37c09] - update style buttons, inputs (64j) +* [GitHub:#6367c0c5] - fix show help description format code (64j) +* [GitHub:#b934ab46] - add check conection to server refactor code (64j) +* [GitHub:#9a081655] - fix favicon form login (64j) +* [GitHub:#f5728a10] - refactor getSettings (Pathologic) +* [GitHub:#10cb5dd8] - [F] fix for check version in update with version_compare (dmi3yy) +* [GitHub:#c3d1109c] - fix file names (dmi3yy) +* [GitHub:#d8aabd61] - fix my local (dmi3yy) +* [GitHub:#eaba6e8e] - fix trouble with my local git (dmi3yy) +* [GitHub:#b7a8e801] - refactor evoTooltips in header.php (Serg) +* [GitHub:#3c862c21] - no message (dmi3yy) +* [GitHub:#c7fef5a3] - no message (dmi3yy) +* [GitHub:#8c123fc5] - refactor evoTooltips in header.php (Serg) +* [GitHub:#4edf578d] - update evoTooltips in header.php (Serg) +* [GitHub:#805667dc] - refactor evoSortable in header.php (Serg) +* [GitHub:#389480ed] - Update categories.js (Serg) +* [GitHub:#58d75d20] - Update .gitignore (yamamoto) +* [GitHub:#f7ea5e48] - update evoSortable in header.php (64j) +* [GitHub:#3cc61fad] - update evoSortable in header.php (64j) +* [GitHub:#053269be] - update manager categories remove mootools sortable, replace evoSortable (64j) +* [GitHub:#452d879b] - add evoSortable in header.php refactor code (64j) +* [GitHub:#01d63014] - Fix @396814f#commitcomment-23456321 (yamamoto) +* [GitHub:#8219b64f] - 1.3x version noticies draft (Nicola) +* [GitHub:#581cd64b] - modx evo version noticies (Nicola) +* [GitHub:#8745f307] - added support for both (modx and evo) cms name in version noticies (Nicola) +* [GitHub:#7ab5558c] - updated help logs tab for evo (Nicola) +* [GitHub:#9d64b02f] - updated help documentation tab for evo (Nicola) +* [GitHub:#f7505a33] - updated about tab for Evo (Nicola) +* [GitHub:#36e4bc09] - updated help templates path (Nicola) +* [GitHub:#f8e41287] - moved help templates to manager/actions (Nicola) +* [GitHub:#2fb69eab] - update default style refactor (64j) +* [GitHub:#35070b9e] - remove unused css files (64j) +* [GitHub:#48767ee7] - update manager categories refactor code, replace jQuery, Mootools (64j) +* [GitHub:#7df8acaf] - update evo tooltip (64j) +* [GitHub:#9906b5a9] - update document.static (64j) +* [GitHub:#72fa4754] - update evo tooltip (64j) +* [GitHub:#65dfe495] - update messages.static (64j) +* [GitHub:#0b747ac6] - update style move_document.php (64j) +* [GitHub:#4bc440a1] - update style table data base add tooltips (64j) +* [GitHub:#f4d30ca7] - resolve #135 (64j) +* [GitHub:#fcd6b4ee] - Refactor - Use $_SERVER['REQUEST_TIME'] (yamamoto) +* [GitHub:#7f986c70] - [I] New - $modx->config['enable_cache'] (yamamoto) +* [GitHub:#40514b5c] - Code cleanup (readable flow) (yamamoto) +* [GitHub:#2e81ff4b] - [Fix] Missing parse modifier (yamamoto) +* [GitHub:#b45cc3a7] - [F] Cross References bug [*pagetitle@parent*] (yamamoto) +* [GitHub:#396814fe] - [F] #134 Fix bug Cross References (yamamoto) +* [GitHub:#26a9c185] - Fix @7f3a73f (yamamoto) +* [GitHub:#0fbb8c6b] - Fix @LITERAL (yamamoto) +* [GitHub:#7f3a73f3] - remove etomite "compatibility" (Pathologic) +* [GitHub:#d6b4f634] - add css class tab-content (64j) +* [GitHub:#b3ecfd0f] - refactor bkmanager (64j) +* [GitHub:#387dd53b] - add tooltips in header.php (64j) +* [GitHub:#0cbe8999] - [I] #116 Display EVO tags on page (yamamoto) +* [GitHub:#4d984082] - Refactor (yamamoto) +* [GitHub:#7d7b44d6] - fix #130 (Serg) +* [GitHub:#a6d99c4c] - fix #130 (Serg) +* [GitHub:#d36bf3f9] - https://github.com/evolution-cms/evolution/issues/135 reverted the css fix and changed class in the module (Nicola) +* [GitHub:#c5ec13ed] - revert https://github.com/Nicola1971/evolution/commit/0a6889f553e1ea59406a29638fc311b59f22f37a (Nicola) +* [GitHub:#9b2b89f4] - update DLMenu (Pathologic) +* [GitHub:#60e644c6] - fix redundant tag (Pathologic) +* [GitHub:#268da0f6] - update install (Pathologic) +* [GitHub:#3de4fda4] - fix #127 (Pathologic) +* [GitHub:#456b6e20] - update demo content (Pathologic) +* [GitHub:#eba6019b] - solve #130 (Pathologic) +* [GitHub:#9fa434b2] - [I] #116 Display EVO tags on page (yamamoto) +* [GitHub:#0a6889f5] - [f] for Manage Categories Help Toggle Not Work https://github.com/evolution-cms/evolution/issues/135 (Nicola) +* [GitHub:#594e693a] - [F] Replace "\" by "/" to fit MODX_BASE_PATH (Deesen) +* [GitHub:#3b3f6a8e] - [I] $modx->db->lastQuery (yamamoto) +* [GitHub:#74fbdbf9] - [C]: Code clean-up (yamamoto) +* [GitHub:#90391b27] - fix contextmenu (64j) +* [GitHub:#71f2aa95] - fix #127 (Pathologic) +* [GitHub:#3315496d] - remove mootools (64j) +* [GitHub:#ff34df05] - remove mootools addEvent (64j) +* [GitHub:#e6729fae] - remove mootools in datepicker.js (64j) +* [GitHub:#96b11bf3] - add quotes install/config.tpl (64j) +* [GitHub:#80def3ae] - fix #132 (64j) +* [GitHub:#73af528e] - add newline at end of file #126 (64j) +* [GitHub:#3884e3ed] - added createdon, editedon (64j) +* [GitHub:#63741625] - update DocLister and FormLister (Pathologic) +* [GitHub:#9ea9881d] - fix #127 (Pathologic) +* [GitHub:#a6a2abd6] - update #126 add cache name and props disable snippets and chunks (64j) +* [GitHub:#4787482d] - revert https://github.com/evolution-cms/evolution/commit/fb9f8cc4f864c4ef8db7e9e6d744e66d602835c9 (Pathologic) +* [GitHub:#27df9335] - fix #127 (Pathologic) +* [GitHub:#fb9f8cc4] - fix #127 (Pathologic) +* [GitHub:#a039d981] - fix #129 (64j) +* [GitHub:#f9dab1a3] - add check role #126 (64j) +* [GitHub:#3d24e2a4] - added disable/enable snippets and chuncks #126 (64j) +* [GitHub:#7a7428a6] - fix errors PHP7 undefined variables (64j) +* [GitHub:#696d96e7] - add createdon, editedon to tv-parameters (#126 related) (Pathologic) +* [GitHub:#39f7f8f3] - resolve #126 (Pathologic) +* [GitHub:#b3717c22] - add newline at end of file (64j) +* [GitHub:#ce25057f] - fix #128 (64j) +* [GitHub:#87e768f0] - fix #83 format code (64j) +* [GitHub:#6ab7fce9] - fix issue #83 (64j) +* [GitHub:#ae1112b1] - format code modules.static (64j) +* [GitHub:#47cb461c] - fix issue #105 (64j) +* [GitHub:#e5ec1383] - update issue #105 (64j) +* [GitHub:#c941e22a] - resolve issue #105 (64j) +* [GitHub:#e902a162] - solved #124 (Pathologic) +* [GitHub:#d2e38987] - updated manager italian language for evo1.3.3 (Nicola) +* [GitHub:#8d387fed] - updated italian language for evo1.3.3 (Nicola) +* [GitHub:#f3136b07] - fix form-check in bkmanager (64j) +* [GitHub:#29781a47] - update viewport (64j) +* [GitHub:#d4230da8] - update style table nowrap format code (64j) +* [GitHub:#91a53c45] - update searchbar refactor code (64j) +* [GitHub:#94ddd2fd] - Refactor (yamamoto) +* [GitHub:#9927da82] - update width columns (64j) +* [GitHub:#87bf03d2] - format code (64j) +* [GitHub:#33414537] - resolve #90 (64j) +* [GitHub:#58da6fe7] - fix #121 (64j) +* [GitHub:#48e9dfff] - [F] #99 Use config['docid_incrmnt_method'] when duplicating resources (Deesen) +* [GitHub:#6dce1e32] - Delete 090_Восстановление паролей пользователями.md (Anton Kolesnikov) +* [GitHub:#268d46aa] - Delete 075_Активация учетных записей.md (Anton Kolesnikov) +* [GitHub:#11b1366f] - Delete 070_Регистрация пользователей.md (Anton Kolesnikov) +* [GitHub:#129a0a4c] - Delete 060_Авторизация пользователей.md (Anton Kolesnikov) +* [GitHub:#07a6e604] - [I] #55 @FILE for chunks - {{@FILE:assets/chunks/header.html}} (Deesen) +* [GitHub:#d62b4f9b] - update data sortable (64j) +* [GitHub:#aa951d9c] - update style system info (64j) +* [GitHub:#7d6d1305] - remove extra character (64j) +* [GitHub:#1d7082c8] - format code PSR2 (64j) +* [GitHub:#33a7d473] - format code (64j) +* [GitHub:#aa04a374] - update sort columns (64j) +* [GitHub:#4d62717c] - fix #112 (64j) +* [GitHub:#4ed6f32e] - foram code (64j) +* [GitHub:#76a38432] - update for porblem OnManagerTopPrerender (64j) +* [GitHub:#be8031ff] - fix z-index action buttons for codeMirror full screen (64j) +* [GitHub:#e26b2bee] - Update style.css (Serg) +* [GitHub:#2759f4f6] - fix mce buttons (Serg) +* [GitHub:#d37f6323] - fix #110 (Serg) +* [GitHub:#58b89e16] - fix #110 (Serg) +* [GitHub:#2b899254] - update style buttons actions (64j) +* [GitHub:#dcaca322] - fix codemirror remove mootools fix hotkeys (64j) +* [GitHub:#48aa4b44] - [R] update style tvars image / file (64j) +* [GitHub:#e4a1360f] - [R] update style mutate password (64j) +* [GitHub:#ddd98de5] - [R] update style logging static (64j) +* [GitHub:#893f83fc] - [R] update style search page (64j) +* [GitHub:#9ef5b101] - [R] update style page clear cache (64j) +* [GitHub:#cde514e7] - [R] update style managment roles (64j) +* [GitHub:#38e267c9] - [R] update style managment users / roles (64j) +* [GitHub:#db46e561] - [F] fix #107 (64j) +* [GitHub:#71ad7bd6] - [F] fix #106 (64j) +* [GitHub:#d84c5433] - [R] update style elements (64j) +* [GitHub:#873bf1fa] - [R] update style page webusers permissions (64j) +* [GitHub:#14096b71] - [R] update style page managers permissions (64j) +* [GitHub:#b3cdd621] - [F] fix #63 (64j) +* [GitHub:#4b0a4fc3] - [F] fix #103 (Pathologic) +* [GitHub:#c90042e4] - [F] fix #83 (64j) +* [GitHub:#45a8aa77] - [C]remove deprecated libs (Pathologic) +* [GitHub:#a7243bb3] - [F] #92 (Pathologic) +* [GitHub:#a3bac9d8] - [F] #71 (64j) +* [GitHub:#7b60d2cc] - [F] #71 fix permissions (64j) +* [GitHub:#2b2a2a62] - [C]remove redundant code - tags are cleaned in cleanUpMODXTags (Pathologic) +* [GitHub:#8fd7d31f] - [F] Avoid "Fatal error: Call to undefined function curl_init()" (Deesen) +* [GitHub:#60a77940] - [F] fix #94 Hide rss widgets if rss_url_news and rss_url_security settings are empty (dmi3yy) +* [GitHub:#bd649a9f] - [F] #93 (Pathologic) +* [GitHub:#12007dec] - [F] #87 missing OnManagerTopPrerender (Nicola) + + Evolution CMS 1.3.3 (Jul 20, 2017) * [GitHub:#f83719a0] - [F] fix for multiTV<10.0.12 (need branch name Evolution) (dmi3yy) * [GitHub:#3ac1ef3f] - [F] fix issues #73 update login form (64j) diff --git a/install/assets/snippets/DDocInfo.tpl b/install/assets/snippets/DDocInfo.tpl deleted file mode 100644 index 0731dacb50..0000000000 --- a/install/assets/snippets/DDocInfo.tpl +++ /dev/null @@ -1,29 +0,0 @@ -//documentObject['id']; -$field = isset($field) ? (string)$field : 'id'; -if($field == 'id'){ - $out = $id; -}else{ - if($modx->documentObject['id'] == $id){ - $out = isset($modx->documentObject[$field]) ? $modx->documentObject[$field] : ''; - if(is_array($out)){ - $out = isset($out[1]) ? $out[1] : ''; - } - }else{ - $out = $modx->doc->edit($id)->get($field); - } -} -return (string)$out; \ No newline at end of file diff --git a/install/assets/snippets/DLBeforeAfter.tpl b/install/assets/snippets/DLBeforeAfter.tpl deleted file mode 100644 index 82e0a7a9a6..0000000000 --- a/install/assets/snippets/DLBeforeAfter.tpl +++ /dev/null @@ -1,15 +0,0 @@ -//[+pagetitle+]
    ` - * &tplOnNewChar=`@CODE:
    [+char+] ([+total+])
    ` - * &tplCharSeparator=`@CODE:
    ` - * &orderBy=`BINARY pagetitle ASC` - * ]] - */ - -return require MODX_BASE_PATH.'assets/snippets/DocLister/snippet.DLFirstChar.php'; \ No newline at end of file diff --git a/install/assets/snippets/DLPrevNext.tpl b/install/assets/snippets/DLPrevNext.tpl deleted file mode 100644 index e0a0d90706..0000000000 --- a/install/assets/snippets/DLPrevNext.tpl +++ /dev/null @@ -1,15 +0,0 @@ -//INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +?> +

    +
      +
    • fix minor issues +
    • +
    From e323f74a5f4a800a444dab929b9f6d78005aa2db Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Thu, 24 Aug 2017 14:11:29 +0300 Subject: [PATCH 298/338] fix changelog --- assets/docs/changelog.txt | 36 ------------------- .../actions/help/version_notices/1.3.4.php | 16 +++++++-- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/assets/docs/changelog.txt b/assets/docs/changelog.txt index 8ff983a17d..dfbe3601b2 100644 --- a/assets/docs/changelog.txt +++ b/assets/docs/changelog.txt @@ -2,42 +2,6 @@ This file shows the changes in recent releases of Evolution CMS. The most curren development release, and is only shown to give an idea of what's currently in the pipeline. Evolution CMS 1.3.4 (Aug 24, 2017) -* [GitHub:#d03412a7] - Updater one more check for use from manager only (dmi3yy) -* [GitHub:#ec2c7f23] - update FormLister to 1.7.8 (dmi3yy) -* [GitHub:#60619960] - update DocLister 1.3.11 (dmi3yy) -* [GitHub:#e3c58c40] - [F] fix Ditto sorting by pub_date leads to no results #179 (dmi3yy) -* [GitHub:#46074033] - [F] correct #184 (Serg) -* [GitHub:#ee3128ac] - [F] update style buttons in manage elements add margin (64j) -* [GitHub:#2c3785ca] - [I] Quick Manager : New "Load Font Awesome css in front-end" plugin setting (Nicola) -* [GitHub:#afb7b0d7] - [R] refactor datePicker javascript es2015 standard for job in IE11 (64j) -* [GitHub:#0dc8d416] - update forms.css change color radio and checkbox (64j) -* [GitHub:#2e8a052d] - [F] Fix - mm_widget_showimagetvs by https url (yamamoto) -* [GitHub:#6b015400] - fix DocManager which_browser for tvars add DatePicker format code (64j) -* [GitHub:#9832bbd3] - fix quickly filter elements disabled press enter (64j) -* [GitHub:#54b89c95] - refactor Document Manager remove mootools (64j) -* [GitHub:#ac62798a] - remove unused DBAPI methods (Pathologic) -* [GitHub:#05a7b383] - fix #24 (Pathologic) -* [GitHub:#2139dcb5] - fix #23 (Pathologic) -* [GitHub:#74fc4606] - refactor Manage Gategories deleted mootools (64j) -* [GitHub:#51993f44] - update header.php add evo.draggable (64j) -* [GitHub:#84cfb156] - fix (Pathologic) -* [GitHub:#eb7956c8] - fix warning tabPage in FF (64j) -* [GitHub:#d9f95baf] - fix #38 (Pathologic) -* [GitHub:#d541bcc7] - fix inputs and buttons padding, width (64j) -* [GitHub:#c59efff4] - fix (Pathologic) -* [GitHub:#f52a6e96] - Remove Japanese comment (yamamoto) -* [GitHub:#8370c6b4] - New - [*value:makeUrl*] modifier (yamamoto) -* [GitHub:#616cfb17] - New - Core modifier math (yamamoto) -* [GitHub:#b00cd21b] - Refactor (yamamoto) -* [GitHub:#6573becd] - Code cleanup (yamamoto) -* [GitHub:#e8bb914b] - Code cleanup (yamamoto) -* [GitHub:#25117c60] - Fix - :id modifier (yamamoto) -* [GitHub:#ec6168a3] - Fix - typo (yamamoto) -* [GitHub:#f3c5a4b8] - Code cleanup (yamamoto) -* [GitHub:#cfcff99d] - [F] #173 Wayfinder [+wf.level+] no output any more (yamamoto) -* [GitHub:#4889cf8f] - Ditto - Code clean up (yamamoto) -* [GitHub:#abc194e2] - refactor MODxMailer (Pathologic) -:...skipping... * [GitHub:#30e0efc9] - fix version (dmi3yy) * [GitHub:#d03412a7] - Updater one more check for use from manager only (dmi3yy) * [GitHub:#ec2c7f23] - update FormLister to 1.7.8 (dmi3yy) diff --git a/manager/actions/help/version_notices/1.3.4.php b/manager/actions/help/version_notices/1.3.4.php index cb5767676a..b1e44713ac 100644 --- a/manager/actions/help/version_notices/1.3.4.php +++ b/manager/actions/help/version_notices/1.3.4.php @@ -3,6 +3,18 @@ ?>

      -
    • fix minor issues -
    • +
    • update FormLister to 1.7.8 (dmi3yy)
    • +
    • update DocLister to 1.3.11 (dmi3yy)
    • +
    • @FILE for chunks - {{@FILE:assets/chunks/header.html}}
    • +
    • remove mootols from manage category
    • +
    • added disable/enable snippets and chuncks #126
    • +
    • Depricated keywords and metatags (not used by default from 1.0.8 version) use TV for this.
    • +
    • new settings for group TVs (http://take.ms/OmFYb)
    • +
    • add header("X-XSS-Protection: 0"); for correct work filamanager.
    • +
    • Add DLSitemap and DLMenu snippets
    • +
    • Remove DLBuildMenu
    • +
    • Refactor manager search and fix permision for this
    • +
    • remove etomite "compatibility"
    • +
    • New - $modx->config['enable_cache']
    • +
    • New - [*value:makeUrl*] modifier
    From 4903a8bd3604bf36b3e98e71753883f7f738fb6e Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 25 Aug 2017 14:59:11 +0300 Subject: [PATCH 299/338] fix saved roles users #130 --- manager/processors/save_role.processor.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/manager/processors/save_role.processor.php b/manager/processors/save_role.processor.php index 68360fae00..0f7d952961 100644 --- a/manager/processors/save_role.processor.php +++ b/manager/processors/save_role.processor.php @@ -75,8 +75,6 @@ 'exec_module' => $exec_module, 'view_eventlog' => $view_eventlog, 'delete_eventlog' => $delete_eventlog, - 'manage_metatags' => $manage_metatags, - 'edit_doc_metatags' => $edit_doc_metatags, 'new_web_user' => $new_web_user, 'edit_web_user' => $edit_web_user, 'save_web_user' => $save_web_user, From 57747d3cc8ed4344071d113b493bcddac9c72c05 Mon Sep 17 00:00:00 2001 From: Serg <64j@mail.ru> Date: Fri, 25 Aug 2017 15:02:08 +0300 Subject: [PATCH 300/338] fix saved roles users #130 --- manager/actions/mutate_role.dynamic.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/manager/actions/mutate_role.dynamic.php b/manager/actions/mutate_role.dynamic.php index 1a185317c9..f6b3fa31a6 100644 --- a/manager/actions/mutate_role.dynamic.php +++ b/manager/actions/mutate_role.dynamic.php @@ -131,7 +131,6 @@ function changestate(element) { echo render_form('publish_document', $_lang['role_publish_doc']); echo render_form('delete_document', $_lang['role_delete_doc']); echo render_form('empty_trash', $_lang['role_empty_trash']); - echo render_form('edit_doc_metatags', $_lang['role_edit_doc_metatags']); echo render_form('empty_cache', $_lang['role_cache_refresh']); echo render_form('view_unpublished', $_lang['role_view_unpublished']); ?> @@ -276,7 +275,6 @@ function changestate(element) { echo render_form('logs', $_lang['role_view_logs']); echo render_form('settings', $_lang['role_edit_settings']); echo render_form('bk_manager', $_lang['role_bk_manager']); - echo render_form('manage_metatags', $_lang['role_manage_metatags']); echo render_form('import_static', $_lang['role_import_static']); echo render_form('export_static', $_lang['role_export_static']); echo render_form('remove_locks', $_lang['role_remove_locks']); From 7374ccf611c92ffe643d793b1f2635e9012a2627 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 25 Aug 2017 15:25:44 +0300 Subject: [PATCH 301/338] fix eng translate --- manager/includes/lang/english.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manager/includes/lang/english.inc.php b/manager/includes/lang/english.inc.php index 1e339f5e48..1d69bdfd8e 100644 --- a/manager/includes/lang/english.inc.php +++ b/manager/includes/lang/english.inc.php @@ -1081,8 +1081,8 @@ $_lang["top_howmany_message"] = 'When viewing reports, how large should the \'Top ...\' lists be?'; $_lang["top_howmany_title"] = 'Top how many'; $_lang["total"] = 'total'; -$_lang["track_visitors_message"] = 'Provides a hook for analytics Plugins, for example to flag whether or not visits to a specific Resource are logged.'; -$_lang["track_visitors_title"] = 'Enable Stats Tracking'; +$_lang["track_visitors_message"] = 'Check to show the child resources in the document tree'; +$_lang["track_visitors_title"] = 'Show child resources'; $_lang["tree_page_click"] = 'Page Click Behavior'; $_lang["tree_page_click_message"] = 'The default behavior when clicking on a page in the site tree.'; $_lang["use_breadcrumbs"] = 'Show navigation'; From 2c2fe39b3a711dcef90b2877aeb4aafaf4423667 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Fri, 25 Aug 2017 22:22:12 +0900 Subject: [PATCH 302/338] #187 Ditto is missing placeholders when built-in filters are enabled https://github.com/evolution-cms/evolution/issues/187 --- assets/snippets/ditto/classes/ditto.class.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 023bccc4ad..8970994c2b 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -352,7 +352,8 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a $i = 0; while($i<10) { $_ = $output; - $output = $modx->parseText($output,$placeholders); + if(strpos($output,'[+')!==false) $output = $modx->parseText($output,$placeholders); + else $output = $modx->parseDocumentSource($output); if($_===$output) break; $i++; } From ffe64306045edbf2cdcc3abf212db9e0cbb76175 Mon Sep 17 00:00:00 2001 From: Piotr Matysiak Date: Sat, 26 Aug 2017 19:56:06 +0200 Subject: [PATCH 303/338] Make sortable list more condensed Saving some space https://image.prntscr.com/image/sqBlMKj4TCKY7tozogjP4A.png --- manager/media/style/default/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index f6b9ed06ac..5274ad226f 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -240,7 +240,7 @@ ul.breadcrumbs span::after { margin-left: 2em; font-family: FontAwesome; content .grid img { vertical-align: middle; padding-right: 4px; } /* SORTABLELIST */ ul.sortableList { margin: 0; } -ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: .5rem; margin: .0625rem 0; border: 1px solid #ccc; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } +ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: .15rem .5rem; margin: .0825rem 0; border: 1px solid #ccc; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0, 0.15); transition: color .3s, box-shadow .3s, transform 0s, z-index 0s; } /* [ TOOLTIPS ] */ .evo-tooltip, .custom-tip { position: fixed; z-index: 13000; width: 13rem; margin: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); -webkit-box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); } From 3b70064c819c46ab79b5876c3460d8efb47df3f7 Mon Sep 17 00:00:00 2001 From: Piotr Matysiak Date: Sat, 26 Aug 2017 22:35:46 +0200 Subject: [PATCH 304/338] Update to Make sortable list more condensed --- manager/media/style/default/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 5274ad226f..0160a6f814 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -240,7 +240,7 @@ ul.breadcrumbs span::after { margin-left: 2em; font-family: FontAwesome; content .grid img { vertical-align: middle; padding-right: 4px; } /* SORTABLELIST */ ul.sortableList { margin: 0; } -ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: .15rem .5rem; margin: .0825rem 0; border: 1px solid #ccc; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } +ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: 0.461538em 1em; margin: .0625rem 0; border: 1px solid #ccc; line-height: 1.230769; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0, 0.15); transition: color .3s, box-shadow .3s, transform 0s, z-index 0s; } /* [ TOOLTIPS ] */ .evo-tooltip, .custom-tip { position: fixed; z-index: 13000; width: 13rem; margin: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); -webkit-box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); } From 2b5e8ca4473918e8ae37fc9f5e07ad083af5a59b Mon Sep 17 00:00:00 2001 From: Piotr Matysiak Date: Sat, 26 Aug 2017 22:41:23 +0200 Subject: [PATCH 305/338] Update to Make sortable list more condensed --- manager/media/style/default/css/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/media/style/default/css/custom.css b/manager/media/style/default/css/custom.css index 0160a6f814..6d7107cb92 100644 --- a/manager/media/style/default/css/custom.css +++ b/manager/media/style/default/css/custom.css @@ -240,7 +240,7 @@ ul.breadcrumbs span::after { margin-left: 2em; font-family: FontAwesome; content .grid img { vertical-align: middle; padding-right: 4px; } /* SORTABLELIST */ ul.sortableList { margin: 0; } -ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: 0.461538em 1em; margin: .0625rem 0; border: 1px solid #ccc; line-height: 1.230769; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } +ul.sortableList li { position: relative; z-index: 1; float: left; clear: both; max-width: 100%; width: 30rem; list-style: none; font-weight: bold; cursor: move; padding: 0.46153846em 1em; margin: .0625rem 0; border: 1px solid #ccc; line-height: 1.23076923; background-color: #fff; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); box-shadow: none; transition: color .3s, box-shadow .3s, transform .3s, z-index .3s step-end; } ul.sortableList li.ghost { z-index: 2; box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0, 0.15); transition: color .3s, box-shadow .3s, transform 0s, z-index 0s; } /* [ TOOLTIPS ] */ .evo-tooltip, .custom-tip { position: fixed; z-index: 13000; width: 13rem; margin: 1rem; padding: 0.9rem 1rem; font-size: 0.75rem; line-height: 1.5; font-family: sans-serif; text-align: left; color: #333; background-color: #fff; visibility: hidden; transition-duration: .3s; transform: translate3d(1rem, 0, 0); -webkit-box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); box-shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15); } From 835353772e7433fc6f1714e706e2174a2b55c665 Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sun, 27 Aug 2017 10:05:56 +0300 Subject: [PATCH 306/338] fix variable documentDirty --- manager/includes/header.inc.php | 49 +++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 38b8d87d3d..22649b5f04 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -106,15 +106,18 @@ b = b || {}; } let o = { - el: null, handleClass: b.handleClass || 'ghost', complete: function() { + el: null, + handleClass: b.handleClass || 'ghost', + complete: function(c) { if ('function' === typeof b.complete) { - b.complete(); + b.complete(c); } - }, change: function() { + }, + change: function(c) { if ('function' === typeof b.change) { - b.change(); + b.change(c); } - }, + } }; function onmousedown(e) @@ -152,7 +155,7 @@ function onmousemove(e) o.el.style.transform = 'translateY(' + y + 'px)'; } - function onmouseup(e) + function onmouseup() { o.el.style.webkitTransform = ''; o.el.style.transform = ''; @@ -160,7 +163,7 @@ function onmouseup(e) document.removeEventListener('mousemove', onmousemove); document.removeEventListener('mouseup', onmouseup); document.onselectstart = null; - o.complete(); + o.complete(o.el); } for (let i = 0; i < a.length; i++) { @@ -181,18 +184,24 @@ function onmouseup(e) handle: { start: function(c) { 'function' === typeof b.handle.start ? b.handle.start.call(c) : ''; - }, end: function(c) { - 'function' === typeof b.handle.end ? b.handle.end.call(c) : ''; }, - }, container: { - className: b.container.className || 'drop', classOver: b.container.classOver || 'over', over: function(c) { + end: function(c) { + 'function' === typeof b.handle.end ? b.handle.end.call(c) : ''; + } + }, + container: { + className: b.container.className || 'drop', + classOver: b.container.classOver || 'over', + over: function(c) { 'function' === typeof b.container.over ? b.container.over.call(c) : ''; - }, leave: function(c) { + }, + leave: function(c) { 'function' === typeof b.container.leave ? b.container.leave.call(c) : ''; - }, drop: function(c, i) { - 'function' === typeof b.container.drop ? b.container.drop.call(c, i) : ''; }, - }, + drop: function(c, i) { + 'function' === typeof b.container.drop ? b.container.drop.call(c, i) : ''; + } + } }; o.container.els = document.querySelectorAll('.' + o.container.className); @@ -224,7 +233,7 @@ function onmousemove(e) } } - function onmouseup(e) + function onmouseup() { document.removeEventListener('mousemove', onmousemove); document.removeEventListener('mouseup', onmouseup); @@ -267,7 +276,7 @@ function onmouseup(e) a = 'string' === typeof a ? document.querySelectorAll(a) : a; } let h = { - containerClass: b && b.containerClass || 'tab-body', + containerClass: b && b.containerClass || 'tab-body' }; for (let i = 0; i < a.length; i++) { @@ -281,7 +290,7 @@ function onmouseup(e) a[i].nextElementSibling.classList.add('in'); a[i].classList.remove('collapsed'); } - }; + } } } }; @@ -391,8 +400,8 @@ function doRefresh(r) } } - let documentDirty = false; - let timerForUnload; + var documentDirty = false; + var timerForUnload; function checkDirt(evt) { From b8b75b24ffc69e47923a2e0003c41c51f3629a8f Mon Sep 17 00:00:00 2001 From: 64j <64j@mail.ru> Date: Sun, 27 Aug 2017 10:07:38 +0300 Subject: [PATCH 307/338] fix #192 --- manager/includes/header.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/includes/header.inc.php b/manager/includes/header.inc.php index 22649b5f04..d453bd8841 100644 --- a/manager/includes/header.inc.php +++ b/manager/includes/header.inc.php @@ -298,7 +298,7 @@ function onmouseup() // check connection to server evo.checkConnectionToServer = function() { let xhr = new ( window.ActiveXObject || XMLHttpRequest )('Microsoft.XMLHTTP'); - xhr.open('HEAD', '//' + window.location.hostname + window.location.pathname.replace('index.php', 'includes/version.inc.php') + '?time=' + new Date().getTime(), false); + xhr.open('HEAD', 'includes/version.inc.php?time=' + new Date().getTime(), false); try { xhr.send(); return (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304); From d3760b2f55c10cc22662849bbb80af6c71bd1602 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Sun, 27 Aug 2017 13:34:01 +0300 Subject: [PATCH 308/338] no need update.php in extras module --- assets/modules/store/update.php | 46 --------------------------------- 1 file changed, 46 deletions(-) delete mode 100755 assets/modules/store/update.php diff --git a/assets/modules/store/update.php b/assets/modules/store/update.php deleted file mode 100755 index a2079eb816..0000000000 --- a/assets/modules/store/update.php +++ /dev/null @@ -1,46 +0,0 @@ -open(dirname(__FILE__).'/update.zip'); -$zip->extractTo( dirname(__FILE__) ); -$zip->close(); -echo dirname(__FILE__).'/update.zip'; -unlink('update.zip'); -?> From 1bac7219502b2bd650dab086d6d4a714e69943d3 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 08:37:23 +0900 Subject: [PATCH 309/338] #190 Ditto does not recognize &dateSource parameter any more https://github.com/evolution-cms/evolution/issues/190 --- assets/snippets/ditto/classes/ditto.class.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 8970994c2b..1c3939e465 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -305,7 +305,7 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a if (in_array("date",$this->fields["display"]["custom"])) { $timestamp = ($resource[$dateSource] != "0") ? $resource[$dateSource] : $resource["createdon"]; if (is_array($timestamp)) { - $timestamp[1] = is_int($timestamp[1]) ? $timestamp[1] : strtotime($timestamp[1]); + $timestamp[1] = preg_match('@^[1-9][0-9]*$@',$timestamp[1]) ? $timestamp[1] : strtotime($timestamp[1]); $timestamp = $timestamp[1] + $timestamp[0]; } $placeholders['date'] = strftime($dateFormat,$timestamp); @@ -902,7 +902,7 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d $TVIDs = array(); while ($resource = $modx->db->getRow($rs)) { if ($dateSource !== false) { - if(!is_int($resource[$dateSource])) $resource[$dateSource] = strtotime($resource[$dateSource]); + if(!preg_match('@^[1-9][0-9]*$@',$resource[$dateSource])) $resource[$dateSource] = strtotime($resource[$dateSource]); if($modx->config['server_offset_time'] != 0) $resource[$dateSource] += $modx->config['server_offset_time']; } From 19cfd3265a38b74adee7f4c9045d194c0abf7fb7 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 10:03:55 +0900 Subject: [PATCH 310/338] #188 Ditto in dashboard widget permission issue https://github.com/evolution-cms/evolution/issues/188 --- assets/snippets/ditto/classes/ditto.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 1c3939e465..a7b8c91df1 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -892,7 +892,7 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d $sqlWhere[] =$published; $sqlWhere[] ="AND sc.deleted='{$deleted}'"; $sqlWhere[] = $where; - if($public) $sqlWhere[] = "AND ({$access})"; + if($public && $access) $sqlWhere[] = "AND ({$access})"; $sqlWhere[] = 'GROUP BY sc.id'; $rs= $modx->db->select("DISTINCT {$fields}",$from,$sqlWhere,$sort,$limit); if(!$modx->db->getRecordCount($rs)) return false; From abfcdcf6b833333d36ecf5634a717e00e6a93972 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 11:29:47 +0900 Subject: [PATCH 311/338] Code cleanup --- .../ditto/classes/ditto.class.inc.php | 325 +++++++++--------- 1 file changed, 163 insertions(+), 162 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index a7b8c91df1..0f4aeef1e6 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -12,16 +12,16 @@ class ditto { function __construct($dittoID,$format,$language,$debug) { $this->format = $format; - $GLOBALS["ditto_lang"] = $language; + $GLOBALS['ditto_lang'] = $language; $this->prefetch = false; $this->advSort = false; $this->sqlOrderBy = array(); $this->customReset = array(); - $this->constantFields[] = array("db","tv"); - $this->constantFields["db"] = array("id","type","contentType","pagetitle","longtitle","description","alias","link_attributes","published","pub_date","unpub_date","parent","isfolder","introtext","content","richtext","template","menuindex","searchable","cacheable","createdby","createdon","editedby","editedon","deleted","deletedon","deletedby","publishedon","publishedby","menutitle","donthit","privateweb","privatemgr","content_dispo","hidemenu"); - $this->constantFields["tv"] = $this->getTVList(); - $GLOBALS["ditto_constantFields"] = $this->constantFields; - $this->fields = array("display"=>array(),"backend"=>array("tv"=>array(),"db"=>array("id", "published"))); + $this->constantFields[] = array('db','tv'); + $this->constantFields['db'] = explode(',', 'id,type,contentType,pagetitle,longtitle,description,alias,link_attributes,published,pub_date,unpub_date,parent,isfolder,introtext,content,richtext,template,menuindex,searchable,cacheable,createdby,createdon,editedby,editedon,deleted,deletedon,deletedby,publishedon,publishedby,menutitle,donthit,privateweb,privatemgr,content_dispo,hidemenu'); + $this->constantFields['tv'] = $this->getTVList(); + $GLOBALS['ditto_constantFields'] = $this->constantFields; + $this->fields = array('display'=>array(),'backend'=>array('tv'=>array(),'db'=>array('id', 'published'))); $this->sortOrder = false; $this->customPlaceholdersMap = array(); $this->template = new template(); @@ -36,9 +36,8 @@ function __construct($dittoID,$format,$language,$debug) { function getTVList() { global $modx; - $table = $modx->getFullTableName("site_tmplvars"); - $tvs = $modx->db->select("name", $table); // TODO: make it so that it only pulls those that apply to the current template + $tvs = $modx->db->select('name', '[+prefix+]site_tmplvars'); $dbfields = $modx->db->getColumn('name', $tvs); return $dbfields; } @@ -52,14 +51,16 @@ function addField($name,$location,$type=false) { if ($type === false) { $type = $this->getDocVarType($name); } - if ($type == "tv:prefix") { - $type = "tv"; + if ($type == 'tv:prefix') { + $type = 'tv'; $name = substr($name, 2); } - if ($location == "*") { - $this->fields["backend"][$type][] = $name; - $this->fields["display"][$type][] = $name; - } else { + if ($location == '*') { + if(!in_array($name,$this->fields['backend'][$type])) + $this->fields['backend'][$type][] = $name; + if(!in_array($name,$this->fields['display'][$type])) + $this->fields['display'][$type][] = $name; + } elseif(!in_array($name,$this->fields[$location][$type])) { $this->fields[$location][$type][] = $name; } } @@ -114,12 +115,12 @@ function removeField($name,$location,$type) { // --------------------------------------------------- function setDisplayFields($fields,$hiddenFields) { - $this->fields["display"] = $fields; - if (count($this->fields["display"]['qe']) > 0) { - $this->addField("pagetitle","display","db"); + $this->fields['display'] = $fields; + if (count($this->fields['display']['qe']) > 0) { + $this->addField('pagetitle','display','db'); } if ($hiddenFields) { - $this->addFields($hiddenFields,"display"); + $this->addFields($hiddenFields,'display'); } } @@ -130,17 +131,17 @@ function setDisplayFields($fields,$hiddenFields) { function getDocVarType($field) { global $ditto_constantFields; - $tvFields = $ditto_constantFields["tv"]; - $dbFields = $ditto_constantFields["db"]; + $tvFields = $ditto_constantFields['tv']; + $dbFields = $ditto_constantFields['db']; if(in_array($field, $tvFields)){ - return "tv"; + return 'tv'; }else if(in_array(substr($field,2), $tvFields)) { - return "tv:prefix"; + return 'tv:prefix'; // TODO: Remove TV Prefix support } else if(in_array($field, $dbFields)){ - return "db"; + return 'db'; } else { - return "unknown"; + return 'unknown'; } } @@ -173,11 +174,11 @@ function parseOrderBy($orderBy,$randomize) { $sortDir = substr($input,$position); $sortDir = !empty($sortDir) ? trim($sortDir) : 'asc'; $sortBy = $this->checkAdvSort($sortBy,$sortDir); - $this->addField($sortBy,"backend"); + $this->addField($sortBy,'backend'); $orderBy['parsed'][] = array($sortBy,strtoupper($sortDir)); } } - $orderBy['sql'] = implode(', ',$this->sqlOrderBy); + $orderBy['sql'] = join(', ',$this->sqlOrderBy); unset($orderBy['unparsed']); return $orderBy; } @@ -187,17 +188,17 @@ function parseOrderBy($orderBy,$randomize) { // Check the advSortString // --------------------------------------------------- function checkAdvSort($sortBy,$sortDir='asc') { - $advSort = array ("pub_date","unpub_date","editedon","deletedon","publishedon"); + $advSort = array ('pub_date','unpub_date','editedon','deletedon','publishedon'); $type = $this->getDocVarType($sortBy); switch($type) { - case "tv:prefix": + case 'tv:prefix': $sortBy = substr($sortBy, 2); $this->advSort = true; break; - case "tv": + case 'tv': $this->advSort = true; break; - case "db": + case 'db': if (in_array($sortBy, $advSort)) { $this->advSort = true; $this->customReset[] = $sortBy; @@ -215,33 +216,33 @@ function checkAdvSort($sortBy,$sortDir='asc') { // --------------------------------------------------- function parseFilters($filter=false,$cFilters=false,$pFilters = false,$globalDelimiter,$localDelimiter) { - $parsedFilters = array("basic"=>array(),"custom"=>array()); + $parsedFilters = array('basic'=>array(),'custom'=>array()); $filters = explode($globalDelimiter, $filter); if ($filter && count($filters) > 0) { foreach ($filters AS $filter) { if (!empty($filter)) { $filterArray = explode($localDelimiter, $filter); $source = $filterArray[0]; - $this->addField($source,"backend"); + $this->addField($source,'backend'); $value = $filterArray[1]; $mode = (isset ($filterArray[2])) ? $filterArray[2] : 1; - $parsedFilters["basic"][] = array("source"=>$source,"value"=>$value,"mode"=>$mode); + $parsedFilters['basic'][] = array('source'=>$source,'value'=>$value,'mode'=>$mode); } } } if ($cFilters) { foreach ($cFilters as $name=>$value) { if (!empty($name) && !empty($value)) { - $parsedFilters["custom"][$name] = $value[1]; - $this->addFields($value[0],"backend"); + $parsedFilters['custom'][$name] = $value[1]; + $this->addFields($value[0],'backend'); } } // TODO: Replace addField with addFields with callback } if($pFilters) { foreach ($pFilters as $filter) { foreach ($filter as $name=>$value) { - $parsedFilters["basic"][] = $value; - $this->addFields($value["source"],"backend"); + $parsedFilters['basic'][] = $value; + $this->addFields($value['source'],'backend'); } } // TODO: Replace addField with addFields with callback } @@ -257,53 +258,53 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a global $modx,$ditto_lang; if (!is_array($resource)) { - return $ditto_lang["resource_array_error"]; + return $ditto_lang['resource_array_error']; } $placeholders = array(); $contentVars = array(); foreach ($resource as $name=>$value) { - $placeholders["$name"] = $value; - $contentVars["[*$name*]"] = $value; + $placeholders[$name] = $value; + $contentVars["[*{$name}*]"] = $value; } // set author placeholder - if (in_array("author",$this->fields["display"]["custom"])) { + if (in_array('author',$this->fields['display']['custom'])) { $placeholders['author'] = $this->getAuthor($resource['createdby']); } // set title placeholder - if (in_array("title",$this->fields["display"]["custom"])) { + if (in_array('title',$this->fields['display']['custom'])) { $placeholders['title'] = $resource['pagetitle']; } // set sequence placeholder - if (in_array("ditto_iteration",$this->fields["display"]["custom"])) { + if (in_array('ditto_iteration',$this->fields['display']['custom'])) { $placeholders['ditto_iteration'] = $x; } //Added by Andchir - //if (in_array("ditto_index",$this->fields["display"]["custom"])) { + //if (in_array('ditto_index',$this->fields['display']['custom'])) { $r_start = isset($_GET['start']) ? $_GET['start'] : 0; $placeholders['ditto_index'] = $r_start+$x+1; //} //Added by Dmi3yy placeholder ditto_class - if ($x % 2 == 0) {$class="even";} else {$class="odd";} - if ($x==0) $class.=" first"; - if ($x==($stop -1)) $class.=" last"; - if ($resource['id'] == $modx->documentObject['id']) $class.=" current"; + if ($x % 2 == 0) {$class='even';} else {$class='odd';} + if ($x==0) $class.=' first'; + if ($x==($stop -1)) $class.=' last'; + if ($resource['id'] == $modx->documentObject['id']) $class.=' current'; $placeholders['ditto_class'] = $class; // set url placeholder - if (in_array("url",$this->fields["display"]["custom"])) { + if (in_array('url',$this->fields['display']['custom'])) { if($resource['id']==$modx->config['site_start']) $placeholders['url'] = $modx->config['site_url']; else $placeholders['url'] = $modx->makeURL($resource['id'],'','','full'); } - if (in_array("date",$this->fields["display"]["custom"])) { - $timestamp = ($resource[$dateSource] != "0") ? $resource[$dateSource] : $resource["createdon"]; + if (in_array('date',$this->fields['display']['custom'])) { + $timestamp = ($resource[$dateSource] != '0') ? $resource[$dateSource] : $resource['createdon']; if (is_array($timestamp)) { $timestamp[1] = preg_match('@^[1-9][0-9]*$@',$timestamp[1]) ? $timestamp[1] : strtotime($timestamp[1]); $timestamp = $timestamp[1] + $timestamp[0]; @@ -311,18 +312,18 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a $placeholders['date'] = strftime($dateFormat,$timestamp); } - if (in_array("content",$this->fields["display"]["db"]) && $this->format != "html") { + if (in_array('content',$this->fields['display']['db']) && $this->format != 'html') { $placeholders['content'] = $this->relToAbs($resource['content'], $modx->config['site_url']); } - if (in_array("introtext",$this->fields["display"]["db"]) && $this->format != "html") { + if (in_array('introtext',$this->fields['display']['db']) && $this->format != 'html') { $placeholders['introtext'] = $this->relToAbs($resource['introtext'], $modx->config['site_url']); } $customPlaceholders = $ph; // set custom placeholder foreach ($ph as $name=>$value) { - if ($name != "*") { + if ($name != '*') { $placeholders[$name] = call_user_func($value[1],$resource); unset($customPlaceholders[$name]); } @@ -332,8 +333,8 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a $placeholders = call_user_func($value,$placeholders); } - if (count($this->fields["display"]['qe']) > 0) { - $placeholders = $this->renderQELinks($this->template->fields['qe'],$resource,$ditto_lang["edit"]." : ".$resource['pagetitle']." : ",$placeholders); + if (count($this->fields['display']['qe']) > 0) { + $placeholders = $this->renderQELinks($this->template->fields['qe'],$resource,$ditto_lang['edit'].' : '.$resource['pagetitle'].' : ',$placeholders); // set QE Placeholders } @@ -363,8 +364,8 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a } if ($removeChunk) { foreach ($removeChunk as $chunk) { - $output = str_replace('{{'.$chunk.'}}',"",$output); - $output = str_replace($modx->getChunk($chunk),"",$output); + $output = str_replace('{{'.$chunk.'}}','',$output); + $output = str_replace($modx->getChunk($chunk),'',$output); // remove chunk that is not wanted } } @@ -381,17 +382,17 @@ function parseFields($placeholders,$seeThruUnpub,$dateSource,$randomize) { $this->parseCustomPlaceholders($placeholders); $this->parseDBFields($seeThruUnpub); if ($randomize != 0) { - $this->addField($randomize,"backend"); + $this->addField($randomize,'backend'); } - $this->addField("id","display","db"); - $this->addField("pagetitle","display","db"); - $this->addField("parent","display","db"); - $checkOptions = array("pub_date","unpub_date","editedon","deletedon","publishedon"); + $this->addField('id','display','db'); + $this->addField('pagetitle','display','db'); + $this->addField('parent','display','db'); + $checkOptions = array('pub_date','unpub_date','editedon','deletedon','publishedon'); if (in_array($dateSource,$checkOptions)) { - $this->addField("createdon","display"); + $this->addField($dateSource,'display'); } - if (in_array("date",$this->fields["display"]["custom"])) { - $this->addField($dateSource,"display"); + if (in_array('date',$this->fields['display']['custom'])) { + $this->addField($dateSource,'display'); } $this->fields = $this->arrayUnique($this->fields); } @@ -418,13 +419,13 @@ function arrayUnique($array) { function parseCustomPlaceholders($placeholders) { foreach ($placeholders as $name=>$value) { - $this->addField($name,"display","custom"); - $this->removeField($name,"display","unknown"); + $this->addField($name,'display','custom'); + $this->removeField($name,'display','unknown'); $source = $value[0]; $qe = isset($value[2]) ? $value[2] : ''; if(is_array($source)) { - if(strpos($source[0],",")!==false){ + if(strpos($source[0],',')!==false){ $fields = array_filter(array_map('trim', explode(',', $source[0]))); foreach ($fields as $field) { $this->addField($field,$source[1]); @@ -437,7 +438,7 @@ function parseCustomPlaceholders($placeholders) { } else if(is_array($value)) { $fields = array_filter(array_map('trim', explode(',', $source))); foreach ($fields as $field) { - $this->addField($field,"display"); + $this->addField($field,'display'); $this->customPlaceholdersMap[$name] = $field; } } @@ -456,15 +457,15 @@ function parseCustomPlaceholders($placeholders) { function parseDBFields($seeThruUnpub) { if (!$seeThruUnpub) { - $this->addField("parent","backend","db"); + $this->addField('parent','backend','db'); } - if (in_array("author",$this->fields["display"]["custom"])) { - $this->fields["display"]["db"][] = "createdby"; + if (in_array('author',$this->fields['display']['custom'])) { + $this->fields['display']['db'][] = 'createdby'; } - if (count($this->fields["display"]["tv"]) >= 0) { - $this->addField("published","display","db"); + if (count($this->fields['display']['tv']) >= 0) { + $this->addField('published','display','db'); } } @@ -475,22 +476,22 @@ function parseDBFields($seeThruUnpub) { function renderQELinks($fields, $resource, $QEPrefix,$placeholders) { global $modx,$dittoID; - $table = $modx->getFullTableName("site_modules"); - $idResult = $modx->db->select("id", $table,"name='QuickEdit'","id","1"); + $table = $modx->getFullTableName('site_modules'); + $idResult = $modx->db->select('id', $table,"name='QuickEdit'",'id','1'); $id = $modx->db->getValue($idResult); - $custom = array("author","date","url","title"); + $custom = array('author','date','url','title'); $set = $modx->hasPermission('exec_module'); foreach ($fields as $dv) { $ds = $dv; - if ($dv == "title") { - $ds = "pagetitle"; + if ($dv == 'title') { + $ds = 'pagetitle'; } - if (!in_array($dv,$custom) && in_array($dv,$this->fields["display"]["custom"])) { + if (!in_array($dv,$custom) && in_array($dv,$this->fields['display']['custom'])) { $value = $this->customPlaceholdersMap[$dv]; $ds = $value; - if (is_array($value) && $value[0] == "qe") { + if (is_array($value) && $value[0] == 'qe') { $value = $value[1]; - if (substr($value,0,7) == "@GLOBAL") { + if (substr($value,0,7) == '@GLOBAL') { $key = trim(substr($value,7)); $ds = $GLOBALS[$key]; } @@ -528,7 +529,7 @@ public static function getAuthor($createdby) { // get admin user name $user = $modx->getUserInfo(1); } - return ($user['fullname'] != "") ? $user['fullname'] : $user['username']; + return ($user['fullname'] != '') ? $user['fullname'] : $user['username']; } // --------------------------------------------------- @@ -571,8 +572,8 @@ function userSort($resource,$sort) { function multiSort($resource,$orderBy) { $sort_arr = array(); - foreach($resource AS $uniqid => $row){ - foreach($row AS $key=>$value){ + foreach($resource as $uniqid => $row){ + foreach($row as $key=>$value){ $sort_arr[$key][$uniqid] = $value; } } @@ -593,29 +594,29 @@ function multiSort($resource,$orderBy) { function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, $seeThruUnpub, $hideFolders, $hidePrivate, $showInMenuOnly, $myWhere, $dateSource, $limit, $summarize, $filter, $paginate, $randomize) { global $modx; - if (($summarize == 0 && $summarize != "all") || count($IDs) == 0 || ($IDs == false && $IDs != "0")) { + if (($summarize == 0 && $summarize != 'all') || count($IDs) == 0 || ($IDs == false && $IDs != '0')) { return array(); } // Get starting IDs; switch($IDType) { - case "parents": - $IDs = explode(",",$IDs); + case 'parents': + $IDs = explode(',',$IDs); $documentIDs = $this->getChildIDs($IDs, $depth); break; - case "documents": + case 'documents': if(!preg_match('@^[0-9, ]*$@',$IDs)) exit(sprintf('Illegal value of &documents: %s', $IDs)); - $documentIDs = explode(",",$IDs); + $documentIDs = explode(',',$IDs); break; } - if ($this->advSort == false && $hideFolders==0 && $showInMenuOnly==0 && $myWhere == "" && $filter == false && $hidePrivate == 1) { + if ($this->advSort == false && $hideFolders==0 && $showInMenuOnly==0 && $myWhere == '' && $filter == false && $hidePrivate == 1) { $this->prefetch = false; $documents = $this->getDocumentsIDs($documentIDs, $showPublishedOnly); $documentIDs = array(); if ($documents) { foreach ($documents as $null=>$doc) { - $documentIDs[] = $doc["id"]; + $documentIDs[] = $doc['id']; } } return $documentIDs; @@ -634,15 +635,15 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, if ($showInMenuOnly) { $where[] = 'hidemenu = 0'; } - $where = implode(" AND ", $where); - $limit = ($limit == 0) ? "" : $limit; + $where = join(' AND ', $where); + $limit = ($limit == 0) ? '' : $limit; // set limit $customReset = $this->customReset; - if ($this->debug) {$this->addField("pagetitle","backend","db");} + if ($this->debug) {$this->addField('pagetitle','backend','db');} - if (count($customReset) > 0) {$this->addField("createdon","backend","db");} - $resource = $this->getDocuments($documentIDs,$this->fields["backend"]["db"],$TVs,$orderBy,$showPublishedOnly,0,$hidePrivate,$where,$limit,$randomize,$dateSource); + if (count($customReset) > 0) {$this->addField('createdon','backend','db');} + $resource = $this->getDocuments($documentIDs,$this->fields['backend']['db'],$TVs,$orderBy,$showPublishedOnly,0,$hidePrivate,$where,$limit,$randomize,$dateSource); // EPO - End of change (then see line 692 - if ($limit) array_slice($resource, 0, $limit); ) @@ -658,14 +659,14 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, } for ($i = 0; $i < $recordCount; $i++) { if (!$seeThruUnpub) { - $published = $parentList[$resource[$i]["parent"]]; - if ($published == "0") + $published = $parentList[$resource[$i]['parent']]; + if ($published == '0') unset ($resource[$i]); } if (count($customReset) > 0) { foreach ($customReset as $field) { - if ($resource[$i][$field] === "0") { - $resource[$i][$field] = $resource[$i]["createdon"]; + if ($resource[$i][$field] === '0') { + $resource[$i][$field] = $resource[$i]['createdon']; } } } @@ -689,7 +690,7 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, //intersel - see above in order to limit the array to $limit. if ($limit) $resource=array_slice($resource, 0, $limit); - $fields = (array_intersect($this->fields["backend"],$this->fields["display"])); + $fields = (array_intersect($this->fields['backend'],$this->fields['display'])); $readyFields = array(); foreach ($fields as $field) { $readyFields = array_merge($readyFields,$field); @@ -703,7 +704,7 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, if (in_array($key,$readyFields)) { $keep[$iKey][$key] = $v; } - if ($this->getDocVarType($key) == "tv:prefix") { + if ($this->getDocVarType($key) == 'tv:prefix') { if (in_array(substr($key,2),$readyFields)) { $keep[$iKey][$key] = $v; } @@ -711,11 +712,11 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, } } - $this->prefetch = array("resource"=>$keep,"fields"=>$fields); + $this->prefetch = array('resource'=>$keep,'fields'=>$fields); if ($this->debug) { - $this->prefetch["dbg_resource"] = $dbg_resource; - $this->prefetch["dbg_IDs_pre"] = $documentIDs; - $this->prefetch["dbg_IDs_post"] = $processedIDs; + $this->prefetch['dbg_resource'] = $dbg_resource; + $this->prefetch['dbg_IDs_pre'] = $documentIDs; + $this->prefetch['dbg_IDs_post'] = $processedIDs; } if (count($processedIDs) > 0) { if ($randomize != 0) {shuffle($processedIDs);} @@ -736,7 +737,7 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, function weightedRandom($resource,$field,$show) { $type = $this->getDocVarType($field); - if ($type == "unknown") { + if ($type == 'unknown') { return $resource; // handle vad field passed } @@ -767,11 +768,11 @@ function getParentList() { $parents = array(); foreach ($kids as $item => $value) { if ($item != 0) { - $pInfo = $modx->getPageInfo($item,0,"published"); + $pInfo = $modx->getPageInfo($item,0,'published'); } else { - $pInfo["published"] = "1"; + $pInfo['published'] = '1'; } - $parents[$item] = $pInfo["published"]; + $parents[$item] = $pInfo['published']; } return $parents; } @@ -781,12 +782,12 @@ function getParentList() { // Apeend a TV to the documents array // --------------------------------------------------- - function appendTV($tvname="",$docIDs){ + function appendTV($tvname='',$docIDs){ global $modx; - $baspath= MODX_MANAGER_PATH."/includes"; - include_once $baspath . "/tmplvars.format.inc.php"; - include_once $baspath . "/tmplvars.commands.inc.php"; + $baspath= MODX_MANAGER_PATH.'/includes'; + include_once $baspath . '/tmplvars.format.inc.php'; + include_once $baspath . '/tmplvars.commands.inc.php'; $tb1 = $modx->getFullTableName("site_tmplvar_contentvalues"); $tb2 = $modx->getFullTableName("site_tmplvars"); @@ -942,14 +943,14 @@ function getDocumentsIDs($ids= array (), $published= 1) { if (count($ids) == 0) { return false; } else { - $tblsc= $modx->getFullTableName("site_content"); - $tbldg= $modx->getFullTableName("document_groups"); + $tblsc= $modx->getFullTableName('site_content'); + $tbldg= $modx->getFullTableName('document_groups'); if ($docgrp= $modx->getUserDocGroups()) - $docgrp= implode(",", $docgrp); - $access= ($modx->isFrontend() ? "sc.privateweb=0" : "1='" . $_SESSION['mgrRole'] . "' OR sc.privatemgr=0") . - (!$docgrp ? "" : " OR dg.document_group IN ($docgrp)"); - $published = ($published) ? "AND sc.published=1" : ""; - $result= $modx->db->select("DISTINCT sc.id", "{$tblsc} sc LEFT JOIN {$tbldg} dg on dg.document = sc.id", "(sc.id IN (" . implode(',', $ids) . ") $published AND sc.deleted=0) AND ({$access}) GROUP BY sc.id"); + $docgrp= join(',', $docgrp); + $access= ($modx->isFrontend() ? 'sc.privateweb=0' : "1='" . $_SESSION['mgrRole'] . "' OR sc.privatemgr=0") . + (!$docgrp ? '' : " OR dg.document_group IN ($docgrp)"); + $published = ($published) ? 'AND sc.published=1' : ''; + $result= $modx->db->select('DISTINCT sc.id', "{$tblsc} sc LEFT JOIN {$tbldg} dg on dg.document = sc.id", '(sc.id IN (' . join(',', $ids) . ") $published AND sc.deleted=0) AND ({$access}) GROUP BY sc.id"); $resourceArray = $modx->db->makeArray($result); return $resourceArray; } @@ -992,9 +993,9 @@ public static function buildURL($args,$id=false,$dittoIdentifier=false) { } } if (!is_array($args)) { - $args = explode("&",$args); + $args = explode('&',$args); foreach ($args as $arg) { - $arg = explode("=",$arg); + $arg = explode('=',$arg); $query[$dittoID.$arg[0]] = rawurlencode(trim($arg[1])); } } else { @@ -1002,12 +1003,12 @@ public static function buildURL($args,$id=false,$dittoIdentifier=false) { $query[$dittoID.$name] = rawurlencode(trim($value)); } } - $queryString = ""; + $queryString = ''; foreach ($query as $param=>$value) { - //$queryString .= '&'.$param.'='.(is_array($value) ? implode(",",$value) : $value); + //$queryString .= '&'.$param.'='.(is_array($value) ? join(',',$value) : $value); if (!is_array($value)) { - if (!($modx->config['seostrict']=='1' and $param == $dittoID."start" and !$value)) $queryString .= '&'.$param.'='.$value; + if (!($modx->config['seostrict']=='1' && $param == $dittoID.'start' && !$value)) $queryString .= '&'.$param.'='.$value; } else { foreach ($value as $key=>$val) { @@ -1017,7 +1018,7 @@ public static function buildURL($args,$id=false,$dittoIdentifier=false) { } $cID = ($id !== false) ? $id : $modx->documentObject['id']; $url = $modx->makeURL(trim($cID), '', $queryString); - return ($modx->config['xhtml_urls']) ? $url : str_replace("&","&",$url); + return ($modx->config['xhtml_urls']) ? $url : str_replace('&','&',$url); } // --------------------------------------------------- @@ -1028,7 +1029,7 @@ public static function buildURL($args,$id=false,$dittoIdentifier=false) { function getParam($param,$langString){ // get a parameter value and if it is not set get the default language string value global $modx,$ditto_lang; - $output = ""; + $output = ''; if (substr($param,0,1)==='@') { $output = $this->template->fetch($param); } else if(!empty($param)) { @@ -1060,10 +1061,10 @@ function paginate($start, $stop, $total, $summarize, $tplPaginateNext, $tplPagin $previousplaceholder = $this->template->replace(array('lang:previous'=>$ditto_lang['prev']),$tplPaginatePreviousOff); $nextplaceholder = $this->template->replace(array('lang:next'=>$ditto_lang['next']),$tplPaginateNextOff); } else { - $previousplaceholder = ""; - $nextplaceholder = ""; + $previousplaceholder = ''; + $nextplaceholder = ''; } - $split = ""; + $split = ''; if ($previous > -1 && $next < $total) $split = $paginateSplitterCharacter; if ($previous > -1) @@ -1090,7 +1091,7 @@ function paginate($start, $stop, $total, $summarize, $tplPaginateNext, $tplPagin $min_x = $max_x - $max_paginate + 1; } - $modx->setPlaceholder("dittoID", $dittoID); + $modx->setPlaceholder('dittoID', $dittoID); $pages = ''; for ($x = 0; $x <= $totalpages -1; $x++) { $inc = $x * $summarize; @@ -1101,27 +1102,27 @@ function paginate($start, $stop, $total, $summarize, $tplPaginateNext, $tplPagin if ($inc != $start) { $pages .= $this->template->replace(array('url'=>$this->buildURL("start=$inc"),'page'=>$display),$tplPaginatePage); } else { - $modx->setPlaceholder($dittoID."currentPage", $display); + $modx->setPlaceholder($dittoID.'currentPage', $display); $pages .= $this->template->replace(array('page'=>$display),$tplPaginateCurrentPage); } } if ($totalpages>1){ - $modx->setPlaceholder($dittoID."next", $nextplaceholder); - $modx->setPlaceholder($dittoID."previous", $previousplaceholder); - $modx->setPlaceholder($dittoID."pages", $pages); + $modx->setPlaceholder($dittoID.'next', $nextplaceholder); + $modx->setPlaceholder($dittoID.'previous', $previousplaceholder); + $modx->setPlaceholder($dittoID.'pages', $pages); }elseif($paginateAlwaysShowLinks == 1){ - $modx->setPlaceholder($dittoID."next", $nextplaceholder); - $modx->setPlaceholder($dittoID."previous", $previousplaceholder); - $modx->setPlaceholder($dittoID."pages", $pages); + $modx->setPlaceholder($dittoID.'next', $nextplaceholder); + $modx->setPlaceholder($dittoID.'previous', $previousplaceholder); + $modx->setPlaceholder($dittoID.'pages', $pages); } - $modx->setPlaceholder($dittoID."splitter", $split); - $modx->setPlaceholder($dittoID."start", $start +1); - $modx->setPlaceholder($dittoID."urlStart", $start); - $modx->setPlaceholder($dittoID."stop", $limiter); - $modx->setPlaceholder($dittoID."total", $total); - $modx->setPlaceholder($dittoID."perPage", $summarize); - $modx->setPlaceholder($dittoID."totalPages", $totalpages); - $modx->setPlaceholder($dittoID."ditto_pagination_set", true); + $modx->setPlaceholder($dittoID.'splitter', $split); + $modx->setPlaceholder($dittoID.'start', $start +1); + $modx->setPlaceholder($dittoID.'urlStart', $start); + $modx->setPlaceholder($dittoID.'stop', $limiter); + $modx->setPlaceholder($dittoID.'total', $total); + $modx->setPlaceholder($dittoID.'perPage', $summarize); + $modx->setPlaceholder($dittoID.'totalPages', $totalpages); + $modx->setPlaceholder($dittoID.'ditto_pagination_set', true); } // --------------------------------------------------- @@ -1130,20 +1131,20 @@ function paginate($start, $stop, $total, $summarize, $tplPaginateNext, $tplPagin // --------------------------------------------------- function noResults($text,$paginate) { global $modx, $dittoID; - $set = $modx->getPlaceholder($dittoID."ditto_pagination_set"); + $set = $modx->getPlaceholder($dittoID.'ditto_pagination_set'); if ($paginate && $set !== true) { - $modx->setPlaceholder("dittoID", $dittoID); - $modx->setPlaceholder($dittoID."next", ""); - $modx->setPlaceholder($dittoID."previous", ""); - $modx->setPlaceholder($dittoID."splitter", ""); - $modx->setPlaceholder($dittoID."start", 0); - $modx->setPlaceholder($dittoID."urlStart", "#start"); - $modx->setPlaceholder($dittoID."stop", 0); - $modx->setPlaceholder($dittoID."total", 0); - $modx->setPlaceholder($dittoID."pages", ""); - $modx->setPlaceholder($dittoID."perPage", 0); - $modx->setPlaceholder($dittoID."totalPages", 0); - $modx->setPlaceholder($dittoID."currentPage", 0); + $modx->setPlaceholder('dittoID', $dittoID); + $modx->setPlaceholder($dittoID.'next', ''); + $modx->setPlaceholder($dittoID.'previous', ''); + $modx->setPlaceholder($dittoID.'splitter', ''); + $modx->setPlaceholder($dittoID.'start', 0); + $modx->setPlaceholder($dittoID.'urlStart', '#start'); + $modx->setPlaceholder($dittoID.'stop', 0); + $modx->setPlaceholder($dittoID.'total', 0); + $modx->setPlaceholder($dittoID.'pages', ''); + $modx->setPlaceholder($dittoID.'perPage', 0); + $modx->setPlaceholder($dittoID.'totalPages', 0); + $modx->setPlaceholder($dittoID.'currentPage', 0); } return $text; } From d78a184ed654959c3df71b40da7bf83e1b43f86c Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 11:30:22 +0900 Subject: [PATCH 312/338] Code cleanup --- .../ditto/classes/ditto.class.inc.php | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 0f4aeef1e6..bee95d02a7 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -498,7 +498,7 @@ function renderQELinks($fields, $resource, $QEPrefix,$placeholders) { } } - $js = "window.open('".MODX_MANAGER_URL."index.php?a=112&id=".$id."&doc=".$resource["id"]."&var=".$ds."', 'QuickEditor', 'width=525, height=300, toolbar=0, menubar=0, status=0, alwaysRaised=1, dependent=1');"; + $js = sprintf("window.open('%sindex.php?a=112&id=%s&doc=%s&var=%s', 'QuickEditor', 'width=525, height=300, toolbar=0, menubar=0, status=0, alwaysRaised=1, dependent=1');", MODX_MANAGER_URL,$id,$resource['id'],$ds); $url = $this->buildURL("qe_open=true",$modx->documentIdentifier,$dittoID); unset($custom[3]); @@ -542,10 +542,11 @@ function customSort($data, $fields, $order) { // user contributed $sortfields = array_filter(array_map('trim', explode(',', $fields))); - $code = ""; - for ($c = 0; $c < count($sortfields); $c++) - $code .= "\$retval = strnatcmp(\$a['$sortfields[$c]'], \$b['$sortfields[$c]']); if(\$retval) return \$retval; "; - $code .= "return \$retval;"; + $code = ''; + foreach($sortfields as $field) { + $code .= sprintf('$retval = strnatcmp($a["%s"], $b["%s"]); if($retval) return $retval; ',$field,$field); + } + $code .= 'return $retval;'; $params = ($order == 'ASC') ? '$a,$b' : '$b,$a'; uasort($data, create_function($params, $code)); @@ -578,11 +579,11 @@ function multiSort($resource,$orderBy) { } } - $array_multisort = 'return array_multisort('; + $_ =''; foreach ($orderBy['parsed'] as $sort) { - $array_multisort .= '$sort_arr["'.$sort[0].'"], SORT_'.$sort[1].', '; + $_ .= sprintf('$sort_arr["%s"], SORT_%s, ', $sort[0], $sort[1]); } - $array_multisort .= '$resource);'; + $array_multisort = sprintf('return array_multisort( %s $resource);', $_); eval($array_multisort); return $resource; } @@ -789,37 +790,40 @@ function appendTV($tvname='',$docIDs){ include_once $baspath . '/tmplvars.format.inc.php'; include_once $baspath . '/tmplvars.commands.inc.php'; - $tb1 = $modx->getFullTableName("site_tmplvar_contentvalues"); - $tb2 = $modx->getFullTableName("site_tmplvars"); - - $rs= $modx->db->select( - "stv.name,stc.tmplvarid,stc.contentid,stv.type,stv.display,stv.display_params,stc.value", - "{$tb1} AS stc LEFT JOIN {$tb2} AS stv ON stv.id=stc.tmplvarid", - "stv.name='{$tvname}' AND stc.contentid IN (".implode($docIDs,",").")", - "stc.contentid ASC" - ); + $fields = 'stv.name,stc.tmplvarid,stc.contentid,stv.type,stv.display,stv.display_params,stc.value'; + $from[] = '[+prefix+]site_tmplvar_contentvalues AS stc'; + $from[] = 'LEFT JOIN [+prefix+]site_tmplvars AS stv ON stv.id=stc.tmplvarid'; + $where = sprintf("stv.name='%s' AND stc.contentid IN (%s)", $modx->db->escape($tvname), join($docIDs,',')); + $rs= $modx->db->select($fields, $from, $where, 'stc.contentid ASC'); $resourceArray = array(); while ($row = $modx->db->getRow($rs)) { - $resourceArray["#".$row['contentid']][$row['name']] = getTVDisplayFormat($row['name'], $row['value'], $row['display'], $row['display_params'], $row['type'],$row['contentid']); - $resourceArray["#".$row['contentid']]["tv".$row['name']] = $resourceArray["#".$row['contentid']][$row['name']]; + extract($row,EXTR_PREFIX_ALL,'p_'); + $key = '#'.$p_contentid; + $resourceArray[$key][$tvname] = getTVDisplayFormat($p_name,$p_value,$p_display,$p_display_params,$p_type,$p_contentid); + $resourceArray[$key]['tv'.$tvname] = $resourceArray[$key][$tvname]; } if (count($resourceArray) != count($docIDs)) { - $rs = $modx->db->select("id,name,type,display,display_params,default_text", $tb2, "name='{$tvname}'", '', 1); + $field = 'id,name,type,display,display_params,default_text'; + $where = sprintf("name='%s'",$modx->db->escape($tvname)); + $rs = $modx->db->select($field, '[+prefix+]site_tmplvars', $where, '', 1); $row = $modx->db->getRow($rs); - if (strtoupper($row['default_text']) == '@INHERIT') { + extract($row,EXTR_PREFIX_ALL,'p_'); + if (strtoupper($p_default_text) == '@INHERIT') { foreach ($docIDs as $id) { - $defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'], $id); - if (!isset($resourceArray["#".$id])) { - $resourceArray["#$id"][$tvname] = $defaultOutput; - $resourceArray["#$id"]["tv".$tvname] = $resourceArray["#$id"][$tvname]; + $defaultOutput = getTVDisplayFormat($p_name, $p_default_text, $p_display, $p_display_params, $p_type, $id); + $k = '#'.$id; + if (!isset($resourceArray[$k])) { + $resourceArray[$k][$tvname] = $defaultOutput; + $resourceArray[$k]['tv'.$tvname] = $resourceArray[$k][$tvname]; } } } else { - $defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'],$row['id']); + $defaultOutput = getTVDisplayFormat($p_name, $p_default_text, $p_display, $p_display_params, $p_type, $p_id); foreach ($docIDs as $id) { - if (!isset($resourceArray["#".$id])) { - $resourceArray["#$id"][$tvname] = $defaultOutput; - $resourceArray["#$id"]["tv".$tvname] = $resourceArray["#$id"][$tvname]; + $k = '#'.$id; + if (!isset($resourceArray[$k])) { + $resourceArray[$k][$tvname] = $defaultOutput; + $resourceArray[$k]['tv'.$tvname] = $resourceArray[$k][$tvname]; } } } From 82c8a6d8190c9987bc7852d85b861fe710653a3d Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 12:15:47 +0900 Subject: [PATCH 313/338] Remove - $ditto->renderQELinks() --- .../ditto/classes/ditto.class.inc.php | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index bee95d02a7..3130f1486f 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -116,9 +116,6 @@ function removeField($name,$location,$type) { function setDisplayFields($fields,$hiddenFields) { $this->fields['display'] = $fields; - if (count($this->fields['display']['qe']) > 0) { - $this->addField('pagetitle','display','db'); - } if ($hiddenFields) { $this->addFields($hiddenFields,'display'); } @@ -333,11 +330,6 @@ function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=a $placeholders = call_user_func($value,$placeholders); } - if (count($this->fields['display']['qe']) > 0) { - $placeholders = $this->renderQELinks($this->template->fields['qe'],$resource,$ditto_lang['edit'].' : '.$resource['pagetitle'].' : ',$placeholders); - // set QE Placeholders - } - if ($phx == 1 && !$modx->config['enable_filter']) { $PHs = $placeholders; foreach($PHs as $key=>$output) { @@ -422,7 +414,6 @@ function parseCustomPlaceholders($placeholders) { $this->addField($name,'display','custom'); $this->removeField($name,'display','unknown'); $source = $value[0]; - $qe = isset($value[2]) ? $value[2] : ''; if(is_array($source)) { if(strpos($source[0],',')!==false){ @@ -442,11 +433,6 @@ function parseCustomPlaceholders($placeholders) { $this->customPlaceholdersMap[$name] = $field; } } - - if (!is_null($qe)) { - $this->customPlaceholdersMap[$name] = array('qe',$qe); - } - } } @@ -469,48 +455,6 @@ function parseDBFields($seeThruUnpub) { } } - // --------------------------------------------------- - // Function: renderQELinks - // Render QE links when needed - // --------------------------------------------------- - - function renderQELinks($fields, $resource, $QEPrefix,$placeholders) { - global $modx,$dittoID; - $table = $modx->getFullTableName('site_modules'); - $idResult = $modx->db->select('id', $table,"name='QuickEdit'",'id','1'); - $id = $modx->db->getValue($idResult); - $custom = array('author','date','url','title'); - $set = $modx->hasPermission('exec_module'); - foreach ($fields as $dv) { - $ds = $dv; - if ($dv == 'title') { - $ds = 'pagetitle'; - } - if (!in_array($dv,$custom) && in_array($dv,$this->fields['display']['custom'])) { - $value = $this->customPlaceholdersMap[$dv]; - $ds = $value; - if (is_array($value) && $value[0] == 'qe') { - $value = $value[1]; - if (substr($value,0,7) == '@GLOBAL') { - $key = trim(substr($value,7)); - $ds = $GLOBALS[$key]; - } - } - } - - $js = sprintf("window.open('%sindex.php?a=112&id=%s&doc=%s&var=%s', 'QuickEditor', 'width=525, height=300, toolbar=0, menubar=0, status=0, alwaysRaised=1, dependent=1');", MODX_MANAGER_URL,$id,$resource['id'],$ds); - $url = $this->buildURL("qe_open=true",$modx->documentIdentifier,$dittoID); - - unset($custom[3]); - if ($set && !in_array($dv,$custom)) { - $placeholders["#$dv"] = $placeholders["$dv"].'« '.$QEPrefix.$dv.''; - } else { - $placeholders["#$dv"] = $placeholders["$dv"]; - } - } - return $placeholders; - } - // --------------------------------------------------- // Function: getAuthor // Get the author name, or if not available the username From ac4c1d379b71767afc3ef5d4499bc71d53a0b5e8 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 19:27:19 +0900 Subject: [PATCH 314/338] Refactor --- .../ditto/classes/ditto.class.inc.php | 228 +++++++++--------- 1 file changed, 113 insertions(+), 115 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 3130f1486f..506302735c 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -132,10 +132,10 @@ function getDocVarType($field) { $dbFields = $ditto_constantFields['db']; if(in_array($field, $tvFields)){ return 'tv'; - }else if(in_array(substr($field,2), $tvFields)) { + }elseif(in_array(substr($field,2), $tvFields)) { return 'tv:prefix'; // TODO: Remove TV Prefix support - } else if(in_array($field, $dbFields)){ + } elseif(in_array($field, $dbFields)){ return 'db'; } else { return 'unknown'; @@ -251,120 +251,112 @@ function parseFilters($filter=false,$cFilters=false,$pFilters = false,$globalDel // Render the document output // --------------------------------------------------- - function render($resource, $template, $removeChunk,$dateSource,$dateFormat,$ph=array(),$phx=1,$x=0,$stop=1) { + function render($doc, $template, $removeChunk,$dateSource,$dateFormat,$customPlaceholders=array(),$phx=1,$x=0,$stop=1) { global $modx,$ditto_lang; - if (!is_array($resource)) { - return $ditto_lang['resource_array_error']; - } - $placeholders = array(); + if (!is_array($doc)) return $ditto_lang['resource_array_error']; + + $ph = $doc; $contentVars = array(); - foreach ($resource as $name=>$value) { - $placeholders[$name] = $value; + $exFields =& $this->fields['display']['custom']; + + foreach ($doc as $name=>$value) { $contentVars["[*{$name}*]"] = $value; } - // set author placeholder - if (in_array('author',$this->fields['display']['custom'])) { - $placeholders['author'] = $this->getAuthor($resource['createdby']); - } - - // set title placeholder - if (in_array('title',$this->fields['display']['custom'])) { - $placeholders['title'] = $resource['pagetitle']; - } - - // set sequence placeholder - if (in_array('ditto_iteration',$this->fields['display']['custom'])) { - $placeholders['ditto_iteration'] = $x; - } + if (in_array('author',$exFields)) $ph['author'] = $this->getAuthor($doc['createdby']); + if (in_array('title',$exFields)) $ph['title'] = $doc['pagetitle']; + if (in_array('ditto_iteration',$exFields)) $ph['ditto_iteration'] = $x; //Added by Andchir - //if (in_array('ditto_index',$this->fields['display']['custom'])) { - $r_start = isset($_GET['start']) ? $_GET['start'] : 0; - $placeholders['ditto_index'] = $r_start+$x+1; - //} + $r_start = isset($_GET['start']) ? $_GET['start'] : 0; + $ph['ditto_index'] = $r_start+$x+1; //Added by Dmi3yy placeholder ditto_class - if ($x % 2 == 0) {$class='even';} else {$class='odd';} - if ($x==0) $class.=' first'; - if ($x==($stop -1)) $class.=' last'; - if ($resource['id'] == $modx->documentObject['id']) $class.=' current'; - $placeholders['ditto_class'] = $class; + $class = array(); + if($x % 2 == 0) $class[] = 'even'; + else $class[] = 'odd'; + + if ($x==0) $class[] = 'first'; + if ($x==($stop -1)) $class[] = 'last'; + if ($doc['id'] == $modx->documentIdentifier) $class[] = 'current'; + $ph['ditto_class'] = join(' ', $class); // set url placeholder - if (in_array('url',$this->fields['display']['custom'])) { - if($resource['id']==$modx->config['site_start']) - $placeholders['url'] = $modx->config['site_url']; - else - $placeholders['url'] = $modx->makeURL($resource['id'],'','','full'); + if (in_array('url',$exFields)) { + if($doc['id']==$modx->config['site_start']) $ph['url'] = $modx->config['site_url']; + else $ph['url'] = $modx->makeURL($doc['id'],'','','full'); } - if (in_array('date',$this->fields['display']['custom'])) { - $timestamp = ($resource[$dateSource] != '0') ? $resource[$dateSource] : $resource['createdon']; + if (in_array('date',$exFields)) { + $timestamp = ($doc[$dateSource] != '0') ? $doc[$dateSource] : $doc['createdon']; if (is_array($timestamp)) { - $timestamp[1] = preg_match('@^[1-9][0-9]*$@',$timestamp[1]) ? $timestamp[1] : strtotime($timestamp[1]); + if(!$this->isNum($timestamp[1])) $timestamp[1] = strtotime($timestamp[1]); $timestamp = $timestamp[1] + $timestamp[0]; } - $placeholders['date'] = strftime($dateFormat,$timestamp); + $ph['date'] = strftime($dateFormat,$timestamp); } if (in_array('content',$this->fields['display']['db']) && $this->format != 'html') { - $placeholders['content'] = $this->relToAbs($resource['content'], $modx->config['site_url']); + $ph['content'] = $this->relToAbs($doc['content'], $modx->config['site_url']); } if (in_array('introtext',$this->fields['display']['db']) && $this->format != 'html') { - $placeholders['introtext'] = $this->relToAbs($resource['introtext'], $modx->config['site_url']); + $ph['introtext'] = $this->relToAbs($doc['introtext'], $modx->config['site_url']); } - $customPlaceholders = $ph; // set custom placeholder - foreach ($ph as $name=>$value) { + foreach ($customPlaceholders as $name=>$value) { if ($name != '*') { - $placeholders[$name] = call_user_func($value[1],$resource); + $ph[$name] = call_user_func($value[1],$doc); unset($customPlaceholders[$name]); } } foreach ($customPlaceholders as $name=>$value) { - $placeholders = call_user_func($value,$placeholders); + $ph = call_user_func($value,$ph); } - if ($phx == 1 && !$modx->config['enable_filter']) { - $PHs = $placeholders; - foreach($PHs as $key=>$output) { - $placeholders[$key] = str_replace( array_keys( $contentVars ), array_values( $contentVars ), $output ); - } - unset($PHs); - $phx = new prePHx($template); - $phx->setPlaceholders($placeholders); - $output = $phx->output(); - } - elseif ($phx == 1 && $modx->config['enable_filter']) { - $output = $template; - $i = 0; - while($i<10) { - $_ = $output; - if(strpos($output,'[+')!==false) $output = $modx->parseText($output,$placeholders); - else $output = $modx->parseDocumentSource($output); - if($_===$output) break; - $i++; - } - } else { - $output = $this->template->replace($placeholders,$template); + if ($phx) $output = $this->parseModifiers($template,$ph,$contentVars); + else { + $output = $this->template->replace($ph,$template); $output = $this->template->replace($contentVars,$output); } + if ($removeChunk) { foreach ($removeChunk as $chunk) { $output = str_replace('{{'.$chunk.'}}','',$output); $output = str_replace($modx->getChunk($chunk),'',$output); - // remove chunk that is not wanted + // remove chunk that is not wanted } } - return $output; } + function parseModifiers($tpl,$ph,$contentVars){ + global $modx; + if ($modx->config['enable_filter']) { + $content = $tpl; + $i = 0; + while($i<10) { + $bt = $content; + if(strpos($content,'[+')!==false) $content = $modx->parseText($content,$ph); + else $content = $modx->parseDocumentSource($content); + if($bt===$content) break; + $i++; + } + } + else { + foreach($ph as $key=>$content) { + $ph[$key] = str_replace( array_keys($contentVars), array_values($contentVars), $content ); + } + $phx = new prePHx($tpl); + $phx->setPlaceholders($ph); + $content = $phx->output(); + } + return $content; + } + // --------------------------------------------------- // Function: parseFields // Find the fields that are contained in the custom placeholders or those that are needed in other functions @@ -419,18 +411,18 @@ function parseCustomPlaceholders($placeholders) { if(strpos($source[0],',')!==false){ $fields = array_filter(array_map('trim', explode(',', $source[0]))); foreach ($fields as $field) { - $this->addField($field,$source[1]); - $this->customPlaceholdersMap[$name] = $field; + $this->addField($field,$source[1]); + $this->customPlaceholdersMap[$name] = $field; } } else { $this->addField($source[0],$source[1]); $this->customPlaceholdersMap[$name] = $source[0]; } // TODO: Replace addField with addFields with callback - } else if(is_array($value)) { + } elseif(is_array($value)) { $fields = array_filter(array_map('trim', explode(',', $source))); foreach ($fields as $field) { - $this->addField($field,'display'); - $this->customPlaceholdersMap[$name] = $field; + $this->addField($field,'display'); + $this->customPlaceholdersMap[$name] = $field; } } } @@ -633,7 +625,7 @@ function determineIDs($IDs, $IDType, $TVs, $orderBy, $depth, $showPublishedOnly, } //intersel - see above in order to limit the array to $limit. - if ($limit) $resource=array_slice($resource, 0, $limit); + if ($limit) $resource=array_slice($resource, 0, $limit); $fields = (array_intersect($this->fields['backend'],$this->fields['display'])); $readyFields = array(); @@ -739,14 +731,14 @@ function appendTV($tvname='',$docIDs){ $from[] = 'LEFT JOIN [+prefix+]site_tmplvars AS stv ON stv.id=stc.tmplvarid'; $where = sprintf("stv.name='%s' AND stc.contentid IN (%s)", $modx->db->escape($tvname), join($docIDs,',')); $rs= $modx->db->select($fields, $from, $where, 'stc.contentid ASC'); - $resourceArray = array(); + $docs = array(); while ($row = $modx->db->getRow($rs)) { extract($row,EXTR_PREFIX_ALL,'p_'); $key = '#'.$p_contentid; - $resourceArray[$key][$tvname] = getTVDisplayFormat($p_name,$p_value,$p_display,$p_display_params,$p_type,$p_contentid); - $resourceArray[$key]['tv'.$tvname] = $resourceArray[$key][$tvname]; + $docs[$key][$tvname] = getTVDisplayFormat($p_name,$p_value,$p_display,$p_display_params,$p_type,$p_contentid); + $docs[$key]['tv'.$tvname] = $docs[$key][$tvname]; } - if (count($resourceArray) != count($docIDs)) { + if (count($docs) != count($docIDs)) { $field = 'id,name,type,display,display_params,default_text'; $where = sprintf("name='%s'",$modx->db->escape($tvname)); $rs = $modx->db->select($field, '[+prefix+]site_tmplvars', $where, '', 1); @@ -756,23 +748,23 @@ function appendTV($tvname='',$docIDs){ foreach ($docIDs as $id) { $defaultOutput = getTVDisplayFormat($p_name, $p_default_text, $p_display, $p_display_params, $p_type, $id); $k = '#'.$id; - if (!isset($resourceArray[$k])) { - $resourceArray[$k][$tvname] = $defaultOutput; - $resourceArray[$k]['tv'.$tvname] = $resourceArray[$k][$tvname]; + if (!isset($docs[$k])) { + $docs[$k][$tvname] = $defaultOutput; + $docs[$k]['tv'.$tvname] = $docs[$k][$tvname]; } } } else { $defaultOutput = getTVDisplayFormat($p_name, $p_default_text, $p_display, $p_display_params, $p_type, $p_id); foreach ($docIDs as $id) { $k = '#'.$id; - if (!isset($resourceArray[$k])) { - $resourceArray[$k][$tvname] = $defaultOutput; - $resourceArray[$k]['tv'.$tvname] = $resourceArray[$k][$tvname]; + if (!isset($docs[$k])) { + $docs[$k][$tvname] = $defaultOutput; + $docs[$k]['tv'.$tvname] = $docs[$k][$tvname]; } } } } - return $resourceArray; + return $docs; } // --------------------------------------------------- @@ -807,7 +799,7 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d // modify field names to use sc. table reference $fields= 'sc.'.join(',sc.',$fields); - if ($randomize != 0) $sort = 'RAND()'; + if ($randomize != 0) $sort = 'RAND()'; else $sort= $orderBy['sql']; //Added by Andchir (http://modx-shopkeeper.ru/) @@ -831,13 +823,13 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d } } - $published = ($published) ? 'AND sc.published=1' : ''; + $published = ($published) ? 'AND sc.published=1' : ''; $from = array(); $from[] = "[+prefix+]site_content AS sc {$left_join_tvc}"; $from[] = 'LEFT JOIN [+prefix+]document_groups dg on dg.document = sc.id'; $sqlWhere = array(); - $sqlWhere[] = 'sc.id IN (' . join(',', $ids) . ')'; + $sqlWhere[] = sprintf('sc.id IN (%s)', join(',', $ids)); $sqlWhere[] =$published; $sqlWhere[] ="AND sc.deleted='{$deleted}'"; $sqlWhere[] = $where; @@ -846,25 +838,26 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d $rs= $modx->db->select("DISTINCT {$fields}",$from,$sqlWhere,$sort,$limit); if(!$modx->db->getRecordCount($rs)) return false; - $resourceArray= array (); + $docs = array(); $TVData = array(); - $TVIDs = array(); - while ($resource = $modx->db->getRow($rs)) { + $TVIDs = array(); + while ($doc = $modx->db->getRow($rs)) { if ($dateSource !== false) { - if(!preg_match('@^[1-9][0-9]*$@',$resource[$dateSource])) $resource[$dateSource] = strtotime($resource[$dateSource]); + if(!$this->isNum($doc[$dateSource])) $doc[$dateSource] = strtotime($doc[$dateSource]); if($modx->config['server_offset_time'] != 0) - $resource[$dateSource] += $modx->config['server_offset_time']; + $doc[$dateSource] += $modx->config['server_offset_time']; } - if ($this->prefetch == true && $this->sortOrder !== false) - $resource['ditto_sort'] = $this->sortOrder[$resource['id']]; - $TVIDs[] = $resource['id']; - $resourceArray['#'.$resource['id']] = $resource; + if ($this->prefetch && $this->sortOrder!==false) $doc['ditto_sort'] = $this->sortOrder[$doc['id']]; + + $k = '#'.$doc['id']; if (count($this->prefetch['resource']) > 0) { - $x = '#'.$resource['id']; - $resourceArray[$x] = array_merge($resource,$this->prefetch['resource'][$x]); + $docs[$k] = array_merge($doc,$this->prefetch['resource'][$k]); // merge the prefetch array and the normal array } + else $docs[$k] = $doc; + + $TVIDs[] = $doc['id']; } $TVs = array_unique($TVs); @@ -874,11 +867,11 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d } } - $resourceArray = array_merge_recursive($resourceArray,$TVData); + $docs = array_merge_recursive($docs,$TVData); if ($this->prefetch == true && $this->sortOrder !== false) - $resourceArray = $this->customSort($resourceArray,'ditto_sort','ASC'); + $docs = $this->customSort($docs,'ditto_sort','ASC'); - return $resourceArray; + return $docs; } // --------------------------------------------------- @@ -891,16 +884,17 @@ function getDocumentsIDs($ids= array (), $published= 1) { if (count($ids) == 0) { return false; } else { - $tblsc= $modx->getFullTableName('site_content'); - $tbldg= $modx->getFullTableName('document_groups'); if ($docgrp= $modx->getUserDocGroups()) $docgrp= join(',', $docgrp); - $access= ($modx->isFrontend() ? 'sc.privateweb=0' : "1='" . $_SESSION['mgrRole'] . "' OR sc.privatemgr=0") . - (!$docgrp ? '' : " OR dg.document_group IN ($docgrp)"); - $published = ($published) ? 'AND sc.published=1' : ''; - $result= $modx->db->select('DISTINCT sc.id', "{$tblsc} sc LEFT JOIN {$tbldg} dg on dg.document = sc.id", '(sc.id IN (' . join(',', $ids) . ") $published AND sc.deleted=0) AND ({$access}) GROUP BY sc.id"); - $resourceArray = $modx->db->makeArray($result); - return $resourceArray; + $from[] = '[+prefix+]site_content sc'; + $from[] = 'LEFT JOIN [+prefix+]document_groups dg on dg.document=sc.id'; + $published = $published ? 'AND sc.published=1' : ''; + $access = $modx->isFrontend() ? 'sc.privateweb=0' : sprintf("1='%s' OR sc.privatemgr=0", $_SESSION['mgrRole']); + if($docgrp) $access.= " OR dg.document_group IN ($docgrp)"; + $where = sprintf('(sc.id IN (%s) %s AND sc.deleted=0) AND (%s) GROUP BY sc.id', join(',',$ids), $published, $access); + $rs= $modx->db->select('DISTINCT sc.id', $from, $where); + $docs = $modx->db->makeArray($rs); + return $docs; } } @@ -980,7 +974,7 @@ function getParam($param,$langString){ $output = ''; if (substr($param,0,1)==='@') { $output = $this->template->fetch($param); - } else if(!empty($param)) { + } elseif(!empty($param)) { $output = $modx->getChunk($param); } else { $output = $ditto_lang[$langString]; @@ -1096,7 +1090,7 @@ function noResults($text,$paginate) { } return $text; } - + // --------------------------------------------------- // Function: relToAbs // Convert relative urls to absolute URLs @@ -1105,4 +1099,8 @@ function noResults($text,$paginate) { function relToAbs($text, $base) { return preg_replace('#(href|src)="([^:"]*)(?:")#','$1="'.$base.'$2"',$text); } + + function isNum($str='') { + return preg_match('@^[1-9][0-9]*$@',$str); + } } From 904b5410641413e7b2371485cc3d0aa9695e696f Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 19:30:01 +0900 Subject: [PATCH 315/338] Code cleanup --- assets/snippets/ditto/snippet.ditto.php | 208 ++++++++++++------------ 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/assets/snippets/ditto/snippet.ditto.php b/assets/snippets/ditto/snippet.ditto.php index dbc6341f3c..47751c8546 100644 --- a/assets/snippets/ditto/snippet.ditto.php +++ b/assets/snippets/ditto/snippet.ditto.php @@ -22,11 +22,11 @@ //---Core Settings---------------------------------------------------- // -$ditto_version = "2.1.2"; +$ditto_version = '2.1.2'; // Ditto version being executed -if(!isset($ditto_base)) $ditto_base = 'assets/snippets/ditto/'; -$ditto_base = $modx->config['base_path'].ltrim($ditto_base,'/'); +if(isset($ditto_base)) $ditto_base = $modx->config['base_path'].ltrim($ditto_base,'/'); +else $ditto_base = __DIR__ . '/'; /* Param: ditto_base @@ -54,11 +54,11 @@ This is case sensitive Default: - "" - blank + '' - blank */ if(!isset($language)) $language = $modx->config['manager_language']; if (!is_file("{$ditto_base}lang/{$language}.inc.php")) { - $language ="english"; + $language ='english'; } /* Param: language @@ -70,9 +70,9 @@ Any language name with a corresponding file in the &ditto_base/lang folder Default: - "english" + 'english' */ -$format = (isset($format)) ? strtolower($format) : "html" ; +$format = (isset($format)) ? strtolower($format) : 'html' ; /* Param: format @@ -80,16 +80,16 @@ Output format to use Options: - - "html" - - "json" - - "xml" - - "atom" - - "rss" + - 'html' + - 'json' + - 'xml' + - 'atom' + - 'rss' Default: - "html" + 'html' */ -$config = (isset($config)) ? $config : "default"; +$config = (isset($config)) ? $config : 'default'; /* Param: config @@ -97,11 +97,11 @@ Load a custom configuration Options: - "default" - default blank config file + 'default' - default blank config file CONFIG_NAME - Other configs installed in the configs folder or in any folder within the MODX base path via @FILE Default: - "default" + 'default' Related: - @@ -137,7 +137,7 @@ Default: 1 - on */ -$extenders = isset($extenders) ? explode(",",$extenders) : array(); +$extenders = isset($extenders) ? explode(',',$extenders) : array(); /* Param: extenders @@ -160,59 +160,59 @@ // Variable: placeholders // Initialize custom placeholders array for configs or extenders to add to -$filters = array("custom"=>array(),"parsed"=>array()); +$filters = array('custom'=>array(),'parsed'=>array()); // Variable: filters // Holds both the custom filters array for configs or extenders to add to // and the parsed filters array. To add to this array, use the following format // (code) - // $filters["parsed"][] = array("name" => array("source"=>$source,"value"=>$value,"mode"=>$mode)); - // $filters["custom"][] = array("source","callback_function"); + // $filters['parsed'][] = array('name' => array('source'=>$source,'value'=>$value,'mode'=>$mode)); + // $filters['custom'][] = array('source','callback_function'); $orderBy = array('parsed'=>array(),'custom'=>array(),'unparsed'=>(isset($orderBy) ? $orderBy : '')); // Variable: orderBy // An array that holds all criteria to sort the result set by. // Note that using a custom sort will disable all other sorting. // (code) - // $orderBy["parsed"][] = array("sortBy","sortDir"); - // $orderBy["custom"][] = array("sortBy","callback_function"); + // $orderBy['parsed'][] = array('sortBy','sortDir'); + // $orderBy['custom'][] = array('sortBy','callback_function'); //---Includes-------------------------------------------------------- // $files = array ( - "base_language" => $ditto_base."lang/english.inc.php", - "language" => $ditto_base."lang/$language.inc.php", - "main_class" => $ditto_base."classes/ditto.class.inc.php", - "template_class" => $ditto_base."classes/template.class.inc.php", - "filter_class" => $ditto_base."classes/filter.class.inc.php", - "format" => $ditto_base."formats/$format.format.inc.php", - "config" => $ditto_base."configs/default.config.php", - "user_config" => (substr($config, 0, 5) != "@FILE") ? $ditto_base."configs/$config.config.php" : $modx->config['base_path'].trim(substr($config, 5)) + 'base_language' => "{$ditto_base}lang/english.inc.php", + 'language' => "{$ditto_base}lang/{$language}.inc.php", + 'main_class' => "{$ditto_base}classes/ditto.class.inc.php", + 'template_class' => "{$ditto_base}classes/template.class.inc.php", + 'filter_class' => "{$ditto_base}classes/filter.class.inc.php", + 'format' => "{$ditto_base}formats/$format.format.inc.php", + 'config' => "{$ditto_base}configs/default.config.php", + 'user_config' => (substr($config, 0, 5) != '@FILE') ? "{$ditto_base}configs/{$config}.config.php" : $modx->config['base_path'].trim(substr($config, 5)) ); -if ($phx == 1) { - $files["prePHx_class"] = $ditto_base."classes/phx.pre.class.inc.php"; +if ($phx == 1 && !$modx->config['enable_filter']) { + $files['prePHx_class'] = $ditto_base.'classes/phx.pre.class.inc.php'; } if (isset($randomize)) { - $files["randomize_class"] = $ditto_base."classes/random.class.inc.php"; + $files['randomize_class'] = $ditto_base.'classes/random.class.inc.php'; } if ($debug == 1) { - $files["modx_debug_class"] = $ditto_base."debug/modxDebugConsole.class.php"; - $files["debug_class"] = $ditto_base."classes/debug.class.inc.php"; - $files["debug_templates"] = $ditto_base."debug/debug.templates.php"; + $files['modx_debug_class'] = $ditto_base."debug/modxDebugConsole.class.php"; + $files['debug_class'] = $ditto_base."classes/debug.class.inc.php"; + $files['debug_templates'] = $ditto_base."debug/debug.templates.php"; } $files = array_unique($files); foreach ($files as $filename => $filevalue) { - if (file_exists($filevalue) && strpos($filename,"class")) { + if (is_file($filevalue) && strpos($filename,'class')!==false) { include_once($filevalue); - } else if (file_exists($filevalue)) { + } elseif (is_file($filevalue)) { include($filevalue); - } else if ($filename == "language") { - $modx->logEvent(1, 3, "Language file does not exist Please check: " . $filevalue, "Ditto " . $ditto_version); - return "Language file does not exist Please check: " . $filevalue; + } elseif ($filename == 'language') { + $modx->logEvent(1, 3, 'Language file does not exist Please check: ' . $filevalue, 'Ditto ' . $ditto_version); + return 'Language file does not exist Please check: ' . $filevalue; } else { - $modx->logEvent(1, 3, $filevalue . " " . $_lang['file_does_not_exist'], "Ditto " . $ditto_version); - return $filevalue . " " . $_lang['file_does_not_exist']; + $modx->logEvent(1, 3, $filevalue . ' ' . $_lang['file_does_not_exist'], 'Ditto ' . $ditto_version); + return $filevalue . ' ' . $_lang['file_does_not_exist']; } } @@ -222,19 +222,19 @@ $ditto = new ditto($dittoID, $format, $_lang, $dbg_templates); // create a new Ditto instance in the specified format and language with the requested debug level } else { - $modx->logEvent(1,3,$_lang['invalid_class'],"Ditto ".$ditto_version); + $modx->logEvent(1,3,$_lang['invalid_class'],'Ditto '.$ditto_version); return $_lang['invalid_class']; } //---Initiate Extenders---------------------------------------------- // if (isset($tagData)) { - $extenders[] = "tagging"; + $extenders[] = 'tagging'; } if(count($extenders) > 0) { $extenders = array_unique($extenders); foreach ($extenders as $extender) { - if(substr($extender, 0, 5) != "@FILE") { - $extender_path = $ditto_base."extenders/".$extender.".extender.inc.php"; + if(substr($extender, 0, 5) != '@FILE') { + $extender_path = "{$ditto_base}extenders/{$extender}.extender.inc.php"; } else { $extender_path = $modx->config['base_path'].trim(substr($extender, 5)); } @@ -242,8 +242,8 @@ if (file_exists($extender_path)){ include($extender_path); } else { - $modx->logEvent(1, 3, $extender . " " . $_lang['extender_does_not_exist'], "Ditto ".$ditto_version); - return $extender . " " . $_lang['extender_does_not_exist']; + $modx->logEvent(1, 3, $extender . ' ' . $_lang['extender_does_not_exist'], 'Ditto '.$ditto_version); + return $extender . ' ' . $_lang['extender_does_not_exist']; } } } @@ -254,12 +254,12 @@ if (isset($limit)) {$queryLimit = $limit;} if (isset($sortBy) || isset($sortDir) || is_null($orderBy['unparsed'])) { $sortDir = isset($sortDir) ? strtoupper($sortDir) : 'DESC'; - $sortBy = isset($sortBy) ? $sortBy : "createdon"; + $sortBy = isset($sortBy) ? $sortBy : 'createdon'; $orderBy['parsed'][]=array($sortBy,$sortDir); } // Allow backwards compatibility -$idType = isset($documents) ? "documents" : "parents"; +$idType = isset($documents) ? 'documents' : 'parents'; // Variable: idType // type of IDs provided; can be either parents or documents @@ -298,7 +298,7 @@ - */ -$IDs = ($idType == "parents") ? $parents : $documents; +$IDs = ($idType == 'parents') ? $parents : $documents; // Variable: IDs // Internal variable which holds the set of IDs for Ditto to fetch @@ -339,7 +339,7 @@ - - */ -$dateSource = isset($dateSource) ? $dateSource : "createdon"; +$dateSource = isset($dateSource) ? $dateSource : 'createdon'; /* Param: dateSource @@ -350,12 +350,12 @@ # - Any UNIX timestamp from MODX fields or TVs such as createdon, pub_date, or editedon Default: - "createdon" + 'createdon' Related: - */ -$dateFormat = isset($dateFormat)? $dateFormat : $_lang["dateFormat"]; +$dateFormat = isset($dateFormat)? $dateFormat : $_lang['dateFormat']; /* Param: dateFormat @@ -371,7 +371,7 @@ Related: - */ -$display = isset($display) ? $display : "all"; +$display = isset($display) ? $display : 'all'; /* Param: display @@ -380,16 +380,16 @@ Options: # - Any number - "all" - All documents found + 'all' - All documents found Default: - "all" + 'all' Related: - - */ -$total = isset($total) ? $total : "all"; +$total = isset($total) ? $total : 'all'; /* Param: total @@ -398,10 +398,10 @@ Options: # - Any number - "all" - All documents found + 'all' - All documents found Default: - "all" - All documents found + 'all' - All documents found Related: - @@ -521,7 +521,7 @@ Related: - */ -$where = (isset($where))? $where : ""; +$where = (isset($where))? $where : ''; /* Param: where @@ -537,7 +537,7 @@ Related: - */ -$noResults = isset($noResults)? $ditto->getParam($noResults,"no_documents") : $_lang['no_documents']; +$noResults = isset($noResults)? $ditto->getParam($noResults,'no_documents') : $_lang['no_documents']; /* Param: noResults @@ -550,7 +550,7 @@ Default: [LANG] */ -$removeChunk = isset($removeChunk) ? explode(",",$removeChunk) : false; +$removeChunk = isset($removeChunk) ? explode(',',$removeChunk) : false; /* Param: removeChunk @@ -564,7 +564,7 @@ Default: [NULL] */ -$hiddenFields = isset($hiddenFields) ? explode(",",$hiddenFields) : false; +$hiddenFields = isset($hiddenFields) ? explode(',',$hiddenFields) : false; /* Param: hiddenFields @@ -591,7 +591,7 @@ Default: 0 */ -$globalFilterDelimiter = isset($globalFilterDelimiter) ? $globalFilterDelimiter : "|"; +$globalFilterDelimiter = isset($globalFilterDelimiter) ? $globalFilterDelimiter : '|'; /* Param: globalFilterDelimiter @@ -602,7 +602,7 @@ Any character not used in the filters Default: - "|" + '|' Related: - @@ -610,7 +610,7 @@ - */ -$localFilterDelimiter = isset($localFilterDelimiter) ? $localFilterDelimiter : ","; +$localFilterDelimiter = isset($localFilterDelimiter) ? $localFilterDelimiter : ','; /* Param: localFilterDelimiter @@ -621,17 +621,17 @@ Any character not used in the filter itself Default: - "," + ',' Related: - - - */ -$filters["custom"] = isset($cFilters) ? array_merge($filters["custom"],$cFilters) : $filters["custom"]; -$filters["parsed"] = isset($parsedFilters) ? array_merge($filters["parsed"],$parsedFilters) : $filters["parsed"]; +$filters['custom'] = isset($cFilters) ? array_merge($filters['custom'],$cFilters) : $filters['custom']; +$filters['parsed'] = isset($parsedFilters) ? array_merge($filters['parsed'],$parsedFilters) : $filters['parsed']; // handle 2.0.0 compatibility -$filter = (isset($filter) || ($filters["custom"] != false) || ($filters["parsed"] != false)) ? $ditto->parseFilters($filter,$filters["custom"],$filters["parsed"],$globalFilterDelimiter,$localFilterDelimiter) : false; +$filter = (isset($filter) || ($filters['custom'] != false) || ($filters['parsed'] != false)) ? $ditto->parseFilters($filter,$filters['custom'],$filters['parsed'],$globalFilterDelimiter,$localFilterDelimiter) : false; /* Param: filter @@ -700,12 +700,12 @@ 0 - off; returns output */ $templates = array( - "default" => "@CODE" . $_lang['default_template'], - "base" => (isset($tpl)) ? $tpl : NULL, - "alt" => (isset($tplAlt)) ? $tplAlt : NULL, - "first" => (isset($tplFirst)) ? $tplFirst : NULL, - "last" => (isset($tplLast)) ? $tplLast : NULL, - "current" => (isset($tplCurrentDocument)) ? $tplCurrentDocument : NULL + 'default' => '@CODE' . $_lang['default_template'], + 'base' => (isset($tpl)) ? $tpl : NULL, + 'alt' => (isset($tplAlt)) ? $tplAlt : NULL, + 'first' => (isset($tplFirst)) ? $tplFirst : NULL, + 'last' => (isset($tplLast)) ? $tplLast : NULL, + 'current' => (isset($tplCurrentDocument)) ? $tplCurrentDocument : NULL ); /* Param: tpl @@ -800,7 +800,7 @@ $ditto->parseFields($placeholders,$seeThruUnpub,$dateSource,$randomize); // parse the fields into the field array -$documentIDs = $ditto->determineIDs($IDs, $idType, $ditto->fields["backend"]["tv"], $orderBy, $depth, $showPublishedOnly, $seeThruUnpub, $hideFolders, $hidePrivate, $showInMenuOnly, $where, $dateSource, $queryLimit, $display, $filter,$paginate, $randomize); +$documentIDs = $ditto->determineIDs($IDs, $idType, $ditto->fields['backend']['tv'], $orderBy, $depth, $showPublishedOnly, $seeThruUnpub, $hideFolders, $hidePrivate, $showInMenuOnly, $where, $dateSource, $queryLimit, $display, $filter,$paginate, $randomize); // retrieves a list of document IDs that meet the criteria and populates the $resources array with them $count = count($documentIDs); // count the number of documents to be retrieved @@ -810,13 +810,13 @@ if ($count > 0) { // if documents are returned continue with execution - $total = ($total == "all") ? $count : min($total,$count); + $total = ($total == 'all') ? $count : min($total,$count); // set total equal to count if all documents are to be included - $display = ($display == "all") ? min($count,$total) : min($display,$total); + $display = ($display == 'all') ? min($count,$total) : min($display,$total); // allow show to use all option - $stop = ($save != "1") ? min($total-$start,$display) : min($count,$total); + $stop = ($save != '1') ? min($total-$start,$display) : min($count,$total); // set initial stop count if($paginate == 1) { @@ -979,17 +979,17 @@ // generate the pagination placeholders } - $dbFields = $ditto->fields["display"]["db"]; + $dbFields = $ditto->fields['display']['db']; // get the database fields - $TVs = $ditto->fields["display"]["tv"]; + $TVs = $ditto->fields['display']['tv']; // get the TVs if(isset($orderBy['parsed'][0][1])) { switch($orderBy['parsed'][0][1]) { - case "DESC": + case 'DESC': $stop = ($ditto->prefetch === false) ? $stop + $start + $offset : $stop + $offset; $start += $offset; break; - case "ASC": + case 'ASC': $start += $offset; $stop += $start; break; @@ -999,16 +999,16 @@ if ($ditto->prefetch !== false) { $documentIDs = array_slice($documentIDs,$start,$stop); // set the document IDs equal to the trimmed array - $dbFields = array_diff($dbFields,$ditto->prefetch["fields"]["db"]); + $dbFields = array_diff($dbFields,$ditto->prefetch['fields']['db']); // calculate the difference between the database fields and those already prefetched - $dbFields[] = "id"; + $dbFields[] = 'id'; // append id to the db fields array - $TVs = array_diff($TVs,$ditto->prefetch["fields"]["tv"]); + $TVs = array_diff($TVs,$ditto->prefetch['fields']['tv']); // calculate the difference between the tv fields and those already prefetched $start = 0; $stop = min($display,($queryLimit != 0) ? $queryLimit : $display,count($documentIDs)); } else { - $queryLimit = ($queryLimit == 0) ? "" : $queryLimit; + $queryLimit = ($queryLimit == 0) ? '' : $queryLimit; } $resource = $ditto->getDocuments($documentIDs, $dbFields, $TVs, $orderBy, $showPublishedOnly, 0, $hidePrivate, $where, $queryLimit, $randomize, $dateSource); @@ -1017,7 +1017,7 @@ // initialize the output variable and send the header if ($resource) { - if ($randomize != "0" && $randomize != "1") { + if ($randomize != '0' && $randomize != '1') { $resource = $ditto->weightedRandom($resource,$randomize,$stop); // randomize the documents } @@ -1025,11 +1025,11 @@ $resource = array_values($resource); for ($x=$start;$x<$stop;$x++) { - $template = $ditto->template->determine($templates,$x,0,$stop,$resource[$x]["id"]); + $template = $ditto->template->determine($templates,$x,0,$stop,$resource[$x]['id']); // choose the template to use and set the code of that template to the template variable $renderedOutput = $ditto->render($resource[$x], $template, $removeChunk, $dateSource, $dateFormat, $placeholders,$phx,abs($start-$x),$stop); // render the output using the correct template, in the correct format and language - $modx->setPlaceholder($dittoID."item[".abs($start-$x)."]",$renderedOutput); + $modx->setPlaceholder($dittoID.'item['.abs($start-$x).']',$renderedOutput); /* Placeholder: item[x] @@ -1051,8 +1051,8 @@ // --------------------------------------------------- if($save) { - $modx->setPlaceholder($dittoID."ditto_object", $ditto); - $modx->setPlaceholder($dittoID."ditto_resource", ($save == "1") ? array_slice($resource,$display) : $resource); + $modx->setPlaceholder($dittoID.'ditto_object', $ditto); + $modx->setPlaceholder($dittoID.'ditto_resource', ($save == '1') ? array_slice($resource,$display) : $resource); } } else { $output = $header.$ditto->noResults($noResults,$paginate).$footer; @@ -1063,16 +1063,16 @@ if ($debug == 1) { $ditto_params =& $modx->event->params; - if (!isset($_GET["ditto_".$dittoID."debug"])) { - $_SESSION["ditto_debug_$dittoID"] = $ditto->debug->render_popup($ditto, $ditto_base, $ditto_version, $ditto_params, $documentIDs, array("db"=>$dbFields,"tv"=>$TVs), $display, $templates, $orderBy, $start, $stop, $total,$filter,$resource); + if (!isset($_GET['ditto_'.$dittoID.'debug'])) { + $_SESSION['ditto_debug_$dittoID'] = $ditto->debug->render_popup($ditto, $ditto_base, $ditto_version, $ditto_params, $documentIDs, array('db'=>$dbFields,'tv'=>$TVs), $display, $templates, $orderBy, $start, $stop, $total,$filter,$resource); } - if (isset($_GET["ditto_".$dittoID."debug"])) { - switch ($_GET["ditto_".$dittoID."debug"]) { - case "open" : - exit($_SESSION["ditto_debug_$dittoID"]); + if (isset($_GET['ditto_'.$dittoID.'debug'])) { + switch ($_GET['ditto_'.$dittoID.'debug']) { + case 'open' : + exit($_SESSION['ditto_debug_$dittoID']); break; - case "save" : - $ditto->debug->save($_SESSION["ditto_debug_$dittoID"],"ditto".strtolower($ditto_version)."_debug_doc".$modx->documentIdentifier.".html"); + case 'save' : + $ditto->debug->save($_SESSION['ditto_debug_$dittoID'],'ditto'.strtolower($ditto_version).'_debug_doc'.$modx->documentIdentifier.'.html'); break; } } else { @@ -1085,4 +1085,4 @@ $output = str_replace(array('[+ditto+]', '[+wrapper+]'), $output, $outerTpl); } -return ($save != 3) ? $output : ""; \ No newline at end of file +return ($save != 3) ? $output : ''; \ No newline at end of file From 00525ebddfa87cd3dc43b2874ab6da0c9041a443 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 19:31:29 +0900 Subject: [PATCH 316/338] Code cleanup --- .../ditto/classes/debug.class.inc.php | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/assets/snippets/ditto/classes/debug.class.inc.php b/assets/snippets/ditto/classes/debug.class.inc.php index 287ce4bb16..2068c84c65 100644 --- a/assets/snippets/ditto/classes/debug.class.inc.php +++ b/assets/snippets/ditto/classes/debug.class.inc.php @@ -16,8 +16,8 @@ class debug extends modxDebugConsole { // --------------------------------------------------- function render_link($dittoID,$ditto_base) { global $ditto_lang,$modx; - $base_url = str_replace($modx->config["base_path"],$modx->config["site_url"],$ditto_base); - return $this->makeLink($ditto_lang["debug"],$ditto_lang["open_dbg_console"], $ditto_lang["save_dbg_console"],$base_url.'debug/',"ditto_".$dittoID); + $base_url = str_replace($modx->config['base_path'],$modx->config['site_url'],$ditto_base); + return $this->makeLink($ditto_lang['debug'],$ditto_lang['open_dbg_console'], $ditto_lang['save_dbg_console'],$base_url.'debug/','ditto_'.$dittoID); } // --------------------------------------------------- // Function: render_popup @@ -26,24 +26,24 @@ function render_link($dittoID,$ditto_base) { function render_popup($ditto,$ditto_base,$ditto_version, $ditto_params, $IDs, $fields, $summarize, $templates, $orderBy, $start, $stop, $total,$filter,$resource) { global $ditto_lang,$modx; $tabs = array(); - $fields = (count($fields["db"]) > 0 && count($fields["tv"]) > 0) ? array_merge_recursive($ditto->fields,array("retrieved"=>$fields)) : $ditto->fields; + $fields = (count($fields['db']) > 0 && count($fields['tv']) > 0) ? array_merge_recursive($ditto->fields,array('retrieved'=>$fields)) : $ditto->fields; - $tabs[$ditto_lang["info"]] = $this->prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $start, $stop, $total); - $tabs[$ditto_lang["params"]] = $this->makeParamTable($ditto_params,$ditto_lang["params"]); - $tabs[$ditto_lang["fields"]] = "
    ".$this->array2table($this->cleanArray($fields), true, true)."
    "; - $tabs[$ditto_lang["templates"]] = $this->makeParamTable($this->prepareTemplates($templates),$ditto_lang["templates"]); + $tabs[$ditto_lang['info']] = $this->prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $start, $stop, $total); + $tabs[$ditto_lang['params']] = $this->makeParamTable($ditto_params,$ditto_lang['params']); + $tabs[$ditto_lang['fields']] = "
    ".$this->array2table($this->cleanArray($fields), true, true).'
    '; + $tabs[$ditto_lang['templates']] = $this->makeParamTable($this->prepareTemplates($templates),$ditto_lang['templates']); if ($filter !== false) { - $tabs[$ditto_lang["filters"]] = $this->prepareFilters($this->cleanArray($filter)); + $tabs[$ditto_lang['filters']] = $this->prepareFilters($this->cleanArray($filter)); } if ($ditto->prefetch == true) { - $tabs[$ditto_lang["prefetch_data"]] = $this->preparePrefetch($ditto->prefetch); + $tabs[$ditto_lang['prefetch_data']] = $this->preparePrefetch($ditto->prefetch); } if (count($resource) > 0 && $resource) { - $tabs[$ditto_lang["retrieved_data"]] = $this->prepareDocumentInfo($resource); + $tabs[$ditto_lang['retrieved_data']] = $this->prepareDocumentInfo($resource); } - $base_url = str_replace($modx->config["base_path"],$modx->config["site_url"],$ditto_base); + $base_url = str_replace($modx->config['base_path'],$modx->config['site_url'],$ditto_base); $generatedOn = "\r\n\r\n".''; return $this->render($tabs,$ditto_lang['debug'],$base_url).$generatedOn; } @@ -55,16 +55,16 @@ function render_popup($ditto,$ditto_base,$ditto_version, $ditto_params, $IDs, $f function preparePrefetch($prefetch) { global $ditto_lang; $ditto_IDs = array(); - if (count($prefetch["dbg_IDs_pre"]) > 0) { - $ditto_IDs[$ditto_lang["ditto_IDs_all"]." (".count($prefetch["dbg_IDs_pre"]).")"] = implode(",",$prefetch["dbg_IDs_pre"]); + if (count($prefetch['dbg_IDs_pre']) > 0) { + $ditto_IDs[$ditto_lang['ditto_IDs_all'].' ('.count($prefetch['dbg_IDs_pre']).')'] = implode(',',$prefetch['dbg_IDs_pre']); } - if (count($prefetch["dbg_IDs_post"]) > 0) { - $ditto_IDs[$ditto_lang["ditto_IDs_selected"]." (".count($prefetch["dbg_IDs_post"]).")"] = implode(", ",$prefetch["dbg_IDs_post"]); + if (count($prefetch['dbg_IDs_post']) > 0) { + $ditto_IDs[$ditto_lang['ditto_IDs_selected'].' ('.count($prefetch['dbg_IDs_post']).')'] = implode(', ',$prefetch['dbg_IDs_post']); } else { - $ditto_IDs[$ditto_lang["ditto_IDs_selected"]." (0)"] = strip_tags($ditto_lang["no_documents"]); + $ditto_IDs[$ditto_lang['ditto_IDs_selected'].' (0)'] = strip_tags($ditto_lang['no_documents']); } - $out = $this->array2table(array($ditto_lang["prefetch_data"]=>$ditto_IDs),true,true); - return $out.$this->prepareDocumentInfo($prefetch["dbg_resource"]); + $out = $this->array2table(array($ditto_lang['prefetch_data']=>$ditto_IDs),true,true); + return $out.$this->prepareDocumentInfo($prefetch['dbg_resource']); } // --------------------------------------------------- @@ -72,9 +72,9 @@ function preparePrefetch($prefetch) { // Create the content of the Filters tab // --------------------------------------------------- function prepareFilters($filter) { - $output = ""; + $output = ''; foreach ($filter as $name=>$value) { - if ($name == "custom") { + if ($name == 'custom') { foreach ($value as $name=>$value) { $output .= $this->array2table(array($name=>$value), true, true); } @@ -91,11 +91,11 @@ function prepareFilters($filter) { // --------------------------------------------------- function prepareDocumentInfo($resource) { global $ditto_lang; - $output = ""; + $output = ''; if (count($resource) > 0) { foreach ($resource as $item) { - $header = str_replace(array('[+pagetitle+]','[+id+]'),array($item['pagetitle'],$item['id']),$this->templates["item"]); - $output .= $this->makeParamTable($item,$header,true,true,true,"resource"); + $header = str_replace(array('[+pagetitle+]','[+id+]'),array($item['pagetitle'],$item['id']),$this->templates['item']); + $output .= $this->makeParamTable($item,$header,true,true,true,'resource'); } } return $output; @@ -112,7 +112,7 @@ function prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $st $items[$ditto_lang['total']] = $total; $items[$ditto_lang['start']] = $start; $items[$ditto_lang['stop']] = $stop; - $items[$ditto_lang['ditto_IDs']] = (count($IDs) > 0) ? wordwrap(implode(", ",$IDs),100, "
    ") : $ditto_lang['none']; + $items[$ditto_lang['ditto_IDs']] = (count($IDs) > 0) ? wordwrap(implode(', ',$IDs),100, '
    ') : $ditto_lang['none']; $output = ''; if (is_array($orderBy['parsed']) && count($orderBy['parsed']) > 0) { $sort = array(); @@ -121,7 +121,7 @@ function prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $st } $output = $this->array2table($this->cleanArray($sort), true, true); } - return $this->makeParamTable($items,$ditto_lang["basic_info"],false,false).$output; + return $this->makeParamTable($items,$ditto_lang['basic_info'],false,false).$output; } // --------------------------------------------------- @@ -133,16 +133,16 @@ function prepareTemplates($templates) { $displayTPLs = array(); foreach ($templates as $name=>$value) { switch ($name) { - case "base": - $displayName = "tpl"; + case 'base': + $displayName = 'tpl'; break; - case "default": - $displayName = "tpl"; + case 'default': + $displayName = 'tpl'; break; default: - $displayName = "tpl".strtoupper($name{0}).substr($name,1); + $displayName = 'tpl'.strtoupper($name{0}).substr($name,1); break; } $displayTPLs[$displayName] = $value; From a439d20797d887f768d7c3b6b9fb95da16256322 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 20:21:39 +0900 Subject: [PATCH 317/338] Code cleanup --- .../ditto/classes/template.class.inc.php | 143 +++++++----------- 1 file changed, 54 insertions(+), 89 deletions(-) diff --git a/assets/snippets/ditto/classes/template.class.inc.php b/assets/snippets/ditto/classes/template.class.inc.php index ac53c1b065..3617828f29 100644 --- a/assets/snippets/ditto/classes/template.class.inc.php +++ b/assets/snippets/ditto/classes/template.class.inc.php @@ -15,18 +15,17 @@ class template{ // Set the class language and fields variables // --------------------------------------------------- function __construct() { - $this->language = $GLOBALS["ditto_lang"]; + $this->language = $GLOBALS['ditto_lang']; $this->fields = array ( - "db" => array (), - "tv" => array (), - "custom" => array (), - "item" => array (), - "qe" => array (), - "phx" => array (), - "rss" => array (), - "json" => array (), - "xml" => array (), - "unknown" => array() + 'db' => array (), + 'tv' => array (), + 'custom' => array (), + 'item' => array (), + 'phx' => array (), + 'rss' => array (), + 'json' => array (), + 'xml' => array (), + 'unknown' => array() ); } @@ -36,42 +35,29 @@ function __construct() { // Check to make sure they have fields, and sort the fields // --------------------------------------------------- function process($template) { - if (!isset($template["base"])) { - $template["base"] = $template["default"]; - } else { - unset($template["default"]); - } + if (!isset($template['base'])) $template['base'] = $template['default']; + else unset($template['default']); + foreach ($template as $name=>$tpl) { - if(!empty($tpl) && $tpl != "") { - $templates[$name] = $this->fetch($tpl); - } + if(!empty($tpl) && $tpl != '') $templates[$name] = $this->fetch($tpl); } $fieldList = array(); foreach ($templates as $tplName=>$tpl) { $check = $this->findTemplateVars($tpl); - if (is_array($check)) { - $fieldList = array_merge($check, $fieldList); - } else { + if (is_array($check)) $fieldList = array_merge($check, $fieldList); + else { switch ($tplName) { - case "base": - $displayName = "tpl"; - break; - - case "default": - $displayName = "tpl"; - break; - - default: - $displayName = "tpl".$tplName; - break; + case 'base' : + case 'default': $displayName = 'tpl';break; + default : $displayName = 'tpl'.$tplName; } - $templates[$tplName] = str_replace("[+tpl+]",$displayName,$this->language["bad_tpl"]); + $templates[$tplName] = str_replace('[+tpl+]',$displayName,$this->language['bad_tpl']); } } $fieldList = array_unique($fieldList); $fields = $this->sortFields($fieldList); - $checkAgain = array ("qe", "json", "xml"); + $checkAgain = array ('json', 'xml'); foreach ($checkAgain as $type) { $fields = array_merge_recursive($fields, $this->sortFields($fields[$type])); } @@ -87,7 +73,7 @@ function findTemplateVars($tpl) { preg_match_all('~\[\+(.*?)\+\]~', $tpl, $matches); $TVs = array(); foreach($matches[1] as $tv) { - $match = explode(":", $tv); + $match = explode(':', $tv); $TVs[strtolower($match[0])] = $match[0]; } if (count($TVs) >= 1) { @@ -103,48 +89,35 @@ function findTemplateVars($tpl) { // --------------------------------------------------- function sortFields ($fieldList) { global $ditto_constantFields; - $dbFields = $ditto_constantFields["db"]; - $tvFields = $ditto_constantFields["tv"]; + $dbFields = $ditto_constantFields['db']; + $tvFields = $ditto_constantFields['tv']; $fields = array ( - "db" => array (), - "tv" => array (), - "custom" => array (), - "item" => array (), - "qe" => array (), - "phx" => array (), - "rss" => array (), - "json" => array (), - "xml" => array (), - "unknown" => array() + 'db' => array (), + 'tv' => array (), + 'custom' => array (), + 'item' => array (), + 'phx' => array (), + 'rss' => array (), + 'json' => array (), + 'xml' => array (), + 'unknown' => array() ); - $custom = array("author","date","url","title","ditto_iteration"); + $custom = array('author','date','url','title','ditto_iteration'); foreach ($fieldList as $field) { - if (substr($field, 0, 4) == "rss_") { - $fields['rss'][] = substr($field,4); - }else if (substr($field, 0, 4) == "xml_") { - $fields['xml'][] = substr($field,4); - }else if (substr($field, 0, 5) == "json_") { - $fields['json'][] = substr($field,5); - }else if (substr($field, 0, 5) == "item[") { - $fields['item'][] = substr($field, 4); - }else if (substr($field, 0, 1) == "#") { - $fields['qe'][] = substr($field,1); - }else if (substr($field, 0, 4) == "phx:") { - $fields['phx'][] = $field; - }else if (in_array($field, $dbFields)) { - $fields['db'][] = $field; - }else if(in_array($field, $tvFields)){ - $fields['tv'][] = $field; - }else if(substr($field, 0, 2) == "tv" && in_array(substr($field,2), $tvFields)) { - $fields['tv'][] = substr($field,2); + if (substr($field, 0, 4) == 'rss_') $fields['rss'][] = substr($field,4); + elseif(substr($field, 0, 4) == 'xml_') $fields['xml'][] = substr($field,4); + elseif(substr($field, 0, 5) == 'json_') $fields['json'][] = substr($field,5); + elseif(substr($field, 0, 5) == 'item[') $fields['item'][] = substr($field,4); + elseif(substr($field, 0, 4) == 'phx:') $fields['phx'][] = $field; + elseif(in_array($field, $dbFields)) $fields['db'][] = $field; + elseif(in_array($field, $tvFields)) $fields['tv'][] = $field; + elseif(substr($field, 0, 2) == 'tv' && in_array(substr($field,2), $tvFields)) + $fields['tv'][] = substr($field,2); // TODO: Remove TV Prefix support in Ditto - }else if (in_array($field, $custom)) { - $fields['custom'][] = $field; - }else { - $fields['unknown'][] = $field; - } + elseif(in_array($field, $custom)) $fields['custom'][] = $field; + else $fields['unknown'][] = $field; } return $fields; } @@ -171,19 +144,13 @@ function determine($templates,$x,$start,$stop,$id) { global $modx; // determine current template - $currentTPL = "base"; - if ($x % 2 && !empty($templates["alt"])) { - $currentTPL = "alt"; - } - if ($id == $modx->documentObject['id'] && !empty($templates["current"])){ - $currentTPL = "current"; - } - if ($x == 0 && !empty($templates["first"])) { - $currentTPL = "first"; - } - if ($x == ($stop -1) && !empty($templates["last"])) { - $currentTPL = "last"; - } + if ($x == ($stop -1) && !empty($templates['last'])) $currentTPL = 'last'; + elseif ($x == 0 && !empty($templates['first'])) $currentTPL = 'first'; + elseif ($id == $modx->documentIdentifier && !empty($templates['current'])) + $currentTPL = 'current'; + elseif ($x % 2 && !empty($templates['alt'])) $currentTPL = 'alt'; + else $currentTPL = 'base'; + $this->current = $currentTPL; return $templates[$currentTPL]; } @@ -201,7 +168,7 @@ function fetch($tpl){ $template = $modx->getChunk(substr($tpl, 7)); } elseif(substr($tpl, 0, 5) == '@FILE') { $path = trim(substr($tpl, 6)); - if(strpos($path, $modx->config['base_url'].'manager/includes/config.inc.php')===false) + if(strpos($path, 'manager/includes/config.inc.php')===false) $template = file_get_contents($path); } elseif(substr($tpl, 0, 5) == '@CODE') { $template = substr($tpl, 6); @@ -230,7 +197,7 @@ function fetch($tpl){ // --------------------------------------------------- function get_file_contents($filename) { if (!function_exists('file_get_contents')) { - $fhandle = fopen($filename, "r"); + $fhandle = fopen($filename, 'r'); $fcontents = fread($fhandle, filesize($filename)); fclose($fhandle); } else { @@ -239,5 +206,3 @@ function get_file_contents($filename) { return $fcontents; } } - -?> \ No newline at end of file From 53e98689baab9f851ba6b9da226fd82a358595ce Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 20:22:36 +0900 Subject: [PATCH 318/338] Code cleanup --- .../ditto/classes/ditto.class.inc.php | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 506302735c..a71061c808 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -12,11 +12,11 @@ class ditto { function __construct($dittoID,$format,$language,$debug) { $this->format = $format; - $GLOBALS['ditto_lang'] = $language; - $this->prefetch = false; - $this->advSort = false; - $this->sqlOrderBy = array(); - $this->customReset = array(); + $GLOBALS['ditto_lang'] = $language; + $this->prefetch = false; + $this->advSort = false; + $this->sqlOrderBy = array(); + $this->customReset = array(); $this->constantFields[] = array('db','tv'); $this->constantFields['db'] = explode(',', 'id,type,contentType,pagetitle,longtitle,description,alias,link_attributes,published,pub_date,unpub_date,parent,isfolder,introtext,content,richtext,template,menuindex,searchable,cacheable,createdby,createdon,editedby,editedon,deleted,deletedon,deletedby,publishedon,publishedby,menutitle,donthit,privateweb,privatemgr,content_dispo,hidemenu'); $this->constantFields['tv'] = $this->getTVList(); @@ -26,7 +26,7 @@ function __construct($dittoID,$format,$language,$debug) { $this->customPlaceholdersMap = array(); $this->template = new template(); - if (!is_null($debug)) {$this->debug = new debug($debug);} + if (!is_null($debug)) $this->debug = new debug($debug); } // --------------------------------------------------- @@ -36,7 +36,7 @@ function __construct($dittoID,$format,$language,$debug) { function getTVList() { global $modx; - // TODO: make it so that it only pulls those that apply to the current template + // TODO: make it so that it only pulls those that apply to the current template $tvs = $modx->db->select('name', '[+prefix+]site_tmplvars'); $dbfields = $modx->db->getColumn('name', $tvs); return $dbfields; @@ -56,10 +56,8 @@ function addField($name,$location,$type=false) { $name = substr($name, 2); } if ($location == '*') { - if(!in_array($name,$this->fields['backend'][$type])) - $this->fields['backend'][$type][] = $name; - if(!in_array($name,$this->fields['display'][$type])) - $this->fields['display'][$type][] = $name; + if(!in_array($name,$this->fields['backend'][$type])) $this->fields['backend'][$type][] = $name; + if(!in_array($name,$this->fields['display'][$type])) $this->fields['display'][$type][] = $name; } elseif(!in_array($name,$this->fields[$location][$type])) { $this->fields[$location][$type][] = $name; } @@ -74,11 +72,8 @@ function addField($name,$location,$type=false) { function addFields($fields,$location='*',$delimiter=',',$callback=false) { if (empty($fields)) return false; if (!is_array($fields)) { - if (strpos($fields,$delimiter) !== false) { - $fields = explode($delimiter,$fields); - } else { - $fields = array($fields); - } + if (strpos($fields,$delimiter)!==false) $fields = explode($delimiter,$fields); + else $fields = array($fields); } foreach ($fields as $field) { if (is_array($field)) { @@ -90,9 +85,7 @@ function addFields($fields,$location='*',$delimiter=',',$callback=false) { } $this->addField($name,$location,$type); - if ($callback !== false) { - call_user_func_array($callback, array($name)); - } + if ($callback !== false) call_user_func_array($callback, array($name)); } return true; } @@ -104,9 +97,7 @@ function addFields($fields,$location='*',$delimiter=',',$callback=false) { function removeField($name,$location,$type) { $key = array_search ($name, $this->fields[$location][$type]); - if ($key !== false) { - unset($this->fields[$location][$type][$key]); - } + if ($key !== false) unset($this->fields[$location][$type][$key]); } // --------------------------------------------------- @@ -116,9 +107,7 @@ function removeField($name,$location,$type) { function setDisplayFields($fields,$hiddenFields) { $this->fields['display'] = $fields; - if ($hiddenFields) { - $this->addFields($hiddenFields,'display'); - } + if ($hiddenFields) $this->addFields($hiddenFields,'display'); } // --------------------------------------------------- @@ -128,18 +117,14 @@ function setDisplayFields($fields,$hiddenFields) { function getDocVarType($field) { global $ditto_constantFields; + $tvFields = $ditto_constantFields['tv']; $dbFields = $ditto_constantFields['db']; - if(in_array($field, $tvFields)){ - return 'tv'; - }elseif(in_array(substr($field,2), $tvFields)) { - return 'tv:prefix'; - // TODO: Remove TV Prefix support - } elseif(in_array($field, $dbFields)){ - return 'db'; - } else { - return 'unknown'; - } + + if(in_array($field, $tvFields)) return 'tv'; + elseif(in_array(substr($field,2), $tvFields)) return 'tv:prefix'; // TODO: Remove TV Prefix support + elseif(in_array($field, $dbFields)) return 'db'; + else return 'unknown'; } // --------------------------------------------------- From b0b219735f4da1bf1f2c3f1cf86cca2a7f54f16e Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 20:32:05 +0900 Subject: [PATCH 319/338] Code cleanup --- .../ditto/classes/debug.class.inc.php | 276 +++++++------ .../ditto/classes/filter.class.inc.php | 263 ++++++------ .../ditto/classes/random.class.inc.php | 241 ++++++----- .../ditto/classes/template.class.inc.php | 374 +++++++++--------- assets/snippets/ditto/snippet.ditto.php | 24 +- 5 files changed, 587 insertions(+), 591 deletions(-) diff --git a/assets/snippets/ditto/classes/debug.class.inc.php b/assets/snippets/ditto/classes/debug.class.inc.php index 2068c84c65..66324f37fe 100644 --- a/assets/snippets/ditto/classes/debug.class.inc.php +++ b/assets/snippets/ditto/classes/debug.class.inc.php @@ -3,153 +3,151 @@ /* * Title: Debug Class * Purpose: - * The Debug class contains all functions relating to Ditto's - * implimentation of the MODX debug console + * The Debug class contains all functions relating to Ditto's + * implimentation of the MODX debug console */ class debug extends modxDebugConsole { - var $debug; - - // --------------------------------------------------- - // Function: render_link - // Render the links to the debug console - // --------------------------------------------------- - function render_link($dittoID,$ditto_base) { - global $ditto_lang,$modx; - $base_url = str_replace($modx->config['base_path'],$modx->config['site_url'],$ditto_base); - return $this->makeLink($ditto_lang['debug'],$ditto_lang['open_dbg_console'], $ditto_lang['save_dbg_console'],$base_url.'debug/','ditto_'.$dittoID); - } - // --------------------------------------------------- - // Function: render_popup - // Render the contents of the debug console - // --------------------------------------------------- - function render_popup($ditto,$ditto_base,$ditto_version, $ditto_params, $IDs, $fields, $summarize, $templates, $orderBy, $start, $stop, $total,$filter,$resource) { - global $ditto_lang,$modx; - $tabs = array(); - $fields = (count($fields['db']) > 0 && count($fields['tv']) > 0) ? array_merge_recursive($ditto->fields,array('retrieved'=>$fields)) : $ditto->fields; - - $tabs[$ditto_lang['info']] = $this->prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $start, $stop, $total); - $tabs[$ditto_lang['params']] = $this->makeParamTable($ditto_params,$ditto_lang['params']); - $tabs[$ditto_lang['fields']] = "
    ".$this->array2table($this->cleanArray($fields), true, true).'
    '; - $tabs[$ditto_lang['templates']] = $this->makeParamTable($this->prepareTemplates($templates),$ditto_lang['templates']); - - if ($filter !== false) { - $tabs[$ditto_lang['filters']] = $this->prepareFilters($this->cleanArray($filter)); - } + var $debug; + + // --------------------------------------------------- + // Function: render_link + // Render the links to the debug console + // --------------------------------------------------- + function render_link($dittoID,$ditto_base) { + global $ditto_lang,$modx; + $base_url = str_replace($modx->config['base_path'],$modx->config['site_url'],$ditto_base); + return $this->makeLink($ditto_lang['debug'],$ditto_lang['open_dbg_console'], $ditto_lang['save_dbg_console'],$base_url.'debug/','ditto_'.$dittoID); + } + // --------------------------------------------------- + // Function: render_popup + // Render the contents of the debug console + // --------------------------------------------------- + function render_popup($ditto,$ditto_base,$ditto_version, $ditto_params, $IDs, $fields, $summarize, $templates, $orderBy, $start, $stop, $total,$filter,$resource) { + global $ditto_lang,$modx; + $tabs = array(); + $fields = (count($fields['db']) > 0 && count($fields['tv']) > 0) ? array_merge_recursive($ditto->fields,array('retrieved'=>$fields)) : $ditto->fields; + + $tabs[$ditto_lang['info']] = $this->prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $start, $stop, $total); + $tabs[$ditto_lang['params']] = $this->makeParamTable($ditto_params,$ditto_lang['params']); + $tabs[$ditto_lang['fields']] = "
    ".$this->array2table($this->cleanArray($fields), true, true).'
    '; + $tabs[$ditto_lang['templates']] = $this->makeParamTable($this->prepareTemplates($templates),$ditto_lang['templates']); + + if ($filter !== false) { + $tabs[$ditto_lang['filters']] = $this->prepareFilters($this->cleanArray($filter)); + } - if ($ditto->prefetch == true) { - $tabs[$ditto_lang['prefetch_data']] = $this->preparePrefetch($ditto->prefetch); - } - if (count($resource) > 0 && $resource) { - $tabs[$ditto_lang['retrieved_data']] = $this->prepareDocumentInfo($resource); - } - $base_url = str_replace($modx->config['base_path'],$modx->config['site_url'],$ditto_base); - $generatedOn = "\r\n\r\n".''; - return $this->render($tabs,$ditto_lang['debug'],$base_url).$generatedOn; - } - - // --------------------------------------------------- - // Function: preparePrefetch - // Create the content of the Prefetch tab - // --------------------------------------------------- - function preparePrefetch($prefetch) { - global $ditto_lang; - $ditto_IDs = array(); - if (count($prefetch['dbg_IDs_pre']) > 0) { - $ditto_IDs[$ditto_lang['ditto_IDs_all'].' ('.count($prefetch['dbg_IDs_pre']).')'] = implode(',',$prefetch['dbg_IDs_pre']); - } - if (count($prefetch['dbg_IDs_post']) > 0) { - $ditto_IDs[$ditto_lang['ditto_IDs_selected'].' ('.count($prefetch['dbg_IDs_post']).')'] = implode(', ',$prefetch['dbg_IDs_post']); - } else { - $ditto_IDs[$ditto_lang['ditto_IDs_selected'].' (0)'] = strip_tags($ditto_lang['no_documents']); - } - $out = $this->array2table(array($ditto_lang['prefetch_data']=>$ditto_IDs),true,true); - return $out.$this->prepareDocumentInfo($prefetch['dbg_resource']); - } + if ($ditto->prefetch == true) { + $tabs[$ditto_lang['prefetch_data']] = $this->preparePrefetch($ditto->prefetch); + } + if (count($resource) > 0 && $resource) { + $tabs[$ditto_lang['retrieved_data']] = $this->prepareDocumentInfo($resource); + } + $base_url = str_replace($modx->config['base_path'],$modx->config['site_url'],$ditto_base); + $generatedOn = "\r\n\r\n".''; + return $this->render($tabs,$ditto_lang['debug'],$base_url).$generatedOn; + } + + // --------------------------------------------------- + // Function: preparePrefetch + // Create the content of the Prefetch tab + // --------------------------------------------------- + function preparePrefetch($prefetch) { + global $ditto_lang; + $ditto_IDs = array(); + if (count($prefetch['dbg_IDs_pre']) > 0) { + $ditto_IDs[$ditto_lang['ditto_IDs_all'].' ('.count($prefetch['dbg_IDs_pre']).')'] = implode(',',$prefetch['dbg_IDs_pre']); + } + if (count($prefetch['dbg_IDs_post']) > 0) { + $ditto_IDs[$ditto_lang['ditto_IDs_selected'].' ('.count($prefetch['dbg_IDs_post']).')'] = implode(', ',$prefetch['dbg_IDs_post']); + } else { + $ditto_IDs[$ditto_lang['ditto_IDs_selected'].' (0)'] = strip_tags($ditto_lang['no_documents']); + } + $out = $this->array2table(array($ditto_lang['prefetch_data']=>$ditto_IDs),true,true); + return $out.$this->prepareDocumentInfo($prefetch['dbg_resource']); + } - // --------------------------------------------------- - // Function: prepareFilters - // Create the content of the Filters tab - // --------------------------------------------------- - function prepareFilters($filter) { - $output = ''; - foreach ($filter as $name=>$value) { - if ($name == 'custom') { - foreach ($value as $name=>$value) { - $output .= $this->array2table(array($name=>$value), true, true); - } - } else { - $output .= $this->array2table(array($name=>$value), true, true); - } - } - return $output; - } - - // --------------------------------------------------- - // Function: prepareDocumentInfo - // Create the output for the Document Info tab - // --------------------------------------------------- - function prepareDocumentInfo($resource) { - global $ditto_lang; - $output = ''; - if (count($resource) > 0) { - foreach ($resource as $item) { - $header = str_replace(array('[+pagetitle+]','[+id+]'),array($item['pagetitle'],$item['id']),$this->templates['item']); - $output .= $this->makeParamTable($item,$header,true,true,true,'resource'); - } - } - return $output; - } + // --------------------------------------------------- + // Function: prepareFilters + // Create the content of the Filters tab + // --------------------------------------------------- + function prepareFilters($filter) { + $output = ''; + foreach ($filter as $name=>$value) { + if ($name == 'custom') { + foreach ($value as $name=>$value) { + $output .= $this->array2table(array($name=>$value), true, true); + } + } else { + $output .= $this->array2table(array($name=>$value), true, true); + } + } + return $output; + } + + // --------------------------------------------------- + // Function: prepareDocumentInfo + // Create the output for the Document Info tab + // --------------------------------------------------- + function prepareDocumentInfo($resource) { + global $ditto_lang; + $output = ''; + if (count($resource) > 0) { + foreach ($resource as $item) { + $header = str_replace(array('[+pagetitle+]','[+id+]'),array($item['pagetitle'],$item['id']),$this->templates['item']); + $output .= $this->makeParamTable($item,$header,true,true,true,'resource'); + } + } + return $output; + } - // --------------------------------------------------- - // Function: prepareBasicInfo - // Create the outut for the Info ta - // --------------------------------------------------- - function prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $start, $stop, $total) { - global $ditto_lang,$dittoID,$modx; - $items[$ditto_lang['version']] = $ditto_version; - $items[$ditto_lang['summarize']] = $summarize; - $items[$ditto_lang['total']] = $total; - $items[$ditto_lang['start']] = $start; - $items[$ditto_lang['stop']] = $stop; - $items[$ditto_lang['ditto_IDs']] = (count($IDs) > 0) ? wordwrap(implode(', ',$IDs),100, '
    ') : $ditto_lang['none']; - $output = ''; - if (is_array($orderBy['parsed']) && count($orderBy['parsed']) > 0) { - $sort = array(); - foreach ($orderBy['parsed'] as $key=>$value) { - $sort[$key] = array($ditto_lang['sortBy']=>$value[0],$ditto_lang['sortDir']=>$value[1]); - } - $output = $this->array2table($this->cleanArray($sort), true, true); - } - return $this->makeParamTable($items,$ditto_lang['basic_info'],false,false).$output; - } + // --------------------------------------------------- + // Function: prepareBasicInfo + // Create the outut for the Info ta + // --------------------------------------------------- + function prepareBasicInfo($ditto,$ditto_version, $IDs, $summarize, $orderBy, $start, $stop, $total) { + global $ditto_lang,$dittoID,$modx; + $items[$ditto_lang['version']] = $ditto_version; + $items[$ditto_lang['summarize']] = $summarize; + $items[$ditto_lang['total']] = $total; + $items[$ditto_lang['start']] = $start; + $items[$ditto_lang['stop']] = $stop; + $items[$ditto_lang['ditto_IDs']] = (count($IDs) > 0) ? wordwrap(implode(', ',$IDs),100, '
    ') : $ditto_lang['none']; + $output = ''; + if (is_array($orderBy['parsed']) && count($orderBy['parsed']) > 0) { + $sort = array(); + foreach ($orderBy['parsed'] as $key=>$value) { + $sort[$key] = array($ditto_lang['sortBy']=>$value[0],$ditto_lang['sortDir']=>$value[1]); + } + $output = $this->array2table($this->cleanArray($sort), true, true); + } + return $this->makeParamTable($items,$ditto_lang['basic_info'],false,false).$output; + } - // --------------------------------------------------- - // Function: prepareTemplates - // Create the output for the Templates tab - // --------------------------------------------------- - function prepareTemplates($templates) { - global $ditto_lang; - $displayTPLs = array(); - foreach ($templates as $name=>$value) { - switch ($name) { - case 'base': - $displayName = 'tpl'; - break; + // --------------------------------------------------- + // Function: prepareTemplates + // Create the output for the Templates tab + // --------------------------------------------------- + function prepareTemplates($templates) { + global $ditto_lang; + $displayTPLs = array(); + foreach ($templates as $name=>$value) { + switch ($name) { + case 'base': + $displayName = 'tpl'; + break; - case 'default': - $displayName = 'tpl'; - break; + case 'default': + $displayName = 'tpl'; + break; - default: - $displayName = 'tpl'.strtoupper($name{0}).substr($name,1); - break; - } - $displayTPLs[$displayName] = $value; - } - return $displayTPLs; - } + default: + $displayName = 'tpl'.strtoupper($name{0}).substr($name,1); + break; + } + $displayTPLs[$displayName] = $value; + } + return $displayTPLs; + } } - -?> \ No newline at end of file diff --git a/assets/snippets/ditto/classes/filter.class.inc.php b/assets/snippets/ditto/classes/filter.class.inc.php index 6efaeb9c24..6bc65791ea 100644 --- a/assets/snippets/ditto/classes/filter.class.inc.php +++ b/assets/snippets/ditto/classes/filter.class.inc.php @@ -3,148 +3,147 @@ /* * Title: Filter Class * Purpose: - * The Filter class contains all functions relating to filtering, - * the removing of documents from the result set + * The Filter class contains all functions relating to filtering, + * the removing of documents from the result set */ class filter { - var $array_key, $filtertype, $filterValue, $filterArgs; + var $array_key, $filtertype, $filterValue, $filterArgs; // --------------------------------------------------- // Function: execute // Filter documents via either a custom filter or basic filter // --------------------------------------------------- - function execute($resource, $filter) { - global $modx; - foreach ($filter["basic"] AS $currentFilter) { - if (is_array($currentFilter) && count($currentFilter) > 0) { - $this->array_key = $currentFilter["source"]; - if(substr($currentFilter["value"],0,5) != "@EVAL") { - $this->filterValue = $currentFilter["value"]; - } else { - $this->filterValue = $modx->safeEval(substr($currentFilter["value"],5)); - } - if(strpos($this->filterValue,'[+') !== false) { - $this->filterValue = $modx->mergePlaceholderContent($this->filterValue); - } - $this->filtertype = (isset ($currentFilter["mode"])) ? $currentFilter["mode"] : 1; - $resource = array_filter($resource, array($this, "basicFilter")); - } - } - foreach ($filter["custom"] AS $currentFilter) { - $resource = array_filter($resource, $currentFilter); - } - return $resource; - } - + function execute($resource, $filter) { + global $modx; + foreach ($filter["basic"] AS $currentFilter) { + if (is_array($currentFilter) && count($currentFilter) > 0) { + $this->array_key = $currentFilter["source"]; + if(substr($currentFilter["value"],0,5) != "@EVAL") { + $this->filterValue = $currentFilter["value"]; + } else { + $this->filterValue = $modx->safeEval(substr($currentFilter["value"],5)); + } + if(strpos($this->filterValue,'[+') !== false) { + $this->filterValue = $modx->mergePlaceholderContent($this->filterValue); + } + $this->filtertype = (isset ($currentFilter["mode"])) ? $currentFilter["mode"] : 1; + $resource = array_filter($resource, array($this, "basicFilter")); + } + } + foreach ($filter["custom"] AS $currentFilter) { + $resource = array_filter($resource, $currentFilter); + } + return $resource; + } + // --------------------------------------------------- // Function: basicFilter // Do basic comparison filtering // --------------------------------------------------- - - function basicFilter ($value) { - $unset = 1; - switch ($this->filtertype) { - case "!=" : - case 1 : - if (!isset ($value[$this->array_key]) || $value[$this->array_key] != $this->filterValue) - $unset = 0; - break; - case "==" : - case 2 : - if ($value[$this->array_key] == $this->filterValue) - $unset = 0; - break; - case "<" : - case 3 : - if ($value[$this->array_key] < $this->filterValue) - $unset = 0; - break; - case ">" : - case 4 : - if ($value[$this->array_key] > $this->filterValue) - $unset = 0; - break; - case "<=" : - case 5 : - if (!($value[$this->array_key] <= $this->filterValue)) - $unset = 0; - break; - case ">=" : - case 6 : - if (!($value[$this->array_key] >= $this->filterValue)) - $unset = 0; - break; - - // Cases 7 & 8 created by MODX Testing Team Member ZAP - case 7 : - if (strpos($value[$this->array_key], $this->filterValue)===FALSE) - $unset = 0; - break; - case 8 : - if (strpos($value[$this->array_key], $this->filterValue)!==FALSE) - $unset = 0; - break; - - // Cases 9-11 created by highlander - case 9 : // case insenstive version of #7 - exclude records that do not contain the text of the criterion - if (strpos(strtolower($value[$this->array_key]), strtolower($this->filterValue))===FALSE) - $unset = 0; - break; - case 10 : // case insenstive version of #8 - exclude records that do contain the text of the criterion - if (strpos(strtolower($value[$this->array_key]), strtolower($this->filterValue))!==FALSE) - $unset = 0; - break; - case 11 : // checks leading character of the field - $firstChr = strtoupper(substr($value[$this->array_key], 0, 1)); - if ($firstChr!=$this->filterValue) - $unset = 0; - break; - //Added by Andchir (http://modx-shopkeeper.ru/) - case 12 : - $inputArr = explode('~',$value[$this->array_key]); - $check = 0; - foreach($inputArr as $val){ - if(empty($this->filterValue) || empty($val)) - return; - if (strpos($this->filterValue, $val)!==false) - $check++; - } - $unset = $check>0 ? 1 : 0; - unset($val,$check); - break; - //Added by Dmi3yy - case 13 : - $inputArr = explode('~',$value[$this->array_key]); - $check = 0; - foreach($inputArr as $val){ - if(empty($this->filterValue) || empty($val)) - return; - - $iA = explode('~',$this->filterValue); - foreach($iA as $ii){ - $iB = explode(',',$val); - foreach($iB as $iii){ - if (trim($ii) == trim($iii)) - $check++; - } - } - } - $unset = $check>0 ? 1 : 0; - unset($val,$check); - break; - // Cases 21-22 created by Sergey Davydov 08.11.2011 - case 21 : // array version of #1 - exlude records that do not in miltiple values such a "65||115" and have output delimeted list by comma - if (!isset ($value[$this->array_key]) || !in_array($this->filterValue,explode(',',$value[$this->array_key]))) - $unset = 0; - break; - case 22 : // array version of #2 - exlude records that in miltiple values such a "65||115" and have output delimeted list by comma - if (in_array($this->filterValue,explode(',',$value[$this->array_key]))) - $unset = 0; - break; - } - return $unset; - } - + + function basicFilter ($value) { + $unset = 1; + switch ($this->filtertype) { + case "!=" : + case 1 : + if (!isset ($value[$this->array_key]) || $value[$this->array_key] != $this->filterValue) + $unset = 0; + break; + case "==" : + case 2 : + if ($value[$this->array_key] == $this->filterValue) + $unset = 0; + break; + case "<" : + case 3 : + if ($value[$this->array_key] < $this->filterValue) + $unset = 0; + break; + case ">" : + case 4 : + if ($value[$this->array_key] > $this->filterValue) + $unset = 0; + break; + case "<=" : + case 5 : + if (!($value[$this->array_key] <= $this->filterValue)) + $unset = 0; + break; + case ">=" : + case 6 : + if (!($value[$this->array_key] >= $this->filterValue)) + $unset = 0; + break; + + // Cases 7 & 8 created by MODX Testing Team Member ZAP + case 7 : + if (strpos($value[$this->array_key], $this->filterValue)===FALSE) + $unset = 0; + break; + case 8 : + if (strpos($value[$this->array_key], $this->filterValue)!==FALSE) + $unset = 0; + break; + + // Cases 9-11 created by highlander + case 9 : // case insenstive version of #7 - exclude records that do not contain the text of the criterion + if (strpos(strtolower($value[$this->array_key]), strtolower($this->filterValue))===FALSE) + $unset = 0; + break; + case 10 : // case insenstive version of #8 - exclude records that do contain the text of the criterion + if (strpos(strtolower($value[$this->array_key]), strtolower($this->filterValue))!==FALSE) + $unset = 0; + break; + case 11 : // checks leading character of the field + $firstChr = strtoupper(substr($value[$this->array_key], 0, 1)); + if ($firstChr!=$this->filterValue) + $unset = 0; + break; + //Added by Andchir (http://modx-shopkeeper.ru/) + case 12 : + $inputArr = explode('~',$value[$this->array_key]); + $check = 0; + foreach($inputArr as $val){ + if(empty($this->filterValue) || empty($val)) + return; + if (strpos($this->filterValue, $val)!==false) + $check++; + } + $unset = $check>0 ? 1 : 0; + unset($val,$check); + break; + //Added by Dmi3yy + case 13 : + $inputArr = explode('~',$value[$this->array_key]); + $check = 0; + foreach($inputArr as $val){ + if(empty($this->filterValue) || empty($val)) + return; + + $iA = explode('~',$this->filterValue); + foreach($iA as $ii){ + $iB = explode(',',$val); + foreach($iB as $iii){ + if (trim($ii) == trim($iii)) + $check++; + } + } + } + $unset = $check>0 ? 1 : 0; + unset($val,$check); + break; + // Cases 21-22 created by Sergey Davydov 08.11.2011 + case 21 : // array version of #1 - exlude records that do not in miltiple values such a "65||115" and have output delimeted list by comma + if (!isset ($value[$this->array_key]) || !in_array($this->filterValue,explode(',',$value[$this->array_key]))) + $unset = 0; + break; + case 22 : // array version of #2 - exlude records that in miltiple values such a "65||115" and have output delimeted list by comma + if (in_array($this->filterValue,explode(',',$value[$this->array_key]))) + $unset = 0; + break; + } + return $unset; + } + } -?> \ No newline at end of file diff --git a/assets/snippets/ditto/classes/random.class.inc.php b/assets/snippets/ditto/classes/random.class.inc.php index 23642c2cb6..38c5a1a085 100644 --- a/assets/snippets/ditto/classes/random.class.inc.php +++ b/assets/snippets/ditto/classes/random.class.inc.php @@ -7,126 +7,125 @@ Info : Please email me if there is any feature you want or there is any bugs. I will fix them as soon as possible. *********************************/ - + class random{ -var $data = array(); -function add($string,$weight=1){ - $this->data[] = array('s' => $string, 'w' => $weight); + var $data = array(); + function add($string,$weight=1){ + $this->data[] = array('s' => $string, 'w' => $weight); + } + function optimize(){ + foreach($this->data as $var){ + if($new[$var['s']]){ + $new[$var['s']] += $var['w']; + }else{ + $new[$var['s']] = $var['w']; + } + } + unset($this->data); + foreach($new as $key=>$var){ + $this->data[] = array('s' => $key, 'w' => $var); + } + } + + function select($amount=1){ + if($amount == 1){ + $rand = array_rand($this->data); + $result = $this->data[$rand]['s']; + }else{ + $i = 0; + while($i<$amount){ + $result[] = $this->data[array_rand($this->data)]['s']; + ++$i; + } + } + return $result; + } + + function select_unique($amount=1){ + if($amount == 1){ + $rand = array_rand($this->data); + $result = $this->data[$rand]['s']; + }else{ + $rand = array_rand($this->data, $amount); + foreach($rand as $var){ + $result[] = $this->data[$var]['s']; + } + } + return $result; + } + + function select_weighted($amount=1){ + $count = count($this->data); + $i = 0; + $max = -1; + while($i < $count){ + $max += $this->data[$i]['w']; + ++$i; + } + if(1 == $amount){ + $rand = mt_rand(0, $max); + $w = 0; $n = 0; + while($w <= $rand){ + $w += $this->data[$n]['w']; + ++$n; + } + $key = $this->data[$n-1]['s']; + }else{ + $i = 0; + while($i<$amount){ + $random[] = mt_rand(0, $max); + ++$i; + } + sort($random); + $i = 0; + $n = 0; + $w = 0; + while($i<$amount){ + while($w<=$random[$i]){ + $w += $this->data[$n]['w']; + ++$n; + } + $key[] = $this->data[$n-1]['s']; + ++$i; + } + } + return $key; + } + + function select_weighted_unique($amount=1){ + $count = count($this->data); + $i = 0; + if($amount >= $count){ + while($i < $count){ + $return[] = $this->data[$i]['s']; + ++$i; + } + return $return; + }else{ + $max = -1; + while($i < $count){ + $max += $this->data[$i]['w']; + ++$i; + } + + $i = 0; + while($i < $amount){ + $max -= $sub; + $w = 0; + $n = 0; + $num = mt_rand(0,$max); + while($w <= $num){ + $w += $this->data[$n]['w']; + ++$n; + } + $sub = $this->data[$n-1]['w']; + $key[] = $this->data[$n-1]['s']; + + unset($this->data[$n-1]); + $this->data = array_merge($this->data); + ++$i; + } + return $key; + } + } } -function optimize(){ - foreach($this->data as $var){ - if($new[$var['s']]){ - $new[$var['s']] += $var['w']; - }else{ - $new[$var['s']] = $var['w']; - } - } - unset($this->data); - foreach($new as $key=>$var){ - $this->data[] = array('s' => $key, 'w' => $var); - } -} - -function select($amount=1){ - if($amount == 1){ - $rand = array_rand($this->data); - $result = $this->data[$rand]['s']; - }else{ - $i = 0; - while($i<$amount){ - $result[] = $this->data[array_rand($this->data)]['s']; - ++$i; - } - } - return $result; -} - -function select_unique($amount=1){ - if($amount == 1){ - $rand = array_rand($this->data); - $result = $this->data[$rand]['s']; - }else{ - $rand = array_rand($this->data, $amount); - foreach($rand as $var){ - $result[] = $this->data[$var]['s']; - } - } - return $result; -} - -function select_weighted($amount=1){ - $count = count($this->data); - $i = 0; - $max = -1; - while($i < $count){ - $max += $this->data[$i]['w']; - ++$i; - } - if(1 == $amount){ - $rand = mt_rand(0, $max); - $w = 0; $n = 0; - while($w <= $rand){ - $w += $this->data[$n]['w']; - ++$n; - } - $key = $this->data[$n-1]['s']; - }else{ - $i = 0; - while($i<$amount){ - $random[] = mt_rand(0, $max); - ++$i; - } - sort($random); - $i = 0; - $n = 0; - $w = 0; - while($i<$amount){ - while($w<=$random[$i]){ - $w += $this->data[$n]['w']; - ++$n; - } - $key[] = $this->data[$n-1]['s']; - ++$i; - } - } - return $key; -} - -function select_weighted_unique($amount=1){ - $count = count($this->data); - $i = 0; - if($amount >= $count){ - while($i < $count){ - $return[] = $this->data[$i]['s']; - ++$i; - } - return $return; - }else{ - $max = -1; - while($i < $count){ - $max += $this->data[$i]['w']; - ++$i; - } - - $i = 0; - while($i < $amount){ - $max -= $sub; - $w = 0; - $n = 0; - $num = mt_rand(0,$max); - while($w <= $num){ - $w += $this->data[$n]['w']; - ++$n; - } - $sub = $this->data[$n-1]['w']; - $key[] = $this->data[$n-1]['s']; - - unset($this->data[$n-1]); - $this->data = array_merge($this->data); - ++$i; - } - return $key; - } -} -} -?> \ No newline at end of file diff --git a/assets/snippets/ditto/classes/template.class.inc.php b/assets/snippets/ditto/classes/template.class.inc.php index 3617828f29..e71a5fe7b4 100644 --- a/assets/snippets/ditto/classes/template.class.inc.php +++ b/assets/snippets/ditto/classes/template.class.inc.php @@ -3,206 +3,206 @@ /* * Title: Template Class * Purpose: - * The Template class contains all functions relating to Ditto's - * handling of templates and any supporting functions they need + * The Template class contains all functions relating to Ditto's + * handling of templates and any supporting functions they need */ class template{ - var $language,$fields,$current; + var $language,$fields,$current; - // --------------------------------------------------- - // Function: template - // Set the class language and fields variables - // --------------------------------------------------- - function __construct() { - $this->language = $GLOBALS['ditto_lang']; - $this->fields = array ( - 'db' => array (), - 'tv' => array (), - 'custom' => array (), - 'item' => array (), - 'phx' => array (), - 'rss' => array (), - 'json' => array (), - 'xml' => array (), - 'unknown' => array() - ); - } + // --------------------------------------------------- + // Function: template + // Set the class language and fields variables + // --------------------------------------------------- + function __construct() { + $this->language = $GLOBALS['ditto_lang']; + $this->fields = array ( + 'db' => array (), + 'tv' => array (), + 'custom' => array (), + 'item' => array (), + 'phx' => array (), + 'rss' => array (), + 'json' => array (), + 'xml' => array (), + 'unknown' => array() + ); + } - // --------------------------------------------------- - // Function: process - // Take the templates and parse them for tempalte variables, - // Check to make sure they have fields, and sort the fields - // --------------------------------------------------- - function process($template) { - if (!isset($template['base'])) $template['base'] = $template['default']; - else unset($template['default']); - - foreach ($template as $name=>$tpl) { - if(!empty($tpl) && $tpl != '') $templates[$name] = $this->fetch($tpl); - } - $fieldList = array(); - foreach ($templates as $tplName=>$tpl) { - $check = $this->findTemplateVars($tpl); - if (is_array($check)) $fieldList = array_merge($check, $fieldList); - else { - switch ($tplName) { - case 'base' : - case 'default': $displayName = 'tpl';break; - default : $displayName = 'tpl'.$tplName; - } - $templates[$tplName] = str_replace('[+tpl+]',$displayName,$this->language['bad_tpl']); - } - } + // --------------------------------------------------- + // Function: process + // Take the templates and parse them for tempalte variables, + // Check to make sure they have fields, and sort the fields + // --------------------------------------------------- + function process($template) { + if (!isset($template['base'])) $template['base'] = $template['default']; + else unset($template['default']); + + foreach ($template as $name=>$tpl) { + if(!empty($tpl) && $tpl != '') $templates[$name] = $this->fetch($tpl); + } + $fieldList = array(); + foreach ($templates as $tplName=>$tpl) { + $check = $this->findTemplateVars($tpl); + if (is_array($check)) $fieldList = array_merge($check, $fieldList); + else { + switch ($tplName) { + case 'base' : + case 'default': $displayName = 'tpl';break; + default : $displayName = 'tpl'.$tplName; + } + $templates[$tplName] = str_replace('[+tpl+]',$displayName,$this->language['bad_tpl']); + } + } - $fieldList = array_unique($fieldList); - $fields = $this->sortFields($fieldList); - $checkAgain = array ('json', 'xml'); - foreach ($checkAgain as $type) { - $fields = array_merge_recursive($fields, $this->sortFields($fields[$type])); - } - $this->fields = $fields; - return $templates; - } + $fieldList = array_unique($fieldList); + $fields = $this->sortFields($fieldList); + $checkAgain = array ('json', 'xml'); + foreach ($checkAgain as $type) { + $fields = array_merge_recursive($fields, $this->sortFields($fields[$type])); + } + $this->fields = $fields; + return $templates; + } - // --------------------------------------------------- - // Function: findTemplateVars - // Find al the template variables in the template - // --------------------------------------------------- - function findTemplateVars($tpl) { - preg_match_all('~\[\+(.*?)\+\]~', $tpl, $matches); - $TVs = array(); - foreach($matches[1] as $tv) { - $match = explode(':', $tv); - $TVs[strtolower($match[0])] = $match[0]; - } - if (count($TVs) >= 1) { - return array_values($TVs); - } else { - return false; - } - } + // --------------------------------------------------- + // Function: findTemplateVars + // Find al the template variables in the template + // --------------------------------------------------- + function findTemplateVars($tpl) { + preg_match_all('~\[\+(.*?)\+\]~', $tpl, $matches); + $TVs = array(); + foreach($matches[1] as $tv) { + $match = explode(':', $tv); + $TVs[strtolower($match[0])] = $match[0]; + } + if (count($TVs) >= 1) { + return array_values($TVs); + } else { + return false; + } + } - // --------------------------------------------------- - // Function: sortFields - // Sort the array of fields provided by type - // --------------------------------------------------- - function sortFields ($fieldList) { - global $ditto_constantFields; - $dbFields = $ditto_constantFields['db']; - $tvFields = $ditto_constantFields['tv']; - $fields = array ( - 'db' => array (), - 'tv' => array (), - 'custom' => array (), - 'item' => array (), - 'phx' => array (), - 'rss' => array (), - 'json' => array (), - 'xml' => array (), - 'unknown' => array() - ); - - $custom = array('author','date','url','title','ditto_iteration'); + // --------------------------------------------------- + // Function: sortFields + // Sort the array of fields provided by type + // --------------------------------------------------- + function sortFields ($fieldList) { + global $ditto_constantFields; + $dbFields = $ditto_constantFields['db']; + $tvFields = $ditto_constantFields['tv']; + $fields = array ( + 'db' => array (), + 'tv' => array (), + 'custom' => array (), + 'item' => array (), + 'phx' => array (), + 'rss' => array (), + 'json' => array (), + 'xml' => array (), + 'unknown' => array() + ); + + $custom = array('author','date','url','title','ditto_iteration'); - foreach ($fieldList as $field) { - if (substr($field, 0, 4) == 'rss_') $fields['rss'][] = substr($field,4); - elseif(substr($field, 0, 4) == 'xml_') $fields['xml'][] = substr($field,4); - elseif(substr($field, 0, 5) == 'json_') $fields['json'][] = substr($field,5); - elseif(substr($field, 0, 5) == 'item[') $fields['item'][] = substr($field,4); - elseif(substr($field, 0, 4) == 'phx:') $fields['phx'][] = $field; - elseif(in_array($field, $dbFields)) $fields['db'][] = $field; - elseif(in_array($field, $tvFields)) $fields['tv'][] = $field; - elseif(substr($field, 0, 2) == 'tv' && in_array(substr($field,2), $tvFields)) - $fields['tv'][] = substr($field,2); - // TODO: Remove TV Prefix support in Ditto - elseif(in_array($field, $custom)) $fields['custom'][] = $field; - else $fields['unknown'][] = $field; - } - return $fields; - } + foreach ($fieldList as $field) { + if (substr($field, 0, 4) == 'rss_') $fields['rss'][] = substr($field,4); + elseif(substr($field, 0, 4) == 'xml_') $fields['xml'][] = substr($field,4); + elseif(substr($field, 0, 5) == 'json_') $fields['json'][] = substr($field,5); + elseif(substr($field, 0, 5) == 'item[') $fields['item'][] = substr($field,4); + elseif(substr($field, 0, 4) == 'phx:') $fields['phx'][] = $field; + elseif(in_array($field, $dbFields)) $fields['db'][] = $field; + elseif(in_array($field, $tvFields)) $fields['tv'][] = $field; + elseif(substr($field, 0, 2) == 'tv' && in_array(substr($field,2), $tvFields)) + $fields['tv'][] = substr($field,2); + // TODO: Remove TV Prefix support in Ditto + elseif(in_array($field, $custom)) $fields['custom'][] = $field; + else $fields['unknown'][] = $field; + } + return $fields; + } - // --------------------------------------------------- - // Function: replace - // Replcae placeholders with their values - // --------------------------------------------------- + // --------------------------------------------------- + // Function: replace + // Replcae placeholders with their values + // --------------------------------------------------- public static function replace( $placeholders, $tpl ) { - $keys = array(); - $values = array(); - foreach ($placeholders as $key=>$value) { - $keys[] = '[+'.$key.'+]'; - $values[] = $value; - } - return str_replace($keys,$values,$tpl); - } + $keys = array(); + $values = array(); + foreach ($placeholders as $key=>$value) { + $keys[] = '[+'.$key.'+]'; + $values[] = $value; + } + return str_replace($keys,$values,$tpl); + } - // --------------------------------------------------- - // Function: determine - // Determine the correct template to apply - // --------------------------------------------------- - function determine($templates,$x,$start,$stop,$id) { - global $modx; + // --------------------------------------------------- + // Function: determine + // Determine the correct template to apply + // --------------------------------------------------- + function determine($templates,$x,$start,$stop,$id) { + global $modx; - // determine current template - if ($x == ($stop -1) && !empty($templates['last'])) $currentTPL = 'last'; - elseif ($x == 0 && !empty($templates['first'])) $currentTPL = 'first'; - elseif ($id == $modx->documentIdentifier && !empty($templates['current'])) - $currentTPL = 'current'; - elseif ($x % 2 && !empty($templates['alt'])) $currentTPL = 'alt'; - else $currentTPL = 'base'; - - $this->current = $currentTPL; - return $templates[$currentTPL]; - } + // determine current template + if ($x == ($stop -1) && !empty($templates['last'])) $currentTPL = 'last'; + elseif ($x == 0 && !empty($templates['first'])) $currentTPL = 'first'; + elseif ($id == $modx->documentIdentifier && !empty($templates['current'])) + $currentTPL = 'current'; + elseif ($x % 2 && !empty($templates['alt'])) $currentTPL = 'alt'; + else $currentTPL = 'base'; + + $this->current = $currentTPL; + return $templates[$currentTPL]; + } - // --------------------------------------------------- - // Function: fetch - // Get a template, based on version by Doze - // - // http://forums.modx.com/thread/41066/support-comments-for-ditto?page=2#dis-post-237942 - // --------------------------------------------------- - function fetch($tpl){ - global $modx; - $template = ''; - if(substr($tpl, 0, 6) == '@CHUNK') { - $template = $modx->getChunk(substr($tpl, 7)); - } elseif(substr($tpl, 0, 5) == '@FILE') { - $path = trim(substr($tpl, 6)); - if(strpos($path, 'manager/includes/config.inc.php')===false) - $template = file_get_contents($path); - } elseif(substr($tpl, 0, 5) == '@CODE') { - $template = substr($tpl, 6); - } elseif(strpos($tpl, '[+') !==false) { - $template = $tpl; - } elseif(substr($tpl, 0, 9) == '@DOCUMENT') { - $docid = trim(substr($tpl, 10)); - if(preg_match('@^[1-9][0-9]*$@',$docid)) - $template = $modx->getField('content',$docid); - } else { - $template = $modx->getChunk($tpl); - } - - if(strpos($template,'[!')!==false) - $template = str_replace(array('[!','!]'),array('[[',']]'),$template); - elseif($template===''||$template===false) - $template = $this->language['missing_placeholders_tpl']; - return $template; - } + // --------------------------------------------------- + // Function: fetch + // Get a template, based on version by Doze + // + // http://forums.modx.com/thread/41066/support-comments-for-ditto?page=2#dis-post-237942 + // --------------------------------------------------- + function fetch($tpl){ + global $modx; + $template = ''; + if(substr($tpl, 0, 6) == '@CHUNK') { + $template = $modx->getChunk(substr($tpl, 7)); + } elseif(substr($tpl, 0, 5) == '@FILE') { + $path = trim(substr($tpl, 6)); + if(strpos($path, 'manager/includes/config.inc.php')===false) + $template = file_get_contents($path); + } elseif(substr($tpl, 0, 5) == '@CODE') { + $template = substr($tpl, 6); + } elseif(strpos($tpl, '[+') !==false) { + $template = $tpl; + } elseif(substr($tpl, 0, 9) == '@DOCUMENT') { + $docid = trim(substr($tpl, 10)); + if(preg_match('@^[1-9][0-9]*$@',$docid)) + $template = $modx->getField('content',$docid); + } else { + $template = $modx->getChunk($tpl); + } + + if(strpos($template,'[!')!==false) + $template = str_replace(array('[!','!]'),array('[[',']]'),$template); + elseif($template===''||$template===false) + $template = $this->language['missing_placeholders_tpl']; + return $template; + } - // --------------------------------------------------- - // Function: get_file_contents - // Returns the contents of file name passed - // - // From http://www.nutt.net/2006/07/08/file_get_contents-function-for-php-4/#more-210 - // --------------------------------------------------- - function get_file_contents($filename) { - if (!function_exists('file_get_contents')) { - $fhandle = fopen($filename, 'r'); - $fcontents = fread($fhandle, filesize($filename)); - fclose($fhandle); - } else { - $fcontents = file_get_contents($filename); - } - return $fcontents; - } + // --------------------------------------------------- + // Function: get_file_contents + // Returns the contents of file name passed + // + // From http://www.nutt.net/2006/07/08/file_get_contents-function-for-php-4/#more-210 + // --------------------------------------------------- + function get_file_contents($filename) { + if (!function_exists('file_get_contents')) { + $fhandle = fopen($filename, 'r'); + $fcontents = fread($fhandle, filesize($filename)); + fclose($fhandle); + } else { + $fcontents = file_get_contents($filename); + } + return $fcontents; + } } diff --git a/assets/snippets/ditto/snippet.ditto.php b/assets/snippets/ditto/snippet.ditto.php index 47751c8546..210c7849dc 100644 --- a/assets/snippets/ditto/snippet.ditto.php +++ b/assets/snippets/ditto/snippet.ditto.php @@ -6,7 +6,7 @@ * Summarizes and lists pages to create blogs, catalogs, PR archives, bio listings and more * * @category snippet - * @version 2.1.2 + * @version 2.1.2 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL) * @internal @properties * @internal @modx_category Content @@ -218,9 +218,9 @@ //---Initiate Class-------------------------------------------------- // if (class_exists('ditto')) { - $dbg_templates = (isset($dbg_templates)) ? $dbg_templates : NULL; - $ditto = new ditto($dittoID, $format, $_lang, $dbg_templates); - // create a new Ditto instance in the specified format and language with the requested debug level + $dbg_templates = (isset($dbg_templates)) ? $dbg_templates : NULL; + $ditto = new ditto($dittoID, $format, $_lang, $dbg_templates); + // create a new Ditto instance in the specified format and language with the requested debug level } else { $modx->logEvent(1,3,$_lang['invalid_class'],'Ditto '.$ditto_version); return $_lang['invalid_class']; @@ -700,12 +700,12 @@ 0 - off; returns output */ $templates = array( - 'default' => '@CODE' . $_lang['default_template'], - 'base' => (isset($tpl)) ? $tpl : NULL, - 'alt' => (isset($tplAlt)) ? $tplAlt : NULL, - 'first' => (isset($tplFirst)) ? $tplFirst : NULL, - 'last' => (isset($tplLast)) ? $tplLast : NULL, - 'current' => (isset($tplCurrentDocument)) ? $tplCurrentDocument : NULL + 'default' => '@CODE' . $_lang['default_template'], + 'base' => (isset($tpl)) ? $tpl : NULL, + 'alt' => (isset($tplAlt)) ? $tplAlt : NULL, + 'first' => (isset($tplFirst)) ? $tplFirst : NULL, + 'last' => (isset($tplLast)) ? $tplLast : NULL, + 'current' => (isset($tplCurrentDocument)) ? $tplCurrentDocument : NULL ); /* Param: tpl @@ -1081,8 +1081,8 @@ } // outerTpl by Dmi3yy & Jako if (isset($outerTpl) && $resource) { - $outerTpl = $ditto->template->fetch($outerTpl); - $output = str_replace(array('[+ditto+]', '[+wrapper+]'), $output, $outerTpl); + $outerTpl = $ditto->template->fetch($outerTpl); + $output = str_replace(array('[+ditto+]', '[+wrapper+]'), $output, $outerTpl); } return ($save != 3) ? $output : ''; \ No newline at end of file From 12c5c36f3acec69a50283c7a40330ae5263629f2 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Mon, 28 Aug 2017 15:17:31 +0300 Subject: [PATCH 320/338] delete deprecated code --- assets/lib/MODxAPI/modResource.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/lib/MODxAPI/modResource.php b/assets/lib/MODxAPI/modResource.php index 63bfed59c6..8c6b190915 100644 --- a/assets/lib/MODxAPI/modResource.php +++ b/assets/lib/MODxAPI/modResource.php @@ -44,8 +44,6 @@ class modResource extends MODxAPI 'publishedby' => 0, 'menutitle' => '', 'donthit' => 0, - 'haskeywords' => 0, - 'hasmetatags' => 0, 'privateweb' => 0, 'privatemgr' => 0, 'content_dispo' => 0, From c0702676bec92db5777daa4ea80ed088eb03bcc3 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Mon, 28 Aug 2017 15:34:20 +0300 Subject: [PATCH 321/338] fix 65 Plugin parameters are lost after update to the new version --- install/instprocessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/instprocessor.php b/install/instprocessor.php index 93ac92a42d..afd9e2408e 100644 --- a/install/instprocessor.php +++ b/install/instprocessor.php @@ -581,7 +581,7 @@ function parseProperties($propertyString) { } } if($insert === true) { - $properties = mysqli_real_escape_string($conn, parseProperties($properties, true)); + $properties = mysqli_real_escape_string($conn, propUpdate($properties,$row['properties'])); if(!mysqli_query($sqlParser->conn, "INSERT INTO $dbase.`".$table_prefix."site_plugins` (name,description,plugincode,properties,moduleguid,disabled,category) VALUES('$name','$desc','$plugin','$properties','$guid','0',$category);")) { echo "

    ".mysqli_error($sqlParser->conn)."

    "; return; From c1aeda5e3f93fe336a123125c4866d1d14ae3bea Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 22:11:05 +0900 Subject: [PATCH 322/338] Refactor --- .../ditto/classes/filter.class.inc.php | 83 +++++++++---------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/assets/snippets/ditto/classes/filter.class.inc.php b/assets/snippets/ditto/classes/filter.class.inc.php index 6bc65791ea..aac86f1f94 100644 --- a/assets/snippets/ditto/classes/filter.class.inc.php +++ b/assets/snippets/ditto/classes/filter.class.inc.php @@ -16,23 +16,23 @@ class filter { // --------------------------------------------------- function execute($resource, $filter) { global $modx; - foreach ($filter["basic"] AS $currentFilter) { - if (is_array($currentFilter) && count($currentFilter) > 0) { - $this->array_key = $currentFilter["source"]; - if(substr($currentFilter["value"],0,5) != "@EVAL") { - $this->filterValue = $currentFilter["value"]; - } else { - $this->filterValue = $modx->safeEval(substr($currentFilter["value"],5)); - } - if(strpos($this->filterValue,'[+') !== false) { - $this->filterValue = $modx->mergePlaceholderContent($this->filterValue); - } - $this->filtertype = (isset ($currentFilter["mode"])) ? $currentFilter["mode"] : 1; - $resource = array_filter($resource, array($this, "basicFilter")); + foreach ($filter['basic'] as $current) { + + if (!is_array($current) || count($current)==0) continue; + + if(substr($current['value'],0,5) == '@EVAL') $this->filterValue = $modx->safeEval(substr($current['value'],5)); + else $this->filterValue = $current['value']; + + if(strpos($this->filterValue,'[+') !== false) { + $this->filterValue = $modx->mergePlaceholderContent($this->filterValue); } + + $this->array_key = $current['source']; + $this->filtertype = isset ($current['mode']) ? $current['mode'] : 1; + $resource = array_filter($resource, array($this, 'basicFilter')); } - foreach ($filter["custom"] AS $currentFilter) { - $resource = array_filter($resource, $currentFilter); + foreach ($filter['custom'] as $current) { + $resource = array_filter($resource, $current); } return $resource; } @@ -44,65 +44,66 @@ function execute($resource, $filter) { function basicFilter ($value) { $unset = 1; + $key = $this->array_key; switch ($this->filtertype) { - case "!=" : + case '!=' : case 1 : - if (!isset ($value[$this->array_key]) || $value[$this->array_key] != $this->filterValue) + if (!isset ($value[$key]) || $value[$key] != $this->filterValue) $unset = 0; break; - case "==" : + case '==' : case 2 : - if ($value[$this->array_key] == $this->filterValue) + if ($value[$key] == $this->filterValue) $unset = 0; break; - case "<" : + case '<' : case 3 : - if ($value[$this->array_key] < $this->filterValue) + if ($value[$key] < $this->filterValue) $unset = 0; break; - case ">" : + case '>' : case 4 : - if ($value[$this->array_key] > $this->filterValue) + if ($value[$key] > $this->filterValue) $unset = 0; break; - case "<=" : + case '<=' : case 5 : - if (!($value[$this->array_key] <= $this->filterValue)) + if (!($value[$key] <= $this->filterValue)) $unset = 0; break; - case ">=" : + case '>=' : case 6 : - if (!($value[$this->array_key] >= $this->filterValue)) + if (!($value[$key] >= $this->filterValue)) $unset = 0; break; // Cases 7 & 8 created by MODX Testing Team Member ZAP case 7 : - if (strpos($value[$this->array_key], $this->filterValue)===FALSE) + if (strpos($value[$key], $this->filterValue)===FALSE) $unset = 0; break; case 8 : - if (strpos($value[$this->array_key], $this->filterValue)!==FALSE) + if (strpos($value[$key], $this->filterValue)!==FALSE) $unset = 0; break; // Cases 9-11 created by highlander case 9 : // case insenstive version of #7 - exclude records that do not contain the text of the criterion - if (strpos(strtolower($value[$this->array_key]), strtolower($this->filterValue))===FALSE) + if (strpos(strtolower($value[$key]), strtolower($this->filterValue))===FALSE) $unset = 0; break; case 10 : // case insenstive version of #8 - exclude records that do contain the text of the criterion - if (strpos(strtolower($value[$this->array_key]), strtolower($this->filterValue))!==FALSE) + if (strpos(strtolower($value[$key]), strtolower($this->filterValue))!==FALSE) $unset = 0; break; case 11 : // checks leading character of the field - $firstChr = strtoupper(substr($value[$this->array_key], 0, 1)); + $firstChr = strtoupper(substr($value[$key], 0, 1)); if ($firstChr!=$this->filterValue) $unset = 0; break; //Added by Andchir (http://modx-shopkeeper.ru/) case 12 : - $inputArr = explode('~',$value[$this->array_key]); + $inputArr = explode('~',$value[$key]); $check = 0; foreach($inputArr as $val){ if(empty($this->filterValue) || empty($val)) @@ -115,7 +116,7 @@ function basicFilter ($value) { break; //Added by Dmi3yy case 13 : - $inputArr = explode('~',$value[$this->array_key]); + $inputArr = explode('~',$value[$key]); $check = 0; foreach($inputArr as $val){ if(empty($this->filterValue) || empty($val)) @@ -125,8 +126,7 @@ function basicFilter ($value) { foreach($iA as $ii){ $iB = explode(',',$val); foreach($iB as $iii){ - if (trim($ii) == trim($iii)) - $check++; + if (trim($ii) == trim($iii)) $check++; } } } @@ -134,16 +134,15 @@ function basicFilter ($value) { unset($val,$check); break; // Cases 21-22 created by Sergey Davydov 08.11.2011 - case 21 : // array version of #1 - exlude records that do not in miltiple values such a "65||115" and have output delimeted list by comma - if (!isset ($value[$this->array_key]) || !in_array($this->filterValue,explode(',',$value[$this->array_key]))) + case 21 : // array version of #1 - exlude records that do not in miltiple values such a '65||115' and have output delimeted list by comma + if (!isset ($value[$key]) || !in_array($this->filterValue,explode(',',$value[$key]))) $unset = 0; break; - case 22 : // array version of #2 - exlude records that in miltiple values such a "65||115" and have output delimeted list by comma - if (in_array($this->filterValue,explode(',',$value[$this->array_key]))) + case 22 : // array version of #2 - exlude records that in miltiple values such a '65||115' and have output delimeted list by comma + if (in_array($this->filterValue,explode(',',$value[$key]))) $unset = 0; break; } - return $unset; + return $unset; } - } From fd19168d7a8e77971f3317704294d180eeca8083 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Mon, 28 Aug 2017 22:12:07 +0900 Subject: [PATCH 323/338] Refactor --- .../extenders/tagging.extender.class.inc.php | 174 ++++++++++++++++ .../ditto/extenders/tagging.extender.inc.php | 190 +----------------- 2 files changed, 176 insertions(+), 188 deletions(-) create mode 100644 assets/snippets/ditto/extenders/tagging.extender.class.inc.php diff --git a/assets/snippets/ditto/extenders/tagging.extender.class.inc.php b/assets/snippets/ditto/extenders/tagging.extender.class.inc.php new file mode 100644 index 0000000000..cfaa019caf --- /dev/null +++ b/assets/snippets/ditto/extenders/tagging.extender.class.inc.php @@ -0,0 +1,174 @@ +delimiter = $delimiter; + $this->source = $this->parseTagData($source); + $this->mode = $mode; + $this->landing = $landing; + $this->format = $format; + $this->givenTags = $this->prepGivenTags($givenTags); + $this->caseSensitive = $caseSensitive; + $this->displayDelimiter = $displayDelimiter; + $this->sort = $sort; + $this->displayMode = $displayMode; + $this->tpl = $tpl; + $this->callback = $callback; + } + + function prepGivenTags ($givenTags) { + global $modx,$_GET,$dittoID; + + $getTags = !empty($_GET[$dittoID.'tags']) ? $modx->stripTags(trim($_GET[$dittoID.'tags'])) : false; + // Get tags from the $_GET array + + $tags1 = array(); + $tags2 = array(); + + if ($getTags !== false) $tags1 = explode($this->delimiter,$getTags); + + if ($givenTags !== false) $tags2 = explode($this->delimiter,$givenTags); + + $kTags = array(); + $tags = array_merge($tags1,$tags2); + foreach ($tags as $tag) { + if (empty($tag)) continue; + + if (!$this->caseSensitive) $tag = strtolower($tag); + $tag = trim($tag); + $kTags[strtolower($tag)] = $tag; + } + return $kTags; + } + + function tagFilter ($value) { + if ($this->caseSensitive == false) { + $documentTags = array_values(array_flip($this->givenTags)); + $filterTags = array_values(array_flip($this->combineTags($this->source, $value,true))); + } else { + $documentTags = $this->givenTags; + $filterTags =$this->combineTags($this->source, $value,true); + } + $compare = array_intersect($filterTags, $documentTags); + $commonTags = count($compare); + $totalTags = count($filterTags); + $docTags = count($documentTags); + + $unset = 1; + switch ($this->mode) { + case 'onlyAllTags' : + if ($commonTags != $docTags) $unset = 0; + break; + case 'removeAllTags' : + if ($commonTags == $docTags) $unset = 0; + break; + case 'onlyTags' : + if ($commonTags > $totalTags || $commonTags == 0) $unset = 0; + break; + case 'removeTags' : + if ($commonTags <= $totalTags && $commonTags != 0) $unset = 0; + break; + } + return $unset; + } + + function makeLinks($resource) { + return $this->tagLinks($this->combineTags($this->source,$resource,true), $this->delimiter, $this->landing, $this->format); + } + + function parseTagData($tagData,$names=array()) { + return explode(',',$tagData); + } + + function combineTags($tagData, $resource, $array=false) { + if ($this->callback !== false) { + return call_user_func_array($this->callback,array('tagData'=>$tagData,'resource'=>$resource,'array'=>$array)); + } + $tags = array(); + foreach ($tagData as $source) { + if(!empty($resource[$source])) { + $tags[] = $resource[$source]; + } + } + $kTags = array(); + $tags = explode($this->delimiter,implode($this->delimiter,$tags)); + foreach ($tags as $tag) { + if (!empty($tag)) { + if ($this->caseSensitive) { + $kTags[trim($tag)] = trim($tag); + } else { + $kTags[strtolower(trim($tag))] = trim($tag); + } + } + } + return ($array == true) ? $kTags : implode($this->delimiter,$kTags); + } + + function tagLinks($tags, $tagDelimiter, $tagID=false, $format='html') { + global $ditto_lang,$modx; + if(count($tags) == 0 && $format=='html') { + return $ditto_lang['none']; + } else if (count($tags) == 0 && ($format=='rss' || $format=='xml' || $format == 'xml')) + { + return ''.$ditto_lang['none'].''; + } + + $output = ''; + if ($this->sort) { + ksort($tags); + } + + // set templates array + $tplRss = "\r\n".' [+tag+]'; + $tpl = ($this->tpl == false) ? '' : $this->tpl; + + $tpl = (in_array($format, array('rss','xml','atom')) && $templates['user'] == false) ? $tplRss : $tpl; + + if ($this->displayMode == 1) { + foreach ($tags as $tag) { + $tagDocID = (!$tagID) ? $modx->documentObject['id'] : $tagID; + $url = ditto::buildURL("tags={$tag}&start=0",$tagDocID); + $output .= template::replace(array('url'=>$url,'tag'=>$tag),$tpl); + $output .= ($format != 'rss' && $format != 'xml' && $format != 'atom') ? $this->displayDelimiter : ''; + } + } else if (!in_array($format, array('rss','xml','atom')) && $this->displayMode == 2) { + $tagList = array(); + foreach ($tags as $tag) { + $tagDocID = (!$tagID) ? $modx->documentObject['id'] : $tagID; + $url = ditto::buildURL("tags={$tag}&start=0",$tagDocID); + $tagList[] = template::replace(array('url'=>$url,'tag'=>$tag),$tpl); + } + $output = $this->makeList($tagList, 'ditto_tag_list', 'ditto_tag_'); + } + + return (!in_array($format, array('rss','xml','atom'))) ? substr($output,0,-1*strlen($this->displayDelimiter)) : $output; + } + + function makeList($array, $ulroot= 'root', $ulprefix= 'sub_', $type= '', $ordered= false, $tablevel= 0) { + // first find out whether the value passed is an array + if (!is_array($array)) { + return '
    • Bad list
    '; + } + if (!empty ($type)) { + $typestr= " style='list-style-type: {$type}'"; + } else { + $typestr= ''; + } + $tabs= ''; + for ($i= 0; $i < $tablevel; $i++) { + $tabs .= "\t"; + } + $listhtml= $ordered == true ? $tabs . "
      \n" : $tabs . "
        \n"; + foreach ($array as $key => $value) { + if (is_array($value)) { + $listhtml .= $tabs . "\t
      • " . $key . "\n" . $this->makeList($value, $ulprefix . $ulroot, $ulprefix, $type, $ordered, $tablevel +2) . $tabs . "\t
      • \n"; + } else { + $listhtml .= $tabs . "\t
      • " . $value . "
      • \n"; + } + } + $listhtml .= $ordered == true ? $tabs . "
    \n" : $tabs . "\n"; + return $listhtml; + } +} diff --git a/assets/snippets/ditto/extenders/tagging.extender.inc.php b/assets/snippets/ditto/extenders/tagging.extender.inc.php index 6ba6ec9aff..3b2152182f 100644 --- a/assets/snippets/ditto/extenders/tagging.extender.inc.php +++ b/assets/snippets/ditto/extenders/tagging.extender.inc.php @@ -1,5 +1,7 @@ delimiter = $delimiter; - $this->source = $this->parseTagData($source); - $this->mode = $mode; - $this->landing = $landing; - $this->format = $format; - $this->givenTags = $this->prepGivenTags($givenTags); - $this->caseSensitive = $caseSensitive; - $this->displayDelimiter = $displayDelimiter; - $this->sort = $sort; - $this->displayMode = $displayMode; - $this->tpl = $tpl; - $this->callback = $callback; - } - - function prepGivenTags ($givenTags) { - global $modx,$_GET,$dittoID; - - $getTags = !empty($_GET[$dittoID.'tags']) ? $modx->stripTags(trim($_GET[$dittoID.'tags'])) : false; - // Get tags from the $_GET array - - $tags1 = array(); - $tags2= array(); - - if ($getTags !== false) { - $tags1 = explode($this->delimiter,$getTags); - } - - if ($givenTags !== false) { - $tags2 = explode($this->delimiter,$givenTags); - } - - $kTags = array(); - $tags = array_merge($tags1,$tags2); - foreach ($tags as $tag) { - if (!empty($tag)) { - if ($this->caseSensitive) { - $kTags[trim($tag)] = trim($tag); - } else { - $kTags[strtolower(trim($tag))] = trim($tag); - } - } - } - return $kTags; - } - - function tagFilter ($value) { - if ($this->caseSensitive == false) { - $documentTags = array_values(array_flip($this->givenTags)); - $filterTags = array_values(array_flip($this->combineTags($this->source, $value,true))); - } else { - $documentTags = $this->givenTags; - $filterTags =$this->combineTags($this->source, $value,true); - } - $compare = array_intersect($filterTags, $documentTags); - $commonTags = count($compare); - $totalTags = count($filterTags); - $docTags = count($documentTags); - $unset = 1; - - switch ($this->mode) { - case "onlyAllTags" : - if ($commonTags != $docTags) - $unset = 0; - break; - case "removeAllTags" : - if ($commonTags == $docTags) - $unset = 0; - break; - case "onlyTags" : - if ($commonTags > $totalTags || $commonTags == 0) - $unset = 0; - break; - case "removeTags" : - if ($commonTags <= $totalTags && $commonTags != 0) - $unset = 0; - break; - } - return $unset; - } - - function makeLinks($resource) { - return $this->tagLinks($this->combineTags($this->source,$resource,true), $this->delimiter, $this->landing, $this->format); - } - - function parseTagData($tagData,$names=array()) { - return explode(",",$tagData); - } - - function combineTags($tagData, $resource, $array=false) { - if ($this->callback !== false) { - return call_user_func_array($this->callback,array('tagData'=>$tagData,'resource'=>$resource,'array'=>$array)); - } - $tags = array(); - foreach ($tagData as $source) { - if(!empty($resource[$source])) { - $tags[] = $resource[$source]; - } - } - $kTags = array(); - $tags = explode($this->delimiter,implode($this->delimiter,$tags)); - foreach ($tags as $tag) { - if (!empty($tag)) { - if ($this->caseSensitive) { - $kTags[trim($tag)] = trim($tag); - } else { - $kTags[strtolower(trim($tag))] = trim($tag); - } - } - } - return ($array == true) ? $kTags : implode($this->delimiter,$kTags); - } - - function tagLinks($tags, $tagDelimiter, $tagID=false, $format="html") { - global $ditto_lang,$modx; - if(count($tags) == 0 && $format=="html") { - return $ditto_lang['none']; - } else if (count($tags) == 0 && ($format=="rss" || $format=="xml" || $format == "xml")) - { - return "".$ditto_lang['none'].""; - } - - $output = ""; - if ($this->sort) { - ksort($tags); - } - - // set templates array - $tplRss = "\r\n"." [+tag+]"; - $tpl = ($this->tpl == false) ? '' : $this->tpl; - - $tpl = (($format == "rss" || $format == "xml" || $format == "atom") && $templates['user'] == false) ? $tplRss : $tpl; - - if ($this->displayMode == 1) { - foreach ($tags as $tag) { - $tagDocID = (!$tagID) ? $modx->documentObject['id'] : $tagID; - $url = ditto::buildURL("tags=$tag&start=0",$tagDocID); - $output .= template::replace(array('url'=>$url,'tag'=>$tag),$tpl); - $output .= ($format != "rss" && $format != "xml" && $format != "atom") ? $this->displayDelimiter : ''; - } - } else if ($format != "rss" && $format != "xml" && $format != "atom" && $this->displayMode == 2) { - $tagList = array(); - foreach ($tags as $tag) { - $tagDocID = (!$tagID) ? $modx->documentObject['id'] : $tagID; - $url = ditto::buildURL("tags=$tag&start=0",$tagDocID); - $tagList[] = template::replace(array('url'=>$url,'tag'=>$tag),$tpl); - } - $output = $this->makeList($tagList, $ulroot='ditto_tag_list', $ulprefix='ditto_tag_', $type='', $ordered=false, $tablevel=0); - } - - return ($format != "rss" && $format != "xml" && $format != "atom") ? substr($output,0,-1*strlen($this->displayDelimiter)) : $output; - } - - function makeList($array, $ulroot= 'root', $ulprefix= 'sub_', $type= '', $ordered= false, $tablevel= 0) { - // first find out whether the value passed is an array - if (!is_array($array)) { - return "
    • Bad list
    "; - } - if (!empty ($type)) { - $typestr= " style='list-style-type: $type'"; - } else { - $typestr= ""; - } - $tabs= ""; - for ($i= 0; $i < $tablevel; $i++) { - $tabs .= "\t"; - } - $listhtml= $ordered == true ? $tabs . "
      \n" : $tabs . "
        \n"; - foreach ($array as $key => $value) { - if (is_array($value)) { - $listhtml .= $tabs . "\t
      • " . $key . "\n" . $this->makeList($value, $ulprefix . $ulroot, $ulprefix, $type, $ordered, $tablevel +2) . $tabs . "\t
      • \n"; - } else { - $listhtml .= $tabs . "\t
      • " . $value . "
      • \n"; - } - } - $listhtml .= $ordered == true ? $tabs . "
    \n" : $tabs . "\n"; - return $listhtml; - } - } -} - // --------------------------------------------------- // Tagging Parameters // --------------------------------------------------- From cd35be244ded2a1e56ecff95b869b8d0269ec90a Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Mon, 28 Aug 2017 16:28:40 +0300 Subject: [PATCH 324/338] fix tinymce params underfined bug on frontend --- assets/plugins/tinymce4/gsettings/gsettings.rows.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/plugins/tinymce4/gsettings/gsettings.rows.inc.php b/assets/plugins/tinymce4/gsettings/gsettings.rows.inc.php index 876b34ffc2..1a51803705 100644 --- a/assets/plugins/tinymce4/gsettings/gsettings.rows.inc.php +++ b/assets/plugins/tinymce4/gsettings/gsettings.rows.inc.php @@ -1,6 +1,6 @@ '', 'skinsDirectory'=>''); // Hold general settings based on old Modx TinyMCE-Settings // Settings interface rows configuration From 6cc75b5ed4bbff76fc1fe0dc041470b72bacd83d Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Mon, 28 Aug 2017 17:03:24 +0300 Subject: [PATCH 325/338] Fix Ditto when dateSource emply use createdon #190 --- assets/snippets/ditto/classes/ditto.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index a71061c808..69a1981efe 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -358,7 +358,7 @@ function parseFields($placeholders,$seeThruUnpub,$dateSource,$randomize) { $this->addField('parent','display','db'); $checkOptions = array('pub_date','unpub_date','editedon','deletedon','publishedon'); if (in_array($dateSource,$checkOptions)) { - $this->addField($dateSource,'display'); + $this->addField('createdon','display'); } if (in_array('date',$this->fields['display']['custom'])) { $this->addField($dateSource,'display'); From 003c0be99b21a2f6947c77205dd57efa4f82186f Mon Sep 17 00:00:00 2001 From: Dreamer0x01 Date: Mon, 28 Aug 2017 17:25:51 +0300 Subject: [PATCH 326/338] Update document.parser.class.inc.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Если в массиве есть элементы с соответствующими плейсхолдерам ключами, но из значения выставлены в NULL - нужно заполнить соответствующие плейсхолдеры пустыми значениями, а не передавать дальше нераспарсенное наименование плейсхолдера. --- manager/includes/document.parser.class.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index f3ee6c79fb..2bdeac6a4a 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -3570,7 +3570,8 @@ function parseText($tpl='', $ph=array(), $left= '[+', $right= '+]', $execModifie list($key,$modifiers)=$this->splitKeyAndFilter($key); else $modifiers = false; - if(!isset($ph[$key])) continue; +// if(!isset($ph[$key])) continue; + if(!array_key_exists($key,$ph)) continue; //NULL values must be saved in placeholders, if we got them from database string $value = $ph[$key]; From 2c0ad143eb1801314f90b2649d9cfa15e8c27379 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Tue, 29 Aug 2017 00:53:33 +0300 Subject: [PATCH 327/338] fix Ditto TV output --- .../ditto/classes/ditto.class.inc.php | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 69a1981efe..ed7755f3fa 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -716,35 +716,29 @@ function appendTV($tvname='',$docIDs){ $from[] = 'LEFT JOIN [+prefix+]site_tmplvars AS stv ON stv.id=stc.tmplvarid'; $where = sprintf("stv.name='%s' AND stc.contentid IN (%s)", $modx->db->escape($tvname), join($docIDs,',')); $rs= $modx->db->select($fields, $from, $where, 'stc.contentid ASC'); + $docs = array(); while ($row = $modx->db->getRow($rs)) { - extract($row,EXTR_PREFIX_ALL,'p_'); - $key = '#'.$p_contentid; - $docs[$key][$tvname] = getTVDisplayFormat($p_name,$p_value,$p_display,$p_display_params,$p_type,$p_contentid); - $docs[$key]['tv'.$tvname] = $docs[$key][$tvname]; + $docs["#".$row['contentid']][$row['name']] = getTVDisplayFormat($row['name'], $row['value'], $row['display'], $row['display_params'], $row['type'],$row['contentid']); + $docs["#".$row['contentid']]["tv".$row['name']] = $docs["#".$row['contentid']][$row['name']]; } if (count($docs) != count($docIDs)) { - $field = 'id,name,type,display,display_params,default_text'; - $where = sprintf("name='%s'",$modx->db->escape($tvname)); - $rs = $modx->db->select($field, '[+prefix+]site_tmplvars', $where, '', 1); + $rs = $modx->db->select("name,type,display,display_params,default_text", '[+prefix+]site_tmplvars', "name='{$tvname}'", '', 1); $row = $modx->db->getRow($rs); - extract($row,EXTR_PREFIX_ALL,'p_'); - if (strtoupper($p_default_text) == '@INHERIT') { + if (strtoupper($row['default_text']) == '@INHERIT') { foreach ($docIDs as $id) { - $defaultOutput = getTVDisplayFormat($p_name, $p_default_text, $p_display, $p_display_params, $p_type, $id); - $k = '#'.$id; - if (!isset($docs[$k])) { - $docs[$k][$tvname] = $defaultOutput; - $docs[$k]['tv'.$tvname] = $docs[$k][$tvname]; + $defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'], $id); + if (!isset($resourceArray["#".$id])) { + $docs["#$id"][$tvname] = $defaultOutput; + $docs["#$id"]["tv".$tvname] = $docs["#$id"][$tvname]; } } } else { - $defaultOutput = getTVDisplayFormat($p_name, $p_default_text, $p_display, $p_display_params, $p_type, $p_id); + $defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'],$row['contentid']); foreach ($docIDs as $id) { - $k = '#'.$id; - if (!isset($docs[$k])) { - $docs[$k][$tvname] = $defaultOutput; - $docs[$k]['tv'.$tvname] = $docs[$k][$tvname]; + if (!isset($docs["#".$id])) { + $docs["#$id"][$tvname] = $defaultOutput; + $docs["#$id"]["tv".$tvname] = $docs["#$id"][$tvname]; } } } From 623be60e8c9739edcf15151a9e51561441e056ba Mon Sep 17 00:00:00 2001 From: yamamoto Date: Tue, 29 Aug 2017 07:38:12 +0900 Subject: [PATCH 328/338] Code cleanup --- .../extenders/andFilter.extender.inc.php | 30 ++-- .../extenders/countDocs.extender.inc.php | 12 +- .../extenders/customsort.extender.inc.php | 27 ++-- .../extenders/dateFilter.extender.inc.php | 4 +- .../ditto/extenders/distinct.extender.inc.php | 147 +++++++++--------- .../ditto/extenders/example.extender.inc.php | 123 +++++++-------- .../extenders/glossaryFilter.extender.inc.php | 16 +- .../ditto/extenders/jotcount.extender.inc.php | 28 ++-- .../ditto/extenders/level.extender.inc.php | 21 ++- .../ditto/extenders/request.extender.inc.php | 144 +++++++++-------- 10 files changed, 260 insertions(+), 292 deletions(-) diff --git a/assets/snippets/ditto/extenders/andFilter.extender.inc.php b/assets/snippets/ditto/extenders/andFilter.extender.inc.php index 49f749d730..16f32a2e48 100644 --- a/assets/snippets/ditto/extenders/andFilter.extender.inc.php +++ b/assets/snippets/ditto/extenders/andFilter.extender.inc.php @@ -9,37 +9,33 @@ // --------------------------------------------------- // If no fieldname value has been supplied, don't do anything else -if ($andFilterTv === false) { - return false; -} - +if ($andFilterTv === false) return false; + global $tvsarray; $tmparray = explode ( ';', $andFilterTv); foreach ( $tmparray as $tmpvalue ) { - $tmpexplode = explode ( ':', $tmpvalue ); - $tvsarray[] = $tmpexplode; - $filtertvs .= (empty($filtertvs)?"":",") . $tmpexplode[0]; - } - - - -$filters["custom"]["andFilter"] = array( $filtertvs, "andFilter"); + $tmpexplode = explode ( ':', $tmpvalue ); + $tvsarray[] = $tmpexplode; + $filtertvs .= (empty($filtertvs)?'':',') . $tmpexplode[0]; +} + +$filters['custom']['andFilter'] = array( $filtertvs, 'andFilter'); -if (!function_exists("andFilter")) { +if (!function_exists('andFilter')) { function andFilter($resource) { global $modx,$tvsarray; $good = true; foreach ( $tvsarray as $tv ) { $values = explode( ',', $tv[1] ); - if ( array_search($resource[$tv[0]], $values) !== false ) { + if ( array_search($resource[$tv[0]], $values) !== false ) { $good = $good && true; } else { $good = $good && false; } } - if ($good) { return 1; } else { return 0; } - + if ($good) return 1; + else return 0; + } } -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/countDocs.extender.inc.php b/assets/snippets/ditto/extenders/countDocs.extender.inc.php index e0a55809c7..6cd7f3bdc2 100644 --- a/assets/snippets/ditto/extenders/countDocs.extender.inc.php +++ b/assets/snippets/ditto/extenders/countDocs.extender.inc.php @@ -14,9 +14,11 @@ */ $GLOBALS['docCounter'] = 0; - + $filters['custom']['countDocs'] = array('id', 'countDocuments'); - + +$placeholders['count'] = array('id', 'setCountPlaceholder'); + if (!function_exists('countDocuments')) { function countDocuments($resource) { # count documents @@ -24,13 +26,9 @@ function countDocuments($resource) { return 1; } } - -$placeholders['count'] = array('id', 'setCountPlaceholder'); - + if (!function_exists('setCountPlaceholder')) { function setCountPlaceholder($resource) { return $GLOBALS['docCounter']; } } - -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/customsort.extender.inc.php b/assets/snippets/ditto/extenders/customsort.extender.inc.php index f480cdbb00..49b90d41af 100644 --- a/assets/snippets/ditto/extenders/customsort.extender.inc.php +++ b/assets/snippets/ditto/extenders/customsort.extender.inc.php @@ -1,18 +1,15 @@ advSort = true; -?> \ No newline at end of file + +if (!function_exists('customsort')){ + function customsort($a, $b){ + $pos_a = array_search($a['id'], $GLOBALS['documents']); + $pos_b = array_search($b['id'], $GLOBALS['documents']); + + if ($pos_a == $pos_b) return 0; + + return ($pos_a < $pos_b) ? -1 : 1; + } +} diff --git a/assets/snippets/ditto/extenders/dateFilter.extender.inc.php b/assets/snippets/ditto/extenders/dateFilter.extender.inc.php index 38ed17566a..8888e20264 100644 --- a/assets/snippets/ditto/extenders/dateFilter.extender.inc.php +++ b/assets/snippets/ditto/extenders/dateFilter.extender.inc.php @@ -101,7 +101,7 @@ function execute($value) { $year = (!empty($_GET[$dittoID.'year']) && $_GET[$dittoID.'year'] != 'false') ? intval($_GET[$dittoID.'year']) : 0; $month = (!empty($_GET[$dittoID.'month']) && $_GET[$dittoID.'month'] != 'false') ? intval($_GET[$dittoID.'month']) : 0; $day = (!empty($_GET[$dittoID.'day']) && $_GET[$dittoID.'day'] != 'false') ? intval($_GET[$dittoID.'day']) : 0; -} else if ($source == 'params'){ +} elseif ($source == 'params'){ $month = isset($month) ? intval($month) : 0; /* Param: month @@ -226,5 +226,3 @@ function execute($value) { $dateFilterOject = new dateFilter($month,$year,$day,$dateSource); $filters["custom"]["dateFilter"] = array($dateSource,array($dateFilterOject,"execute")); } - -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/distinct.extender.inc.php b/assets/snippets/ditto/extenders/distinct.extender.inc.php index b337178a82..2f64c52901 100755 --- a/assets/snippets/ditto/extenders/distinct.extender.inc.php +++ b/assets/snippets/ditto/extenders/distinct.extender.inc.php @@ -5,41 +5,39 @@ * * Return only distinct / unique results, based on a fieldname supplied as &distinct parameter * - * @Installation: Put file "distinct.extender.inc.php" into /assets/snippets/ditto/extenders + * @Installation: Put file 'distinct.extender.inc.php' into /assets/snippets/ditto/extenders * * @Usage: - * In the Ditto call, add "distinct" to the extenders param, and specify the &distinct parameter with the name(s) of the field which you would like to be unique. - * If you would like to make the combined values of more than one field unique, separate them with commas - * e.g. [[Ditto? &tpl=`myTemplate` &extenders=`distinct` &distinct=`pagetitle`]] -- will return only unique page titles. - * e.g. [[Ditto? &tpl=`myTemplate` &extenders=`distinct` &distinct=`pagetitle,pub_date`]] -- will return only unique page titles for each date. + * In the Ditto call, add 'distinct' to the extenders param, and specify the &distinct parameter with the name(s) of the field which you would like to be unique. + * If you would like to make the combined values of more than one field unique, separate them with commas + * e.g. [[Ditto? &tpl=`myTemplate` &extenders=`distinct` &distinct=`pagetitle`]] -- will return only unique page titles. + * e.g. [[Ditto? &tpl=`myTemplate` &extenders=`distinct` &distinct=`pagetitle,pub_date`]] -- will return only unique page titles for each date. * * @Changelog: - * 1.0.3 (2011-12-30) By Sergey Davydov: Set placeholders distinctCount - common count and distinctIds - ids of distinted items - * 1.0.2 (2012-04-05) by DivanDesign: Now use the DittoID (need for many Ditto calls). - * 1.0.1 by Nick Crossland: Bugfixes only. - * 1.0 by Nick Crossland: initial release. + * 1.0.3 (2011-12-30) By Sergey Davydov: Set placeholders distinctCount - common count and distinctIds - ids of distinted items + * 1.0.2 (2012-04-05) by DivanDesign: Now use the DittoID (need for many Ditto calls). + * 1.0.1 by Nick Crossland: Bugfixes only. + * 1.0 by Nick Crossland: initial release. * * @Author: Nick Crossland (ncrossland), DivanDesign (http://www.DivanDesign.biz) */ $distinct = isset($distinct) ? $distinct : false; /* - Param: distinct + Param: distinct - Purpose: - What field should we search for being distinct? + Purpose: + What field should we search for being distinct? - Options: - Fieldname - - Default: - "default" + Options: + Fieldname + + Default: + 'default' */ // If no fieldname value has been supplied, don't do anything else -if ($distinct === false) { - return false; -} +if ($distinct === false) return false; // It would be nice if this was class based, so it doesn't pollute the global namespace // But - create an array of document values we've seen, and the fieldnames we're making distinct @@ -54,68 +52,65 @@ // Remove any extra spaces from the fieldnames (in case they have been supplied with commas and spaces) $distinct_fieldname[$ddDittoID] = array_map('trim', $distinct_fieldname[$ddDittoID]); -$placeholders['distinctCount'] = array(implode(',',$distinct_fieldname[$ddDittoID]),"distinctCount"); +$placeholders['distinctCount'] = array(implode(',',$distinct_fieldname[$ddDittoID]),'distinctCount'); -if(!function_exists('distinctCount')){ - function distinctCount($resource){ //Not sure if the $resource is needed - global $seen; - global $distinct_fieldname; - global $ddDittoID; +$placeholders['distinctIds'] = array(implode(',',$distinct_fieldname[$ddDittoID]),'distinctIds'); - $distinct_string = ''; - foreach ($distinct_fieldname[$ddDittoID] as $f) { - $distinct_string .= '~'. $f.'|'.$resource[$f]; - } - if (isset($seen[$ddDittoID][$distinct_string])) - return count($seen[$ddDittoID][$distinct_string]); - } -} +// Add the custom function +$filters['custom']['distinct'] = array(implode(',',$distinct_fieldname[$ddDittoID]) ,'makeDistinct'); -$placeholders['distinctIds'] = array(implode(',',$distinct_fieldname[$ddDittoID]),"distinctIds"); -if(!function_exists('distinctIds')){ - function distinctIds($resource){ //Not sure if the $resource is needed - global $seen; - global $distinct_fieldname; - global $ddDittoID; - $distinct_string = ''; - foreach ($distinct_fieldname[$ddDittoID] as $f) { - $distinct_string .= '~'. $f.'|'.$resource[$f]; - } - if (isset($seen[$ddDittoID][$distinct_string])) - return implode(",",$seen[$ddDittoID][$distinct_string]); - } +if(!function_exists('distinctCount')){ + function distinctCount($resource){ //Not sure if the $resource is needed + global $seen; + global $distinct_fieldname; + global $ddDittoID; + + $distinct_string = ''; + foreach ($distinct_fieldname[$ddDittoID] as $f) { + $distinct_string .= '~'. $f.'|'.$resource[$f]; + } + if (isset($seen[$ddDittoID][$distinct_string])) return count($seen[$ddDittoID][$distinct_string]); + } +} +if(!function_exists('distinctIds')){ + function distinctIds($resource){ //Not sure if the $resource is needed + global $seen; + global $distinct_fieldname; + global $ddDittoID; + + $distinct_string = ''; + foreach ($distinct_fieldname[$ddDittoID] as $f) { + $distinct_string .= '~'. $f.'|'.$resource[$f]; + } + if (isset($seen[$ddDittoID][$distinct_string])) return implode(',',$seen[$ddDittoID][$distinct_string]); + } } - // The filter function -if (!function_exists("makeDistinct")) { - - function makeDistinct($resource) { - global $ddDittoID; - global $seen; - global $distinct_fieldname; - - // Make a unique string based on the fieldname and value of each field we've been asked to make distinct - $distinct_string = ''; - foreach ($distinct_fieldname[$ddDittoID] as $f) { - $distinct_string .= '~'. $f.'|'.$resource[$f]; - } - - // Check if this string has been seen yet -- if it has, don't include it in the results - if (isset($seen[$ddDittoID][$distinct_string]) && $seen[$ddDittoID][$distinct_string] ) { // If this value of the fieldname has been seen before, remove it from the list - $seen[$ddDittoID][$distinct_string][] = $resource["id"]; - return false; - } else { -// Otherwise, remember the value has been seen, and allow it in the list (this time) - $seen[$ddDittoID][$distinct_string] = array($resource["id"]); - return true; - } - - } +if (!function_exists('makeDistinct')) { + + function makeDistinct($resource) { + global $ddDittoID; + global $seen; + global $distinct_fieldname; + + // Make a unique string based on the fieldname and value of each field we've been asked to make distinct + $distinct_string = ''; + foreach ($distinct_fieldname[$ddDittoID] as $f) { + $distinct_string .= '~'. $f.'|'.$resource[$f]; + } + + // Check if this string has been seen yet -- if it has, don't include it in the results + if (isset($seen[$ddDittoID][$distinct_string]) && $seen[$ddDittoID][$distinct_string] ) { + // If this value of the fieldname has been seen before, remove it from the list + $seen[$ddDittoID][$distinct_string][] = $resource['id']; + return false; + } else { + // Otherwise, remember the value has been seen, and allow it in the list (this time) + $seen[$ddDittoID][$distinct_string] = array($resource['id']); + return true; + } + } } - -// Add the custom function -$filters["custom"]["distinct"] = array(implode(',',$distinct_fieldname[$ddDittoID]) ,"makeDistinct"); -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/example.extender.inc.php b/assets/snippets/ditto/extenders/example.extender.inc.php index b4dc44fcfd..a63752698f 100644 --- a/assets/snippets/ditto/extenders/example.extender.inc.php +++ b/assets/snippets/ditto/extenders/example.extender.inc.php @@ -3,7 +3,7 @@ /* * Title: Example * Purpose: - * Example file for basing new Extenders on + * Example file for basing new Extenders on */ // --------------------------------------------------- @@ -11,18 +11,18 @@ // Define any parameters needed in the extender or to override Ditto defaults // --------------------------------------------------- -$param = isset($param) ? $param : "default"; +if(!isset($param)) $param = 'default'; /* - Param: param + Param: param - Purpose: - The purpose of your parameter goes here + Purpose: + The purpose of your parameter goes here - Options: - Any options that your parameter can have go here - - Default: - "default" + Options: + Any options that your parameter can have go here + + Default: + 'default' */ // --------------------------------------------------- @@ -30,67 +30,60 @@ // Defin the values of custom placeholders for access in the tpl like so [+phname+] // --------------------------------------------------- -$placeholders['example'] = array(array("pagetitle","*"),"exampleFunction","pagetitle"); - // Variable: $placeholders['example'] - // Add the placeholder example to the custom placeholders list - // with the source pagetitle in both display and backend using the - // exampleFunction callback and pagetitle as the field for QuickEdit. - // If you only needed the placeholder in the frontent you would just - // use "pagetitle" as the first value of the array. If the callback - // was in a class use the array($initialized_class,"member") method. - -if (!function_exists("exampleFunction")) { - // wrap functions in !functino_exists statements to ensure that they are not defined twice - - // --------------------------------------------------- - // Function: exampleFunction - // - // Takes the resource array for an individual document - // and returns the value of the placeholder, in this - // case the uppercase version of the pagetitle - // --------------------------------------------------- - function exampleFunction($resource) { - return strtoupper($resource['pagetitle']); - } -} +$placeholders['example'] = array(array('pagetitle','*'),'exampleFunction','pagetitle'); + // Variable: $placeholders['example'] + // Add the placeholder example to the custom placeholders list + // with the source pagetitle in both display and backend using the + // exampleFunction callback and pagetitle as the field for QuickEdit. + // If you only needed the placeholder in the frontent you would just + // use 'pagetitle' as the first value of the array. If the callback + // was in a class use the array($initialized_class,'member') method. // --------------------------------------------------- // Group: Filters // Define custom or basic filters within the extender to expand Ditto's filtering capabilities // --------------------------------------------------- -$filters["custom"]["exampleFilter"] = array("pagetitle","exampleFilter"); - // Variable: $filters["custom"]["exampleFilter"] - // Add the filter exampleFilter to the custom filters - // list with the source pagetitle and the callback - // exampleFilter - -if (!function_exists("exampleFilter")) { - // wrap functions in !functino_exists statements to ensure that they are not defined twice - - // --------------------------------------------------- - // Function: exampleFilter - // - // Takes the resource array for an individual document - // and asks for the return of a 0 or 1 with 1 removing - // the document and 0 leaving it in the result set. - // In this case, if the lower case value of the pagetitle - // is foo, it is removed while all other documents are shown - // --------------------------------------------------- - function exampleFilter($resource) { - if (strtolower($resource['pagetitle']) == "foo") { - return 1; - } else { - return 0; - } - } -} - -$filters["parsed"][] = array('exampleFilter' => array("source"=>"id","value"=>"9239423942","mode"=>"2")); - // Variable: $filters["parsed"][] - // Add the pre-parsed filter to the parsed filters list with the - // source as id, the value of 9239423942 and the mode 2 +$filters['custom']['exampleFilter'] = array('pagetitle','exampleFilter'); + // Variable: $filters['custom']['exampleFilter'] + // Add the filter exampleFilter to the custom filters + // list with the source pagetitle and the callback + // exampleFilter +$filters['parsed'][] = array('exampleFilter' => array('source'=>'id','value'=>'9239423942','mode'=>'2')); + // Variable: $filters['parsed'][] + // Add the pre-parsed filter to the parsed filters list with the + // source as id, the value of 9239423942 and the mode 2 +if (!function_exists('exampleFunction')) { + // wrap functions in !functino_exists statements to ensure that they are not defined twice + + // --------------------------------------------------- + // Function: exampleFunction + // + // Takes the resource array for an individual document + // and returns the value of the placeholder, in this + // case the uppercase version of the pagetitle + // --------------------------------------------------- + function exampleFunction($resource) { + return strtoupper($resource['pagetitle']); + } +} -?> \ No newline at end of file +if (!function_exists('exampleFilter')) { + // wrap functions in !functino_exists statements to ensure that they are not defined twice + + // --------------------------------------------------- + // Function: exampleFilter + // + // Takes the resource array for an individual document + // and asks for the return of a 0 or 1 with 1 removing + // the document and 0 leaving it in the result set. + // In this case, if the lower case value of the pagetitle + // is foo, it is removed while all other documents are shown + // --------------------------------------------------- + function exampleFilter($resource) { + if (strtolower($resource['pagetitle'])=='foo') return 1; + else return 0; + } +} diff --git a/assets/snippets/ditto/extenders/glossaryFilter.extender.inc.php b/assets/snippets/ditto/extenders/glossaryFilter.extender.inc.php index ca2ba4db8d..a08c38f995 100644 --- a/assets/snippets/ditto/extenders/glossaryFilter.extender.inc.php +++ b/assets/snippets/ditto/extenders/glossaryFilter.extender.inc.php @@ -39,16 +39,14 @@ $filters['custom']['glossaryFilter'] = array($GLOBALS['filterVar'], 'glossaryFilter'); if (!function_exists('glossaryFilter')) { - function glossaryFilter($resource) { - if (!$GLOBALS['filterBy']) { - # do nothing (simply leave document within final dataset) - return 1; - } + function glossaryFilter($resource) { + if (!$GLOBALS['filterBy']) { + // do nothing (simply leave document within final dataset) + return 1; + } $regExpBegin = preg_match('/^(chunk|custom)$/', $GLOBALS['filterMode']) ? '' : '/^['; $regExpEnd = preg_match('/^(chunk|custom)$/', $GLOBALS['filterMode']) ? '' : ']/i' . $GLOBALS['forceUTF8']; - # do filtering + // do filtering return preg_match($regExpBegin . $GLOBALS['filterBy'] . $regExpEnd, $resource[$GLOBALS['filterVar']]) ? 1 : 0; - } + } } - -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/jotcount.extender.inc.php b/assets/snippets/ditto/extenders/jotcount.extender.inc.php index 0f465873b4..483e95b33e 100644 --- a/assets/snippets/ditto/extenders/jotcount.extender.inc.php +++ b/assets/snippets/ditto/extenders/jotcount.extender.inc.php @@ -1,23 +1,21 @@ db->select('uparent, COUNT(*)', $modx->getFullTableName("jot_content"), 'published=1 AND deleted=0 GROUP BY uparent', 'COUNT(*) DESC'); +$where = 'published=1 AND deleted=0 GROUP BY uparent'; +$result = $modx->db->select('uparent, COUNT(*)', '[+prefix+]jot_content', $where, 'COUNT(*) DESC'); $counts = $modx->db->makeArray( $result ); -// document_id => comments_count $jotcount = array(); -foreach($counts as $k=>$v) $jotcount[$v['uparent']] = $v['COUNT(*)']; -// "" jotph() +foreach($counts as $k=>$v) { + $jotcount[$v['uparent']] = $v['COUNT(*)']; +} + $GLOBALS['jotcount'] = $jotcount; -// [+jotcount+] ditto -$placeholders['jotcount'] = array(array("id","*"),"jotph","id"); +$placeholders['jotcount'] = array(array('id','*'),'jotph','id'); -// , [+jotcount+] &tpl -if(!function_exists("jotph")) { - function jotph($resource) { - global $jotcount; - if(!$r = $jotcount[$resource['id']]) $r = 0; - return $r; - } +if(!function_exists('jotph')) { + function jotph($resource) { + global $jotcount; + if(!$r = $jotcount[$resource['id']]) $r = 0; + return $r; + } } -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/level.extender.inc.php b/assets/snippets/ditto/extenders/level.extender.inc.php index 245fe50b4f..e646e4ce3d 100644 --- a/assets/snippets/ditto/extenders/level.extender.inc.php +++ b/assets/snippets/ditto/extenders/level.extender.inc.php @@ -3,16 +3,13 @@ Параметр &level — уровень от корня сайта */ -$GLOBALS["level"] = isset($level) ? (int)$level : 1; -$filters["custom"]["levelFilter"] = array("id","levelFilter"); -if (!function_exists("levelFilter")) { - function levelFilter($resource) { - global $modx,$level; - if (count($modx->getParentIds($resource['id'])) == $level) { - return 1; - } else { - return 0; - } - } +$GLOBALS['level'] = isset($level) ? (int)$level : 1; +$filters['custom']['levelFilter'] = array('id','levelFilter'); + +if (!function_exists('levelFilter')) { + function levelFilter($resource) { + global $modx,$level; + if (count($modx->getParentIds($resource['id'])) == $level) return 1; + else return 0; + } } -?> \ No newline at end of file diff --git a/assets/snippets/ditto/extenders/request.extender.inc.php b/assets/snippets/ditto/extenders/request.extender.inc.php index 6020d719b7..90c68f14bf 100644 --- a/assets/snippets/ditto/extenders/request.extender.inc.php +++ b/assets/snippets/ditto/extenders/request.extender.inc.php @@ -2,101 +2,99 @@ /* * Title: Request * Purpose: - * Adds support for changing Ditto parameters via URL + * Adds support for changing Ditto parameters via URL * * Note: - * - All variables must be prefixed with ditto_ for the snippet to recognize them! - * - If a Ditto id is set use the sntax + * - All variables must be prefixed with ditto_ for the snippet to recognize them! + * - If a Ditto id is set use the sntax */ $variables = array(); $stripTags = isset($stripTags) ? $stripTags : 1; /* - Param: stripTags - - Purpose: - Remove HTML tags from the parameters provided + Param: stripTags + + Purpose: + Remove HTML tags from the parameters provided - Options: - 0 - off - 1 - on - - Default: - 1 - on + Options: + 0 - off + 1 - on + + Default: + 1 - on */ -$bad = isset($bad) ? explode(",",$bad) : array("seeThroughtUnpub","showInMenuOnly","showPublishedOnly","debug","start","config","extenders","dittoID"); +$bad = isset($bad) ? explode(',',$bad) : explode(',', 'seeThroughtUnpub,showInMenuOnly,showPublishedOnly,debug,start,config,extenders,dittoID'); /* - Param: bad - - Purpose: - Parameters that are not allowed to be set - - Options: - Any valid Ditto options separated by commas - - Default: - "seeThroughtUnpub,showInMenuOnly,showPublishedOnly,debug,start,config,extenders,dittoID" + Param: bad + + Purpose: + Parameters that are not allowed to be set + + Options: + Any valid Ditto options separated by commas + + Default: + 'seeThroughtUnpub,showInMenuOnly,showPublishedOnly,debug,start,config,extenders,dittoID' */ -$good = isset($good) ? explode(",",$good) : false; +$good = isset($good) ? explode(',',$good) : false; /* - Param: good - - Purpose: - Parameters that are allowed to be set - - Options: - Any valid Ditto options separated by commas - - Default: - All parameters execpt those in &bad + Param: good + + Purpose: + Parameters that are allowed to be set + + Options: + Any valid Ditto options separated by commas + + Default: + All parameters execpt those in &bad */ foreach ($_REQUEST as $name=>$value) { - $saneName = str_replace($dittoID, "", substr($name, 6)); - $dID = ($dittoID == "") ? true : strpos($name, $dittoID); - if ((substr($name, 0, 6) == "ditto_" && $dID) && !in_array($saneName,$bad) && ($good == false || in_array($saneName,$good)) && !preg_match("/[\^`~!\/@\\#\}\$%:;\)\(\{&\*=\|'\+]/", $value)){ - if ($stripTags) $var = $modx->stripTags($value); - if ($saneName == 'orderBy') { - $variables[$saneName] = array('parsed'=>array(),'custom'=>array(),'unparsed'=>trim($value)); - }else{ - $variables[$saneName] = trim($value); - } - } + $saneName = str_replace($dittoID, '', substr($name, 6)); + $dID = ($dittoID == '') ? true : strpos($name, $dittoID); + if ((substr($name, 0, 6) == 'ditto_' && $dID) && !in_array($saneName,$bad) && ($good == false || in_array($saneName,$good)) && !preg_match("/[\^`~!\/@\\#\}\$%:;\)\(\{&\*=\|'\+]/", $value)){ + if ($stripTags) $var = $modx->stripTags($value); + if ($saneName == 'orderBy') { + $variables[$saneName] = array('parsed'=>array(),'custom'=>array(),'unparsed'=>trim($value)); + }else{ + $variables[$saneName] = trim($value); + } + } } /* - Param: dbg - - Purpose: - Output variables being set - - Options: - 0 - off - 1 - on - - Default: - 0 - off + Param: dbg + + Purpose: + Output variables being set + + Options: + 0 - off + 1 - on + + Default: + 0 - off */ -if ($_REQUEST[$dittoID."dbg"]==1) {print_r($variables);} +if ($_REQUEST[$dittoID.'dbg']==1) print_r($variables); extract($variables); // ------------------------------------------------------------------------------// -// Kudo's MultiFilter Code // +// Kudo's MultiFilter Code // // ------------------------------------------------------------------------------// -// Accepts ditto_filter, ditto_filter_2, with continuous numbering // +// Accepts ditto_filter, ditto_filter_2, with continuous numbering // // Note: For complex filtering start with ditto_filter_1 (with one as number)! // // ------------------------------------------------------------------------------// if (isset($filter) && isset($filter_2)) { - $i = 2; - while (isset(${'filter_'.$i})) { - $filter .= '|'.${'filter_'.$i}; - $i++; - } - } elseif (!isset($filter) && isset($filter_1)) { - $filter = $filter_1; - $i = 2; - while (isset(${'filter_'.$i})) { - $filter .= '|'.${'filter_'.$i}; - $i++; - } + $i = 2; + while (isset(${'filter_'.$i})) { + $filter .= '|'.${'filter_'.$i}; + $i++; + } +} elseif (!isset($filter) && isset($filter_1)) { + $filter = $filter_1; + $i = 2; + while (isset(${'filter_'.$i})) { + $filter .= '|'.${'filter_'.$i}; + $i++; + } } - -?> \ No newline at end of file From bd785cf9504ccec449d0cfd5d5da027e169f6639 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Tue, 29 Aug 2017 08:14:01 +0900 Subject: [PATCH 329/338] Fix - $modx->parseDocumentSource() --- manager/includes/document.parser.class.inc.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index 2bdeac6a4a..b31dd1f5c9 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -2044,7 +2044,7 @@ function parseDocumentSource($source) { for ($i= 0; $i < $passes; $i++) { // get source length if this is the final pass if ($i == ($passes -1)) - $st= strlen($source); + $st= md5($source); if ($this->dumpSnippets == 1) { $this->snippetsCode .= "
    PARSE PASS " . ($i +1) . "

    The following snippets (if any) were parsed during this pass.

    "; } @@ -2067,9 +2067,8 @@ function parseDocumentSource($source) { $this->snippetsCode .= "

    "; } if ($i == ($passes -1) && $i < ($this->maxParserPasses - 1)) { - // check if source length was changed - $et= strlen($source); - if ($st != $et) + // check if source content was changed + if ($st != md5($source)) $passes++; // if content change then increase passes because } // we have not yet reached maxParserPasses } From a7c1eb8ecc9fb800bedcb43bf4d42866df4e5931 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Tue, 29 Aug 2017 21:56:03 +0900 Subject: [PATCH 330/338] Fix - $ditto_base directory separator char --- assets/snippets/ditto/snippet.ditto.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/snippets/ditto/snippet.ditto.php b/assets/snippets/ditto/snippet.ditto.php index 210c7849dc..b76b814ce7 100644 --- a/assets/snippets/ditto/snippet.ditto.php +++ b/assets/snippets/ditto/snippet.ditto.php @@ -26,7 +26,7 @@ // Ditto version being executed if(isset($ditto_base)) $ditto_base = $modx->config['base_path'].ltrim($ditto_base,'/'); -else $ditto_base = __DIR__ . '/'; +else $ditto_base = str_replace('\\','/',__DIR__) . '/'; /* Param: ditto_base From 3a941181f94709bc161aedbaa8b57201302ec9b7 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 30 Aug 2017 20:25:09 +0900 Subject: [PATCH 331/338] #188 Ditto in dashboard widget permission issue https://github.com/evolution-cms/evolution/issues/188 --- .../ditto/classes/ditto.class.inc.php | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index ed7755f3fa..92ee192bc6 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -770,7 +770,7 @@ function getChildIDs($IDs, $depth) { // Get documents and append TVs + Prefetch Data, and sort // --------------------------------------------------- - function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $deleted= 0, $public= 1, $where= '', $limit='',$randomize=0,$dateSource=false) { + function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $deleted= 0, $pubOnly= 1, $where= '', $limit='',$randomize=0,$dateSource=false) { global $modx; if (count($ids) == 0) return false; @@ -790,16 +790,18 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d $left_join_tvc = ''; } - if ($public) { + if ($pubOnly) { if($modx->isFrontend()) $access = 'sc.privateweb=0'; elseif($_SESSION['mgrRole']!=1) $access = 'sc.privatemgr=0'; else $access = ''; - // get document groups for current user - if ($docgrp= $modx->getUserDocGroups()) { - if($access) $access .= ' OR '; - $docgrp= join(',', $docgrp); - $access .= "dg.document_group IN ({$docgrp})"; - } + + if($access) { + $docgrp=$modx->getUserDocGroups(); + if($docgrp) { + $access .= sprintf(' OR dg.document_group IN (%s)', join(',', $docgrp)); + $access = "({$access})"; + } + } } $published = ($published) ? 'AND sc.published=1' : ''; @@ -809,10 +811,10 @@ function getDocuments($ids= array (), $fields, $TVs, $orderBy, $published= 1, $d $from[] = 'LEFT JOIN [+prefix+]document_groups dg on dg.document = sc.id'; $sqlWhere = array(); $sqlWhere[] = sprintf('sc.id IN (%s)', join(',', $ids)); - $sqlWhere[] =$published; - $sqlWhere[] ="AND sc.deleted='{$deleted}'"; + $sqlWhere[] = $published; + $sqlWhere[] = "AND sc.deleted='{$deleted}'"; $sqlWhere[] = $where; - if($public && $access) $sqlWhere[] = "AND ({$access})"; + if($pubOnly && $access) $sqlWhere[] = "AND {$access}"; $sqlWhere[] = 'GROUP BY sc.id'; $rs= $modx->db->select("DISTINCT {$fields}",$from,$sqlWhere,$sort,$limit); if(!$modx->db->getRecordCount($rs)) return false; @@ -863,14 +865,26 @@ function getDocumentsIDs($ids= array (), $published= 1) { if (count($ids) == 0) { return false; } else { - if ($docgrp= $modx->getUserDocGroups()) - $docgrp= join(',', $docgrp); + $ids = join(',',$ids); $from[] = '[+prefix+]site_content sc'; $from[] = 'LEFT JOIN [+prefix+]document_groups dg on dg.document=sc.id'; $published = $published ? 'AND sc.published=1' : ''; - $access = $modx->isFrontend() ? 'sc.privateweb=0' : sprintf("1='%s' OR sc.privatemgr=0", $_SESSION['mgrRole']); - if($docgrp) $access.= " OR dg.document_group IN ($docgrp)"; - $where = sprintf('(sc.id IN (%s) %s AND sc.deleted=0) AND (%s) GROUP BY sc.id', join(',',$ids), $published, $access); + if($modx->isFrontend()) $access = 'sc.privateweb=0'; + elseif($_SESSION['mgrRole']!=1) $access = 'sc.privatemgr=0'; + else $access = ''; + + if($access) { + $docgrp=$modx->getUserDocGroups(); + if($docgrp) { + $access .= sprintf(' OR dg.document_group IN (%s)', join(',', $docgrp)); + $access = "({$access})"; + } + $access = "AND {$access}"; + } + + if($published) $where = sprintf('(sc.id IN (%s) AND sc.published=1 AND sc.deleted=0) %s GROUP BY sc.id', $ids, $access); + else $where = sprintf('(sc.id IN (%s) AND sc.deleted=0) %s GROUP BY sc.id', $ids, $access); + $rs= $modx->db->select('DISTINCT sc.id', $from, $where); $docs = $modx->db->makeArray($rs); return $docs; From 43fc85b388a25a21c7632ea6170b18b523066fc8 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Wed, 30 Aug 2017 20:25:57 +0900 Subject: [PATCH 332/338] Code cleanup --- assets/snippets/ditto/snippet.ditto.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/snippets/ditto/snippet.ditto.php b/assets/snippets/ditto/snippet.ditto.php index b76b814ce7..47ad3f8be5 100644 --- a/assets/snippets/ditto/snippet.ditto.php +++ b/assets/snippets/ditto/snippet.ditto.php @@ -857,7 +857,7 @@ - - */ - $tplPaginatePrevious = isset($tplPaginatePrevious)? $ditto->template->fetch($tplPaginatePrevious) : "[+lang:previous+]"; + $tplPaginatePrevious = isset($tplPaginatePrevious)? $ditto->template->fetch($tplPaginatePrevious) : '[+lang:previous+]'; /* Param: tplPaginatePrevious @@ -877,7 +877,7 @@ - - */ - $tplPaginateNext = isset($tplPaginateNext)? $ditto->template->fetch($tplPaginateNext) : "[+lang:next+]"; + $tplPaginateNext = isset($tplPaginateNext)? $ditto->template->fetch($tplPaginateNext) : '[+lang:next+]'; /* Param: tplPaginateNext @@ -897,7 +897,7 @@ - - */ - $tplPaginateNextOff = isset($tplPaginateNextOff)? $ditto->template->fetch($tplPaginateNextOff) : "[+lang:next+]"; + $tplPaginateNextOff = isset($tplPaginateNextOff)? $ditto->template->fetch($tplPaginateNextOff) : '[+lang:next+]'; /* Param: tplPaginateNextOff @@ -916,7 +916,7 @@ - - */ - $tplPaginatePreviousOff = isset($tplPaginatePreviousOff)? $ditto->template->fetch($tplPaginatePreviousOff) : "[+lang:previous+]"; + $tplPaginatePreviousOff = isset($tplPaginatePreviousOff)? $ditto->template->fetch($tplPaginatePreviousOff) : '[+lang:previous+]'; /* Param: tplPaginatePreviousOff From 4b6c3946746af6aa42b4cefc1b9d60420c71e264 Mon Sep 17 00:00:00 2001 From: yamamoto Date: Thu, 31 Aug 2017 14:31:01 +0900 Subject: [PATCH 333/338] Fix - <@IF><@ELSEIF><@ELSE><@ENDIF> <@IF[*id:is(1)*]> start page <@ELSEIF[*id:is(2)*]> 2nd page <@ELSE> other page <@ENDIF> _parseCTagCMD('[*id:is(1)*]')): ?> start page _parseCTagCMD('[*id:is(2)*]')): ?> 2nd page other page --- .../includes/document.parser.class.inc.php | 168 ++++++++---------- 1 file changed, 78 insertions(+), 90 deletions(-) diff --git a/manager/includes/document.parser.class.inc.php b/manager/includes/document.parser.class.inc.php index b31dd1f5c9..8f00f0a074 100644 --- a/manager/includes/document.parser.class.inc.php +++ b/manager/includes/document.parser.class.inc.php @@ -1190,108 +1190,96 @@ function mergePlaceholderContent($content,$ph=false) { function mergeConditionalTagsContent($content, $iftag='<@IF:', $elseiftag='<@ELSEIF:', $elsetag='<@ELSE>', $endiftag='<@ENDIF>') { - if(strpos($content,'')!==false) $content = str_replace('', $elsetag, $content); - if(strpos($content,'')!==false) $content = str_replace('',$endiftag,$content); - if(strpos($content,'<@ENDIF-->')!==false) $content = str_replace('<@ENDIF-->',$endiftag,$content); - - $bt = md5($content); + $content = $this->_prepareCTag($content, $iftag, $elseiftag, $elsetag, $endiftag); + if(strpos($content,$iftag)===false) return $content; + + $sp = '#'.md5('ConditionalTags'.$_SERVER['REQUEST_TIME']).'#'; + $content = str_replace(array(''),array("{$sp}b","{$sp}e"),$content); - $_ = '#'.md5('ConditionalTags'.$_SERVER['REQUEST_TIME']).'#'; - $s = array('<@IF:' , '<@ELSEIF:', '<@ELSE>', '<@ENDIF>'); - $r = array("{$_}<@IF:", "{$_}<@ELSEIF:", "{$_}<@ELSE>", "{$_}<@ENDIF>"); - $content = str_replace($s, $r, $content); - $splits = explode($_, $content); - unset($_); - foreach($splits as $i=>$split) { + $pieces = explode('<@IF:', $content); + foreach($pieces as $i=>$split) { if($i===0) { $content = $split; - $excute = false; - $depth = 0; continue; } - - if (substr($split,0,5)==='<@IF:') $scope = '@IF'; - elseif(substr($split,0,9)==='<@ELSEIF:') $scope = '@ELSEIF'; - elseif(substr($split,0,6)==='<@ELSE') $scope = '@ELSE'; - elseif(substr($split,0,7)==='<@ENDIF') $scope = '@ENDIF'; - else exit('Unknown error '.__LINE__); - - if($scope==='@IF') $depth++; - if(1<$depth) { - if($scope==='@ENDIF') $depth--; - if($excute) $content .= $split; + list($cmd, $text) = explode('>', $split, 2); + $cmd = str_replace("'","\'",$cmd); + $content .= "_parseCTagCMD('" . $cmd . "')): ?>"; + $content .= $text; + } + $pieces = explode('<@ELSEIF:', $content); + foreach($pieces as $i=>$split) { + if($i===0) { + $content = $split; continue; } - if($scope==='@ENDIF') $depth--; - - if($scope==='@IF' || $scope==='@ELSEIF') { - if($excute) continue; - $_ = md5('@:>@'); - if(strpos($split,':>')!==false) $split = str_replace(':>', ':'.$_, $split); - list($cmd, $text) = explode('>', $split, 2); - $cmd = rtrim($cmd,'-'); - if(strpos($cmd,$_)!==false) $cmd = str_replace($_, '>', $cmd); - if(strpos($text,$_)!==false) $text = str_replace($_, '>', $text); - $cmd = substr($cmd,strpos($cmd,':')+1); - $cmd = trim($cmd); - $reverse = substr($cmd,0,1)==='!' ? true : false; - if($reverse) $cmd = ltrim($cmd,'!'); - - if(strpos($cmd,'[!')!==false) $cmd = str_replace(array('[!','!]'),array('[[',']]'),$cmd); - $safe=0; - $bt=md5(''); - $_ = $this->config['enable_filter']; - $this->config['enable_filter'] = 1; - while($bt!==md5($cmd)) { - $bt = md5($cmd); - if(strpos($cmd,'[*')!==false) $cmd= $this->mergeDocumentContent($cmd); - if(strpos($cmd,'[(')!==false) $cmd= $this->mergeSettingsContent($cmd); - if(strpos($cmd,'{{')!==false) $cmd= $this->mergeChunkContent($cmd); - if(strpos($cmd,'[[')!==false) $cmd= $this->evalSnippets($cmd); - if(strpos($cmd,'[+')!==false - &&strpos($cmd,'[[')===false) $cmd= $this->mergePlaceholderContent($cmd); - $safe++; - if(20<$safe) break; - } - $this->config['enable_filter'] = $_; - $cmd = ltrim($cmd); - $cmd = rtrim($cmd,'-'); - $cmd = trim($cmd); - $cmd = str_ireplace(array(' and ',' or '),array('&&','||'),$cmd); - - if($cmd!=='' && !preg_match('@^[0-9]*$@', $cmd) && preg_match('@^[0-9<= \-\+\*/\(\)%!&|]*$@', $cmd)) - $cmd = (int) eval("return {$cmd};"); - if($cmd < 0) $cmd = 0; - - if( (!$reverse && !empty($cmd)) || ($reverse && empty($cmd)) ) { - $content .= $text; - $excute = true; - } - else $excute = false; - } - elseif($scope==='@ELSE') { - if($excute) continue; - list(, $text) = explode('>', $split, 2); - $content .= $text; - $excute = true; - } - elseif($scope==='@ENDIF') { - list(, $text) = explode('>', $split, 2); - $content .= $text; - $excute = false; - } - } + list($cmd, $text) = explode('>', $split, 2); + $cmd = str_replace("'","\'",$cmd); + $content .= "_parseCTagCMD('" . $cmd . "')): ?>"; + $content .= $text; + } - if(strpos($content,$iftag) && $bt!==md5($content)) - $content = $this->mergeConditionalTagsContent($content, $iftag, $elseiftag, $elsetag, $endiftag); + $content = str_replace(array('<@ELSE>','<@ENDIF>'), array('',''), $content); + ob_start(); + $content = eval('?>'.$content); + $content = ob_get_clean(); + $content = str_replace(array("{$sp}b","{$sp}e"),array(''),$content); return $content; } + private function _prepareCTag($content, $iftag='<@IF:', $elseiftag='<@ELSEIF:', $elsetag='<@ELSE>', $endiftag='<@ENDIF>') { + if(strpos($content,'')!==false) $content = str_replace('', $elsetag, $content); // for jp + if(strpos($content,'')!==false) $content = str_replace('',$endiftag,$content); // for jp + if(strpos($content,'<@ENDIF-->')!==false) $content = str_replace('<@ENDIF-->',$endiftag,$content); + $tags = array($iftag, $elseiftag, $elsetag, $endiftag); + $content = str_ireplace($tags,$tags,$content); // Change to capital letters + return $content; + } + + private function _parseCTagCMD($cmd) { + $cmd = trim($cmd); + $reverse = substr($cmd,0,1)==='!' ? true : false; + if($reverse) $cmd = ltrim($cmd,'!'); + if(strpos($cmd,'[!')!==false) $cmd = str_replace(array('[!','!]'),array('[[',']]'),$cmd); + $safe=0; + $bt=''; + while($safe < 20) { + $bt = md5($cmd); + if(strpos($cmd,'[*')!==false) $cmd= $this->mergeDocumentContent($cmd); + if(strpos($cmd,'[(')!==false) $cmd= $this->mergeSettingsContent($cmd); + if(strpos($cmd,'{{')!==false) $cmd= $this->mergeChunkContent($cmd); + if(strpos($cmd,'[[')!==false) $cmd= $this->evalSnippets($cmd); + if(strpos($cmd,'[+')!==false + &&strpos($cmd,'[[')===false) $cmd= $this->mergePlaceholderContent($cmd); + if($bt===md5($cmd)) break; + $safe++; + } + $cmd = ltrim($cmd); + $cmd = rtrim($cmd,'-'); + $cmd = str_ireplace(array(' and ',' or '),array('&&','||'),$cmd); + + if(!preg_match('@^[0-9]*$@', $cmd) && preg_match('@^[0-9<= \-\+\*/\(\)%!&|]*$@', $cmd)) + $cmd = (int) eval("return {$cmd};"); + else { + $_ = explode(',', '[*,[(,{{,[[,[!,[+'); + foreach($_ as $left) { + if(strpos($cmd,$left)!==false) { + $cmd = 0; + break; + } + } + $cmd = (int) $cmd; + } + if($cmd < 0) $cmd = 0; + if($reverse) $cmd = !$cmd; + return $cmd; + } + /** * Remove Comment-Tags from output like */ From 6726580c2638f283d7e118c3bc4d6c503bef56ef Mon Sep 17 00:00:00 2001 From: Piotr Matysiak Date: Thu, 31 Aug 2017 12:13:32 +0200 Subject: [PATCH 334/338] ElementsInTree 1.5.8 Added option for showing EIT tabs only for administrators (user role 1) --- .../elementsintree/plugin.elementsintree.php | 58 +++++++++++-------- install/assets/plugins/ElementsInTree.tpl | 6 +- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/assets/plugins/elementsintree/plugin.elementsintree.php b/assets/plugins/elementsintree/plugin.elementsintree.php index 83c6dc0a06..ef716b4f41 100644 --- a/assets/plugins/elementsintree/plugin.elementsintree.php +++ b/assets/plugins/elementsintree/plugin.elementsintree.php @@ -8,39 +8,47 @@ if(!defined('MODX_BASE_PATH')) die('What are you doing? Get out of here!'); +$role = $_SESSION['mgrRole']; + +if ( $adminRoleOnly == 'yes' && $role != 1 ) { + return; +} + $eit_base_path = str_replace('\\','/',dirname(__FILE__)) . '/'; + include_once($eit_base_path.'includes/functions.inc.php'); global $_lang; + $e = &$modx->event; if(!isset($_SESSION['elementsInTree'])) $_SESSION['elementsInTree'] = array(); switch($e->name) { - case 'OnManagerMainFrameHeaderHTMLBlock': // Trigger reloading tree for relevant actions - include_once($eit_base_path.'includes/on_manager_main_frame_header_html_block.inc.php'); break; - case 'OnManagerTreePrerender': // Main elementsInTree-part - include_once($eit_base_path.'includes/on_manager_tree_prerender.inc.php'); break; - case 'OnManagerTreeRender': - if(hasAnyPermission()) include_once($eit_base_path.'includes/on_manager_tree_render.inc.php'); - else $e->output('
    '); // Issue 1340 - break; - case 'OnTempFormSave': - case 'OnTVFormSave': - case 'OnChunkFormSave': - case 'OnSnipFormSave': - case 'OnPluginFormSave': - case 'OnModFormSave': - case 'OnTempFormDelete': - case 'OnTVFormDelete': - case 'OnChunkFormDelete': - case 'OnSnipFormDelete': - case 'OnPluginFormDelete': - case 'OnModFormDelete': - // Set reloadTree = true for this events - $_SESSION['elementsInTree']['reloadTree'] = true; break; - default: - if($_GET['r'] == 2) $_SESSION['elementsInTree']['reloadTree'] = true; - return; + case 'OnManagerMainFrameHeaderHTMLBlock': // Trigger reloading tree for relevant actions + include_once($eit_base_path.'includes/on_manager_main_frame_header_html_block.inc.php'); break; + case 'OnManagerTreePrerender': // Main elementsInTree-part + include_once($eit_base_path.'includes/on_manager_tree_prerender.inc.php'); break; + case 'OnManagerTreeRender': + if(hasAnyPermission()) include_once($eit_base_path.'includes/on_manager_tree_render.inc.php'); + else $e->output(''); // Issue 1340 + break; + case 'OnTempFormSave': + case 'OnTVFormSave': + case 'OnChunkFormSave': + case 'OnSnipFormSave': + case 'OnPluginFormSave': + case 'OnModFormSave': + case 'OnTempFormDelete': + case 'OnTVFormDelete': + case 'OnChunkFormDelete': + case 'OnSnipFormDelete': + case 'OnPluginFormDelete': + case 'OnModFormDelete': + // Set reloadTree = true for this events + $_SESSION['elementsInTree']['reloadTree'] = true; break; + default: + if($_GET['r'] == 2) $_SESSION['elementsInTree']['reloadTree'] = true; + return; } return; \ No newline at end of file diff --git a/install/assets/plugins/ElementsInTree.tpl b/install/assets/plugins/ElementsInTree.tpl index 1f3f3ca223..0088ad8fe8 100644 --- a/install/assets/plugins/ElementsInTree.tpl +++ b/install/assets/plugins/ElementsInTree.tpl @@ -5,9 +5,9 @@ * Get access to all Elements and Modules inside Manager sidebar * * @category plugin - * @version 1.5.7 + * @version 1.5.8 * @license http://creativecommons.org/licenses/GPL/2.0/ GNU Public License (GPL v2) - * @internal @properties &tabTreeTitle=Tree Tab Title;text;Docs;;Custom title of Site Tree tab. &useIcons=Use icons in tabs;list;yes,no;yes;;Icons available in EVO version 1.2 or newer. &treeButtonsInTab=Tree Buttons in tab;list;yes,no;yes;;Move Tree Buttons into Site Tree tab. &unifyFrames=Unify Frames;list;yes,no;yes;;Unify Tree and Main frame style. + * @internal @properties &adminRoleOnly=Administrators only;list;yes,no;yes;;Show tabs only for users with administrator role. &treeButtonsInTab=Tree buttons in tab;list;yes,no;yes;;Move Tree buttons into Site Tree tab. &useIcons=Tab icons;list;yes,no;yes;;Use icons in tabs. &unifyFrames=Unify frames;list;yes,no;yes;;Unify style of Tree and Main frame style. &tabTreeTitle=Tree tab title;text;Site;;Custom title of Site Tree tab. * @internal @events OnManagerTreePrerender,OnManagerTreeRender,OnManagerMainFrameHeaderHTMLBlock,OnTempFormSave,OnTVFormSave,OnChunkFormSave,OnSnipFormSave,OnPluginFormSave,OnModFormSave,OnTempFormDelete,OnTVFormDelete,OnChunkFormDelete,OnSnipFormDelete,OnPluginFormDelete,OnModFormDelete * @internal @modx_category Manager and Admin * @internal @installset base @@ -20,7 +20,7 @@ * @author Nicola1971 https://github.com/Nicola1971 * @author Deesen https://github.com/Deesen * @author yama https://github.com/yama - * @lastupdate 27/12/2016 + * @lastupdate 31/08/2017 */ require MODX_BASE_PATH.'assets/plugins/elementsintree/plugin.elementsintree.php'; From f171c5239a813f6f4b487b9ec0bbecb2dcf43d54 Mon Sep 17 00:00:00 2001 From: Piotr Matysiak Date: Thu, 31 Aug 2017 15:00:14 +0200 Subject: [PATCH 335/338] ElementsInTree restyled for new theme --- manager/media/style/default/css/page.css | 29 ++++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/manager/media/style/default/css/page.css b/manager/media/style/default/css/page.css index dba31d8bb2..f52bb45785 100644 --- a/manager/media/style/default/css/page.css +++ b/manager/media/style/default/css/page.css @@ -46,25 +46,30 @@ to { transform: rotate(360deg) } .dark #mainloader { background-color: rgba(236, 240, 241, 0.64); } /* ElementsInTree */ .ElementsInTree #tree .treeframebody { background-color: #fafafa !important; border-right: 1px solid rgba(0, 0, 0, .1) } -.ElementsInTree #tree #treeHolder { height: 100%; max-height: 100%; overflow: hidden; padding: 10px } -.ElementsInTree #tree #tabDoc::before { display: none } -.ElementsInTree #tree .actionButtons--eit { top: 3.7rem; right: 1rem } +.ElementsInTree #tree #treeHolder { height: 100%; max-height: 100%; overflow: hidden; padding: 0 } +.ElementsInTree #tree .actionButtons--eit { top: 3.1rem; right: 1rem } .ElementsInTree #tree .actionButtons--eit li { float: left; margin: 0 0 0 5px !important; } .ElementsInTree #tree .actionButtons--eit li a { padding: 0.5rem; } -.ElementsInTree #tree .tab-page { padding: 0.8rem !important; } -.ElementsInTree #tree .tab-page .panel-group .panel, .ElementsInTree #tree #tabDoc.tab-page > div { max-height: calc(100vh - 11rem) !important; overflow: auto; } -.ElementsInTree #tree .tab-page .panel-group { overflow: visible !important; max-height: none !important; box-sizing: border-box !important } -.ElementsInTree #tree .tab-row { padding: 0; margin-bottom: -1px; } -.ElementsInTree #tree .tab-row .tab { height: 2rem; line-height: 2rem; } -.ElementsInTree #tree .tab-page { background-color: #fff; border: 1px solid #ddd; box-shadow: none } +.ElementsInTree #tree .tab-page { padding: 0.8rem 0 0.8rem 0.8rem !important; background-color: #fff; border: 1px solid #ddd; border-width: 1px 0; box-shadow: none; min-height: 55px; } +.ElementsInTree #tree .tab-page .panel-group .panel, .ElementsInTree #tree #tabDoc.tab-page > div { max-height: calc(100vh - 10rem) !important; overflow: auto; } +.ElementsInTree #tree .tab-page .panel-group { overflow: visible !important; max-height: none !important; box-sizing: border-box !important; padding-top: 5px; } +.ElementsInTree #tree .tab-row { padding: 0; margin-bottom: -1px; display: table; width: 100%; table-layout: fixed; border-top: 1px solid #ddd; } +.ElementsInTree #tree .tab-row .tab { height: 2rem; line-height: 2rem; background-color: transparent; border-color: #ddd; border-width: 0 1px 0 0; display: table-cell; text-align: center; vertical-align: middle; width: 100%; } +.ElementsInTree #tree .tab-row .tab:last-child { border-width: 0; } +.ElementsInTree #tree .tab-row .tab.selected { padding-bottom: 0; background-color: #fff; } .ElementsInTree #tree .form-control { padding: 0.25rem; font-size: 0.8rem; } .ElementsInTree #tree .eltree { line-height: 1.5 } .ElementsInTree #tree .eltree img { width: 0.8em; height: 0.8em } +.ElementsInTree #tree #tabDoc { padding-top: 7px !important; padding-left: 0 !important; padding-left: 0 !important; } +.ElementsInTree #tree #tabDoc::before { display: none } +.ElementsInTree #treeMenu.is-intab { margin-left: 0.1rem; } .ElementsInTree.treeframebody { -webkit-box-shadow: none; box-shadow: none } +.ElementsInTree .filterElements-form--eit { width: 200px !important; width: calc(100% - 85px) !important;} .dark.ElementsInTree #tree .treeframebody { background-color: #1d2023 !important; color: #828282 } -.dark.ElementsInTree #tree .tab-row .tab { color: #7b7b7b; } -.dark.ElementsInTree #tree .tab-row .tab.selected { background-color: #1d2023; border-color: rgba(255, 255, 255, .1); color: #bfbfbf; } -.dark.ElementsInTree #tree .tab-page { background-color: transparent; border-color: rgba(255, 255, 255, .1) } +.dark.ElementsInTree #tree .tab-row { border-top-color: #343739; } +.dark.ElementsInTree #tree .tab-row .tab { color: #7b7b7b; border-color: #343739; } +.dark.ElementsInTree #tree .tab-row .tab.selected { background-color: #24272A; border-color: #343739; color: #bfbfbf; } +.dark.ElementsInTree #tree .tab-page { background-color: #24272A; border-color: rgba(255, 255, 255, .1) } .dark.ElementsInTree #tree .form-control { background-color: rgba(0, 0, 0, 0.4); border-color: rgba(255, 255, 255, 0.09); color: #c7c7c7; } .dark.ElementsInTree #tree a { color: #b7b7b7 } .dark.ElementsInTree #tree .disabledPlugin a { color: #b68282 } From 16fe348150ac876c221d47275aa801b24cbe8d88 Mon Sep 17 00:00:00 2001 From: Piotr Matysiak Date: Thu, 31 Aug 2017 15:29:48 +0200 Subject: [PATCH 336/338] ElementsInTree clean up --- .../assets/css_treeButtonsInTab.tpl | 61 +- .../elementsintree/assets/css_unifyFrames.tpl | 29 +- .../elementsintree/assets/txt_content.tpl | 540 +++++++++++------- manager/media/style/default/css/page.css | 31 +- 4 files changed, 396 insertions(+), 265 deletions(-) diff --git a/assets/plugins/elementsintree/assets/css_treeButtonsInTab.tpl b/assets/plugins/elementsintree/assets/css_treeButtonsInTab.tpl index ed93d2ef25..47b661b93e 100644 --- a/assets/plugins/elementsintree/assets/css_treeButtonsInTab.tpl +++ b/assets/plugins/elementsintree/assets/css_treeButtonsInTab.tpl @@ -1,33 +1,34 @@ - /* Tree Buttons in Tab */ - #treeHolder { - padding-top: 10px; - padding-left: 10px; - } - - #treeMenu { - display: none; - margin-left: 0; - margin-bottom: 6px; - background-color: transparent !important; - border-bottom-width: 0; - } +/* Tree Buttons in Tab */ - #treeMenu.is-intab { - display: table; - } +#treeHolder { + padding-top: 10px; + padding-left: 10px; +} - .treeButton, - .treeButtonDisabled { - padding: 2px 3px; - } +#treeMenu { + display: none; + margin-left: 0; + margin-bottom: 6px; + background-color: transparent !important; + border-bottom-width: 0; +} - #tabDoc { - padding-top: 11px !important; - padding-left: 13px !important; - padding-right: 13px !important; - } - - #floater { - width: 99%; - top: 94px; - } +#treeMenu.is-intab { + display: table; +} + +.treeButton, +.treeButtonDisabled { + padding: 2px 3px; +} + +#tabDoc { + padding-top: 11px !important; + padding-left: 13px !important; + padding-right: 13px !important; +} + +#floater { + width: 99%; + top: 94px; +} diff --git a/assets/plugins/elementsintree/assets/css_unifyFrames.tpl b/assets/plugins/elementsintree/assets/css_unifyFrames.tpl index 387473829a..adbef0d032 100644 --- a/assets/plugins/elementsintree/assets/css_unifyFrames.tpl +++ b/assets/plugins/elementsintree/assets/css_unifyFrames.tpl @@ -1,16 +1,17 @@ - /* Unify Frames */ - body, - div.treeframebody { - background-color: #f2f2f2 !important; - } +/* Unify frames */ - div.treeframebody { - background-color: transparent !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; - } +body, +div.treeframebody { + background-color: #f2f2f2 !important; +} - #treeMenu { - background-color: transparent !important; - border-bottom-color: transparent !important; - } +div.treeframebody { + background-color: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +#treeMenu { + background-color: transparent !important; + border-bottom-color: transparent !important; +} diff --git a/assets/plugins/elementsintree/assets/txt_content.tpl b/assets/plugins/elementsintree/assets/txt_content.tpl index 9a98bce384..ae538aa72c 100644 --- a/assets/plugins/elementsintree/assets/txt_content.tpl +++ b/assets/plugins/elementsintree/assets/txt_content.tpl @@ -1,198 +1,356 @@ diff --git a/manager/media/style/default/css/page.css b/manager/media/style/default/css/page.css index f52bb45785..b96b002964 100644 --- a/manager/media/style/default/css/page.css +++ b/manager/media/style/default/css/page.css @@ -43,33 +43,4 @@ to { transform: rotate(360deg) } } /* dark */ .dark #main { background-color: #ecf0f1 } -.dark #mainloader { background-color: rgba(236, 240, 241, 0.64); } -/* ElementsInTree */ -.ElementsInTree #tree .treeframebody { background-color: #fafafa !important; border-right: 1px solid rgba(0, 0, 0, .1) } -.ElementsInTree #tree #treeHolder { height: 100%; max-height: 100%; overflow: hidden; padding: 0 } -.ElementsInTree #tree .actionButtons--eit { top: 3.1rem; right: 1rem } -.ElementsInTree #tree .actionButtons--eit li { float: left; margin: 0 0 0 5px !important; } -.ElementsInTree #tree .actionButtons--eit li a { padding: 0.5rem; } -.ElementsInTree #tree .tab-page { padding: 0.8rem 0 0.8rem 0.8rem !important; background-color: #fff; border: 1px solid #ddd; border-width: 1px 0; box-shadow: none; min-height: 55px; } -.ElementsInTree #tree .tab-page .panel-group .panel, .ElementsInTree #tree #tabDoc.tab-page > div { max-height: calc(100vh - 10rem) !important; overflow: auto; } -.ElementsInTree #tree .tab-page .panel-group { overflow: visible !important; max-height: none !important; box-sizing: border-box !important; padding-top: 5px; } -.ElementsInTree #tree .tab-row { padding: 0; margin-bottom: -1px; display: table; width: 100%; table-layout: fixed; border-top: 1px solid #ddd; } -.ElementsInTree #tree .tab-row .tab { height: 2rem; line-height: 2rem; background-color: transparent; border-color: #ddd; border-width: 0 1px 0 0; display: table-cell; text-align: center; vertical-align: middle; width: 100%; } -.ElementsInTree #tree .tab-row .tab:last-child { border-width: 0; } -.ElementsInTree #tree .tab-row .tab.selected { padding-bottom: 0; background-color: #fff; } -.ElementsInTree #tree .form-control { padding: 0.25rem; font-size: 0.8rem; } -.ElementsInTree #tree .eltree { line-height: 1.5 } -.ElementsInTree #tree .eltree img { width: 0.8em; height: 0.8em } -.ElementsInTree #tree #tabDoc { padding-top: 7px !important; padding-left: 0 !important; padding-left: 0 !important; } -.ElementsInTree #tree #tabDoc::before { display: none } -.ElementsInTree #treeMenu.is-intab { margin-left: 0.1rem; } -.ElementsInTree.treeframebody { -webkit-box-shadow: none; box-shadow: none } -.ElementsInTree .filterElements-form--eit { width: 200px !important; width: calc(100% - 85px) !important;} -.dark.ElementsInTree #tree .treeframebody { background-color: #1d2023 !important; color: #828282 } -.dark.ElementsInTree #tree .tab-row { border-top-color: #343739; } -.dark.ElementsInTree #tree .tab-row .tab { color: #7b7b7b; border-color: #343739; } -.dark.ElementsInTree #tree .tab-row .tab.selected { background-color: #24272A; border-color: #343739; color: #bfbfbf; } -.dark.ElementsInTree #tree .tab-page { background-color: #24272A; border-color: rgba(255, 255, 255, .1) } -.dark.ElementsInTree #tree .form-control { background-color: rgba(0, 0, 0, 0.4); border-color: rgba(255, 255, 255, 0.09); color: #c7c7c7; } -.dark.ElementsInTree #tree a { color: #b7b7b7 } -.dark.ElementsInTree #tree .disabledPlugin a { color: #b68282 } +.dark #mainloader { background-color: rgba(236, 240, 241, 0.64); } \ No newline at end of file From be94d6de406d7206d49ba91d3c01ef7e0dc25813 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 1 Sep 2017 14:12:24 +0300 Subject: [PATCH 337/338] fix php notice in Ditto --- assets/snippets/ditto/classes/ditto.class.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/snippets/ditto/classes/ditto.class.inc.php b/assets/snippets/ditto/classes/ditto.class.inc.php index 92ee192bc6..3c76a09061 100644 --- a/assets/snippets/ditto/classes/ditto.class.inc.php +++ b/assets/snippets/ditto/classes/ditto.class.inc.php @@ -734,6 +734,7 @@ function appendTV($tvname='',$docIDs){ } } } else { + $row['contentid'] = isset($row['contentid']) ? $row['contentid'] : ''; $defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'],$row['contentid']); foreach ($docIDs as $id) { if (!isset($docs["#".$id])) { From 7a382fcc171ceb79326987f704627da9a87623e5 Mon Sep 17 00:00:00 2001 From: dmi3yy Date: Fri, 1 Sep 2017 15:51:11 +0300 Subject: [PATCH 338/338] 1.3.5 --- assets/docs/changelog.txt | 31 +++++++++++++++++++ .../core/controller/site_content.php | 4 +-- install/assets/snippets/DLcrumbs.tpl | 6 ++-- .../actions/help/version_notices/1.3.5.php | 17 ++++++++++ manager/includes/version.inc.php | 4 +-- 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 manager/actions/help/version_notices/1.3.5.php diff --git a/assets/docs/changelog.txt b/assets/docs/changelog.txt index dfbe3601b2..92f019f78f 100644 --- a/assets/docs/changelog.txt +++ b/assets/docs/changelog.txt @@ -1,6 +1,37 @@ This file shows the changes in recent releases of Evolution CMS. The most current release is usually the development release, and is only shown to give an idea of what's currently in the pipeline. +Evolution CMS 1.3.5 (Sep 01, 2017) +* [GitHub:#be94d6de] - fix php notice in Ditto (dmi3yy) +* [GitHub:#16fe3481] - ElementsInTree clean up (Piotr Matysiak) +* [GitHub:#f171c523] - ElementsInTree restyled for new theme (Piotr Matysiak) +* [GitHub:#6726580c] - ElementsInTree 1.5.8 (Piotr Matysiak) +* [GitHub:#4b6c3946] - Fix - <@IF><@ELSEIF><@ELSE><@ENDIF> (yamamoto) +* [GitHub:#43fc85b3] - Code cleanup (yamamoto) +* [GitHub:#3a941181] - #188 Ditto in dashboard widget permission issue (yamamoto) +* [GitHub:#a7c1eb8e] - Fix - $ditto_base directory separator char (yamamoto) +* [GitHub:#bd785cf9] - Fix - $modx->parseDocumentSource() (yamamoto) +* [GitHub:#623be60e] - Code cleanup (yamamoto) +* [GitHub:#2c0ad143] - fix Ditto TV output (dmi3yy) +* [GitHub:#003c0be9] - Update document.parser.class.inc.php (Dreamer0x01) +* [GitHub:#6cc75b5e] - Fix Ditto when dateSource emply use createdon #190 (dmi3yy) +* [GitHub:#cd35be24] - fix tinymce params underfined bug on frontend (dmi3yy) +* [GitHub:#c0702676] - fix 65 Plugin parameters are lost after update to the new version (dmi3yy) +* [GitHub:#12c5c36f] - delete deprecated code (dmi3yy) +* [GitHub:#ac4c1d37] - Refactor (yamamoto) +* [GitHub:#82c8a6d8] - Remove - $ditto->renderQELinks() (yamamoto) +* [GitHub:#19cfd326] - #188 Ditto in dashboard widget permission issue (yamamoto) +* [GitHub:#1bac7219] - #190 Ditto does not recognize &dateSource parameter any more (yamamoto) +* [GitHub:#d3760b2f] - no need update.php in extras module (dmi3yy) +* [GitHub:#b8b75b24] - fix #192 (64j) +* [GitHub:#83535377] - fix variable documentDirty (64j) +* [GitHub:#3b70064c] - Update to Make sortable list more condensed (Piotr Matysiak) +* [GitHub:#ffe64306] - Make sortable list more condensed (Piotr Matysiak) +* [GitHub:#2c2fe39b] - #187 Ditto is missing placeholders when built-in filters are enabled (yamamoto) +* [GitHub:#7374ccf6] - fix eng translate (dmi3yy) +* [GitHub:#4903a8bd] - fix saved roles users #130 (Serg) + + Evolution CMS 1.3.4 (Aug 24, 2017) * [GitHub:#30e0efc9] - fix version (dmi3yy) * [GitHub:#d03412a7] - Updater one more check for use from manager only (dmi3yy) diff --git a/assets/snippets/DocLister/core/controller/site_content.php b/assets/snippets/DocLister/core/controller/site_content.php index 1e76d834a5..48f4db9f88 100644 --- a/assets/snippets/DocLister/core/controller/site_content.php +++ b/assets/snippets/DocLister/core/controller/site_content.php @@ -96,8 +96,6 @@ public function _render($tpl = '') $tpl = $this->getCFGDef('tpl', '@CODE:[+pagetitle+]
    '); } if ($tpl != '') { - $date = $this->getCFGDef('dateSource', 'pub_date'); - $this->toPlaceholders(count($this->_docs), 1, "display"); // [+display+] - сколько показано на странице. $i = 1; @@ -143,7 +141,7 @@ public function _render($tpl = '') $item['url'] = $this->modx->makeUrl($item['id'], '', '', $this->getCFGDef('urlScheme', '')); } } - + $date = $this->getCFGDef('dateSource', 'pub_date'); if (isset($item[$date])) { if (!$item[$date] && $date == 'pub_date' && isset($item['createdon'])) { $date = 'createdon'; diff --git a/install/assets/snippets/DLcrumbs.tpl b/install/assets/snippets/DLcrumbs.tpl index 1b817ba189..5ab3642a30 100644 --- a/install/assets/snippets/DLcrumbs.tpl +++ b/install/assets/snippets/DLcrumbs.tpl @@ -1,8 +1,8 @@ //INCLUDE_ORDERING_ERROR

    Please use the MODX Content Manager instead of accessing this file directly."); +?> +

    +
      +
    • ElementsInTree restyled for new theme, version 1.5.8 (Piotr Matysiak)
    • +
    • Fix - <@IF><@ELSEIF><@ELSE><@ENDIF> (yamamoto)
    • +
    • Fix Bugs in Ditto with date and placeholders from version 1.3.4 (yamamoto, Dmi3yy)
    • +
    • Fix tinymce params underfined bug on frontend (dmi3yy)
    • +
    • Fix 65 Plugin parameters are lost after update to the new version (dmi3yy)
    • +
    • no need update.php in extras module (dmi3yy)
    • +
    • Fix variable documentDirty (64j)
    • +
    • Make sortable list more condensed (Piotr Matysiak)
    • +
    • #187 Ditto is missing placeholders when built-in filters are enabled (yamamoto)
    • +
    • Fix saved roles users #130 (64j)
    • +
    • Fix #192 evo.checkConnectionToServer function (64j)
    • +
    diff --git a/manager/includes/version.inc.php b/manager/includes/version.inc.php index e9301eeb5d..f3f678117e 100755 --- a/manager/includes/version.inc.php +++ b/manager/includes/version.inc.php @@ -1,5 +1,5 @@