среда, 16 января 2008 г.

сортировка файлов по алфавиту в FCK-менеджере ресурсов

Очень и очень долго рыл по этому вопросу форум и ничего не нашел. Папки и файлы в менеджере ресурсов FCK-Editor (который стоит сейчас по умолчанию как менеджер файлов для TV и прочего) выводятся в соответствии с установками сервера на котором хостится сайт. В большинстве случаев сортировка идет по дате последнего изменения. Когда этих папок становится много, приятней было бы сортировать по алфавиту.

Повторюсь, что на форуме нашел много постов с этим же вопросом, но ни одного вменяемого ответа. Попробовал сам подредактировать mcpuck-коннектор - не осилил.

И вот, мои поиски увенчались успехом - отличное изящное решение от немецкого сообщества MODx (распакуйте архив в корень сайта)

задание шаблона по умолчанию для дочерних документов определенного родителя

Очень давно меня беспокоила необходимость постоянно задавать шаблон для новых документов. Когда речь не идет о периодической информации - шаблон задать нетрудно, однако когда необходимо создавать по нескольку документов в минуту - вопрос стоит достаточно остро. К тому же, ваш заказчик, сам администрируя сайт, может просто забыть выставить нужный шаблон.

В последних версиях MODx появился плагин Inherit Parent Template, с помощью которого можно было создать неопубликованный контейнер и задать ему нужный шаблон, тогда все дочерние документы наследовали этот шаблон. Однако этот способ вынуждал делать лишние контейнеры для каждой категории и создавать иерархию меню отдельно от документов контента.

Итак, хочу представить более менее приемлемое решение. Мы немного изменим вышеупомянутый плагин, чтобы задать родительские документы, новые(!) дочерние документы которых будут автоматически принимать заданный шаблон. Сразу оговорюсь, в моем случае пришлось задавать суперродителей (родителей родителей), однако закомментировав одну строку плагина вы можете иметь возможность задавать просто родителей.

Код нового плагина "Inherit Parent Template" (его можно просто заменить поверх старого):
/*
* Inherit Template from Parent
* Written By Raymond Irving - 12 Oct 2006
*
* Simply results in new documents inherriting the template
* of their parent folder upon creating a new document
*
* Configuration:
* check the OnDocFormPrerender event
*
* Version 1.0
*
*/



global $content;
$e = &$modx->Event;

$parents_and_templates = array (
'4818' => '5', // id родителя => id шаблона (можно посмотреть в БД)
'4817' => '6'
);

switch($e->name) {
case 'OnDocFormPrerender':
if(($_REQUEST['pid'] > 0) && ($id == 0)) {
$parent = $modx->getPageInfo($_REQUEST['pid'],0,'id, parent, template');
$parent = $modx->getPageInfo($parent['parent'],0,'id, parent, template'); //закомментируйте эту строку, если вам нужен родитель первого уровня
$pid = $parent['id'];
if (array_key_exists($pid,$parents_and_templates)) {
$content['template'] = $parents_and_templates[$pid];
}
else {
$content['template'] = $parent['template'];
}
}
break;

default:
return;
break;
}

задать родительский документ и соответствующий шаблон можно в массиве
$parents_and_templates = array (
'4818' => '5',
'4817' => '6'
);

понедельник, 14 января 2008 г.

добавление поля редактирования даты создания документа (createdon) в менеджере

Одной из проблем, с которыми приходилось сталкиваться не раз - запись даты создания документа задним числом. Можно создавать TV типа date, можно записывать даты в pub_date и тд. Однако, если вы не задаете абсолютно всем документам дату в своем параметре и для каких то документов он остается пустым - возникнут проблемы с сортировкой этих документов с помощью Ditto.

