/** * Возвращает список файлов, прикреплённых к документу. */ public static function on_get_list(Context $ctx) { $ids = $ctx->db->getResultsV("nid", "SELECT `nid` FROM `node__rel` WHERE `tid` = ? AND `key` IS NULL AND `nid` IN (SELECT `id` FROM `node` WHERE `class` = 'file')", array($ctx->get('id'))); $output = Node::findXML(array('id' => $ctx->get('id'), 'deleted' => 0)); $output .= html::wrap('files', Node::findXML(array('class' => 'file', 'deleted' => 0, 'id' => $ids), $ctx->db)); return html::em('content', array('name' => 'extrafiles'), $output); }
public function getHTML($data) { if (empty($data[$this->value])) { return null; } $output = "<table>"; $output .= "<tr class='header'>"; $output .= "<th class='check'> </th>"; $output .= "<th class='name'>" . t('Название') . "</th>"; $output .= "<th class='qty'>" . t('Количество') . "</th>"; $output .= "<th class='price'>" . t('Цена') . "</th>"; $output .= "<th class='sum'>" . t('Сумма') . "</th>"; $output .= "</tr>"; $total = 0; foreach ($data[$this->value] as $row) { $output .= "<tr class='product'>"; $output .= "<td class='check'>" . html::em('input', array('type' => 'checkbox', 'name' => $this->value . '_checked[]', 'value' => $row['id'])) . "</td>"; $output .= "<td class='name'>" . html::plain($row['name']) . "</td>"; $output .= "<td class='qty'>" . html::em('input', array('type' => 'text', 'name' => "{$this->value}[{$row['id']}][qty]", 'value' => $row['qty'])) . "</td>"; $output .= "<td class='price'>" . number_format($row['price'], 2) . "</td>"; $output .= "<td class='sum'>" . number_format($row['sum'], 2) . "</td>"; $output .= "</tr>"; $total += $row['sum']; } $output .= "<tr class='total'>"; $output .= "<td> </td>"; $output .= "<td class='total'><strong>" . t('Итого') . ":</td>"; $output .= "<td class='qty'> </td>"; $output .= "<td class='price'> </td>"; $output .= "<td class='sum'>" . number_format($total, 2) . "</td>"; $output .= "</tr>"; $output .= "</table>"; return $output; }
private function renderContent(array $content) { $sum = 0; $rows = '<table class=\'orderdetails\'><thead>'; $rows .= '<tr><th>id</th><th>Название</th><th>Цена</th><th>Количество</th><th>Сумма</th></tr>'; $rows .= '</thead><tbody>'; foreach ($content as $k => $item) { if ($k !== 'total') { $rows .= '<tr>'; $rows .= html::em('td', $item['id']); $rows .= html::em('td', $this->getProductLink($item)); $rows .= html::em('td', array('class' => 'sum'), number_format(abs($item['price']), 2, ',', '.')); if (is_numeric($k)) { $rows .= html::em('td', array('class' => 'qty'), number_format($item['qty'], 0, ',', ' ')); } else { $rows .= html::em('td'); } $rows .= html::em('td', array('class' => 'sum'), number_format(abs($item['sum']), 2, ',', '.')); $rows .= '</tr>'; } } $rows .= '<tr><td colspan=\'3\' class=\'empty\'> </td>' . '<td>' . $content['total']['qty'] . '</td>' . '<td><strong>' . number_format($content['total']['sum'], 2, ',', '.') . '</strong></td></tr>'; $rows .= '</tbody></table>'; return $rows; }
public function render(Context $ctx, array $options = array()) { $options = array_merge(array('name' => 'custom', 'title' => MCMS_HOST_NAME, 'xsl' => os::path('lib', 'modules', 'rss', 'default.xsl'), 'base' => $ctx->url()->getBase($ctx), 'description' => 'News from ' . MCMS_HOST_NAME, 'language' => 'ru', 'url' => 'http://' . MCMS_HOST_NAME . $ctx->url()->string()), $options); $content = html::wrap('nodes', Node::findXML($this->filter, $ctx->db)); $content = html::em('rss', $options, $content); return xslt::transform($content, $options['xsl'], 'text/xml'); }
public static function rpc_post_subscribe(Context $ctx) { $data = $ctx->post; if (empty($data['sections'])) { throw new InvalidArgumentException("Не выбраны разделы для подписки."); } if (false === strpos($data['email'], '@')) { throw new InvalidArgumentException(t('Введённый email не похож на email.')); } // В массиве могут быть и другие данные, поэтому мы // выбираем только то, что нам нужно завернуть. $bulk = array('email' => $data['email'], 'sections' => $data['sections']); $link = new url(array('args' => array('q' => 'subscription.rpc', 'action' => 'confirm', 'code' => base64_encode(serialize($bulk))))); $sections = Node::findXML(array('class' => 'tag', 'deleted' => 0, 'published' => 1, 'id' => $data['sections'], '#sort' => 'name'), $ctx->db, 'section'); if (empty($sections)) { throw new InvalidArgumentException("Выбраны несуществующие разделы для подписки."); } $xml = html::em('message', array('mode' => 'confirm', 'host' => MCMS_HOST_NAME, 'email' => $data['email'], 'base' => $ctx->url()->getBase($ctx), 'confirmLink' => $link->string()), html::em('sections', $sections)); $xsl = $ctx->config->get('modules/subscription/stylesheet', os::path('lib', 'modules', 'subscription', 'message.xsl')); if (false === ($body = xslt::transform($xml, $xsl, null))) { throw new RuntimeException(t('Возникла ошибка при форматировании почтового сообщения.')); } $subject = t('Подписка на новости сайта %host', array('%host' => MCMS_HOST_NAME)); // mcms::debug($data['email'], $subject, $body); BebopMimeMail::send(null, $data['email'], $subject, $body); }
/** * @mcms_message ru.molinos.cms.cron */ public static function taskRun(Context $ctx) { $types = $ctx->config->get('modules/subscription/types', array()); $xsl = $ctx->config->get('modules/subscription/stylesheet', os::path('lib', 'modules', 'subscription', 'message.xsl')); $sub = $ctx->config->get('modules/subscription/subject', 'Новости сайта %host'); if (empty($types)) { return; } $ctx->db->beginTransaction(); $users = Node::find(array('class' => 'subscription', 'deleted' => 0, 'published' => 1, '#sort' => 'name'), $ctx->db); // Обрабатываем активных пользователей. foreach ($users as $user) { $olast = $last = intval($user->last); if ($sections = (array) $user->tags) { list($sql, $params) = Query::build(array('class' => $types, 'tags' => $sections, 'published' => 1, 'deleted' => 0, 'id' => array('>' . ($olast + 1))))->getSelect(array('id', 'xml')); $nodes = $ctx->db->getResultsKV('id', 'xml', $sql, $params); // Отправляем документы. foreach ($nodes as $nid => $node) { $xml = html::em('message', array('mode' => 'regular', 'unsubscribe' => 'subscription.rpc?action=remove&name=' . urlencode($user->name) . '&id=' . $user->id, 'base' => $ctx->url()->getBase($ctx), 'host' => MCMS_HOST_NAME), $node); $body = xslt::transform($xml, $xsl, null); $subject = t($sub, array('%host' => $ctx->url()->host())); BebopMimeMail::send(null, $user->name, $subject, $body); $last = max($last, $nid); } // Запоминаем последнее отправленное сообщение. $user->last = $last; $user->save(); } } $ctx->db->commit(); }
public function preview($data) { if ($url = $data->{$this->value}) { $a = html::em('a', array('href' => $url), html::plain($url)); return html::em('value', array('html' => true), html::cdata($a)); } }
/** * Вывод формы авторизации. * @route GET//login */ public static function on_get_login_form(Context $ctx) { if ($ctx->user->id and !$ctx->get('stay')) { return $ctx->getRedirect(); } if (class_exists('APIStream')) { APIStream::init($ctx); } $handler = array('theme' => $ctx->config->get('modules/auth/login_theme')); $content = ''; foreach ((array) $ctx->registry->poll('ru.molinos.cms.page.head', array($ctx, $handler, null), true) as $block) { if (!empty($block['result'])) { $content .= $block['result']; } } $content .= self::getXML($ctx); $xml = html::em('page', array('status' => 401, 'base' => $ctx->url()->getBase($ctx), 'host' => MCMS_HOST_NAME, 'prefix' => os::webpath(MCMS_SITE_FOLDER, 'themes'), 'back' => urlencode(MCMS_REQUEST_URI), 'next' => $ctx->get('destination'), 'api' => APIStream::getPrefix(), 'query' => $ctx->query()), $content); if (file_exists($xsl = os::path(MCMS_SITE_FOLDER, 'themes', $handler['theme'], 'templates', 'login.xsl'))) { try { return xslt::transform($xml, $xsl); } catch (Exception $e) { } } return xslt::transform($xml, 'lib/modules/auth/xsl/login.xsl'); }
/** * Добавляет главный RSS во все страницы. * @mcms_message ru.molinos.cms.page.head */ public static function on_get_head(Context $ctx) { $result = ''; if ($rss = $ctx->config->get('modules/rss/feedurl')) { $result .= html::em('link', array('rel' => 'alternate', 'type' => 'application/rss+xml', 'href' => $rss, 'title' => $ctx->config->get('modules/rss/feedname'))); } return html::wrap('head', html::cdata($result), array('module' => 'rss', 'weight' => 50)); }
public function format(Node $node, $em) { $value = $node->{$this->value}; $tmp = ''; foreach ((array) $value as $line) { $tmp .= html::em('link', $line); } return html::wrap($em, $tmp); }
public function onGet(array $options) { $sections = array_intersect_key(Node::getSortedList('tag'), array_flip(Node::create('subscription')->getEnabledSections())); $output = html::simpleOptions($sections, 'section', 'sections'); if ($this->description) { $output .= html::em('description', html::cdata($this->description)); } return $output; }
public static function get_info_xml(Context $ctx) { if ($uid = $ctx->user->id) { $xml = Node::findXML(array('class' => 'user', 'published' => 1, 'deleted' => 0, 'id' => $uid), $ctx->db); } if (empty($xml)) { $xml = html::em('node', array('class' => 'user', 'name' => 'anonymous')); } return new Response($xml, 'text/xml'); }
/** * Возвращает код для включения в страницу. * @mcms_message ru.molinos.cms.page.head */ public static function on_get_content(Context $ctx) { $conf = $ctx->config->get('modules/googleanalytics'); if (!empty($conf['account'])) { $proto = empty($_SERVER['HTTPS']) ? 'http' : 'https'; $output = html::em('script', array('src' => $proto . '://www.google-analytics.com/ga.js', 'type' => 'text/javascript')); $output .= '<script type="text/javascript">try{var pageTracker = _gat._getTracker("' . $conf['account'] . '");pageTracker._trackPageview();}catch(err){}</script>'; return html::em('head', array('module' => 'googleanalytics'), html::cdata($output)); } }
/** * Добавляет в предварительный просмотр количество отмеченных документов. */ public function getPreviewXML(Context $ctx) { $result = parent::getPreviewXML($ctx); $count = $ctx->db->fetch("SELECT COUNT(*) FROM node WHERE deleted = 0 AND id IN " . "(SELECT nid FROM node__rel WHERE tid = ?) AND class IN " . "(SELECT name FROM node WHERE class = 'type' AND deleted = 0 AND published = 1)", array($this->id)); if ($count) { $message = t('%count (<a href="@url">список</a>)', array('%count' => $count, '@url' => 'admin/content/list?search=tags%3A' . $this->id)); $result .= html::em('field', array('title' => t('Отмечено документов')), html::em('value', html::cdata($message))); } return $result; }
public static function on_get_delete(Context $ctx) { $list = ''; foreach ((array) $ctx->get('delete') as $name) { $list .= html::em('widget', array('name' => $name)); } if (empty($list)) { throw new PageNotFoundException(); } return html::wrap('content', $list, array('name' => 'delete-widgets', 'title' => t('Виджеты'), 'base' => self::listurl)); }
protected function getData() { $offset = ($this->page - 1) * $this->limit; $sql = "SELECT `timestamp`, `nid`, `uid`, `username`, `ip`, `operation`, `name` FROM `node__log` ORDER BY `lid` DESC LIMIT {$offset}, {$this->limit}"; $output = ''; foreach ($this->ctx->db->getResults($sql) as $row) { $output .= html::em('node', $row); } $this->pgcount = $this->ctx->db->getResult("SELECT COUNT(*) FROM `node__log`") * 1; return html::em('data', array('mode' => 'syslog'), $output); }
public function getXML($data) { if (empty($data[$this->value])) { return; } $items = ''; foreach ($data->{$this->value} as $rid => $info) { $items .= html::em('item', array('uid' => $info['uid'], 'username' => $info['username'], 'rid' => $rid, 'created' => $info['created'])); } return empty($items) ? null : parent::wrapXML(array(), $items); }
public static function on_get_delete(Context $ctx) { $pages = ''; foreach ((array) $ctx->get('check') as $id) { $pages .= html::em('page', urldecode($id)); } if (empty($pages)) { throw new ForbiddenException(t('Не выбраны пути для удаления.')); } return html::wrap('content', $pages, array('name' => 'route-delete')); }
/** * Возвращает результаты по опросу. */ public static function on_get_results(Context $ctx) { $output = ''; $id = $ctx->get('id'); $data = $ctx->db->getResultsKV("option", "count", "SELECT `option`, COUNT(*) AS `count` FROM `node__poll` WHERE `nid` = ? GROUP BY `option`", array($ctx->get('id'))); foreach ($data as $k => $v) { $output .= html::em('option', array('count' => $v), html::cdata($k)); } $voted = $ctx->user->id ? $ctx->db->fetch("SELECT COUNT(*) FROM `node__poll` WHERE `nid` = ? AND `uid` = ?", array($id, $ctx->user->id)) : $ctx->db->fetch("SELECT COUNT(*) FROM `node__poll` WHERE `nid` = ? AND `ip` = ?", array($id, $_SERVER['REMOTE_ADDR'])); return new Response(html::em('results', array('voted' => (bool) $voted), $output), 'text/xml'); }
/** * Настройка правила (форма). */ public static function on_get_edit(Context $ctx) { if (!($name = $ctx->get('name'))) { throw new BadRequestException(t('Не указано имя трансформации (параметр name).')); } if (!($data = $ctx->config->getArray(self::confroot . '/' . $name))) { throw new PageNotFoundException(); } $data['name'] = $name; $form = self::get_schema()->sort()->getForm(array('title' => t('Настройка трансформации «%name»', array('%name' => $name))))->getXML(Control::data($data)); return html::em('content', array('name' => 'form'), $form); }
/** * Вызов api/ads/get.xml * * Возвращает случайные баннеры. * * @route GET//api/ads/get.xml */ public static function on_get_banners(Context $ctx) { $limit = intval($ctx->get('limit', 1)); $sql = "SELECT `node`.`id`, `xml` FROM `node` " . "INNER JOIN `node__banners` ON `node__banners`.`id` = `node`.`id` " . "WHERE `class` = 'banner' AND `deleted` = 0 AND `published` = 1 " . "AND (`time_limit` IS NULL OR `time_limit` < ?) " . "AND (`display_limit` IS NULL OR `display_count` IS NULL OR `display_count` < `display_limit`) " . "ORDER BY RAND() LIMIT " . $limit; $data = $ctx->db->getResultsKV("id", "xml", $sql, array(mcms::now())); $params = array(); $ctx->db->beginTransaction(); $ctx->db->exec("UPDATE `node__banners` SET `display_count` = 0 WHERE `display_count` IS NULL"); $ctx->db->exec("UPDATE `node__banners` SET `display_count` = `display_count` + 1 WHERE `id` " . sql::in(array_keys($data), $params), $params); $ctx->db->commit(); return new Response(html::em('nodes', implode('', $data)), 'text/xml'); }
/** * Добавляет в комментарий информацию о ноде. */ public function getExtraXMLContent() { $content = parent::getExtraXMLContent(); $db = Context::last()->db; $node = $this->node ? $this->node : $db->fetch("SELECT `tid` FROM `node__rel` WHERE `nid` = ? LIMIT 1", array($this->id)); if ($node) { if ($data = $db->getResults("SELECT id, class, name FROM node WHERE id = ?", array($node))) { $content .= html::em('node', $data[0]); } } return $content; }
/** * Возвращает количество комментариев. * @route GET//api/comment/count.xml */ public static function on_count_comments(Context $ctx) { $result = ''; if ($ids = explode(',', $ctx->get('node'))) { $params = array(); if ($data = $ctx->db->getResults($sql = "SELECT n.id AS `id`, COUNT(*) AS `count` FROM node n INNER JOIN node__rel l ON l.tid = n.id INNER JOIN node c ON c.id = l.nid WHERE n.deleted = 0 AND n.published = 1 AND c.deleted = 0 AND c.published = 1 AND c.class = 'comment' AND `n`.`id` " . sql::in($ids, $params) . " GROUP BY n.id", $params)) { foreach ($data as $row) { $result .= html::em('node', $row); } } } return new Response(html::em('counts', $result), 'text/xml'); }
/** * Формирование предварительного просмотра. * * Загружает данные прямо из БД, чтобы видеть метки, которые не дошли * до XML представления. Такие метки выделяются курсивом. */ public function preview($value) { if ($labels = $value->{$this->value}) { $result = array(); foreach ($this->getLabelsFor($value) as $id => $name) { if (!array_key_exists($id, $labels)) { $name = html::em('em', $name); } $result[] = html::em('a', array('href' => 'admin/node/' . $id), $name); } return html::wrap('value', html::cdata(implode(', ', $result)), array('html' => true)); } }
/** * Выводит <link> * @mcms_message ru.molinos.cms.page.head */ public static function on_get_head(Context $ctx, array $pathinfo, $param) { $attrs = array('rel' => 'alternate', 'type' => 'application/x-wiki'); if ($param) { $attrs['title'] = t('Редактировать'); $attrs['href'] = 'admin/node/' . $param; } else { $attrs['title'] = t('Создать документ'); $attrs['href'] = 'admin/create'; } $attrs['href'] = $ctx->url()->getBase($ctx) . $attrs['href'] . '?destination=' . urlencode($_SERVER['REQUEST_URI']); $output = html::em('link', $attrs); return html::em('head', array('module' => 'ueb'), html::cdata($output)); }
public function format(Node $noed, $em) { $value = $node->{$this->value}; if (is_array($value) and !empty($value['lat']) and !empty($value['lon'])) { $ll = $value['lat'] . ',' . $value['lon']; $key = Context::last()->config->get('modules/googlemaps/key'); $img = html::em('img', array('src' => sprintf('http://maps.google.com/staticmap?center=%s&zoom=%u&size=%ux%u&hl=ru&key=%s', $ll, $this->zoom_embed, $this->width, $this->height, $key), 'width' => $this->width, 'height' => $this->height, 'alt' => $value)); if (!($zoom_link = $this->zoom_link)) { $zoom_link = $this->zoom_embed + 2; } $result = html::em('a', array('href' => sprintf('http://maps.google.com/maps?ll=%s&z=%u', $ll, $zoom_link), 'title' => $value), $img); return html::wrap($em, html::cdata($result), array('address' => $value['query'])); } }
/** * Добавляет информацию о разделах в предварительный просмотр. * @mcms_message ru.molinos.cms.hook.preview.xml */ public static function on_preview_tags(Node $node) { if (!$node->checkPermission(ACL::UPDATE)) { return; } if ($data = $node->getDB()->getResultsKV("id", "name", "SELECT `id`, `name` FROM `node` WHERE `deleted` = 0 AND `class` = 'tag' AND `id` IN (SELECT `tid` FROM `node__rel` WHERE `nid` = ?)", array($node->id))) { $result = array(); foreach ($data as $k => $v) { $result[] = html::em('a', array('href' => "admin/node/{$k}?destination=CURRENT"), html::plain($v)); } $result = html::em('value', html::cdata(implode(', ', $result))); return html::em('field', array('html' => true, 'title' => t('Находится в разделах'), 'editurl' => "admin/structure/taxonomy/setup?node={$node->id}&destination=" . urlencode(MCMS_REQUEST_URI)), $result); } }
protected function getData() { $data = Node::find(array('class' => 'type', 'deleted' => 0, '#sort' => '-published name'), $this->ctx->db); $counts = $this->ctx->db->getResultsKV("name", "count", "SELECT `class` AS `name`, COUNT(*) AS `count` FROM `node` WHERE `deleted` = 0 GROUP BY `class`"); $nodes = ''; foreach ($data as $node) { if ($node->isdictionary) { $attrs = array('id' => $node->id, 'name' => $node->name, 'title' => $node->title, 'list' => Node::create($node->name)->getListURL(), 'published' => (bool) $node->published); $attrs['count'] = array_key_exists($node->name, $counts) ? $counts[$node->name] : 0; $nodes .= html::em('node', $attrs); } } return html::wrap('data', $nodes); }
public function testEmptyDiv() { $html = html::em('div'); $this->assertEquals('<div></div>', $html); $html = html::em('script'); $this->assertEquals('<script></script>', $html); $html = html::em('textarea'); $this->assertEquals('<textarea></textarea>', $html); $html = html::em('span'); $this->assertEquals('<span></span>', $html); $html = html::em('base'); $this->assertEquals('<base></base>', $html); $html = html::em('a'); $this->assertEquals('<a></a>', $html); }
protected function onGetGas(array $options) { $config = $this->ctx->config->get('modules/search'); if (empty($config['gas_key'])) { return "<!-- GAS disabled: site key not defined -->"; } elseif (empty($this->gas_ctl)) { return "<!-- GAS disabled: form parent not defined -->"; } elseif (empty($this->gas_root)) { return "<!-- GAS disabled: result container not defined -->"; } if (null === ($host = $this->gas_host)) { $host = $_SERVER['HTTP_HOST']; } return html::em('search', array('mode' => 'gas', 'apikey' => $config['gas_key'], 'hostname' => $host, 'root' => $this->gas_root, 'formctl' => $this->gas_ctl, 'onlyform' => (bool) strcasecmp($this->gas_page, trim($this->ctx->query(), '/')), 'resultpage' => $this->gas_page, 'query' => $options['q'])); }