energine
[ class tree: energine ] [ index: energine ] [ all elements ]

Source for file DataSet.class.php

Documentation is available at DataSet.class.php

  1. <?php
  2. /**
  3.  * Содержит класс DataSet
  4.  *
  5.  * @package energine
  6.  * @subpackage share
  7.  * @author dr.Pavka
  8.  * @copyright Energine 2006
  9.  * @version $Id: DataSet.class.php,v 1.32 2008/12/13 14:10:09 pavka Exp $
  10.  */
  11.  
  12. //require_once('core/framework/Component.class.php');
  13. //require_once('core/framework/DataDescription.class.php');
  14. //require_once('core/framework/Data.class.php');
  15. //require_once('core/framework/SimpleBuilder.class.php');
  16. //require_once('core/framework/Pager.class.php');
  17. //require_once('core/modules/share/components/Toolbar.class.php');
  18.  
  19. /**
  20.  * Предок для формы, списка, и дерева; содержит методы работы с панелью инструментов и набором данных.
  21.  *
  22.  * @package energine
  23.  * @subpackage share
  24.  * @author dr.Pavka
  25.  * @abstract
  26.  */
  27. abstract class DataSet extends Component {
  28.  
  29.     /**
  30.      * Тип компонента - список
  31.      */
  32.     const COMPONENT_TYPE_LIST = 'list';
  33.  
  34.     /**
  35.      * Тип компонента - форма
  36.      */
  37.     const COMPONENT_TYPE_FORM = 'form';
  38.  
  39.     /**
  40.      * Тип формы - форма добавления
  41.      */
  42.     const COMPONENT_TYPE_FORM_ADD = QAL::INSERT;
  43.  
  44.     /**
  45.      * Тип формы - форма редактирования
  46.      */
  47.     const COMPONENT_TYPE_FORM_ALTER = QAL::UPDATE;
  48.  
  49.     /**
  50.      * Префикс названия панели инструментов
  51.      */
  52.     const TB_PREFIX = 'toolbar_';
  53.  
  54.     /**
  55.      * Описание данных
  56.      *
  57.      * @var DataDescription 
  58.      * @access private
  59.      */
  60.     private $dataDescription = false;
  61.  
  62.     /**
  63.      * Данные
  64.      *
  65.      * @var Data 
  66.      * @access private
  67.      */
  68.     private $data = false;
  69.  
  70.     /**
  71.      * Панели инструментов
  72.      *
  73.      * @var array of Toolbar
  74.      * @access private
  75.      */
  76.     private $toolbar = array();
  77.  
  78.     /**
  79.      * JavaScript
  80.      *
  81.      * @var DOMNode 
  82.      * @access protected
  83.      */
  84.     protected $js;
  85.  
  86.     /**
  87.      * Тип компонента
  88.      *
  89.      * @var string 
  90.      * @access private
  91.      */
  92.     private $type;
  93.  
  94.     /**
  95.      * Переводы которые добавляются к форме/списку
  96.      *
  97.      * @var array 
  98.      * @access private
  99.      */
  100.     //private $translations = array();
  101.  
  102.  
  103.     /**
  104.      * Список страниц (pager)
  105.      *
  106.      * @var Pager 
  107.      */
  108.     protected $pager;
  109.  
  110.  
  111.     /**
  112.      * Конструктор класса
  113.      *
  114.      * @return void 
  115.      */
  116.     public function __construct($name$moduleDocument $document,  array $params null{
  117.         parent::__construct($name$module$document,  $params);
  118.         $this->setType(self::COMPONENT_TYPE_FORM);
  119.         if(!$this->getParam('recordsPerPage'))$this->setParam('recordsPerPage'20);
  120.         if($this->getParam('title'))
  121.         $this->setTitle(
  122.         $this->translate($this->getParam('title')
  123.         )
  124.         );
  125.     }
  126.  
  127.     /**
  128.      * Добавлены:
  129.      * Параметр datasetAction
  130.      * Параметр recordsPerPage
  131.      *
  132.      * @return array 
  133.      * @access protected
  134.      */
  135.     protected function defineParams({
  136.         $this->setProperty('action''');
  137.         return array_merge(
  138.         parent::defineParams(),
  139.         array(
  140.         'datasetAction' => '',
  141.         'recordsPerPage' => false,
  142.         'title' => false
  143.         )
  144.         );
  145.     }
  146.  
  147.     /**
  148.      * Устанавливает данные
  149.      *
  150.      * @return void 
  151.      * @access protected
  152.      * @final
  153.      */
  154.     final protected function setData(Data $data{
  155.         $this->data $data;
  156.     }
  157.  
  158.     /**
  159.      * Возвращает объект данных
  160.      *
  161.      * @return Data 
  162.      * @access protected
  163.      * @final
  164.      */
  165.     final protected function getData({
  166.         return $this->data;
  167.     }
  168.  
  169.     /**
  170.      * Возвращает набор тулбаров
  171.      *
  172.      * @param string $toolbarName 
  173.      * @return mixed (array of ToolBar or Toolbar)
  174.      * @access protected
  175.      */
  176.  
  177.     protected function getToolbar($toolbarName false{
  178.         $result array();
  179.         if(!$toolbarName){
  180.             $result $this->toolbar;
  181.         }
  182.         elseif(isset($this->toolbar[$toolbarName])){
  183.             $result $this->toolbar[$toolbarName];
  184.         }
  185.  
  186.         return $result;
  187.     }
  188.     /**
  189.      * Устанавливает объекты тулбара
  190.      *
  191.      * @param mixed 
  192.      * @return void 
  193.      * @access protected
  194.      */
  195.  
  196.     protected function addToolbar($toolbar{
  197.         if(!is_array($toolbar)){
  198.             $toolbar array($toolbar);
  199.         }
  200.         foreach ($toolbar as $tb)
  201.         if($tb instanceof Toolbar){
  202.             $this->toolbar[$tb->getName()$tb;
  203.         }
  204.         else{
  205.             throw new SystemException('ERR_BAD_TOOLBAR'SystemException::ERR_DEVELOPER);
  206.         }
  207.     }
  208.  
  209.     /**
  210.      * Устанавливает описание данных
  211.      *
  212.      * @return void 
  213.      * @access protected
  214.      * @final
  215.      */
  216.     final protected function setDataDescription(DataDescription $dataDescription{
  217.         $this->dataDescription $dataDescription;
  218.     }
  219.  
  220.     /**
  221.      * Возвращает описание данных
  222.      *
  223.      * @return DataDescription 
  224.      * @access protected
  225.      * @final
  226.      */
  227.     final protected function getDataDescription({
  228.         // Существует ли описание данных?
  229.         // Без описания данных компонент не сможет нормально работать.
  230.         if (!$this->dataDescription{
  231.             throw new SystemException('ERR_DEV_NO_DATA_DESCRIPTION'SystemException::ERR_DEVELOPER$this->getName());
  232.         }
  233.  
  234.         // Описание данных не должно быть пустым
  235.         if ($this->dataDescription->getLength(== 0{
  236.             //throw new SystemException('ERR_DEV_EMPTY_DATA_DESCRIPTION', SystemException::ERR_DEVELOPER, $this->getName());
  237.         }
  238.  
  239.         return $this->dataDescription;
  240.     }
  241.  
  242.     /**
  243.      * Подготовительные действия перед вызовом основного действия.
  244.      *
  245.      * @return void 
  246.      * @access protected
  247.      */
  248.     protected function prepare({
  249.         $this->setBuilder($this->createBuilder());
  250.         $this->setDataDescription($this->createDataDescription());
  251.         $this->createPager();
  252.         $data $this->createData();
  253.         if ($data instanceof Data{
  254.             $this->setData($data);
  255.         }
  256.  
  257.         $toolbars $this->createToolbar();
  258.  
  259.         if (!empty($toolbars)) {
  260.             $this->addToolbar($toolbars);
  261.         }
  262.         $this->js $this->buildJS();
  263.     }
  264.  
  265.     /**
  266.      * Создает построитель
  267.      *
  268.      * @return Builder 
  269.      * @access protected
  270.      */
  271.     protected function createBuilder({
  272.         return new SimpleBuilder($this->getTitle());
  273.     }
  274.  
  275.     /**
  276.      * Создаем объект описания данных
  277.      *
  278.      * @return DataDescription 
  279.      * @access protected
  280.      */
  281.     protected function createDataDescription({
  282.         // описание данных из конфигурации
  283.         $configDataDescriptionObject new DataDescription();
  284.         if ($this->config->getCurrentMethodConfig()) {
  285.             $configDataDescriptionObject->loadXML($this->config->getCurrentMethodConfig()->fields);
  286.         }
  287.  
  288.  
  289.         // внешнее описание данных
  290.         $externalDataDescription $this->loadDataDescription();
  291.         if (is_null($externalDataDescription)) {
  292.             throw new SystemException('ERR_DEV_LOAD_DATA_DESCR_IS_FUNCTION'SystemException::ERR_DEVELOPER);
  293.         }
  294.  
  295.         // если существует внешнее описание данных - пересекаем с описанием из конфиг
  296.         if ($externalDataDescription{
  297.             $externalDataDescriptionObject new DataDescription();
  298.             $externalDataDescriptionObject->load($externalDataDescription);
  299.             $configDataDescriptionObject $configDataDescriptionObject->intersect($externalDataDescriptionObject);
  300.         }
  301.  
  302.         return $configDataDescriptionObject;
  303.     }
  304.  
  305.     /**
  306.      * Создание панелей инструментов
  307.      *
  308.      * @return array 
  309.      * @access protected
  310.      */
  311.     protected function createToolbar({
  312.         $result array();
  313.         if ($config $this->config->getCurrentMethodConfig()) {
  314.             foreach($config->toolbar as $toolbarDescription){
  315.                 $toolbarName ((string)$toolbarDescription['name'])?
  316.                 (string)$toolbarDescription['name']:
  317.                 self::TB_PREFIX.$this->getName();
  318.  
  319.                 $toolbar new Toolbar($toolbarName);
  320.                 $toolbar->attachToComponent($this);
  321.                 $toolbar->loadXML($toolbarDescription);
  322.                 $toolbar->translate();
  323.                 $result[$toolbarName$toolbar;
  324.             }
  325.         }
  326.         return $result;
  327.     }
  328.  
  329.     /**
  330.      * Создает листалку
  331.      *
  332.      * @return void 
  333.      * @access protected
  334.      */
  335.  
  336.     protected function createPager({
  337.         $recordsPerPage intval($this->getParam('recordsPerPage'));
  338.         if ($recordsPerPage 0{
  339.             $this->pager new Pager($recordsPerPage);
  340.             if ($this->isActive(&& $this->getType(== self::COMPONENT_TYPE_LIST{
  341.                 $actionParams $this->getActionParams();
  342.                 if (isset($actionParams[0])) {
  343.                     $page intval($actionParams[0]);
  344.                 }
  345.                 else {
  346.                     $page 1;
  347.                 }
  348.                 $this->pager->setCurrentPage($page);
  349.             }
  350.  
  351.             $this->pager->setProperty('title'$this->translate('TXT_PAGES'));
  352.         }
  353.     }
  354.  
  355.     /**
  356.      * Абстрактный метод загрузки данных
  357.      *
  358.      * @return mixed 
  359.      * @access protected
  360.      */
  361.     protected function loadData({
  362.         return false;
  363.     }
  364.  
  365.     /**
  366.      * Абстрактный метод загрузки описания данных
  367.      * Используется для загрузки внешнего описания данных (не из конфигурации)
  368.      *
  369.      * @return mixed 
  370.      * @access protected
  371.      */
  372.     protected function loadDataDescription({
  373.         return false;
  374.     }
  375.  
  376.     /**
  377.      * Проверяет наличие пострителя
  378.      * передает ему данные и описание данны
  379.      *
  380.      * @return DOMDocument 
  381.      * @access public
  382.      */
  383.     public function build({
  384.         if (!$this->getBuilder()) {
  385.             throw new SystemException('ERR_DEV_NO_BUILDER'SystemException::ERR_CRITICAL$this->getName());
  386.         }
  387.  
  388.         // передаем данные и описание данных построителю
  389.         if ($this->getData()) {
  390.             $this->getBuilder()->setData($this->getData());
  391.         }
  392.         $this->getBuilder()->setDataDescription($this->getDataDescription());
  393.  
  394.         // вызываем родительский метод построения
  395.         $result parent::build();
  396.  
  397.  
  398.         if ($this->js{
  399.             $result->documentElement->appendChild($result->importNode($this->jstrue));
  400.         }
  401.         $toolbars $this->getToolbar();
  402.  
  403.         if (!empty($toolbars)) 
  404.             foreach ($toolbars as $tb)
  405.                 if($toolbar $tb->build()){
  406.                  $result->documentElement->appendChild(
  407.                      $result->importNode($toolbartrue)
  408.                  );         
  409.                 }
  410.         if ($this->pager && $this->getType(== self::COMPONENT_TYPE_LIST && $pagerData $this->pager->build()) {
  411.             $pager $result->importNode($pagerDatatrue);
  412.             $result->documentElement->appendChild($pager);
  413.         }
  414.  
  415.         //Работа с константами переводов
  416.         if (($methodConfig $this->config->getCurrentMethodConfig()) && $methodConfig->translations{
  417.             foreach ($methodConfig->translations->translation as $translation{
  418.                 $this->addTranslation((string)$translation['const']);
  419.             }
  420.         }
  421.  
  422.         return $result;
  423.     }
  424.  
  425.     /**
  426.      * Загружает данные
  427.      *
  428.      * @return Data 
  429.      * @access protected
  430.      */
  431.     protected function createData({
  432.         $result false;
  433.         $data $this->loadData();
  434.         if (is_null($data)) {
  435.             throw new SystemException('ERR_DEV_LOAD_DATA_IS_FUNCTION'SystemException::ERR_DEVELOPER);
  436.         }
  437.         $result new Data();
  438.  
  439.         if (is_array($data)) {
  440.             $result->load($data);
  441.         }
  442.         return $result;
  443.     }
  444.  
  445.     /**
  446.      * Строит описание JS объектов
  447.      *
  448.      * @return DOMNode 
  449.      * @access protected
  450.      */
  451.     protected function buildJS({
  452.         $result false;
  453.         if (($config $this->config->getCurrentMethodConfig()) && $config->javascript{
  454.             $result $this->doc->createElement('javascript');
  455.             foreach ($config->javascript->include as $value{
  456.                 $JSIncludeXML $this->doc->createElement('include');
  457.                 $JSIncludeXML->setAttribute('name'$value['name']);
  458.                 $JSIncludeXML->setAttribute('path''scripts/');
  459.                 $result->appendChild($JSIncludeXML);
  460.             }
  461.             foreach ($config->javascript->object as $value{
  462.                 $JSObjectXML $this->doc->createElement('object');
  463.                 $JSObjectXML->setAttribute('name'$value['name']);
  464.                 $JSObjectXML->setAttribute('path''scripts/');
  465.                 $result->appendChild($JSObjectXML);
  466.             }
  467.             foreach ($config->javascript->param as $value{
  468.                 $JSParamXML $this->doc->createElement('param'$value);
  469.                 $JSParamXML->setAttribute('name'$value['name']);
  470.                 $result->appendChild($JSParamXML);
  471.             }
  472.         }
  473.         return $result;
  474.     }
  475.  
  476.     /**
  477.      * Устанавливает адрес обработчика формы
  478.      *
  479.      * @param string 
  480.      * @param bool 
  481.      * @access public
  482.      */
  483.     final protected function setDataSetAction($action$isFullURI false{
  484.         // если у нас не полностью сформированный путь, то добавляем информацию о языке + путь к шаблону
  485.         if (!$isFullURI{
  486.             $action $this->request->getLangSegment().
  487.             $this->request->getPath(Request::PATH_TEMPLATEtrue).
  488.             $action;
  489.  
  490.             // если в конце нет слеша - добавляем его
  491.             if (substr($action-1!= '/'{
  492.                 $action .= '/';
  493.             }
  494.         }
  495.  
  496.  
  497.  
  498.         $this->setParam('datasetAction'$action);
  499.         $this->setProperty('action'$action);
  500.     }
  501.  
  502.     /**
  503.      * Возвращает адрес обработчика формы
  504.      *
  505.      * @return string 
  506.      * @access public
  507.      */
  508.     final protected function getDataSetAction({
  509.         return $this->getParam('datasetAction');
  510.     }
  511.  
  512.     /**
  513.      * Устанавливает тип компонента
  514.      *
  515.      * @param string 
  516.      * @return void 
  517.      * @access protected
  518.      */
  519.     final protected function setType($type{
  520.         $this->type $type;
  521.         if (in_array($typearray(self::COMPONENT_TYPE_FORM_ADDself::COMPONENT_TYPE_FORM_ALTER ))) {
  522.             $type self::COMPONENT_TYPE_FORM;
  523.         }
  524.         $this->setProperty('type'$type);
  525.     }
  526.  
  527.     /**
  528.      * Возвращает тип компонента
  529.      *
  530.      * @return string 
  531.      * @access protected
  532.      */
  533.     final protected function getType({
  534.         return $this->type;
  535.     }
  536.  
  537.     /**
  538.      * Устанавливает название компонента
  539.      *
  540.      * @param string $title 
  541.      */
  542.     final protected function setTitle($title{
  543.         $this->setProperty('title'$title);
  544.     }
  545.  
  546.     /**
  547.      * Возвращает название компонента
  548.      *
  549.      * @return string 
  550.      */
  551.     final protected function getTitle({
  552.         return $this->getProperty('title');
  553.     }
  554.  
  555.     /**
  556.      * Добавляет переводы
  557.      *
  558.      * @return void 
  559.      * @access protected
  560.      * @final
  561.      */
  562.  
  563.     final protected function addTranslation($tag{
  564.         $this->document->addTranslation($tag$this);
  565.     }
  566.     /**
  567.      * Метод используется для форматирования даты и времени в полях date и datetime
  568.      * Запрашивается через AJAX
  569.      * Получает данные из POST и возвращает строку даты
  570.      *
  571.      * @return void 
  572.      * @access protected
  573.      * @final
  574.      */
  575.     final protected function formatDate(){
  576.         $result '';
  577.  
  578.         if(isset($_POST['date'])){
  579.             $result $this->dateToString($_POST['date']);
  580.         }
  581.         $this->response->setHeader('Content-Type''text/javascript; charset=utf-8');
  582.         $this->response->write(json_encode($result));
  583.         $this->response->commit();
  584.     }
  585.  
  586.     /**
  587.      * Метод возвращает файл
  588.      *
  589.      * @param $data string данные файла
  590.      * @param $MIMEType string тип файла
  591.      * @param $fileName string имя файла
  592.      *
  593.      * @return void 
  594.      * @access protected
  595.      * @final
  596.      */
  597.  
  598.     final protected function downloadFile($data$MIMEType$fileName{
  599.         $this->response->setHeader('Content-Type'$MIMEType);
  600.         $this->response->setHeader('Content-Disposition'': attachment; filename="'.$fileName.'"');
  601.         $this->response->write($data);
  602.         $this->response->commit();
  603.     }
  604.     /**
  605.      * Чистка от лишних и вердоносных html тегов
  606.      * Вызывается в single режиме
  607.      *
  608.      * @return void 
  609.      * @access protected
  610.      */
  611.  
  612.     protected function cleanup({
  613.         $data = isset($_POST['data']$_POST['data''';
  614.         $data self::cleanupHTML($data);
  615.         $this->response->setHeader('Content-Type''application/xml; charset=utf-8');
  616.         $this->response->write($data);
  617.         $this->response->commit();
  618.     }
  619.     /**
  620.      * Добавляет переводы для тулбара WYSIWYG
  621.      * вызывается в потомках
  622.      * 
  623.      * @return void 
  624.      * @access protected
  625.      * @final
  626.      */
  627.     final protected function addWYSIWYGTranslations(){
  628.         $translations array(
  629.                         'BTN_ITALIC',
  630.                         'BTN_HREF',
  631.                         'BTN_UL',
  632.                         'BTN_OL',
  633.                         'BTN_ALIGN_LEFT',
  634.                         'TXT_PREVIEW',
  635.                         'BTN_FILE_LIBRARY',
  636.                         'BTN_INSERT_IMAGE',
  637.                         'BTN_VIEWSOURCE',
  638.                         'TXT_PREVIEW',
  639.                         'TXT_RESET',
  640.                         'TXT_H1',
  641.                         'TXT_H2',
  642.                         'TXT_H3',
  643.                         'TXT_H4',
  644.                         'TXT_H5',
  645.                         'TXT_H6',
  646.                         'TXT_ADDRESS',
  647.                         'BTN_SAVE',
  648.                         'BTN_BOLD',
  649.                         'BTN_ALIGN_CENTER',
  650.                         'BTN_ALIGN_RIGHT',
  651.                         'BTN_ALIGN_JUSTIFY',
  652.                     );
  653.                 array_walk(
  654.                     $translations,
  655.                     array($this'addTranslation')
  656.                 );
  657.     }
  658.  
  659.     /**
  660.      * Удаляет потенциально опасный и лишний HTML код
  661.      *
  662.      * @param string 
  663.      * @return string 
  664.      * @access protected
  665.      * @static
  666.      */
  667.  
  668.     public static function cleanupHTML($data{
  669.         $aggressive = isset($_GET['aggressive']);
  670.         //dump_log($data);
  671.         //Если подключено расширение tidy
  672.         if(function_exists('tidy_get_output')){
  673.             try {
  674.                 $tidy new tidy();
  675.                 $config array(
  676.                     'bare' => true,
  677.                     'drop-font-tags' => true,
  678.                     'drop-proprietary-attributes' => true,
  679.                     'hide-comments' => true,
  680.                     'logical-emphasis' => true,  
  681.                     'numeric-entities' => true,
  682.                     'show-body-only' => true,
  683.                     'quote-nbsp' => false,
  684.                     'indent' => true,  
  685.                     'wrap' => 0,
  686.                 );
  687.                 if($aggressive){
  688.                     $config array_merge(
  689.                     $config,
  690.                     array(
  691.                          'clean'=> true,
  692.                          'word-2000' => true
  693.                     )
  694.                     );
  695.                 }
  696.                 $data $tidy->repairString($data$config'utf8');
  697.             }
  698.             catch(Exception $dummyError){
  699.                 //Никаких действий предпринимать нет необходимости    
  700.             }
  701.             unset($tidy);
  702.         }
  703.         //dump_log($data, true);
  704.  
  705.         $jewix new Jevix();
  706.         $jewix->cfgSetXHTMLMode(true);
  707.         $jewix->cfgSetAutoBrMode(false);
  708.         $jewix->cfgSetAutoLinkMode(false);
  709.  
  710.         $shortTags  array('br''hr');
  711.         $allowedTags array(
  712.             'a''abbr''acronym''address''b''big''blockquote''br''cite',
  713.             'code''col''colgroup''dd''del''dfn''div''dl''dt''em',
  714.             'h1''h2''h3''h4''h5''h6''hr''i''ins''kbd''li''ol',
  715.             'p''q''s''samp''small''span''strong''sub''sup','pre',
  716.             'table''tbody''td''tfoot''th''thead''tr''tt''u''ul''var'
  717.             );
  718.              
  719.             if (!$aggressive{
  720.                 $allowedTags array_merge($allowedTagsarray(
  721.                 'img',
  722.                 'object',
  723.                 'param',
  724.                 'embed',
  725.                 'map',
  726.                 'area'
  727.                 ));
  728.                 array_push($shortTags'img');
  729.             }
  730.             $jewix->cfgAllowTags($allowedTags);
  731.             $jewix->cfgSetTagShort($shortTags);
  732.  
  733.             $jewix->cfgSetTagNoTypography(array('code''pre''blockquote'));
  734.             $jewix->cfgSetTagPreformatted(array('code''pre''blockquote'));
  735.  
  736.             $jewix->cfgAllowTagParams('table'array('cellpadding''cellspacing'));
  737.             $jewix->cfgAllowTagParams('td'array('colspan''rowspan'));
  738.             $jewix->cfgAllowTagParams('th'array('colspan''rowspan'));
  739.             $jewix->cfgAllowTagParams('a'array('href''target'));
  740.  
  741.  
  742.             $jewix->cfgSetTagCutWithContent(array('script''iframe'));
  743.             if(!$aggressive){
  744.                 array_walk($allowedTagscreate_function('$element, $key, $jewix''$jewix->cfgAllowTagParams($element, array("id", "class", "style"));')$jewix);
  745.                 $jewix->cfgAllowTagParams('img',
  746.                 array(
  747.                     'align'
  748.                     'alt'
  749.                     'src'
  750.                     'vspace'
  751.                     'width',
  752.                     'hspace',
  753.                     'height',
  754.                     'border'
  755.                     )
  756.                     );
  757.             }
  758.  
  759.             $errors false;
  760.             $data $jewix->parse($data$errors);
  761.             //dump_log($errors, true);
  762.             $data =
  763.             str_replace(
  764.             (strpos($data'%7E'))?str_replace('~''%7E',Request::getInstance()->getBasePath()):Request::getInstance()->getBasePath(),
  765.                  '',
  766.             $data
  767.             );
  768.             //$data = str_replace('&amp;', '&', $data);
  769.             //dump_log($data, true);
  770.             return $data;
  771.     }
  772. }
В создании документации нам помог: phpDocumentor