Вот захотелось набраться наглости и сделать в панели редактирования документа дополнительное поле, позволяющее редактировать дату создания документа (createdon). Создавая документ задним числом, вы просто редактируете дату его создания, а по умолчанию естественно задается текущая дата. Итак нужно выполнить следующие шаги:
  1. в manager/actions/mutate_content.dynamic.php меняем
    // retain form values if template was changed
    // edited to convert pub_date and unpub_date
    // sottwell 02-09-2006
    if ($formRestored == true || isset ($_REQUEST['newtemplate'])) {
    $content = array_merge($content, $_POST);
    $content["content"] = $_POST["ta"];
    if (empty ($content["pub_date"])) {
    unset ($content["pub_date"]);
    } else {
    $pub_date = $content['pub_date'];
    list ($d, $m, $Y, $H, $M, $S) = sscanf($pub_date, "%2d-%2d-%4d %2d:%2d:%2d");
    $pub_date = strtotime("$m/$d/$Y $H:$M:$S");
    $content['pub_date'] = $pub_date;
    }
    if (empty ($content["unpub_date"])) {
    unset ($content["unpub_date"]);
    } else {
    $unpub_date = $content['unpub_date'];
    list ($d, $m, $Y, $H, $M, $S) = sscanf($unpub_date, "%2d-%2d-%4d %2d:%2d:%2d");
    $unpub_date = strtotime("$m/$d/$Y $H:$M:$S");
    $content['unpub_date'] = $unpub_date;
    }
    }
    на
    // retain form values if template was changed
    // edited to convert pub_date and unpub_date
    // sottwell 02-09-2006
    if ($formRestored == true || isset ($_REQUEST['newtemplate'])) {
    $content = array_merge($content, $_POST);
    $content["content"] = $_POST["ta"];
    if (empty ($content["pub_date"])) {
    unset ($content["pub_date"]);
    } else {
    $pub_date = $content['pub_date'];
    list ($d, $m, $Y, $H, $M, $S) = sscanf($pub_date, "%2d-%2d-%4d %2d:%2d:%2d");
    $pub_date = strtotime("$m/$d/$Y $H:$M:$S");
    $content['pub_date'] = $pub_date;
    }
    if (empty ($content["unpub_date"])) {
    unset ($content["unpub_date"]);
    } else {
    $unpub_date = $content['unpub_date'];
    list ($d, $m, $Y, $H, $M, $S) = sscanf($unpub_date, "%2d-%2d-%4d %2d:%2d:%2d");
    $unpub_date = strtotime("$m/$d/$Y $H:$M:$S");
    $content['unpub_date'] = $unpub_date;
    }

    if (empty ($content["createdon"])) {
    unset ($content["createdon"]);
    } else {
    $createdon = $content['createdon'];
    list ($d, $m, $Y, $H, $M, $S) = sscanf($createdon, "%2d-%2d-%4d %2d:%2d:%2d");
    $createdon = strtotime("$m/$d/$Y $H:$M:$S");
    $content['createdon'] = $createdon;
    }
    }

  2. добавляем в manager/actions/mutate_content.dynamic.php до строки 700(приблизительно, строка содержит <input name="pub_date">
    <tr>
    <td><span class="warning">Дата создания</span></td>
    <td>
    <?php
    $timestamp = time();
    ?>
    <input name="createdon" value="<?php echo $content['createdon']=="0" || !isset($content['createdon']) ? strftime("%d-%m-%Y %H:%M:%S", $timestamp) : strftime("%d-%m-%Y %H:%M:%S", $content['createdon']); ?>" onblur="documentDirty=true;" />
    <a onclick="documentDirty=false; cal0.popup();" onmouseover="window.status='<?php echo $_lang['select_date']; ?>'; return true;" onmouseout="window.status=''; return true;" style="cursor:pointer; cursor:hand"><img src="media/style/<?php echo $manager_theme ? "$manager_theme/":""; ?>images/icons/cal.gif" width="16" height="16" border="0" alt="<?php echo $_lang['select_date']; ?>" /></a>
    </td>
    </tr>
  3. добавляем в manager/actions/mutate_content.dynamic.php в самый конец файла, в после строки
    <script type="text/javascript">
    ... следующий код:
      var cal0 = new calendar1(document.forms['mutate'].elements['createdon'], document.getElementById("pub_date_show"));
    cal0.path="<?php echo str_replace("index.php", "media/", $_SERVER["PHP_SELF"]); ?>";
    cal0.year_scroll = true;
    cal0.time_comp = true;
  4. добавляем в manager/processors/save_content.processor.php после строки "$hidemenu = intval($_POST['hidemenu']);":
    $createdon = $_POST['createdon'];
    list ($d, $m, $Y, $H, $M, $S) = sscanf($createdon, "%2d-%2d-%4d %2d:%2d:%2d"); //added by yentsun
    $createdon = mktime($H, $M, $S, $m, $d, $Y);
  5. в manager/processors/save_content.processor.php меняем sql-запрос, начинающийся с INSERT на
    $sql = "INSERT INTO $tblsc (introtext,content, pagetitle, longtitle, type, description, alias, link_attributes, isfolder, richtext, published, parent, template, menuindex, searchable, cacheable, createdby, createdon, editedby, editedon, publishedby, publishedon, pub_date, unpub_date, contentType, content_dispo, donthit, menutitle, hidemenu)
    VALUES('" . $introtext . "','" . $content . "', '" . $pagetitle . "', '" . $longtitle . "', '" . $type . "', '" . $description . "', '" . $alias . "', '" . $link_attributes . "', '" . $isfolder . "', '" . $richtext . "', '" . $published . "', '" . $parent . "', '" . $template . "', '" . $menuindex . "', '" . $searchable . "', '" . $cacheable . "', '" . $modx->getLoginUserID() . "', " . $createdon . ", '" . $modx->getLoginUserID() . "', " . time() . ", " . $publishedby . ", " . $publishedon . ", '$pub_date', '$unpub_date', '$contentType', '$contentdispo', '$donthit', '$menutitle', '$hidemenu')";
    , блок
    $sql = "UPDATE $tblsc SET introtext='$introtext', content='$content', pagetitle='$pagetitle', longtitle='$longtitle', type='$type', description='$description', alias='$alias', link_attributes='$link_attributes',
    isfolder=$isfolder, richtext=$richtext, published=$published, pub_date=$pub_date, unpub_date=$unpub_date, parent=$parent, template=$template, menuindex='$menuindex',
    searchable=$searchable, cacheable=$cacheable, editedby=" . $modx->getLoginUserID() . ", editedon=" . time() . ", publishedon=$publishedon, publishedby=$publishedby, contentType='$contentType', content_dispo='$contentdispo', donthit='$donthit', menutitle='$menutitle', hidemenu='$hidemenu' WHERE id=$id;";
    на
    $sql = "UPDATE $tblsc SET introtext='$introtext', content='$content', pagetitle='$pagetitle', longtitle='$longtitle', type='$type', description='$description', alias='$alias', link_attributes='$link_attributes',
    isfolder=$isfolder, richtext=$richtext, published=$published, pub_date=$pub_date, unpub_date=$unpub_date, parent=$parent, template=$template, menuindex='$menuindex',
    searchable=$searchable, cacheable=$cacheable, editedby=" . $modx->getLoginUserID() . ", editedon=" . time() . ", publishedon=$publishedon, publishedby=$publishedby, contentType='$contentType', content_dispo='$contentdispo', donthit='$donthit', menutitle='$menutitle', hidemenu='$hidemenu', createdon='$createdon' WHERE id=$id;";
    (добавляем в хвост запроса строку createdon='$createdon')


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

Хотите запечатлеть важнейшие моменты в жизни? Воспользуйтесь свадебной фотографией Марины Салмановой.

четверг, 10 января 2008 г.

выод лимитированного количества теговых ссылок

Задача: есть некое количество документов, в которых слишком много тегов. Это конечно не нормальная ситуация, однако предположим что такие документы есть и нам нужно выводить тегов не более заданного числа

Решение: плейсхолдер Ditto [+tagLinks+], отвечающий за вывод теговых ссылок, параметра лимитирования не имеет, поэтому нам придется написать свой phx-фильтр:

$options = explode('|', $options);

$delimiter = (!empty($options[0])) ? $options[0] : ', ';
$links_limit = (!empty($options[1])) ? $options[1] : 3;
$url = $options[2];
$links_class = (!empty($options[3])) ? $options[3] : 'tag_link';

$array = explode($delimiter, $output);
$tail = (count($array)>$links_limit) ? '...' : '';
for ($i=0; $i<=$links_limit-1; $i++) {
$retval .= '<a class="'.$links_class.'" href="[(base_url)]'.$url.'?tags='.urlencode($array[$i]).'">'.$array[$i].'</a>';
}
return $retval.$tail;

назовем его например phx:taglinks_limited и вызовем следующим образом (в шаблоне Ditto):
[+tags:taglinks_limited=`, |2|[~[*id*]~]|ditto_tag`+]

параметры нашего фильтра разделяются символом "|" и расшифровываются как разделитель тегов|количество выводимых ссылок|url страницы с выводом документов по тегу|CSS-класс теговых ссылок

нюансы перехода от windows-1251 к utf-8

Проблема: после перехода сайта на utf-8 все работает нормально за исключением следующих моментов
  • фраза "без категории" в управлении ресурсами отображается как "??? ?????????"
  • после сохранения кода сниппетов, чанков и тд, все кириллические символы внутри превращаются в вопросы
Причина: не настроена кодировка соединения самого менеджера с базой (или какого то его блока)

Решение: взято из форума. В файле manager/index.php около строки 133...

    mysql_select_db($dbase);
mysql_query("SET NAMES 'utf8';",$modxDBConn);
mysql_query("SET CHARACTER SET 'utf8';",$modxDBConn);
mysql_query("SET SESSION collation_connection = 'utf8_general_ci';",$modxDBConn);
В некоторых случаях придется сделать похожие изменения и в файле manager/includes/extenders/dbapi.mysql.class.inc.php около 90 строки (см. сообщение в форуме)

считывание файла xls с помощью php

Задача: считать информацию из файла Excel в массивы php для последующего вывода в динамический файл javascript.

Решение: отлично справляется бесплатный скрипт PHP-ExcelReader, созданный нашим соотечественником, Вадимом Ткаченко.

Пример калькулятора, работающего от подгружаемого xls-файла можно найти на сайте tclogic.ru