/** * mm_widget_template * @version 1.0 (2013-01-01) * * A template for creating new widgets * * @uses ManagerManager plugin 0.4. * * @link http:// * * @copyright 2013 */ function mm_widget_template($fields, $other_param = 'defaultValue', $roles = '', $templates = '') { global $modx, $mm_fields, $mm_current_page; $e =& $modx->event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { // Your output should be stored in a string, which is outputted at the end // It will be inserted as a Javascript block (with jQuery), which is executed on document ready // We always put a JS comment, which makes debugging much easier $output = "// -------------- mm_widget_template :: Begin ------------- \n"; // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); // You might want to check whether the current page's template uses the TVs that have been // supplied, to save processing page which don't contain them $count = tplUseTvs($mm_current_page['template'], $fields); if ($count == false) { return; } // We have functions to include JS or CSS external files you might need // The standard ModX API methods don't work here $output .= includeJs('assets/plugins/managermanager/widgets/template/javascript.js'); $output .= includeCss('assets/plugins/managermanager/widgets/template/styles.css'); // Do something for each of the fields supplied foreach ($fields as $targetTv) { // If it's a TV, we may need to map the field name, to what it's ID is. // This can be obtained from the mm_fields array $tv_id = $mm_fields[$targetTv]['fieldname']; } //JS comment for end of widget $output .= "// -------------- mm_widget_template :: End ------------- \n"; // Send the output to the browser $e->output($output . "\n"); } }
/** * mm_widget_colors * @version 1.1 (2012-11-13) * * Adds a color selection widget to the specified TVs. * * @uses ManagerManager plugin 0.4. * * @link http://code.divandesign.biz/modx/mm_widget_colors/1.1 * * @copyright 2012 */ function mm_widget_colors($fields, $default = '#ffffff', $roles = '', $templates = '') { global $modx, $mm_fields, $mm_current_page; $e =& $modx->event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $output = ''; // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } // Does this page's template use any of these TVs? If not, quit. $tv_count = tplUseTvs($mm_current_page['template'], $fields); if ($tv_count === false) { return; } // Insert some JS $output .= includeJs($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/colors/farbtastic.js'); // Insert some CSS $output .= includeCss($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/colors/farbtastic.css'); // Go through each of the fields supplied foreach ($fields as $tv) { $tv_id = $mm_fields[$tv]['fieldname']; $output .= ' // ----------- Color widget for ' . $tv_id . ' -------------- $j("#' . $tv_id . '").css("background-image","none"); $j("#' . $tv_id . '").after(\'<div id="colorpicker' . $tv_id . '"></div>\'); if ($j("#' . $tv_id . '").val() == ""){ $j("#' . $tv_id . '").val("' . $default . '"); } $j("#colorpicker' . $tv_id . '").farbtastic("#' . $tv_id . '"); $j("#colorpicker' . $tv_id . '").mouseup(function(){ // mark the document as dirty, or the value wont be saved $j("#' . $tv_id . '").trigger("change"); }); '; } $e->output($output . "\n"); } }
/** * mm_widget_colors * @version 1.2 (2013-12-11) * * A widget for ManagerManager plugin that allows text field to be turned into a color picker storing a chosen hex value in the field on the document editing page. * * @uses ManagerManager plugin 0.6. * * @param $fields {comma separated string} - The name(s) of the template variables this should apply to. @required * @param $default {string} - Which color in hex format should be selected by default in new documents. This is only used in situations where the TV does not have a default value specified in the TV definition. Default: '#ffffff'. * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Id of the templates to which this widget is applied (when this parameter is empty then widget is applied to the all templates). Default: ''. * * @event OnDocFormPrerender * @event OnDocFormRender * * @link http://code.divandesign.biz/modx/mm_widget_colors/1.2 * * @copyright 2013 */ function mm_widget_colors($fields, $default = '#ffffff', $roles = '', $templates = '') { if (!useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; $output = ''; if ($e->name == 'OnDocFormPrerender') { $output .= includeJsCss($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/colors/farbtastic.js', 'html', 'farbtastic', '1.2'); $output .= includeJsCss($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/colors/farbtastic.css', 'html'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page, $mm_fields; // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); // Does this page's template use any of these TVs? If not, quit. $tv_count = tplUseTvs($mm_current_page['template'], $fields); if ($tv_count === false) { return; } $output .= "//---------- mm_widget_colors :: Begin -----\n"; // Go through each of the fields supplied foreach ($fields as $tv) { $tv_id = $mm_fields[$tv]['fieldname']; $output .= ' $j("#' . $tv_id . '").css("background-image","none"); $j("#' . $tv_id . '").after(\'<div id="colorpicker' . $tv_id . '"></div>\'); if ($j("#' . $tv_id . '").val() == ""){ $j("#' . $tv_id . '").val("' . $default . '"); } $j("#colorpicker' . $tv_id . '").farbtastic("#' . $tv_id . '"); $j("#colorpicker' . $tv_id . '").mouseup(function(){ // mark the document as dirty, or the value wont be saved $j("#' . $tv_id . '").trigger("change"); }); '; } $output .= "//---------- mm_widget_colors :: End -----\n"; $e->output($output); } } }
/** * mm_ddYMap * @version 1.4.3 (2013-12-10) * * @desc A widget for ManagerManager plugin allowing Yandex Maps integration. * * @uses ManagerManager plugin 0.6. * * @param $tvs {comma separated string} - TV names to which the widget is applied. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Id of the templates to which this widget is applied (when this parameter is empty then widget is applied to the all templates). Default: ''. * @param $w {'auto'; integer} - Width of the map container. Default: 'auto'. * @param $h {integer} - Height of the map container. Default: 400. * @param $hideField {boolean} - Original coordinates field hiding status (true — hide, false — show). Default: true. * * @event OnDocFormPrerender * @event OnDocFormRender * * @link http://code.divandesign.biz/modx/mm_ddymap/1.4.3 * * @copyright 2013, DivanDesign * http://www.DivanDesign.biz */ function mm_ddYMap($tvs, $roles = '', $templates = '', $w = 'auto', $h = '400', $hideField = true) { if (!useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; if ($e->name == 'OnDocFormPrerender') { //The main js file including $output = includeJsCss($modx->config['site_url'] . 'assets/plugins/managermanager/widgets/ddymap/jquery.ddMM.mm_ddYMap.js', 'html', 'jquery.ddMM.mm_ddYMap', '1.0.2'); //The Yandex.Maps library including $output .= includeJsCss('http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU&onload=mm_ddYMap_init', 'html', 'api-maps.yandex.ru', '2.0'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page; $output = ''; //if we've been supplied with a string, convert it into an array $tvs = makeArray($tvs); $usedTvs = tplUseTvs($mm_current_page['template'], $tvs, '', 'id', 'name'); if ($usedTvs == false) { return; } $output .= "//---------- mm_ddYMap :: Begin -----\n"; //Iterate over supplied TVs instead of doing so to the result of tplUseTvs() to maintain rendering order. foreach ($tvs as $tv) { //If this $tv is used in a current template if (isset($usedTvs[$tv])) { $output .= ' $j("#tv' . $usedTvs[$tv]['id'] . '").mm_ddYMap({ hideField: ' . intval($hideField) . ', width: "' . $w . '", height: "' . $h . '" }); '; } } $output .= "//---------- mm_ddYMap :: End -----\n"; $e->output($output); } } }
/** * mm_ddGMap * @version 1.2b (2014-05-14) * * @desc Widget for ManagerManager plugin allowing Google Maps integration. * * @uses ManagerManager plugin 0.6.1. * * @param $tvs {comma separated string} - TV names to which the widget is applied. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Id of the templates to which this widget is applied (when this parameter is empty then widget is applied to the all templates). Default: ''. * @param $w {'auto'; integer} - Width of the map container. Default: 'auto'. * @param $h {integer} - Height of the map container. Default: 400. * @param $hideField {0; 1} - Original coordinates field hiding status (1 — hide, 0 — show). Default: 1. * * @link http://code.divandesign.biz/modx/mm_ddgmap/1.2b * * @copyright 2014, DivanDesign * http://www.DivanDesign.biz */ function mm_ddGMap($tvs, $roles = '', $templates = '', $w = 'auto', $h = '400', $hideField = true) { if (!useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; if ($e->name == 'OnDocFormPrerender') { global $modx_lang_attribute; //The main js file including $output = includeJsCss($modx->config['site_url'] . 'assets/plugins/managermanager/widgets/ddgmap/jquery.ddMM.mm_ddGMap.js', 'html', 'jquery.ddMM.mm_ddGMap', '1.0'); //The Google.Maps library including $output .= includeJsCss('http://maps.google.com/maps/api/js?sensor=false&hl=' . $modx_lang_attribute . '&callback=mm_ddGMap_init', 'html', 'maps.google.com', '0'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page; $output = ''; $tvs = makeArray($tvs); $usedTvs = tplUseTvs($mm_current_page['template'], $tvs, '', 'id', 'name'); if ($usedTvs == false) { return; } $output .= "//---------- mm_ddGMap :: Begin -----\n"; //Iterate over supplied TVs instead of doing so to the result of tplUseTvs() to maintain rendering order. foreach ($tvs as $tv) { //If this $tv is used in a current template if (isset($usedTvs[$tv])) { $output .= ' $j("#tv' . $usedTvs[$tv]['id'] . '").mm_ddGMap({ hideField: ' . intval($hideField) . ', width: "' . $w . '", height: "' . $h . '" }); '; } } $output .= "//---------- mm_ddGMap :: End -----\n"; $e->output($output); } } }
function mm_widget_template($fields, $other_param = 'defaultValue', $roles = '', $templates = '') { global $modx, $content, $mm_fields; $e =& $modx->Event; if (useThisRule($roles, $templates)) { // Your output should be stored in a string, which is outputted at the end // It will be inserted as a Javascript block (with jQuery), which is executed on document ready $output = ''; // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); // You might want to check whether the current page's template uses the TVs that have been // supplied, to save processing page which don't contain them // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } $count = tplUseTvs($content['template'], $fields); if ($count == false) { return; } // We always put a JS comment, which makes debugging much easier $output .= "// -------------- Widget name ------------- \n"; // We have functions to include JS or CSS external files you might need // The standard ModX API methods don't work here $output .= includeJs('/assets/plugins/managermanager/widgets/template/javascript.js'); $output .= includeCss('/assets/plugins/managermanager/widgets/template/styles.css'); // Do something for each of the fields supplied foreach ($fields as $targetTv) { // If it's a TV, we may need to map the field name, to what it's ID is. // This can be obtained from the mm_fields array $tv_id = $mm_fields[$targetTv]['fieldname']; } } // end if $e->output($output . "\n"); // Send the output to the browser }
function mm_widget_googlemap($fields, $googleApiKey = '', $default = '', $roles = '', $templates = '') { global $modx, $mm_fields, $mm_current_page, $modx_lang_attribute; $e =& $modx->event; if (useThisRule($roles, $templates)) { $output = ''; $fields = makeArray($fields); $count = tplUseTvs($mm_current_page['template'], $fields); if ($count == false) { return; } $output .= "// -------------- googlemap widget ------------- \n"; $output .= includeJs($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/googlemap/googlemap.js'); $output .= includeJs("http://maps.google.com/maps?file=api&sensor=false&key={$googleApiKey}&async=2&hl={$modx_lang_attribute}"); foreach ($fields as $targetTv) { $tv_id = $mm_fields[$targetTv]['fieldname']; $output .= "googlemap('{$tv_id}','{$default}');"; } $e->output($output . "\n"); // Send the output to the browser } }
/** * mm_ddNumericFields * @version 1.1.1 (2013-12-11) * * A widget for ManagerManager plugin denying using any chars in TV fields but numeric. * * @uses ManagerManager plugin 0.6. * * @param $tvs {comma separated string} - TV names to which the widget is applied. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Id of the templates to which this widget is applied. Default: ''. * @param $allowFloat {0; 1} - Float number availability status (1 — float numbers may be used, 0 — float numbers using is not available). Default: 1. * @param $decimals {integer} - Number of chars standing after comma (0 — any). Default: 0. * * @link http://code.divandesign.biz/modx/mm_ddnumericfields/1.1.1 * * @copyright 2013, DivanDesign * http://www.DivanDesign.biz */ function mm_ddNumericFields($tvs = '', $roles = '', $templates = '', $allowFloat = 1, $decimals = 0) { global $modx, $mm_current_page; $e =& $modx->Event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $tvs = tplUseTvs($mm_current_page['template'], $tvs); if ($tvs == false) { return; } $output = ''; $output .= "//---------- mm_ddNumericFields :: Begin -----\n"; foreach ($tvs as $tv) { $output .= ' $j("#tv' . $tv['id'] . '").ddNumeric({ allowFloat: ' . intval($allowFloat) . ', decimals: ' . intval($decimals) . ' }); '; } $output .= "//---------- mm_ddNumericFields :: End -----\n"; $e->output($output); } }
/** * mm_widget_showimagetvs * @version 1.2.1 (2014-05-07) * * @desc A widget for ManagerManager plugin that allows the preview of images chosen in image TVs to be shown on the document editing page. * Emulates showimagestv plugin, which is not compatible with ManagerManager. * * @uses ManagerManager plugin 0.6.1. * * @param $tvs {comma separated string} - The name(s) of the template variables this should apply to. Default: ''. * @param $maxWidth {integer} - Preferred maximum width of the preview. Default: 300. * @param $maxHeight {integer} - Preferred maximum height of the preview. Default: 100. * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Id of the templates to which this widget is applied (when this parameter is empty then widget is applied to the all templates). Default: ''. * * @link http://code.divandesign.biz/modx/mm_widget_showimagetvs/1.2.1 * * @copyright 2014 */ function mm_widget_showimagetvs($tvs = '', $maxWidth = 300, $maxHeight = 100, $thumbnailerUrl = '', $roles = '', $templates = '') { if (!useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; if ($e->name == 'OnDocFormPrerender') { //The main js file including $output = includeJsCss($modx->config['site_url'] . 'assets/plugins/managermanager/widgets/showimagetvs/jquery.ddMM.mm_widget_showimagetvs.js', 'html', 'jquery.ddMM.mm_widget_showimagetvs', '1.0.1'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page; $output = ''; // Does this page's template use any image TVs? If not, quit now! $tvs = tplUseTvs($mm_current_page['template'], $tvs, 'image'); if ($tvs == false) { return; } $output .= "//---------- mm_widget_showimagetvs :: Begin -----\n"; // Go through each TV foreach ($tvs as $tv) { $output .= ' $j("#tv' . $tv['id'] . '").mm_widget_showimagetvs({ thumbnailerUrl: "' . trim($thumbnailerUrl) . '", width: ' . intval($maxWidth) . ', height: ' . intval($maxHeight) . ', }); '; } $output .= "//---------- mm_widget_showimagetvs :: End -----\n"; $e->output($output); } } }
/** * mm_ddGMap * @version 1.1.1 (2012-11-13) * * Позволяет интегрировать карту Google Maps для получения координат. * * @uses ManagerManager plugin 0.4. * * @param $tvs {string; comma separated string} - Имя TV, для которой необходимо применить виджет. * @param $roles {string; comma separated string} - Роли, для которых необходимо применить виждет, пустое значение — все роли. По умолчанию: ''. * @param $templates {string; comma separated string} - Шаблоны, для которых необходимо применить виджет, пустое значение — все шаблоны. По умолчанию: ''. * @param $w {string; integer} - Ширина контейнера с картой. По умолчанию: 'auto'. * @param $h {integer} - Высота контейнера с картой. По умолчанию: 400. * @param $hideField {boolean} - Необходимо ли скрывать оригинальное текстовое поле с координатами. По умолчанию: true. * * @link http://code.divandesign.biz/modx/mm_ddgmap/1.1.1 * * @copyright 2012, DivanDesign * http://www.DivanDesign.biz */ function mm_ddGMap($tvs, $roles = '', $templates = '', $w = 'auto', $h = '400', $hideField = true) { global $modx, $content, $mm_fields, $modx_lang_attribute; $e =& $modx->Event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $output = ''; // if we've been supplied with a string, convert it into an array $tvs = makeArray($tvs); // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } $tvs = tplUseTvs($page_template, $tvs); if ($tvs == false) { return; } $style = 'width: ' . $w . 'px; height: ' . $h . 'px; position: relative; border: 1px solid #c3c3c3;'; // We always put a JS comment, which makes debugging much easier $output .= "// -------------- mm_ddGMap :: Begin ------------- \n"; // Do something for each of the fields supplied foreach ($tvs as $tv) { // If it's a TV, we may need to map the field name, to what it's ID is. // This can be obtained from the mm_fields array $tv_id = 'tv' . $tv['id']; $output .= ' //TV с координатами var coordFieldId = "' . $tv_id . '", $coordinatesField = $j("#" + coordFieldId); //Координаты var ddLatLng = $coordinatesField.val(); //Родитель var $coordFieldParent = $coordinatesField.parents("tr:first"); //Запоминаем название поля var sectionName = $coordFieldParent.find(".warning").text(); //Скрываем родителя и разделитель $coordFieldParent.hide().prev("tr").hide(); //Контейнер для карты var $sectionConteiner = $j("<div class=\\"sectionHeader\\">" + sectionName + "</div><div class=\\"sectionBody tmplvars\\"><div class=\\"ddGMap" + coordFieldId + "\\" style=\\"' . $style . '\\"></div></div>"); //Добавляем контейнер $coordinatesField.parents(".tab-page:first").append($sectionConteiner); //Если скрывать не надо, засовываем перед картой if (!' . intval($hideField) . '){ $coordinatesField.insertBefore(".ddGMap" + coordFieldId); } //Если координаты не заданны, то задаём дефолт if(ddLatLng == "") ddLatLng = "55.19396010947335,61.3670539855957"; ddLatLng = ddLatLng.split(","); //Callback функция для GM window.ddgminitialize = function(){ var GM = google.maps; var myOptions = { zoom: 15, center: new GM.LatLng(ddLatLng[0],ddLatLng[1]), mapTypeId: GM.MapTypeId.ROADMAP, streetViewControl: false, scrollwheel: false }; var map = new GM.Map($sectionConteiner.find(".ddGMap" + coordFieldId).get(0), myOptions); //Добавляем маркер на карту var GMMarker = new GM.Marker({ position: new GM.LatLng(ddLatLng[0],ddLatLng[1]), map: map, draggable: true }); //При перетаскивании маркера GM.event.addListener(GMMarker, "drag", function(event){ var position = event.latLng;//Координаты $coordinatesField.val(position.lat() + "," + position.lng());//Сохраняем значение в поле }); //При клике на карте GM.event.addListener(map, "click", function(event){ var position = event.latLng;//Новые координаты GMMarker.setPosition(position);//Меняем позицию маркера map.setCenter(position);//Центрируем карту на маркере $coordinatesField.val(position.lat() + "," + position.lng());//Сохраняем значение в поле }); }; //Подключаем карту, вызываем callback функцию $j(window).on("load.ddEvents", function(){ $j("body").append("<script type=\\"text/javascript\\" src=\\"http://maps.google.com/maps/api/js?sensor=false&hl=' . $modx_lang_attribute . '&callback=ddgminitialize\\">"); }); '; } $output .= "// -------------- mm_ddGMap :: End ------------- \n"; $e->output($output . "\n"); } }
/** * mm_ddSelectDocuments * @version 1.2.2 (2014-02-14) * * @desc A widget for ManagerManager that makes selection of documents ids easier. * * @uses ManagerManager 0.6. * @uses ddTools 0.10. * * @param $tvs {comma separated string} - TVs names that the widget is applied to. @required * @param $roles {comma separated string} - Roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Templates IDs for which the widget is applying (empty value means the widget is applying to all templates). Default: ''. * @param $parentIds {comma separated string} - Parent documents IDs. @required * @param $depth {integer} - Depth of search. Default: 1. * @param $filter {separated string} - Filter clauses, separated by '&' between pairs and by '=' between keys and values. For example, 'template=15&published=1' means to choose the published documents with template id=15. Default: ''. * @param $max {integer} - The largest number of elements that can be selected by user (“0” means selection without a limit). Default: 0. * @param $labelMask {string} - Template to be used while rendering elements of the document selection list. It is set as a string containing placeholders for document fields and TVs. Also, there is the additional placeholder “[+title+]” that is substituted with either “menutitle” (if defined) or “pagetitle”. Default: '[+title+] ([+id+])'. * * @event OnDocFormPrerender * @event OnDocFormRender * * @link http://code.divandesign.biz/modx/mm_ddselectdocuments/1.2.2 * * @copyright 2014, DivanDesign * http://www.DivanDesign.biz */ function mm_ddSelectDocuments($tvs = '', $roles = '', $templates = '', $parentIds, $depth = 1, $filter = '', $max = 0, $labelMask = '[+title+] ([+id+])') { if (empty($parentIds) || !useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; $output = ''; if ($e->name == 'OnDocFormPrerender') { $pluginDir = $modx->config['site_url'] . 'assets/plugins/managermanager/'; $widgetDir = $pluginDir . 'widgets/ddselectdocuments/'; $output .= includeJsCss($widgetDir . 'ddselectdocuments.css', 'html'); $output .= includeJsCss($pluginDir . 'js/jquery-ui-1.10.3.min.js', 'html', 'jquery-ui', '1.10.3'); $output .= includeJsCss($widgetDir . 'jquery.ddMultipleInput-1.2.1.min.js', 'html', 'jquery.ddMultipleInput', '1.2.1'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page; $tvs = tplUseTvs($mm_current_page['template'], $tvs); if ($tvs == false) { return; } $filter = ddTools::explodeAssoc($filter, '&', '='); //Необходимые поля preg_match_all('~\\[\\+([^\\+\\]]*?)\\+\\]~', $labelMask, $matchField); $fields = array_unique(array_merge(array_keys($filter), array('pagetitle', 'id'), $matchField[1])); if (($title_pos = array_search('title', $fields)) !== false) { unset($fields[$title_pos]); $fields = array_unique(array_merge($fields, array('menutitle'))); } //Рекурсивно получает все необходимые документы if (!function_exists('ddGetDocs')) { function ddGetDocs($parentIds = array(0), $filter = array(), $depth = 1, $labelMask = '[+pagetitle+] ([+id+])', $fields = array('pagetitle', 'id')) { //Получаем дочерние документы текущего уровня $docs = array(); //Перебираем всех родителей foreach ($parentIds as $parent) { //Получаем документы текущего родителя $tekDocs = ddTools::getDocumentChildrenTVarOutput($parent, $fields, false); //Если что-то получили if (is_array($tekDocs)) { //Запомним $docs = array_merge($docs, $tekDocs); } } $result = array(); //Если что-то есть if (count($docs) > 0) { //Перебираем полученные документы foreach ($docs as $val) { //Если фильтр пустой, либо не пустой и документ удовлетворяет всем условиям if (empty($filter) || count(array_intersect_assoc($filter, $val)) == count($filter)) { $val['title'] = empty($val['menutitle']) ? $val['pagetitle'] : $val['menutitle']; //Записываем результат $tmp = ddTools::parseText($labelMask, $val, '[+', '+]', false); if (strlen(trim($tmp)) == 0) { $tmp = ddTools::parseText('[+pagetitle+] ([+id+])', $val, '[+', '+]', false); } $result[] = array('label' => $tmp, 'value' => $val['id']); } //Если ещё надо двигаться глубже if ($depth > 1) { //Сливаем результат с дочерними документами $result = array_merge($result, ddGetDocs(array($val['id']), $filter, $depth - 1, $labelMask, $fields)); } } } return $result; } } //Получаем все дочерние документы $docs = ddGetDocs(explode(',', $parentIds), $filter, $depth, $labelMask, $fields); if (count($docs) == 0) { return; } if (version_compare(PHP_VERSION, '5.4.0') >= 0) { $jsonDocs = json_encode($docs, JSON_UNESCAPED_UNICODE); } else { $jsonDocs = preg_replace_callback('/\\\\u([0-9a-f]{4})/i', create_function('$matches', '$sym = mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UTF-16"); return $sym;'), json_encode($docs)); } $output .= "//---------- mm_ddSelectDocuments :: Begin -----\n"; foreach ($tvs as $tv) { $output .= ' $j("#tv' . $tv['id'] . '").ddMultipleInput({source: ' . $jsonDocs . ', max: ' . $max . '}); '; } $output .= "//---------- mm_ddSelectDocuments :: End -----\n"; $e->output($output); } } }
/** * mm_ddReadonly * @version 1.0.1 (2013-07-13) * * @desc Makes fields only readable. * * @uses ManagerManager plugin 0.5.1. * * @param $fields {comma separated string} - The name(s) of the document fields (or TVs) for which the widget is applying. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Templates IDs for which the widget is applying (empty value means the widget is applying to all templates). Default: ''. * * @link http://code.divandesign.biz/modx/mm_ddreadonly/1.0.1 * * @copyright 2013, DivanDesign * http://www.DivanDesign.biz */ function mm_ddReadonly($fields = '', $roles = '', $templates = '') { global $modx, $mm_fields, $mm_current_page; $e =& $modx->Event; if (!useThisRule($roles, $templates)) { return; } //Перед сохранением документа if ($e->name == 'OnBeforeDocFormSave') { //Если создаётся новый документ, у него нет никакого id ещё, да и нам пофиг, т.к. никто ничего с ним всё равно не мог сделать до сохранения if ($e->params['mode'] == 'new') { return; } //ID документа $docId = $e->params['id']; //Если нужная переменная в сессии не определена, определим if (!is_array($_SESSION['mm_ddReadonly'])) { $_SESSION['mm_ddReadonly'] = array(); } //Разбиваем переданные поля в массивчик $fields = makeArray($fields); //Получаем id TV. TODO: Оптимизировать, чтобы всё было в один запрос $tvs = tplUseTvs($mm_current_page['template'], $fields, '', 'id,name'); //Результат $resultFields = array(); //Если что-то оплучили if (is_array($tvs) && count($tvs) > 0) { $tvsNames = array(); //Пробежимся, переделаем под удобный нам формат foreach ($tvs as $val) { $tvsNames[$val['id']] = $val['name']; } //Получаем значения TV $tvs = $modx->db->makeArray($modx->db->select('value,tmplvarid AS id', ddTools::$tables['site_tmplvar_contentvalues'], 'contentid=' . $docId . ' AND tmplvarid IN ' . makeSqlList(array_keys($tvsNames)))); //Если что-то нашлось if (count($tvs) > 0) { //Пробежимся foreach ($tvs as $val) { //Если значение не пустое if ($val['value'] != '') { //Запишем значения $resultFields[$tvsNames[$val['id']]] = $val['value']; } } } } //Перебираем поля foreach ($fields as $key => $val) { //Если такого поля нет или это TV if (!isset($mm_fields[$val]) || $mm_fields[$val]['tv'] == 1) { //Снесём unset($fields[$key]); } } if (count($fields) > 0) { //Получаем значения необходимых полей $fields = $modx->db->getRow($modx->db->select(implode(',', $fields), ddTools::$tables['site_content'], 'id=' . $docId)); //Переберём foreach ($fields as $key => $val) { if ($val != '') { $resultFields[$key] = $val; } } } //Если хоть что-то осталось if (count($resultFields) > 0) { //Сохраним значения в сессию, они нам ещё понадобятся $_SESSION['mm_ddReadonly'][$docId] = $resultFields; } //После сохранения документа } else { if ($e->name == 'OnDocFormSave') { //Если создаётся новый документ, у него нет никакого id ещё, да и нам пофиг, т.к. никто ничего с ним всё равно не мог сделать до сохранения if ($e->params['mode'] == 'new') { return; } //ID документа $docId = $e->params['id']; //Если данные о текущем документе есть if (is_array($_SESSION['mm_ddReadonly']) && is_array($_SESSION['mm_ddReadonly'][$docId]) && count($_SESSION['mm_ddReadonly'][$docId]) > 0) { //Обновляем данные документа в соответствии с тем, что было раньше ddTools::updateDocument($docId, $_SESSION['mm_ddReadonly'][$docId]); //Сносим за ненадобностью unset($_SESSION['mm_ddReadonly'][$docId]); } //При копировании документа } else { if ($e->name == 'OnDocDuplicate') { //Получаем id TV $tvs = tplUseTvs($mm_current_page['template'], $fields); //Если что-то оплучили if (is_array($tvs) && count($tvs) > 0) { $tvIds = array(); foreach ($tvs as $val) { $tvIds[] = $val['id']; } //Удаляем значение TV для данного документа $modx->db->delete(ddTools::$tables['site_tmplvar_contentvalues'], '`contentid` = ' . $e->params['new_id'] . ' AND `tmplvarid` IN(' . implode(',', $tvIds) . ')'); } //При рендере документа } else { if ($e->name == 'OnDocFormRender') { //Разбиваем переданные поля в массивчик $fields = makeArray($fields); //Если есть что-то if (count($fields) > 0) { $output = "// ---------------- mm_ddReadonly :: Begin ------------- \n"; $output .= 'var $mm_ddReadonly;'; //Получаем id TV $tvs = tplUseTvs($mm_current_page['template'], $fields); //Если что-то есть if (is_array($tvs) && count($tvs) > 0) { //Перебираем TV foreach ($tvs as $val) { //Вставляем значение перед оригиналом и сносим оригинал нафиг $output .= ' $mm_ddReadonly = $j("#tv' . $val['id'] . '"); $mm_ddReadonly.before($mm_ddReadonly.val()).hide(); '; } } if (count($fields) != count($tvs)) { //Перебираем поля foreach ($fields as $val) { //Если такое поле есть и это не TV if (isset($mm_fields[$val]) && $mm_fields[$val]['tv'] != 1) { $output .= ' $mm_ddReadonly = $j("' . $mm_fields[$val]['fieldtype'] . '[name=\\"' . $mm_fields[$val]['fieldname'] . '\\"]"); $mm_ddReadonly.before($mm_ddReadonly.val()).hide(); '; } } } $output .= "\n// ---------------- mm_ddReadonly :: End -------------"; $e->output($output . "\n"); } } } } } }
/** * getTplMatchedFields * @version 1.0.1 (2013-11-11) * * @desc Returns the array that contains only those of passed fields/TVs which are used in the template. * * @param $fields {comma separated string; array} - Document fields or TVs names. @required * @param $tvTypes {comma separated string; array} - TVs types, e.g. image, text. Default: ''. * @param $tempaleId {integer} - Template ID. Default: $mm_current_page['template']. * * @return {array; false} */ function getTplMatchedFields($fields, $tvTypes = '', $tempaleId = '') { $fields = makeArray($fields); //$fields is required if (empty($fields)) { return false; } //Template of current document by default if (empty($tempaleId)) { global $mm_current_page; $tempaleId = $mm_current_page['template']; } //Only document fields $docFields = array_intersect($fields, ddTools::$documentFields); //If $fields contains no TVs if (count($docFields) == count($fields)) { $fields = $docFields; } else { //Get specified TVs for this template $fields = tplUseTvs($tempaleId, $fields, $tvTypes, 'name', 'name'); //If there are no appropriate TVs if ($fields == false) { if (!empty($docFields)) { $fields = $docFields; } } else { $fields = array_merge(array_keys($fields), $docFields); } } return $fields; }
/** * mm_ddAutoFolders * @version 1.2 (2014-04-18) * * @desc Automatically move documents (OnBeforeDocFormSave event) based on their date (publication date; any date in tv) into folders of year and month (like 2012/02/). If folders (documents) of year and month doesn`t exist they are created automatically OnBeforeDocFormSave event. * * @uses ManagerManager plugin 0.5 * * @param $roles {comma separated string} - List of role IDs this should be applied to. Leave empty (or omit) for all roles. Default: ''. * @param $templates {comma separated string} - List of template IDs this should be applied to. Leave empty (or omit) for all templates. Default: ''. * @param $yearsParents {comma separated string} - IDs of ultimate parents (parents of the years). @required * @param $dateSource {string} - Name of template variable which contains the date. Default: 'pub_date'. * @param $yearFields {string: JSON} - Document fields and/or TVs that are required to be assigned to year documents. An associative array in JSON where the keys and values correspond field names and values respectively. Default: '{"template":0,"published":0}'. * @param $monthFields {string: JSON} - Document fields and/or TVs that are required to be assigned to month documents. An associative array in JSON where the keys and values correspond field names and values respectively. Default: '{"template":0,"published":0}'. * @param $yearPublished {0; 1} - Note this is a deprecated parameter, please, use “$yearFields”. Whether the year documents should be published? Default: —. * @param $monthPublished {0; 1} - Note this is a deprecated parameter, please, use “$monthFields”. Whether the month documents should be published? Default: —. * @param $numericMonth {boolean} - Numeric aliases for month documents. Default: false. * * @link http://code.divandesign.biz/modx/mm_ddautofolders/1.2 * * @copyright 2014, DivanDesign * http://www.DivanDesign.biz */ function mm_ddAutoFolders($roles = '', $templates = '', $yearsParents = '', $dateSource = 'pub_date', $yearFields = '{"template":0,"published":0}', $monthFields = '{"template":0,"published":0}', $yearPublished = NULL, $monthPublished = NULL, $numericMonth = false) { global $modx, $pub_date, $parent, $mm_current_page, $tmplvars, $modx_lang_attribute; $e =& $modx->Event; //$yearsParents is required if ($yearsParents != '' && $e->name == 'OnBeforeDocFormSave' && useThisRule($roles, $templates)) { $defaultFields = array('template' => 0, 'published' => 0); //Функция аналогична методу «$modx->getParentIds» за исключением того, что родитель = 0 тоже выставляется function getParentIds($id) { global $modx; $parents = $modx->getParentIds($id); //Если текущего id нет в массиве, значит его родитель = 0 if (!isset($parents[$id])) { $parents[$id] = 0; //Если текущий документ есть, а его родителя нет, значит родитель родителя = 0 } else { if (!isset($parents[$parents[$id]])) { $parents[$parents[$id]] = 0; } } return $parents; } //Получаем всех родителей текущего документа (или его родителя, если это новый документ) $allParents = getParentIds(is_numeric($e->params['id']) ? $e->params['id'] : $parent); $yearsParents = makeArray($yearsParents); //Перебираем переданных родителей foreach ($yearsParents as $key => $val) { //Если текущий документ не принадлежит к переданному родителю, значит этот родитель лишний if (!isset($allParents[$val])) { unset($yearsParents[$key]); } } //Если остался хоть один родитель (а остаться должен только один) if (count($yearsParents) > 0) { //Сбрасываем ключи $yearsParents = array_values($yearsParents); //Если документ не относится ни к одному переданному родителю, то ничего делать не нужно } else { return; } //Текущее правило $rule = array(); //Дата $ddDate = array(); //Если задано, откуда брать дату и это не дата публикации, пытаемся найти в tv`шках if ($dateSource && $dateSource != 'pub_date') { //Получаем tv с датой для данного шаблона $dateTv = tplUseTvs($mm_current_page['template'], $dateSource); //Если tv удалось получить, такая tv есть и есть её значение if ($dateTv && $dateTv[0]['id'] && $tmplvars[$dateTv[0]['id']] && $tmplvars[$dateTv[0]['id']][1]) { //Если дата в юникс-времени if (is_numeric($tmplvars[$dateTv[0]['id']][1])) { $ddDate['date'] = $tmplvars[$dateTv[0]['id']][1]; } else { //Пытаемся преобразовать в unix-время $ddDate['date'] = strtotime($tmplvars[$dateTv[0]['id']][1]); } } } else { $ddDate['date'] = $pub_date; } //Если не задана дата, выбрасываем if (!$ddDate['date']) { return; } //Псевдонимы родителей (какие должны быть) //Год в формате 4 цифры $ddDate['y'] = date('Y', $ddDate['date']); //Псевдоним месяца (порядковый номер номер с ведущим нолём или название на английском) $ddDate['m'] = $numericMonth ? date('m', $ddDate['date']) : strtolower(date('F', $ddDate['date'])); //Порядковый номер месяца $ddDate['n'] = date('n', $ddDate['date']); //Если язык админки — русский if (strtolower($modx_lang_attribute) == 'ru') { //Все месяцы на русском $ruMonthes = array('Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'); //Название месяца на русском $ddDate['mTitle'] = $ruMonthes[$ddDate['n'] - 1]; } else { //Просто запишем на английском $ddDate['mTitle'] = date('F', $ddDate['date']); } //Получаем список групп документов родителя (пригодится при создании годов и месяцев) $docGroups = $modx->db->getColumn('document_group', $modx->db->select('`document_group`', ddTools::$tables['document_groups'], '`document` = ' . $yearsParents[0])); $yearId = 0; $monthId = 0; //Получаем годы (непосредственных детей корневого родителя) $years = ddTools::getDocumentChildrenTVarOutput($yearsParents[0], array('id'), false, 'menuindex', 'ASC', '', 'alias'); if (isset($years[$ddDate['y']])) { //Получаем id нужного нам года $yearId = $years[$ddDate['y']]['id']; } //For backward compatibility if (is_numeric($yearFields)) { $yearFields = '{"template":' . $yearFields . ',"published":0}'; } if (is_numeric($monthFields)) { $monthFields = '{"template":' . $monthFields . ',"published":0}'; } $yearFields = json_decode($yearFields, true); $monthFields = json_decode($monthFields, true); if (!is_array($yearFields)) { $yearFields = $defaultFields; } if (!is_array($monthFields)) { $monthFields = $defaultFields; } //For backward compatibility too if ($yearPublished !== NULL) { $yearFields['published'] = $yearPublished; } if ($monthPublished !== NULL) { $monthFields['published'] = $monthPublished; } //Если нужный год существует if ($yearId != 0) { //Проставим году нужные параметры ddTools::updateDocument($yearId, array_merge($yearFields, array('isfolder' => 1))); //Получаем месяцы (непосредственных детей текущего года) $months = ddTools::getDocumentChildrenTVarOutput($yearId, array('id'), false, 'menuindex', 'ASC', '', 'alias'); if (isset($months[$ddDate['m']])) { //Получаем id нужного нам месяца $monthId = $months[$ddDate['m']]['id']; } //Если нужный год не существует } else { //Создадим его $yearId = ddTools::createDocument(array_merge($yearFields, array('pagetitle' => $ddDate['y'], 'alias' => $ddDate['y'], 'parent' => $yearsParents[0], 'isfolder' => 1, 'menuindex' => $ddDate['y'] - 2000)), $docGroups); } //Если нужный месяц существует if ($monthId != 0) { //Проставим месяцу нужные параметры ddTools::updateDocument($monthId, array_merge($monthFields, array('isfolder' => 1))); //Если нужный месяц не существует (на всякий случай проверим ещё и год) } else { if ($yearId) { $monthId = ddTools::createDocument(array_merge($monthFields, array('pagetitle' => $ddDate['mTitle'], 'alias' => $ddDate['m'], 'parent' => $yearId, 'isfolder' => 1, 'menuindex' => $ddDate['n'] - 1)), $docGroups); } } //Ещё раз на всякий случай проверим, что с месяцем всё хорошо if ($monthId && $monthId != $parent) { $parent = $monthId; } } }
function mm_widget_tags($fields, $delimiter = ',', $source = '', $display_count = false, $roles = '', $templates = '') { global $modx, $content, $mm_fields; $e =& $modx->Event; if (useThisRule($roles, $templates)) { $output = ''; // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); // And likewise for the data source (if supplied) $source = empty($source) ? $fields : makeArray($source); // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } // Does this page's template use any of these TVs? If not, quit. $field_tvs = tplUseTvs($page_template, $fields); if ($field_tvs == false) { return; } $source_tvs = tplUseTvs($page_template, $source); if ($source_tvs == false) { return; } // Insert some JS and a style sheet into the head $output .= "// -------------- Tag widget include ------------- \n"; $output .= includeJs($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/tags/tags.js'); $output .= includeCss($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/tags/tags.css'); // Go through each of the fields supplied foreach ($fields as $targetTv) { $tv_id = $mm_fields[$targetTv]['fieldname']; // Make an SQL friendly list of fields to look at: //$escaped_sources = array(); //foreach ($source as $s) { //$s=substr($s,2,1); // $escaped_sources[] = "'".$s."'"; //} $sql_sources = implode(',', $source_tvs[0]); // Get the list of current values for this TV $sql = "SELECT `value` FROM " . $modx->getFullTableName('site_tmplvar_contentvalues') . " WHERE tmplvarid IN (" . $sql_sources . ")"; $result = $modx->dbQuery($sql); $all_docs = $modx->db->makeArray($result); $foundTags = array(); foreach ($all_docs as $theDoc) { $theTags = explode($delimiter, $theDoc['value']); foreach ($theTags as $t) { $foundTags[trim($t)]++; } } // Sort the TV values (case insensitively) uksort($foundTags, 'strcasecmp'); $lis = ''; foreach ($foundTags as $t => $c) { $lis .= '<li title="Used ' . $c . ' times">' . jsSafe($t) . ($display_count ? ' (' . $c . ')' : '') . '</li>'; } $html_list = '<ul class="mmTagList" id="' . $tv_id . '_tagList">' . $lis . '</ul>'; // Insert the list of tags after the field $output .= ' // -------------- Tag widget for ' . $targetTv . ' (' . $tv_id . ') -------------- $j("#' . $tv_id . '").after(\'' . $html_list . '\'); '; // Initiate the tagCompleter class for this field $output .= 'var ' . $tv_id . '_tags = new TagCompleter("' . $tv_id . '", "' . $tv_id . '_tagList", "' . $delimiter . '"); '; } } $e->output($output . "\n"); }
/** * mm_ddMultipleFields * @version 4.6 (2014-10-24) * * @desc Widget for plugin ManagerManager that allows you to add any number of fields values (TV) in one document (values is written as one with using separator symbols). For example: a few images. * * @uses ManagerManager plugin 0.6.3. * * @param $tvs {comma separated string} - Names of TV for which the widget is applying. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Templates IDs for which the widget is applying (empty value means the widget is applying to all templates). Default: ''. * @param $columns {comma separated string} - Column types: field — field type column; text — text type column; textarea — multiple lines column; richtext — column with rich text editor; date — date column; id — hidden column containing unique id; select — list with options (parameter “columnsData”). Default: 'field'. * @param $columnsTitle {comma separated string} - Columns titles. Default: ''. * @param $colWidth {comma separated string} - Columns width (one value can be set). Default: 180; * @param $splY {string} - Strings separator. Default: '||'. * @param $splX {string} - Columns separator. Default: '::'. * @param $imgW {integer} - Maximum value of image preview width. Default: 300. * @param $imgH {integer} - Maximum value of image preview height. Default: 100. * @param $minRow {integer} - Minimum number of strings. Default: 0. * @param $maxRow {integer} - Maximum number of strings. Default: 0 (без лимита). * @param $columnsData {separated string} - List of valid values in json format (with “||”). Default: ''. Example: '[['','No selected'],['0','No'],['1','Yes',1]]' * * @event OnDocFormPrerender * @event OnDocFormRender * * @link http://code.divandesign.biz/modx/mm_ddmultiplefields/4.5.1 * * @copyright 2014, DivanDesign * http://www.DivanDesign.biz */ function mm_ddMultipleFields($tvs = '', $roles = '', $templates = '', $columns = 'field', $columnsTitle = '', $colWidth = '180', $splY = '||', $splX = '::', $imgW = 300, $imgH = 100, $minRow = 0, $maxRow = 0, $columnsData = '', $options = array()) { if (!useThisRule($roles, $templates)) { return; } if (is_array($options)) { $options = json_encode($options); } global $modx; $e =& $modx->Event; $output = ''; $site = $modx->config['site_url']; $widgetDir = $site . 'assets/plugins/managermanager/widgets/ddmultiplefields/'; if ($e->name == 'OnDocFormPrerender') { global $_lang; $output .= includeJsCss($site . 'assets/plugins/managermanager/js/jquery-ui-1.10.3.min.js', 'html', 'jquery-ui', '1.10.3'); $output .= includeJsCss($widgetDir . 'ddmultiplefields.css', 'html'); $output .= includeJsCss($widgetDir . 'jquery.ddMM.mm_ddMultipleFields.js', 'html', 'jquery.ddMM.mm_ddMultipleFields', '1.1.1'); $output .= includeJsCss('$j.ddMM.lang.edit = "' . $_lang['edit'] . '";$j.ddMM.lang.confirm_delete_record = "' . $_lang["confirm_delete_record"] . '";', 'html', 'mm_ddMultipleFields_plain', '1', true, 'js'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page; if ($columnsData) { $columnsDataTemp = explode('||', $columnsData); $columnsData = array(); foreach ($columnsDataTemp as $value) { //Евалим знение и записываем результат или исходное значени $eval = @eval($value); $columnsData[] = $eval ? addslashes(json_encode($eval)) : addslashes($value); } //Сливаем в строку, что бы передать на клиент $columnsData = implode('||', $columnsData); } //Стиль превью изображения $imgW = $imgW . (is_numeric($imgW) ? "px" : ""); $imgH = $imgH . (is_numeric($imgH) ? "px" : ""); $stylePrewiew = "max-width:{$imgW}; max-height:{$imgH}; margin: 4px 0; cursor: pointer;"; $tvsMas = tplUseTvs($mm_current_page['template'], $tvs, 'image,file,text,email,textarea', 'id,type'); if ($tvsMas == false) { return; } $output .= "//---------- mm_ddMultipleFields :: Begin -----\n"; //For backward compatibility $columns = makeArray($columns); //Находим колонки, заданные как «field», теперь их нужно будет заменить на «image» и «file» соответственно $columns_fieldIndex = array_keys($columns, 'field'); foreach ($tvsMas as $tv) { //For backward compatibility if ($tv['type'] == 'image' || $tv['type'] == 'file') { //Проходимся по всем колонкам «field» и заменяем на соответствующий тип foreach ($columns_fieldIndex as $val) { $columns[$val] = $tv['type']; } } $output .= ' $j("#tv' . $tv['id'] . '").mm_ddMultipleFields({ splY: "' . $splY . '", splX: "' . $splX . '", coloumns: "' . implode(',', $columns) . '", coloumnsTitle: "' . $columnsTitle . '", coloumnsData: "' . $columnsData . '", colWidth: "' . $colWidth . '", imageStyle: "' . $stylePrewiew . '", minRow: "' . $minRow . '", maxRow: "' . $maxRow . '", options: ' . $options . ' }); '; } //Поругаемся if (!empty($columns_fieldIndex)) { $modx->logEvent(1, 2, '<p>You are currently using the deprecated column type “field”. Please, replace it with “image” or “file” respectively.</p><p>The plugin has been called in the document with template id ' . $mm_current_page['template'] . '.</p>', 'ManagerManager: mm_ddMultipleFields'); } $output .= "//---------- mm_ddMultipleFields :: End -----\n"; $e->output($output); } } }
/** * mm_ddResizeImage * @version 1.3.6 (2014-12-25) * * @desc A widget for ManagerManager plugin that allows image size to be changed (TV) so it is possible to create a little preview (thumb). * * @uses phpThumb lib 1.7.11-201108081537-beta (http://phpthumb.sourceforge.net/). * @uses сниппет ddGetMultipleField 3.0b snippet (if mm_ddMultipleFields fields unparse is required). * * @note replaceFieldVal doesn`t work if $multipleField == 1! * * @param $tvs {comma separated string} - The names of TVs for which the widget is applied. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: '' (to all roles). * @param $templates {comma separated string} - The templates for which the widget is applied (empty value means all templates). Default: '' (to all templates). * @param $width {integer} - Width of the image being created (in px). Empty value means width calculating automatically according to height. At least one of the two parameters must be defined. @required * @param $height {integer} - Height of the image being created (in px). Empty value means height calculating automatically according to width. At least one of the two parameters must be defined. @required * @param $cropping {string} - Cropping status. 0 — cropping is not required; 1— cropping is required (proportions won`t be saved); 'crop_resized' — the image will be resized and cropped; 'fill_sized' — the image will be resized with propotions saving, blank spaze will be filled with «background» color. Default: 'crop_resized'. * @param $suffix {string} - The suffix for the images being created. Its empty value makes initial images to be rewritten! Default: '_ddthumb'. * @param $replaceFieldVal {0; 1} - TV values rewriting status. When this parameter equals 1 then tv values are replaced by the names of the created images. It doesn`t work if multipleField = 1. Default: 0. * @param $background {string} - Background color. It matters if cropping equals 'fill_resized'. Default: '#ffffff'. * @param $multipleField {0; 1} - Multiple field status (for mm_ddMultipleFields). Default: '0'; * @param $colNum {integer} - The number of the column in which the image is located (for mm_ddMultipleFields). Default: 0. * @param $splY {string} - The string delimiter (for mm_ddMultipleFields). Default: '||'. * @param $splX {string} - The column delimiter (for mm_ddMultipleFields). Default: '::'. * @param $num {integer} - The number of the string that will be processed (for mm_ddMultipleFields). Default: 'all'. * @param $allowEnlargement {0; 1} - Allow output enlargement. Default: 1. * * @event OnBeforeDocFormSave. * * @link http://code.divandesign.biz/modx/mm_ddresizeimage/1.3.6 * * @copyright 2014, DivanDesign * http://www.DivanDesign.biz */ function mm_ddResizeImage($tvs = '', $roles = '', $templates = '', $width = '', $height = '', $cropping = 'crop_resized', $suffix = '_ddthumb', $replaceFieldVal = 0, $background = '#FFFFFF', $multipleField = 0, $colNum = 0, $splY = '||', $splX = '::', $num = 'all', $allowEnlargement = 1) { global $modx; $e =& $modx->Event; if (!function_exists('ddCreateThumb')) { /** * Делает превьюшку * * @param $thumbData {array} */ function ddCreateThumb($thumbData) { //Вычислим размеры оригинаольного изображения $originalImg = array(); list($originalImg['width'], $originalImg['height']) = getimagesize($thumbData['originalImage']); //Если хотя бы один из размеров оригинала оказался нулевым (например, это не изображение) — на(\s?)бок if ($originalImg['width'] == 0 || $originalImg['height'] == 0) { return; } //Пропрорции реального изображения $originalImg['ratio'] = $originalImg['width'] / $originalImg['height']; //Если по каким-то причинам высота не задана if ($thumbData['height'] == '' || $thumbData['height'] == 0) { //Вычислим соответственно пропорциям $thumbData['height'] = $thumbData['width'] / $originalImg['ratio']; } //Если по каким-то причинам ширина не задана if ($thumbData['width'] == '' || $thumbData['width'] == 0) { //Вычислим соответственно пропорциям $thumbData['width'] = $thumbData['height'] * $originalImg['ratio']; } //Если превьюшка уже есть и имеет нужный размер, ничего делать не нужно if ($originalImg['width'] == $thumbData['width'] && $originalImg['height'] == $thumbData['height'] && file_exists($thumbData['thumbName'])) { return; } $thumb = new phpThumb(); //зачистка формата файла на выходе $thumb->setParameter('config_output_format', null); //Путь к оригиналу $thumb->setSourceFilename($thumbData['originalImage']); //Качество (для JPEG) = 100 $thumb->setParameter('q', '100'); //Разрешить ли увеличивать изображение $thumb->setParameter('aoe', $thumbData['allowEnlargement']); //Если нужно просто обрезать if ($thumbData['cropping'] == '1') { //Ширина превьюшки $thumb->setParameter('sw', $thumbData['width']); //Высота превьюшки $thumb->setParameter('sh', $thumbData['height']); //Если ширина оригинального изображения больше if ($originalImg['width'] > $thumbData['width']) { //Позиция по оси x оригинального изображения (чтобы было по центру) $thumb->setParameter('sx', ($originalImg['width'] - $thumbData['width']) / 2); } //Если высота оригинального изображения больше if ($originalImg['height'] > $thumbData['height']) { //Позиция по оси y оригинального изображения (чтобы было по центру) $thumb->setParameter('sy', ($originalImg['height'] - $thumbData['height']) / 2); } } else { //Ширина превьюшки $thumb->setParameter('w', $thumbData['width']); //Высота превьюшки $thumb->setParameter('h', $thumbData['height']); //Если нужно уменьшить + отрезать if ($thumbData['cropping'] == 'crop_resized') { $thumb->setParameter('zc', '1'); //Если нужно пропорционально уменьшить, заполнив поля цветом } else { if ($thumbData['cropping'] == 'fill_resized') { //Устанавливаем фон (без решётки) $thumb->setParameter('bg', str_replace('#', '', $thumbData['backgroundColor'])); //Превьюшка должна точно соответствовать размеру и находиться по центру (недостающие области зальются цветом) $thumb->setParameter('far', 'c'); } } } //Создаём превьюшку $thumb->GenerateThumbnail(); //Сохраняем в файл $thumb->RenderToFile($thumbData['thumbName']); } } //Проверим, чтобы было нужное событие, чтобы были заполнены обязательные параметры и что правило подходит под роль if ($e->name == 'OnBeforeDocFormSave' && $tvs != '' && ($width != '' || $height != '') && useThisRule($roles, $templates)) { global $mm_current_page, $tmplvars; //Получаем необходимые tv для данного шаблона (т.к. в mm_ddMultipleFields тип может быть любой, получаем все, а не только изображения) $tvs = tplUseTvs($mm_current_page['template'], $tvs, '', 'id,name'); //Если что-то есть if (is_array($tvs) && count($tvs) > 0) { //Обработка параметров $replaceFieldVal = $replaceFieldVal == '1' ? true : false; $multipleField = $multipleField == '1' ? true : false; //Подключаем phpThumb require_once $modx->config['base_path'] . 'assets/plugins/managermanager/widgets/ddresizeimage/phpthumb.class.php'; //Перебираем их foreach ($tvs as $tv) { //Если в значении tv что-то есть if (isset($tmplvars[$tv['id']]) && trim($tmplvars[$tv['id']][1]) != '') { $image = trim($tmplvars[$tv['id']][1]); //Если это множественное поле if ($multipleField) { //Получим массив изображений $images = $modx->runSnippet('ddGetMultipleField', array('string' => $image, 'rowDelimiter' => $splY, 'colDelimiter' => $splX, 'startRow' => $num == 'all' ? 0 : $num, 'totalRows' => $num == 'all' ? 'all' : 1, 'outputFormat' => 'JSON', 'columns' => $colNum, 'field' => $image, 'splY' => $splY, 'splX' => $splX, 'num' => $num == 'all' ? 0 : $num, 'count' => $num == 'all' ? 'all' : 1, 'format' => 'JSON', 'colNum' => $colNum)); //Если пришла пустота (ни одного изображения заполнено не было) if (trim($images) == '') { $images = array(); } else { if ($num == 'all') { $images = json_decode($images, true); } else { $images = array(trim(stripcslashes($images), '\'\\"')); } } } else { //Запишем в массив одно изображение $images = array($image); } foreach ($images as $image) { //Если есть лишний слэш в начале, убьём его if (strpos($image, '/') === 0) { $image = substr($image, 1); } //На всякий случай проверим, что файл существует if (file_exists($modx->config['base_path'] . $image)) { //Полный путь изображения $imageFullPath = pathinfo($modx->config['base_path'] . $image); //Если имя файла уже заканчивается на суффикс (необходимо при $replaceFieldVal == 1), не будем его добавлять if (substr($imageFullPath['filename'], strlen($suffix) * -1) == $suffix) { $suffix = ''; } //Имя нового изображения $newImageName = $imageFullPath['filename'] . $suffix . '.' . $imageFullPath['extension']; //Делаем превьюшку ddCreateThumb(array('width' => $width, 'height' => $height, 'backgroundColor' => $background, 'cropping' => $cropping, 'thumbName' => $imageFullPath['dirname'] . '/' . $newImageName, 'originalImage' => $modx->config['base_path'] . $image, 'allowEnlargement' => $allowEnlargement)); //Если нужно заменить оригинальное значение TV на вновь созданное и это не $multipleField if ($replaceFieldVal && !$multipleField) { $tmplvars[$tv['id']][1] = dirname($tmplvars[$tv['id']][1]) . '/' . $newImageName; } } } } } } } }
function mm_country_city($countryTV, $cityTV, $roles = '', $templates = '') { global $modx, $content, $mm_fields; $e =& $modx->Event; if (useThisRule($roles, $templates)) { // Your output should be stored in a string, which is outputted at the end // It will be inserted as a Javascript block (with jQuery), which is executed on document ready $output = ''; // You might want to check whether the current page's template uses the TVs that have been // supplied, to save processing page which don't contain them // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } //Проверяем использует ли данный шаблон нужные нам TV $count = tplUseTvs($content['template'], array($countryTV, $cityTV)); if ($count == false) { return; } // We always put a JS comment, which makes debugging much easier $output .= "// -------------- Country_city ------------- \n"; //В ManagerManager нет массива со значениями TV, поэтому единственный способ узнать это через API MODX $tvs = $modx->getTemplateVars(array($countryTV, $cityTV), '*', $content['id'], 0); $tvcountry_value = !empty($tvs[0]['value']) ? $tvs[0]['value'] : 0; $tvcity_value = !empty($tvs[1]['value']) ? $tvs[1]['value'] : 0; //Идентификаторы HTML-элементов с TV. По ним будем искать нужные нам на странице $tvcountry_id = $mm_fields[$countryTV]['fieldname']; $tvcity_id = $mm_fields[$cityTV]['fieldname']; //Выводим JS-скрипт $output .= ' //Загружаем список стран $j.get("' . $modx->config['site_url'] . '/country_city.php??mode=country", function(data) { //Находим TV со страной var s = $j("#' . $tvcountry_id . '"); s.empty(); $j(data).each( function () { var option = $j("<option>").val(this.id); option.text(this.title); //Если ID страны равно значению TV, то выбираем данную страну if (this.id==' . $tvcountry_value . ') option.attr("selected","selected"); s.append(option); }); //Если никакая страна не выбрана, то добавляем пустой элемент в список и делаем его активным if (s.val()!=' . $tvcountry_value . ') s.prepend($j("<option>").attr("selected","selected")); //Навешиваем обработчик события смены страны s.change(countrychange); //Загружаем города countrychange(); },"json" ); //callback-функция, вызываемая при смене страны var countrychange = function () { //Ищем TV со страной и получаем ID выбранной страны var country_id = $j("select#' . $tvcountry_id . '").val(); if (country_id!=0) { $j.get("' . $modx->config['site_url'] . '/country_city.php?mode=city&country_id="+country_id, function(data) { //Находим TV со городом var s = $j("#' . $tvcity_id . '"); s.empty(); $j(data).each( function () { var option = $j("<option>").val(this.id); option.text(this.title); //Если ID города равно значению TV, то выбираем данный город if (this.id==' . $tvcity_value . ') option.attr("selected","selected"); s.append(option); }); //Если никакой город не выбран, то добавляем пустой элемент в список и делаем его активным if (s.val()!=' . $tvcity_value . ') s.prepend($j("<option>").attr("selected","selected")); },"json" ); } } '; } // end if $e->output($output . "\n"); // Send the output to the browser }
/** * mm_requireFields * @version 1.2 (2013-02-11) * * Make fields required. Currently works with text fields only. * In the future perhaps this could deal with other elements. * Originally version by Jelle Jager AKA TobyL - Make fields required * Updated by ncrossland to utilise simpler field handline of MM 0.3.5+; bring jQuery code into line; add indication to required fields * * @uses ManagerManager plugin 0.4. * * @link http://code.divandesign.biz/modx/mm_requirefields/1.2 * * @copyright 2013 */ function mm_requireFields($fields, $roles = '', $templates = '') { global $mm_fields, $mm_current_page, $modx; $e =& $modx->event; // if the current page is being edited by someone in the list of roles, and uses a template in the list of templates if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); if (count($fields) == 0) { return; } $output = "// -------------- mm_requireFields :: Begin ------------- \n"; $output .= ' $j("head").append("<style>.mmRequired { background-image: none !important; background-color: #ff9999 !important; } .requiredIcon { color: #ff0000; font-weight: bold; margin-left: 3px; cursor: help; }</style>"); var requiredHTML = "<span class=\\"requiredIcon\\" title=\\"Required\\">*</span>"; '; $submit_js = ''; $load_js = ''; foreach ($fields as $field) { //ignore for now switch ($field) { // fields for which this doesn't make sense - in my opinion anyway :) case 'keywords': case 'metatags': case 'hidemenu': case 'which_editor': case 'template': case 'menuindex': case 'show_in_menu': case 'parent': case 'is_folder': case 'is_richtext': case 'log': case 'searchable': case 'cacheable': case 'clear_cache': case 'content_type': case 'content_dispo': case 'which_editor': $output .= ''; break; // Pub/unpub dates don't have a type attribute on their input tag in 1.0.2, so add this. Won't do any harm to other versions // Pub/unpub dates don't have a type attribute on their input tag in 1.0.2, so add this. Won't do any harm to other versions case 'pub_date': case 'unpub_date': $load_js .= ' $j("#pub_date, #unpub_date").each(function() { this.type = "text"; }); // Cant use jQuery attr function as datepicker class clashes with jQuery methods '; // no break, because we want to do the things below too. // Ones that follow the regular pattern // no break, because we want to do the things below too. // Ones that follow the regular pattern default: //if it's tv & it's not used in current template if ($mm_fields[$field]['tv'] && tplUseTvs($mm_current_page['template'], $field) === false) { //Go to next field continue; } // What type is this field? $fieldname = $mm_fields[$field]['fieldname']; // What jQuery selector should we use for this fieldtype? switch ($mm_fields[$field]['fieldtype']) { case 'textarea': $selector = "textarea[name={$fieldname}]"; break; case 'input': // If it's an input, we only want to do something if it's a text field $selector = "input[type=text][name={$fieldname}]"; break; default: // all other input types, do nothing $selector = ''; break; } // If we've found something we want to use if (!empty($selector)) { $submit_js .= ' // The element we are targetting (' . $fieldname . ') var $sel = $j("' . $selector . '"); // Check if its valid if($j.trim($sel.val()) == ""){ // If it is empty // Find the label (this will be easier in Evo 1.1 with more semantic code) var lbl = $sel.parent("td").prev("td").children("span.warning").text().replace($j(requiredHTML).text(), ""); // Add the label to the errors array. Would be nice to say which tab it is on, but no // easy way of doing this in 1.0.x as no semantic link between tabs and tab body errors.push(lbl); // Add an event so the hilight is removed upon focussing $sel.addClass("mmRequired").focus(function(){ $j(this).removeClass("mmRequired"); }); } '; $load_js .= ' // Add an indicator this is required (' . $fieldname . ') var $sel = $j("' . $selector . '"); // Find the label (this will be easier in Evo 1.1 with more semantic code) var $lbl = $sel.parent("td").prev("td").children("span.warning").append(requiredHTML); '; } break; } } $output .= $load_js . ' $j("#mutate").submit(function(){ var errors = []; //TODO: The local variable msg is never read var msg = ""; ' . $submit_js . ' if(errors.length > 0){ var errMsg = errors.length + " required fields are missing:\\n\\n "; for (var i = 0; i < errors.length; i++){ errMsg += " - " + errors[i] + " \\n"; } errMsg += " \\nPlease correct the indicated fields."; alert(errMsg); return false; }else{ return true; } }); '; $output .= "// -------------- mm_requireFields :: End ------------- \n"; $e->output($output . "\n"); } }
function mm_widget_showimagetvs($tvs = '', $w = 300, $h = 100, $thumbnailerUrl = '', $roles = '', $templates = '') { global $modx, $content; $e =& $modx->Event; if (useThisRule($roles, $templates)) { $output = ''; $site = $modx->config['site_url']; if (isset($w) || isset($h)) { $w = isset($w) ? $w : 300; $h = isset($h) ? $h : 100; $style = "'max-width:{$w}px; max-height:{$h}px; margin: 4px 0; cursor: pointer;'"; } else { $style = ''; } // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } // Does this page's template use any image TVs? If not, quit now! $tvs = tplUseTvs($page_template, $tvs, 'image'); if ($tvs == false) { return; } $output .= "// ---------------- mm_widget_showimagetvs: Add image preview ------------- \n"; // Go through each TV foreach ($tvs as $tv) { $new_html = ''; $output .= '// Adding preview for tv' . $tv['id'] . ' $j("#tv' . $tv['id'] . '").bind( "change load", function() { // Get the new URL $j(this).addClass("imageField"); var url = $j(this).val(); url = (url != "" && url.search(/http:\\/\\//i) == -1) ? ("' . $site . '" + url) : url; '; // If we have a PHPThumb URL if (!empty($thumbnailerUrl)) { $output .= 'url = "' . $thumbnailerUrl . '?src="+escape(url)+"&w=' . $w . '&h=' . $h . '"; ' . "\n"; } $output .= ' // Remove the old preview tv' . $tv['id'] . ' $j("#tv' . $tv['id'] . 'PreviewContainer").remove(); if (url != "") { // Create a new preview $j("#tv' . $tv['id'] . '").parents("td").append("<div class=\\"tvimage\\" id=\\"tv' . $tv['id'] . 'PreviewContainer\\"><img src=\\""+url+"\\" style=\\""+' . $style . '+"\\" id=\\"tv' . $tv['id'] . 'Preview\\"/></div>"); // Attach a browse event to the picture, so it can trigger too $j("#tv' . $tv['id'] . 'Preview").click( function() { BrowseServer("tv' . $tv['id'] . '"); }); } }).trigger("load"); // Trigger a change event on load '; } $output .= ' // If we have imageTVs on this page, modify the SetUrl function so it triggers a "change" event on the URL field if (typeof(SetUrl) != "undefined") { OriginalSetUrl = SetUrl; // Copy the existing Image browser SetUrl function SetUrl = function(url, width, height, alt) { // Redefine it to also tell the preview to update OriginalSetUrl(url, width, height, alt); $j(".imageField").trigger("change"); } } '; $e->output($output . "\n"); } }
/** * ddSetFieldValue * @version 1.0.3 (2012-11-13) * * Жёстко выставляет необходимые значения заданному полю * * @uses ManagerManager plugin 0.4. * * @todo Основан на mm_default * * @param field {string} - Имя поля, для которого необходимо установить значение. * @param value {string} - Значение, которое необходимо установить. * @param roles {comma separated string} - Id ролей. По умолчанию: для всех ролей. * @param templates {comma separated string} - Id шаблонов. По умолчанию: для всех шаблонов. * * @link http://code.divandesign.biz/modx/mm_ddsetfieldvalue/1.0.3 * * @copyright 2012, DivanDesign * http://www.DivanDesign.biz */ function mm_ddSetFieldValue($field, $value = '', $roles = '', $templates = '') { global $modx, $content, $mm_fields, $mm_current_page; $e =& $modx->event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $output = " // ----------- mm_ddSetFieldValue :: Begin -------------- \n"; //Подбираем правильный формат даты в соответствии с конфигурацией switch ($modx->config['datetime_format']) { case 'dd-mm-YYYY': $date_format = 'd-m-Y'; break; case 'mm/dd/YYYY': $date_format = 'm/d/Y'; break; case 'YYYY/mm/dd': $date_format = 'Y/m/d'; break; } //Смотрим, что за поле надо изменить switch ($field) { //Дата публикации case 'pub_date': $value = $value == '' ? date("{$date_format} H:i:s") : $value; $output .= '$j("input[name=pub_date]").val("' . jsSafe($value) . '"); ' . "\n"; break; //Дата отмены публикации //Дата отмены публикации case 'unpub_date': $value = $value == '' ? date("{$date_format} H:i:s") : $value; $output .= '$j("input[name=unpub_date]").val("' . jsSafe($value) . '"); ' . "\n"; break; //Признак публикации //Признак публикации case 'published': if ($value == '1') { $output .= '$j("input[name=publishedcheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= '$j("input[name=publishedcheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=published]").val("' . $value . '"); ' . "\n"; break; //Признак отображения в меню //Признак отображения в меню case 'show_in_menu': if ($value == '1') { $output .= '$j("input[name=hidemenucheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= '$j("input[name=hidemenucheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=hidemenu]").val("' . ($value == '1' ? '0' : '1') . '"); ' . "\n"; // Note these are reversed from what you'd think break; //Признак скрытия из меню (аналогично show_in_menu, только наоборот) //Признак скрытия из меню (аналогично show_in_menu, только наоборот) case 'hide_menu': if ($value == '0') { $output .= '$j("input[name=hidemenucheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '1'; $output .= '$j("input[name=hidemenucheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=hidemenu]").val("' . $value . '"); ' . "\n"; break; //Признак доступности для поиска //Признак доступности для поиска case 'searchable': if ($value == '1') { $output .= '$j("input[name=searchablecheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= '$j("input[name=searchablecheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=searchable]").val("' . $value . '"); ' . "\n"; break; //Признак кэширования //Признак кэширования case 'cacheable': if ($value == '1') { $output .= '$j("input[name=cacheablecheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= '$j("input[name=cacheablecheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=cacheable]").val("' . $value . '"); ' . "\n"; break; //Признак очистки кэша //Признак очистки кэша case 'clear_cache': if ($value == '1') { $output .= '$j("input[name=syncsitecheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= '$j("input[name=syncsitecheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=syncsite]").val("' . $value . '"); ' . "\n"; break; //Признак папки //Признак папки case 'is_folder': if ($value == '1') { $output .= '$j("input[name=isfoldercheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= '$j("input[name=isfoldercheck]").removeAttr("checked"); ' . "\n"; } break; //Признак использованшия визуального редактора //Признак использованшия визуального редактора case 'is_richtext': $output .= 'var originalRichtextValue = $j("#which_editor:first").val(); ' . "\n"; if ($value == '1') { $output .= '$j("input[name=richtextcheck]").attr("checked", "checked"); ' . "\n"; } else { $value = '0'; $output .= ' $j("input[name=richtextcheck]").removeAttr("checked"); // Make the RTE displayed match the default value that has been set here if (originalRichtextValue != "none"){ $j("#which_editor").val("none"); changeRTE(); } '; $output .= '' . "\n"; } $output .= '$j("input[name=richtext]").val("' . $value . '"); ' . "\n"; break; //Признак логирования //Признак логирования case 'log': //Note these are reversed from what you'd think $value = $value ? '0' : '1'; if ($value == '1') { $output .= '$j("input[name=donthitcheck]").attr("checked", "checked"); ' . "\n"; } else { $output .= '$j("input[name=donthitcheck]").removeAttr("checked"); ' . "\n"; } $output .= '$j("input[name=donthit]").val("' . $value . '"); ' . "\n"; break; //Тип содержимого //Тип содержимого case 'content_type': $output .= '$j("select[name=contentType]").val("' . $value . '");' . "\n"; break; //TV //TV default: // Which template is this page using? $tvsMas = tplUseTvs($mm_current_page['template'], $field); if ($tvsMas) { $output .= '$j("#tv' . $tvsMas[0]['id'] . '").val("' . $value . '");' . "\n"; } break; } $output .= "\n// ---------------- mm_ddSetFieldValue :: End -------------"; $e->output($output . "\n"); } }
/** * mm_widget_tags * @version 1.1.2 (2013-12-11) * * Adds a tag selection widget to the specified TVs. * * @uses ManagerManager plugin 0.6. * * @param $fields {comma separated string} - The name(s) of the template variables this should apply to. @required * @param $delimiter {string} - The sign that separates tags in the field. Default: ','. * @param $source {comma separated string} - The names(s) of the template variables the list of tags should come from. This allows the list of tags to come from a different field than the widget. By default it uses all the TVs listed in “fields” parameter. Default: =$fields. * @param $display_count {boolean} - Display the number of documents using each tag (in brackets after it). Default: false. * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - The templates that the widget is applied to (when this parameter is empty then widget is applied to the all templates). Default: ''. * * @event OnDocFormPrerender * @event OnDocFormRender * * @link http://code.divandesign.biz/modx/mm_widget_tags/1.1.2 * * @copyright 2013 */ function mm_widget_tags($fields, $delimiter = ',', $source = '', $display_count = false, $roles = '', $templates = '') { if (!useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; $output = ''; if ($e->name == 'OnDocFormPrerender') { $output .= includeJsCss($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/tags/tags.js', 'html', 'mm_widget_tags', '1.0'); $output .= includeJsCss($modx->config['base_url'] . 'assets/plugins/managermanager/widgets/tags/tags.css', 'html'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page, $mm_fields; // if we've been supplied with a string, convert it into an array $fields = makeArray($fields); // And likewise for the data source (if supplied) $source = empty($source) ? $fields : makeArray($source); // Does this page's template use any of these TVs? If not, quit. $field_tvs = tplUseTvs($mm_current_page['template'], $fields); if ($field_tvs == false) { return; } $source_tvs = tplUseTvs($mm_current_page['template'], $source); if ($source_tvs == false) { return; } $output .= "//---------- mm_widget_tags :: Begin -----\n"; // Go through each of the fields supplied foreach ($fields as $targetTv) { $tv_id = $mm_fields[$targetTv]['fieldname']; // Make an SQL friendly list of fields to look at: //$escaped_sources = array(); //foreach ($source as $s){ // $s=substr($s,2,1); // $escaped_sources[] = "'".$s."'"; //} $sql_sources = implode(',', $source_tvs[0]); // Get the list of current values for this TV $sql = 'SELECT `value` FROM ' . $modx->getFullTableName('site_tmplvar_contentvalues') . ' WHERE tmplvarid IN (' . $sql_sources . ')'; $result = $modx->db->query($sql); $all_docs = $modx->db->makeArray($result); $foundTags = array(); foreach ($all_docs as $theDoc) { $theTags = explode($delimiter, $theDoc['value']); foreach ($theTags as $t) { $foundTags[trim($t)]++; } } // Sort the TV values (case insensitively) uksort($foundTags, 'strcasecmp'); $lis = ''; foreach ($foundTags as $t => $c) { $lis .= '<li title="Used ' . $c . ' times">' . jsSafe($t) . ($display_count ? ' (' . $c . ')' : '') . '</li>'; } $html_list = '<ul class="mmTagList" id="' . $tv_id . '_tagList">' . $lis . '</ul>'; // Insert the list of tags after the field $output .= ' //mm_widget_tags for “' . $targetTv . '” (' . $tv_id . ') $j("#' . $tv_id . '").after(\'' . $html_list . '\'); '; // Initiate the tagCompleter class for this field $output .= 'var ' . $tv_id . '_tags = new TagCompleter("' . $tv_id . '", "' . $tv_id . '_tagList", "' . $delimiter . '");' . "\n"; } $output .= "//---------- mm_widget_tags :: End -----\n"; $e->output($output); } } }
/** * mm_ddMultipleFields * @version 4.5.1 (2014-05-15) * * @desc Widget for plugin ManagerManager that allows you to add any number of fields values (TV) in one document (values is written as one with using separator symbols). For example: a few images. * * @uses ManagerManager plugin 0.6. * * @param $tvs {comma separated string} - Names of TV for which the widget is applying. @required * @param $roles {comma separated string} - The roles that the widget is applied to (when this parameter is empty then widget is applied to the all roles). Default: ''. * @param $templates {comma separated string} - Templates IDs for which the widget is applying (empty value means the widget is applying to all templates). Default: ''. * @param $columns {comma separated string} - Column types: field — field type column; text — text type column; textarea — multiple lines column; richtext — column with rich text editor; date — date column; id — hidden column containing unique id; select — list with options (parameter “columnsData”). Default: 'field'. * @param $columnsTitle {comma separated string} - Columns titles. Default: ''. * @param $colWidth {comma separated string} - Columns width (one value can be set). Default: 180; * @param $splY {string} - Strings separator. Default: '||'. * @param $splX {string} - Columns separator. Default: '::'. * @param $imgW {integer} - Maximum value of image preview width. Default: 300. * @param $imgH {integer} - Maximum value of image preview height. Default: 100. * @param $minRow {integer} - Minimum number of strings. Default: 0. * @param $maxRow {integer} - Maximum number of strings. Default: 0 (без лимита). * @param $columnsData {separated string} - List of valid values in json format (with “||”). Default: ''. * * @event OnDocFormPrerender * @event OnDocFormRender * * @link http://code.divandesign.biz/modx/mm_ddmultiplefields/4.5.1 * * @copyright 2014, DivanDesign * http://www.DivanDesign.biz */ function mm_ddMultipleFields($tvs = '', $roles = '', $templates = '', $columns = 'field', $columnsTitle = '', $colWidth = '180', $splY = '||', $splX = '::', $imgW = 300, $imgH = 100, $minRow = 0, $maxRow = 0, $columnsData = '') { if (!useThisRule($roles, $templates)) { return; } global $modx; $e =& $modx->Event; $output = ''; $site = $modx->config['site_url']; $widgetDir = $site . 'assets/plugins/managermanager/widgets/ddmultiplefields/'; if ($e->name == 'OnDocFormPrerender') { global $_lang; $output .= includeJsCss($site . 'assets/plugins/managermanager/js/jquery-ui-1.10.3.min.js', 'html', 'jquery-ui', '1.10.3'); $output .= includeJsCss($widgetDir . 'ddmultiplefields.css', 'html'); $output .= includeJsCss($widgetDir . 'jquery.ddMM.mm_ddMultipleFields.js', 'html', 'jquery.ddMM.mm_ddMultipleFields', '1.1.1'); $output .= includeJsCss('$j.ddMM.lang.edit = "' . $_lang['edit'] . '";', 'html', 'mm_ddMultipleFields_plain', '1', true, 'js'); $e->output($output); } else { if ($e->name == 'OnDocFormRender') { global $mm_current_page; if ($columnsData) { $columnsDataTemp = explode('||', $columnsData); $columnsData = array(); foreach ($columnsDataTemp as $value) { //Евалим знение и записываем результат или исходное значени $eval = @eval($value); $columnsData[] = $eval ? addslashes(json_encode($eval)) : addslashes($value); } //Сливаем в строку, что бы передать на клиент $columnsData = implode('||', $columnsData); } //Стиль превью изображения $stylePrewiew = "max-width:{$imgW}px; max-height:{$imgH}px; margin: 4px 0; cursor: pointer;"; $tvsMas = tplUseTvs($mm_current_page['template'], $tvs, 'image,file,text,email,textarea', 'id,type'); if ($tvsMas == false) { return; } $output .= "//---------- mm_ddMultipleFields :: Begin -----\n"; foreach ($tvsMas as $tv) { if ($tv['type'] == 'image') { $browseFuntion = 'BrowseServer'; $makeFieldFunction = 'makeImage'; } else { if ($tv['type'] == 'file') { $browseFuntion = 'BrowseFileServer'; $makeFieldFunction = 'makeNull'; } else { $browseFuntion = 'false'; $makeFieldFunction = 'makeNull'; } } $output .= ' $j("#tv' . $tv['id'] . '").mm_ddMultipleFields({ splY: "' . $splY . '", splX: "' . $splX . '", coloumns: "' . $columns . '", coloumnsTitle: "' . $columnsTitle . '", coloumnsData: "' . $columnsData . '", colWidth: "' . $colWidth . '", imageStyle: "' . $stylePrewiew . '", minRow: "' . $minRow . '", maxRow: "' . $maxRow . '", makeFieldFunction: "' . $makeFieldFunction . '", browseFuntion: ' . $browseFuntion . ' }); '; } $output .= "//---------- mm_ddMultipleFields :: End -----\n"; $e->output($output); } } }
/** * mm_ddAutoFolders * @version 1.0.2 (2013-05-30) * * При сохранении (событие OnBeforeDocFormSave) автоматически перемещает необходимый документ, основываясь на его дате (дата публикации, или любая дата в tv) в папку года и месяца. Если папки (документы) года и/или месяца ещё не созданы, они создадутся автоматически. * * @uses ManagerManager plugin 0.5 * * @param $ddRoles {comma separated string} - ID ролей, к которым необходимо применить правило. Default: ''. * @param $ddTemplates {comma separated string} - ID шаблонов, к которым необходимо применить правило. Default: ''. * @param $ddParent {integer} - ID корневого родителя. @required * @param $ddDateSource {string} - Поле, откуда необходимо брать дату. Default: 'pub_date'. * @param $ddYearTpl {integer} - ID шаблона, который необходимо выставлять документам-годам. Default: 0. * @param $ddMonthTpl {integer} - ID шаблона, который необходимо выставлять документам-месяцам. Default: 0. * @param $ddYearPub {0; 1} - Надо ли публиковать документы-годы. Default: 0. * @param $ddMonthPub {0; 1} - Надо ли публиковать документы-месяцы. Default: 0. * * @link http://code.divandesign.ru/modx/mm_ddautofolders/1.0.2 * * @copyright 2013, DivanDesign * http://www.DivanDesign.ru */ function mm_ddAutoFolders($ddRoles = '', $ddTemplates = '', $ddParent = '', $ddDateSource = 'pub_date', $ddYearTpl = 0, $ddMonthTpl = 0, $ddYearPub = '0', $ddMonthPub = '0') { global $modx, $id, $pub_date, $parent, $template, $document_groups, $tmplvars, $mm_fields, $modx_lang_attribute; $e =& $modx->Event; //$ddParent is required if (is_numeric($ddParent) && $e->name == 'OnBeforeDocFormSave' && useThisRule($ddRoles, $ddTemplates)) { $base_path = $modx->config['base_path']; $widgetDir = $base_path . 'assets/plugins/managermanager/widgets/ddautofolders/'; //Подключаем библиотеку ddTools // require_once $widgetDir.'modx.ddtools.class.php'; //Текущее правило $rule = array(); //Дата $ddDate = array(); //Если задано, откуда брать дату и это не дата публикации, пытаемся найти в tv`шках if ($ddDateSource && $ddDateSource != 'pub_date') { //Получаем tv с датой для данного шаблона $dateTv = tplUseTvs($template, $ddDateSource); //Если tv удалось получить, такая tv есть и есть её значение if ($dateTv && $dateTv[0]['id'] && $tmplvars[$dateTv[0]['id']] && $tmplvars[$dateTv[0]['id']][1]) { //Если дата в юникс-времени if (is_numeric($tmplvars[$dateTv[0]['id']][1])) { $ddDate['date'] = $tmplvars[$dateTv[0]['id']][1]; } else { //Пытаемся преобразовать в unix-время $ddDate['date'] = strtotime($tmplvars[$dateTv[0]['id']][1]); } //Пытаемся преобразовать в unix-время if (!is_numeric($tmplvars[$dateTv[0]['id']][1])) { $ddDate['date'] = strtotime($tmplvars[$dateTv[0]['id']][1]); } } } else { $ddDate['date'] = $pub_date; } //Если не задана дата, выбрасываем if (!$ddDate['date']) { return; } //Псевдонимы родителей (какие должны быть) //Год в формате 4 цифры $ddDate['y'] = date('Y', $ddDate['date']); //Название месяца на английском $ddDate['m'] = strtolower(date('F', $ddDate['date'])); //Порядковый номер месяца $ddDate['n'] = date('n', $ddDate['date']); //Если язык админки — русский if (strtolower($modx_lang_attribute) == 'ru') { //Все месяцы на русском $ruMonthes = array('Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'); //Название месяца на русском $ddDate['mTitle'] = $ruMonthes[$ddDate['n'] - 1]; } else { //Просто запишем на английском $ddDate['mTitle'] = date('F', $ddDate['date']); } //Получаем список групп документов, к которым принадлежит текущий документ (пригодится при создании годов и месяцев) $docGroups = preg_replace('/,\\d*/', '', $document_groups); //Получаем псевдоним корневого родителя $ultimateAlias = ''; //Если корневой родитель не в корне, допишем путь к нему if ($modx->aliasListing[$ddParent]['path'] != '') { $ultimateAlias .= $modx->aliasListing[$ddParent]['path'] . '/'; } $ultimateAlias .= $modx->aliasListing[$ddParent]['alias']; //Получаем годы (непосредственных детей корневого родителя) $years = $modx->getChildIds($ddParent, 1); //Получаем id нужного нам года $yearId = $years[$ultimateAlias . '/' . $ddDate['y']]; //Если нужный год существует if ($yearId) { //Проставим году нужные параметры ddTools::udateDocument($yearId, array('isfolder' => 1, 'template' => $ddYearTpl, 'published' => $ddYearPub)); //Получаем месяцы (непосредственных детей текущего года) $months = $modx->getChildIds($yearId, 1); //Получаем id нужного нам месяца $monthId = $months[$ultimateAlias . '/' . $ddDate['y'] . '/' . $ddDate['m']]; //Если нужный год не существует } else { //Создадим его $yearId = ddTools::createDocument(array('pagetitle' => $ddDate['y'], 'alias' => $ddDate['y'], 'parent' => $ddParent, 'isfolder' => 1, 'template' => $ddYearTpl, 'menuindex' => $ddDate['y'] - 2000, 'published' => $ddYearPub), $docGroups); } // if (!$monthId && $yearId){ //Если нужный месяц существует if ($monthId) { //Проставим месяцу нужные параметры ddTools::udateDocument($monthId, array('isfolder' => 1, 'template' => $ddMonthTpl, 'published' => $ddMonthPub)); //Если нужный месяц не существует (на всякий случай проверим ещё и год) } else { if ($yearId) { $monthId = ddTools::createDocument(array('pagetitle' => $ddDate['mTitle'], 'alias' => $ddDate['m'], 'parent' => $yearId, 'isfolder' => 1, 'template' => $ddMonthTpl, 'menuindex' => $ddDate['n'] - 1, 'published' => $ddMonthPub), $docGroups); } } //Ещё раз на всякий случай проверим, что с месяцем всё хорошо if ($monthId && $monthId != $parent) { $parent = $monthId; } } }
/** * mm_ddMultipleFields * @version 4.3.4 (2012-12-20) * * Позволяет добавлять произвольное количество полей (TV) к одному документу (записывается в одно через разделители). * * @param tvs {comma separated string} - Имена TV, для которых необходимо применить виджет. * @param roles {comma separated string} - Роли, для которых необходимо применить виждет, пустое значение — все роли. По умолчанию: ''. * @param templates {comma separated string} - Id шаблонов, для которых необходимо применить виджет, пустое значение — все шаблоны. По умолчанию: ''. * @param coloumns {comma separated string} - Типы колонок (field — колонка типа поля, text — текстовая колонка, id — скрытое поле с уникальным идентификатором, select — список с выбором значений (см. coloumnsData)). По умолчанию: 'field'. * @param coloumnsTitle {comma separated string} - Названия колонок. По умолчанию: ''. * @param colWidth {comma separated string} - Ширины колонок (может быть задана одна ширина). По умолчанию: 180; * @param splY {string} - Разделитель между строками. По умолчанию: '||'. * @param splX {string} - Разделитель между колонками. По умолчанию: '::'. * @param imgW {integer} - Максимальная ширина превьюшки. По умолчанию: 300. * @param imgH {integer} - Максимальная высота превьюшки. По умолчанию: 100. * @param minRow {integer} - Минимальное количество строк. По умолчанию: 0. * @param maxRow {integer} - Максимальное количество строк. По умолчанию: 0 (без лимита). * @param coloumnsData {separated string} - Список возможных значений для полей в формате json, через ||. По умолчанию: ''. * * @link http://code.divandesign.biz/modx/mm_ddmultiplefields/4.3.4 * * @copyright 2012, DivanDesign * http://www.DivanDesign.ru */ function mm_ddMultipleFields($tvs = '', $roles = '', $templates = '', $coloumns = 'field', $coloumnsTitle = '', $colWidth = '180', $splY = '||', $splX = '::', $imgW = 300, $imgH = 100, $minRow = 0, $maxRow = 0, $coloumnsData = '') { global $modx, $content, $_lang; $e =& $modx->Event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $output = ''; $site = $modx->config['site_url']; $widgetDir = $site . 'assets/plugins/managermanager/widgets/ddmultiplefields/'; if ($coloumnsData) { $coloumnsDataTemp = explode('||', $coloumnsData); $coloumnsData = array(); foreach ($coloumnsDataTemp as $value) { //Евалим знение и записываем результат или исходное значени $eval = @eval($value); $coloumnsData[] = $eval ? addslashes(json_encode($eval)) : $value; } //Сливаем в строку, что бы передать на клиент $coloumnsData = implode('||', $coloumnsData); } //Стиль превью изображения $stylePrewiew = "max-width:{$imgW}px; max-height:{$imgH}px; margin: 4px 0; cursor: pointer;"; // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } $tvsMas = array(); // Does this page's template use any image or file or text TVs? $tvsTemp = tplUseTvs($page_template, $tvs, 'image'); if ($tvsTemp) { foreach ($tvsTemp as $v) { $v['type'] = 'image'; array_push($tvsMas, $v); } } $tvsTemp = tplUseTvs($page_template, $tvs, 'file'); if ($tvsTemp) { foreach ($tvsTemp as $v) { $v['type'] = 'file'; array_push($tvsMas, $v); } } $tvsTemp = tplUseTvs($page_template, $tvs, 'text'); if ($tvsTemp) { foreach ($tvsTemp as $v) { $v['type'] = 'text'; array_push($tvsMas, $v); } } if (count($tvsMas) == 0) { return; } $output .= "// ---------------- mm_ddMultipleFields :: Begin ------------- \n"; //General functions $output .= ' //Если ui-sortable ещё не подключён, подключим if (!$j.ui || !$j.ui.sortable){' . includeJs($widgetDir . 'jquery-ui.custom.min.js') . '} //Проверяем на всякий случай (если вдруг вызывается пару раз) if (!ddMultiple){ ' . includeCss($widgetDir . 'ddmultiplefields.css') . ' var ddMultiple = { //Обновляет мульти-поле, берёт значение из оригинального поля updateField: function(id){ //Если есть текущее поле if (ddMultiple[id].currentField){ //Задаём значение текущему полю (берём у оригинального поля), запускаем событие изменения ddMultiple[id].currentField.val($j.trim($j("#"+id).val())).trigger("change.ddEvents"); //Забываем текущее поле (ибо уже обработали) ddMultiple[id].currentField = false; } }, //Обновляет оригинальное поле TV, собирая данные по мульти-полям updateTv: function(id){ var masRows = new Array(); //Перебираем все строки $j("#"+id+"ddMultipleField .ddFieldBlock").each(function(){ var $this = $j(this), masCol = new Array(), id_field = {index: false, val: false, $field: false}; //Перебираем все колонки, закидываем значения в массив $this.find(".ddField").each(function(index){ //Если поле с типом id if (ddMultiple[id].coloumns[index] == "id"){ id_field.index = index; id_field.$field = $j(this); //Сохраняем значение поля id_field.val = id_field.$field.val(); //Если значение пустое, то генерим if (id_field.val == "") id_field.val = (new Date).getTime(); //Обнуляем значение id_field.$field.val(""); } //Собираем значения строки в массив masCol.push($j.trim($j(this).val())); }); var col = masCol.join(ddMultiple[id].splX); if (col.length != ((masCol.length - 1) * ddMultiple[id].splX.length)){ //Проверяем было ли поле с id if (id_field.index !== false){ //Записываем значение в поле id_field.$field.val(id_field.val); //Обновляем значение в массиве masCol[id_field.index] = id_field.val; //Пересобираем строку col = masCol.join(ddMultiple[id].splX); } masRows.push(col); } }); //Записываем значение в оригинальное поле $j("#"+id).attr("value", ddMultiple.maskQuoutes(masRows.join(ddMultiple[id].splY))); }, //Инициализация //Принимает id оригинального поля, его значения и родителя поля init: function(id, val, target){ //Делаем таблицу мульти-полей, вешаем на таблицу функцию обновления оригинального поля var $ddMultipleField = $j("<table class=\\"ddMultipleField\\" id=\\""+id+"ddMultipleField\\"></table>").appendTo(target). on("change.ddEvents", function(){ddMultiple.updateTv(id);}); //Если заголовков хватает if (ddMultiple[id].coloumnsTitle.length == ddMultiple[id].coloumns.length){ var text = ""; //Создадим шапку $j.each(ddMultiple[id].coloumnsTitle, function(key, val){ text += "<th>"+val+"</th>"; }); $j("<tr><th></th>"+text+"<th></th></tr>").appendTo($ddMultipleField); } //Делаем новые мульти-поля var arr = val.split(ddMultiple[id].splY); //Проверяем на максимальное и минимальное количество строк if (ddMultiple[id].maxRow && arr.length > ddMultiple[id].maxRow) arr.length = ddMultiple[id].maxRow; else if (ddMultiple[id].minRow && arr.length < ddMultiple[id].minRow) arr.length = ddMultiple[id].minRow; for (var i=0, len=arr.length; i<len; i++){ //В случае, если размер массива был увеличен по minRow, значением будет undefined, посему зафигачим пустую строку ddMultiple.makeFieldRow(id, arr[i] || ""); } //Создаём кнопку + ddMultiple.makeAddButton(id); //Добавляем возможность перетаскивания $ddMultipleField.sortable({ items: "tr:has(td)", handle: ".ddSortHandle", cursor: "move", axis: "y", /* tolerance: "pointer",*/ /* containment: "parent",*/ placeholder: "ui-state-highlight", start: function(event, ui){ ui.placeholder.html("<td colspan=\\""+(ddMultiple[id].coloumns.length+2)+"\\"><div></div></td>").find("div").css("height", ui.item.height()); }, stop: function(event, ui){ //Находим родителя таблицы, вызываем функцию обновления поля ui.item.parents(".ddMultipleField:first").trigger("change.ddEvents"); ddMultiple.moveAddButton(id); } }); //Запускаем обновление, если были ограничения if (ddMultiple[id].maxRow || ddMultiple[id].minRow) $ddMultipleField.trigger("change.ddEvents"); }, //Функция создания строки //Принимает id и данные строки makeFieldRow: function(id, val){ //Проверяем привышает ли количество строк максимальное if (ddMultiple[id].maxRow && $j("#"+id+"ddMultipleField .ddFieldBlock").length >= ddMultiple[id].maxRow) return; var $fieldBlock = $j("<tr class=\\"ddFieldBlock "+id+"ddFieldBlock\\" ><td class=\\"ddSortHandle\\"><div></div></td></tr>").appendTo($j("#"+id+"ddMultipleField"));//.on("change.ddEvents",function(){ddMultiple.updateTv(id);}); //Разбиваем переданное значение на колонки val = ddMultiple.maskQuoutes(val).split(ddMultiple[id].splX); var $field; //Перебираем колонки $j.each(ddMultiple[id].coloumns, function(key){ if (!val[key]) val[key] = ""; if (!ddMultiple[id].coloumnsTitle[key]) ddMultiple[id].coloumnsTitle[key] = ""; if (!ddMultiple[id].colWidth[key] || ddMultiple[id].colWidth[key] == "") ddMultiple[id].colWidth[key] = ddMultiple[id].colWidth[key - 1]; var col = ddMultiple.makeFieldCol($fieldBlock); //По умолчанию создаём поле как текстовое $field = ddMultiple.makeText(val[key], ddMultiple[id].coloumnsTitle[key], ddMultiple[id].colWidth[key], col); //Если текущая колонка является полем if(ddMultiple[id].coloumns[key] == "field"){ ddMultiple[id].makeFieldFunction(id, col); //If is file or image if (ddMultiple[id].browseFuntion){ //Create Attach browse button $j("<input class=\\"ddAttachButton\\" type=\\"button\\" value=\\"' . $_lang['insert'] . '\\" />").insertAfter($field).on("click", function(){ ddMultiple[id].currentField = $j(this).siblings(".ddField"); ddMultiple[id].browseFuntion(id); }); } }else if (ddMultiple[id].coloumns[key] == "id"){ if (!($field.val())){ $field.val((new Date).getTime()); } col.hide(); }else if(ddMultiple[id].coloumns[key] == "select"){ $field.remove(); ddMultiple.makeSelect(val[key], ddMultiple[id].coloumnsTitle[key], ddMultiple[id].coloumnsData[key], ddMultiple[id].colWidth[key], col); } }); //Create DeleteButton ddMultiple.makeDeleteButton(id, ddMultiple.makeFieldCol($fieldBlock)); //При изменении и загрузке $j(".ddField", $fieldBlock).on("load.ddEvents change.ddEvents",function(){ $j(this).parents(".ddMultipleField:first").trigger("change.ddEvents"); }); //Специально для полей, содержащих изображения необходимо инициализировать $j(".ddFieldCol:has(.ddField_image) .ddField", $fieldBlock).trigger("change.ddEvents"); return $fieldBlock; }, //Создание колонки поля makeFieldCol: function(fieldRow){ return $j("<td class=\\"ddFieldCol\\"></td>").appendTo(fieldRow); }, //Make delete button makeDeleteButton: function(id, fieldCol){ $j("<input class=\\"ddDeleteButton\\" type=\\"button\\" value=\\"×\\" />").appendTo(fieldCol).on("click", function(){ //Проверяем на минимальное количество строк if (ddMultiple[id].minRow && $j("#"+id+"ddMultipleField .ddFieldBlock").length <= ddMultiple[id].minRow) return; var $this = $j(this), $par = $this.parents(".ddFieldBlock:first"), $table = $this.parents(".ddMultipleField:first"); //Отчистим значения полей $par.find(".ddField").val(""); //Если больше одной строки, то можно удалить текущую строчку if ($par.siblings(".ddFieldBlock").length > 0){ $par.fadeOut(300,function(){ //Если контейнер имеет кнопку добалвения, перенесём её if ($par.find(".ddAddButton").length > 0){ ddMultiple.moveAddButton(id, $par.prev(".ddFieldBlock")); } $par.remove(); //Инициализируем событие изменения $table.trigger("change.ddEvents"); return; }); } //Инициализируем событие изменения $table.trigger("change.ddEvents"); }); }, //Функция создания кнопки +, вызывается при инициализации makeAddButton: function(id){ $j("<input class=\\"ddAddButton\\" type=\\"button\\" value=\\"+\\" />").appendTo($j("#"+id+"ddMultipleField .ddFieldBlock:last .ddFieldCol:last")).on("click", function(){ //Вешаем на кнопку создание новой строки $j(this).appendTo(ddMultiple.makeFieldRow(id, "").find(".ddFieldCol:last")); $j(this).parents(".ddMultipleField:first").trigger("change.ddEvents"); }); }, //Перемещение кнопки + moveAddButton: function(id, target){ //Если не передали, куда вставлять, вставляем в самый конец if (!target) target = $j("#"+id+"ddMultipleField .ddFieldBlock:last"); //Находим кнопку добавления и переносим куда надо $j("#"+id+"ddMultipleField .ddAddButton:first").appendTo(target.find(".ddFieldCol:last")); }, //Make text field makeText: function(value, title, width, fieldCol){ return $j("<input type=\\"text\\" value=\\""+value+"\\" title=\\""+title+"\\" style=\\"width:"+width+"px;\\" class=\\"ddField\\" />").appendTo(fieldCol); }, //Make image field makeImage: function(id, fieldCol){ // Create a new preview and Attach a browse event to the picture, so it can trigger too $j("<div class=\\"ddField_image\\"><img src=\\"\\" style=\\""+ddMultiple[id].imageStyle+"\\" /></div>").appendTo(fieldCol).hide().find("img").on("click", function(){ fieldCol.find(".ddAttachButton").trigger("click"); }).on("load.ddEvents", function(){ //Удаление дерьма, блеать (превьюшка, оставленная от виджета showimagetvs) $j("#"+id+"PreviewContainer").remove(); }); //Находим поле, привязываем события $j(".ddField", fieldCol).on("change.ddEvents load.ddEvents", function(){ var $this = $j(this), url = $this.val(); url = (url != "" && url.search(/http:\\/\\//i) == -1) ? ("' . $site . '" + url) : url; //If field not empty if (url != ""){ //Show preview $this.siblings(".ddField_image").show().find("img").attr("src", url); }else{ //Hide preview $this.siblings(".ddField_image").hide(); } })/*.trigger("change.ddEvents")*/; }, //Функция создания списка makeSelect: function(value, title, data, width, fieldCol){ var $select = $j("<select class=\\"ddField\\">"); if (data){ var dataMas = $j.parseJSON(data); var options = ""; $j.each(dataMas, function(index){ options += "<option value=\\""+ dataMas[index][0] +"\\">" + (dataMas[index][1] ? dataMas[index][1] : dataMas[index][0]) +"</option>"; }); $select.append(options); } if (value) $select.val(value); return $select.appendTo(fieldCol); }, //Функция ничего не делает makeNull: function(id, fieldCol){return false;}, //Маскирует кавычки maskQuoutes: function(text){ text = text.replace(/"/g, """); text = text.replace(/\'/g, "'"); return text; } }; //If we have imageTVs on this page, modify the SetUrl function so it triggers a "change" event on the URL field $j(function(){ if (typeof(SetUrl) != "undefined") { var OldSetUrl = SetUrl; // Copy the existing Image browser SetUrl function SetUrl = function(url, width, height, alt){ // Redefine it to also tell the preview to update if(lastFileCtrl) { var c = $j(document.mutate[lastFileCtrl]); } else if(lastImageCtrl) { var c = $j(document.mutate[lastImageCtrl]); } OldSetUrl(url, width, height, alt); c.trigger("change"); }; } }); } '; foreach ($tvsMas as $tv) { if ($tv['type'] == 'image') { $browseFuntion = 'BrowseServer'; $makeFieldFunction = 'makeImage'; } else { if ($tv['type'] == 'file') { $browseFuntion = 'BrowseFileServer'; $makeFieldFunction = 'makeNull'; } else { $browseFuntion = 'false'; $makeFieldFunction = 'makeNull'; } } $output .= ' //Attach new load event $j("#tv' . $tv['id'] . '").on("load.ddEvents", function(event){ var $this = $j(this), //Оригинальное поле id = $this.attr("id");//id оригинального поля //Проверим на существование (возникали какие-то непонятные варианты, при которых два раза вызов был) if (!ddMultiple[id]){ //Инициализация текущего объекта с правилами ddMultiple[id] = { splY: "' . $splY . '", splX: "' . $splX . '", coloumns: "' . $coloumns . '".split(","), coloumnsTitle: "' . $coloumnsTitle . '".split(","), coloumnsData: \'' . $coloumnsData . '\'.split("||"), colWidth: "' . $colWidth . '".split(","), imageStyle: "' . $stylePrewiew . '", minRow: parseInt("' . $minRow . '", 10), maxRow: parseInt("' . $maxRow . '", 10), makeFieldFunction: ddMultiple.' . $makeFieldFunction . ', browseFuntion: ' . $browseFuntion . ' }; //Скрываем оригинальное поле $this.removeClass("imageField").addClass("originalField").hide(); //Назначаем обработчик события при изменении (необходимо для того, чтобы после загрузки фотки адрес вставлялся в нужное место) $this.on("change.ddEvents", function(){ //Обновляем текущее мульти-поле ddMultiple.updateField($this.attr("id")); }); //Если это файл или изображение, cкрываем оригинальную кнопку if (ddMultiple[id].browseFuntion){$this.next("input[type=button]").hide();} //Создаём мульти-поле ddMultiple.init(id, $this.val(), $this.parent()); } }).trigger("load"); '; } $output .= "\n// ---------------- mm_ddMultipleFields :: End -------------"; $e->output($output . "\n"); } }
/** * mm_widget_showimagetvs * @version 1.1 (2012-11-13) * * Shows a preview of image TVs. * Emulates showimagestv plugin, which is not compatible with ManagerManager. * * @uses ManagerManager plugin 0.4. * * @link http://code.divandesign.biz/modx/mm_widget_showimagetvs/1.1 * * @copyright 2012 */ function mm_widget_showimagetvs($tvs = '', $w = 300, $h = 100, $thumbnailerUrl = '', $roles = '', $templates = '') { global $modx, $content; $e =& $modx->Event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $output = ''; $site = $modx->config['site_url']; if (isset($w) || isset($h)) { $w = isset($w) ? $w : 300; $h = isset($h) ? $h : 100; $style = "'max-width:{$w}px; max-height:{$h}px; margin: 4px 0; cursor: pointer;'"; } else { $style = ''; } // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } // Does this page's template use any image TVs? If not, quit now! $tvs = tplUseTvs($page_template, $tvs, 'image'); if ($tvs == false) { return; } $output .= "// -------------- mm_widget_showimagetvs :: Begin ------------- \n"; // Go through each TV foreach ($tvs as $tv) { $new_html = ''; $output .= ' // Adding preview for tv' . $tv['id'] . ' $j("#tv' . $tv['id'] . '").addClass("imageField").bind("change load", function(){ var $this = $j(this), // Get the new URL url = $this.val(); $this.data("lastvalue", url); url = (url != "" && url.search(/http:\\/\\//i) == -1) ? ("' . $site . '" + url) : url; '; // If we have a PHPThumb URL if (!empty($thumbnailerUrl)) { $output .= 'url = "' . $thumbnailerUrl . '?src="+escape(url)+"&w=' . $w . '&h=' . $h . '"; ' . "\n"; } $output .= ' // Remove the old preview tv' . $tv['id'] . ' $j("#tv' . $tv['id'] . 'PreviewContainer").remove(); if (url != ""){ // Create a new preview $j("#tv' . $tv['id'] . '").parents("td").append("<div class=\\"tvimage\\" id=\\"tv' . $tv['id'] . 'PreviewContainer\\"><img src=\\""+url+"\\" style=\\""+' . $style . '+"\\" id=\\"tv' . $tv['id'] . 'Preview\\"/></div>"); // Attach a browse event to the picture, so it can trigger too $j("#tv' . $tv['id'] . 'Preview").click(function(){ BrowseServer("tv' . $tv['id'] . '"); }); } }).trigger("load"); // Trigger a change event on load '; } $output .= ' // Monitor the image TVs for changes checkImageTVupdates = function(){ $j(".imageField").each(function(){ var $this = $j(this); if ($this.val() != $this.data("lastvalue")){ $this.trigger("change"); } }); } setInterval ("checkImageTVupdates();", 250); '; $output .= "// -------------- mm_widget_showimagetvs :: End ------------- \n"; $e->output($output . "\n"); } }
/** * mm_ddMaxLength * @version 1.0.1 (2012-01-13) * * Позволяет ограничить количество вводимых символов в TV. * * @copyright 2012, DivanDesign * http://www.DivanDesign.ru */ function mm_ddMaxLength($tvs = '', $roles = '', $templates = '', $length = 150) { global $modx, $content; $e =& $modx->Event; if ($e->name == 'OnDocFormRender' && useThisRule($roles, $templates)) { $output = ''; $site = $modx->config['site_url']; // Which template is this page using? if (isset($content['template'])) { $page_template = $content['template']; } else { // If no content is set, it's likely we're adding a new page at top level. // So use the site default template. This may need some work as it might interfere with a default template set by MM? $page_template = $modx->config['default_template']; } // $tvsMas = array(); // Does this page's template use any image or file or text TVs? $tvs = tplUseTvs($page_template, $tvs, 'text,textarea'); // $tvsTemp = tplUseTvs($page_template, $tvs, 'text'); // if ($tvsTemp){ // foreach($tvsTemp as $v){ // $v['type'] = 'text'; // array_push($tvsMas,$v); // } // } // if (count($tvsMas) == 0){ // return; // } if ($tvs == false) { return; } $output .= "// ---------------- mm_ddMaxLength :: Begin ------------- \n"; //General functions $output .= includeJs($site . 'assets/plugins/managermanager/widgets/ddmaxlength/jquery.ddmaxlength-1.0.min.js'); $output .= includeCss($site . 'assets/plugins/managermanager/widgets/ddmaxlength/ddmaxlength.css'); foreach ($tvs as $tv) { $output .= ' $j("#tv' . $tv['id'] . '").addClass("ddMaxLengthField").each(function(){ $j(this).parent().append("<div class=\\"ddMaxLengthCount\\"><span></span></div>"); }).ddMaxLength({ max: ' . $length . ', containerSelector: "div.ddMaxLengthCount span", warningClass: "maxLenghtWarning" }); '; } $output .= ' $j("#mutate").submit(function(){ var ddErrors = new Array(); $j("div.ddMaxLengthCount span").each(function(){ var $this = $j(this), field = $this.parents(".ddMaxLengthCount:first").parent().find(".ddMaxLengthField"); if (parseInt($this.text()) < 0){ field.addClass("maxLenghtErrorField").focus(function(){ field.removeClass("maxLenghtErrorField"); }); ddErrors.push(field.parents("tr").find("td:first-child .warning").text()); } }); if(ddErrors.length > 0){ alert("Некорректно заполнены поля: " + ddErrors.join(",")); return false; } else { return true; } }); '; $output .= "\n// ---------------- mm_ddMaxLength :: End -------------"; $e->output($output . "\n"); } }