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'); }
/** * Добавление произвольных файлов в XML ноды. * @mcms_message ru.molinos.cms.node.xml */ public static function on_get_node_xml(Node $node) { if ($node instanceof FileNode) { return; } return html::wrap('files', Node::findXML(array('class' => 'file', 'deleted' => 0, 'id' => $node->getDB()->getResultsV("nid", "SELECT `nid` FROM `node__rel` WHERE `tid` = ? AND `key` IS NULL", array($node->id))), $node->getDB())); }
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); }
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'); }
/** * Возвращает список комментариев для ноды. */ public static function on_get_list_xml(Context $ctx) { if (!($nid = $ctx->get('node'))) { throw new BadRequestException(t('Не указан идентификатор ноды (GET-параметр node).')); } if (!$ctx->user->hasAccess(ACL::READ, 'comment')) { throw new ForbiddenException(); } $nodes = Node::findXML(array('class' => 'comment', 'deleted' => 0, 'published' => 1, 'tags' => $nid, '#sort' => 'id'), $ctx->db); return new Response(html::em('comments', $nodes), 'text/xml'); }
/** * Возвращает форму входа. */ public function onGet(array $options) { $result = ''; if ($this->ctx->user->id) { $result .= Node::findXML(array('id' => $this->ctx->user->id)); } if (empty($options['uid'])) { return $result . $this->ctx->registry->unicast('ru.molinos.cms.auth.form', array($this->ctx)); } else { $node = $this->ctx->user->getNode(); $form = $node->formGet()->getXML($node); return $result . $form; } }
public function getResponse(Context $ctx) { if (class_exists('APIStream')) { APIStream::init($ctx); } $page = array('status' => 200, 'base' => $ctx->url()->getBase($ctx), 'host' => MCMS_HOST_NAME, 'folder' => $ctx->folder(), 'sitefolder' => os::webpath(MCMS_SITE_FOLDER), 'prefix' => os::webpath(MCMS_SITE_FOLDER, 'themes'), 'query' => $ctx->query(), 'version' => defined('MCMS_VERSION') ? MCMS_VERSION : 'unknown', 'cache' => cache::getInstance()->getName(), 'memory' => ini_get('memory_limit'), 'time' => microtime(true) - MCMS_START_TIME, 'back' => urlencode(MCMS_REQUEST_URI), 'back_raw' => MCMS_REQUEST_URI, 'next' => $ctx->get('destination'), 'api' => 'cms://localhost/api/', 'rss' => class_exists('RSSRouter')); $request = ''; if ($userid = $ctx->user->id) { $request .= html::wrap('user', Node::findXML(array('id' => $userid), $ctx->db)); } $request .= $ctx->url()->getArgsXML(); $this->content .= html::wrap('request', $request); foreach ((array) $ctx->registry->poll('ru.molinos.cms.page.head', array($ctx, array(), null)) as $block) { if (!empty($block['result'])) { $this->content .= $block['result']; } } return xslt::transform(html::em('page', $page, $this->content), $this->xsl); }
/** * Вывод содержимого объекта. */ public static function on_get_dump(Context $ctx) { $filter = array('id' => $ctx->get('node')); if (!$ctx->canDebug()) { $filter['deleted'] = 0; } if ($ctx->get('raw')) { $node = Node::load($filter, $ctx->db); $temp = $node->{'never should this field exist'}; mcms::debug($node); } else { $xml = Node::findXML($filter, $ctx->db); if (empty($xml)) { throw new RuntimeException(t('Для этого документа нет XML представления (такого быть не должно), см. <a href="@url">сырой вариант</a>.', array('@url' => '?q=node/' . $filter['id'] . '/dump&raw=1'))); } $res = new Response('<?xml version="1.0"?>' . $xml, 'text/xml'); $res->send(); } throw new ForbiddenException(); }
/** * Возвращает содержимое корзины в виде XML. */ public function getXML($details = true) { $result = array(); $sumqty = 0; if (count($cart = $this->getItems())) { $sum = $sumqty = 0; $ids = array_keys($cart); foreach ($nodes = Node::find(array('id' => $ids)) as $node) { if (empty($items)) { $qty = $cart[$node->id]; } else { $del = $items[$node->id]['delete']; if ($del) { unset($cart[$node->id]); continue; } $qty = $items[$node->id]['qty']; $cart[$node->id] = $qty; } $sum += $node->price * $qty; $sumqty += $qty; $result[] = array('id' => $node->id, 'name' => $node->getName(), 'qty' => $qty, 'price' => $node->price, 'sum' => $node->price * $qty); } $total = $sum; $conf = $this->ctx->config->getArray('modules/cart'); if (!empty($conf['discount_threshold'])) { if ($sum >= $conf['discount_threshold']) { if (!empty($conf['discount_price'])) { if ('%' == substr($price = $conf['discount_price'], -1)) { $price = $sum / 100 * substr($price, 0, -1); } $result['discount'] = array('name' => t('Скидка %size при заказе от %sum', array('%size' => $conf['discount_price'], '%sum' => number_format($conf['discount_threshold'], 2, ',', '.'))), 'qty' => 1, 'price' => -$price, 'sum' => -$price); $total -= $price; } } } if (!empty($conf['delivery_threshold'])) { if (!empty($conf['delivery_price'])) { $result['delivery'] = array('name' => t('Доставка (бесплатно при заказе от %size)', array('%size' => number_format($conf['delivery_threshold'], 2, ',', '.'))), 'qty' => 1, 'price' => $sum < $conf['delivery_threshold'] ? $conf['delivery_price'] : 0); $result['delivery']['sum'] = $result['delivery']['price']; $total += $result['delivery']['sum']; } } } if ($discounter = $this->ctx->config->get('modules/cart/discounter')) { if (class_exists($discounter)) { $d = new $discounter(); $d->process($result); } } $result['total'] = array('name' => t('Итого'), 'qty' => $sumqty, 'price' => null, 'sum' => 0); mcms::session('cart', $cart); $output = ''; foreach ($result as $k => $v) { if (is_numeric($k)) { $result['total']['sum'] += $v['sum']; $output .= html::em('item', $v); } } $output = html::em('items', $result['total'], $output); if ($details) { $output .= html::wrap('details', Node::findXML(array('deleted' => 0, 'published' => 1, 'id' => array_keys($cart)))); } return $output; }
/** * Возвращает информацию об объекте. * * Информация об объекте включает прикреплённые к нему файлы и привязанные * документы. Если у пользователя нет доступа к объекту — кидает * ForbiddenException; если объект не опубликован — кидает ForbiddenException * (независимо от прав пользователя); если объект является разделом — кидает * PageNotFoundException (потому, что для разделов есть TagsWidget). * * @param array $options параметры, которые насобирал getRequestOptions() * * @return array Информация об объекте, содержит ключи: "document" (описание * объекта, включая прикреплённые файлы и другие объекты), "tags" (полное * описание разделов, к которым прикреплён объект), "schema" (описание * структуры объекта) и "neighbors" со ссылками на соседей ("prev" и "next"), * если настройки виджета велят возвращать эту информацию. */ protected function onGetView(array $options) { if (isset($options['document']['class']) and !$this->ctx->user->hasAccess(ACL::READ, $options['document']['class'])) { throw new PageNotFoundException(); } if (isset($options['document']['xml'])) { $output = $options['document']['xml']; } else { $output = Node::findXML(array('id' => $options['document']['id'], 'deleted' => 0, 'published' => 1), $this->ctx->db); } if ($this->show_sections) { $sections = Node::findXML($q = array('class' => 'tag', 'tagged' => $options['document']['id'], 'published' => 1, 'deleted' => 0), $this->ctx->db); } elseif (isset($options['section']['xml'])) { $sections = $options['section']['xml']; } if (isset($sections)) { $output .= html::wrap('sections', $sections); } return $output; }
/** * Возвращает список доступных пользователю типов. */ public static function on_get_create_types(Context $ctx) { $nodes = Node::findXML(array('class' => 'type', 'name' => $ctx->user->getAccess(ACL::CREATE), '-name' => $ctx->user->getAnonymous()->getAccess(ACL::CREATE), 'published' => 1, '#sort' => 'name'), $ctx->db); return new Response(html::em('nodes', $nodes), 'text/xml'); }
/** * Обработчик GET-запросов. * * @param array $options параметры запроса. * * @return array данные для шаблона, ключи: sections (вложенный список * подразделов), path (путь к текущему разделу). */ public function onGet(array $options) { if (!empty($options['root'])) { return html::wrap('sections', Node::findXML(array('class' => 'tag', 'deleted' => 0, 'published' => 1, '#sort' => 'left', 'parent_id' => $options['root']), $this->ctx->db)); } }
public function onGet(array $options) { return Node::findXML(array('class' => $this->type, 'deleted' => 0, 'published' => 1, '#sort' => 'name'), $this->ctx->db); }
private static function getDashboardXML(Database $db, array $query, array $options) { return html::wrap('content', Node::findXML($query, $db), $options); }
/** * Редактирование нескольких файлов (форма). */ public static function on_get_edit_form(Context $ctx) { $nodes = Node::findXML(array('class' => 'file', 'id' => explode(' ', $ctx->get('files')), 'deleted' => 0)); return html::em('content', array('name' => 'editfiles', 'title' => t('Редактирование файлов'), 'action' => 'admin/files/edit?destination=' . urlencode($ctx->get('destination')) . '&sendto=' . urlencode($ctx->get('sendto')), 'path' => os::webpath(MCMS_SITE_FOLDER, $ctx->config->get('modules/files/storage')), 'ids' => $ctx->get('files')), $nodes); }
protected function getData() { if ('404' == $this->preset) { $data = array(); $limit = $this->ctx->get('limit', 10); $offset = $limit * $this->ctx->get('page') - $limit; foreach ($this->ctx->db->getResults("SELECT * FROM `node__fallback` ORDER BY `old` LIMIT {$offset}, {$limit}") as $row) { $row['_links'] = array('edit' => array('href' => '?q=admin/content/edit/404' . '&subid=' . urlencode($row['old']) . '&destination=CURRENT', 'title' => 'Изменить', 'icon' => 'edit'), 'delete' => array('href' => '?q=admin.rpc&action=404&mode=delete' . '&src=' . urlencode($row['old']) . '&destination=CURRENT', 'title' => 'Удалить', 'icon' => 'delete')); if (!empty($row['new'])) { $row['new'] = html::em('a', array('href' => '?q=' . urlencode($row['new'])), html::plain($row['new'])); } if (!empty($row['ref'])) { $url = new url($row['ref']); if (0 === strpos($name = $url->host, 'www.')) { $name = substr($name, 4); } $row['ref'] = html::link($row['ref'], $name); } $data[] = $row; } return $data; } $result = ''; $filter = $this->getNodeFilter(); if (null !== $this->limit) { $filter['#limit'] = $this->limit; $filter['#offset'] = ($this->page - 1) * $this->limit; } $result = Node::findXML($filter); return html::em('data', $result); }
/** * Возвращает разделы, в которые помещён документ. */ public static function on_get_selected(Context $ctx) { $xml = Node::findXML(array('deleted' => 0, 'class' => 'tag', 'tagged' => $ctx->get('node'))); return new Response(html::em('nodes', $xml), 'text/xml'); }
/** * Вставляет ноду в родительский объект. */ public function format(Node $node, $em) { $ids = array(); foreach ((array) $node->{$this->value} as $v) { if (empty($v)) { } elseif (is_object($v)) { $ids[] = $v->id; } elseif (is_array($v)) { // как так получается?! $ids[] = $v['id']; } else { $ids[] = $v; } } if ('more' == $this->details) { $result = Node::findXML(array('class' => $this->dictionary, 'deleted' => 0, 'id' => $ids)); } else { $params = array($this->dictionary); $data = Context::last()->db->getResults("SELECT `id`, `class`, `published`, `name` FROM {node} WHERE `class` = ? AND `id` " . sql::in($ids, $params), $params); $result = ''; foreach ($data as $row) { $result .= html::em('node', $row); } } if (empty($result)) { mcms::debug($ids, $node); } return html::em($em, $result); }
/** * Диспетчер запросов. * * В зависимости от GET-параметра mode вызывает один из методов: onGetList() * или больше никакой. Гасит ошибки NoIndexException, возвращая вместо них * массив с ключём "error", значение которого содержит описание ошибки. * * @param array $options то, что насобирал getRequestOptions(). * * @return mixed то, что вернул конкретный метод-обработчик. */ public function onGet(array $options) { $count = null; $result = html::wrap('nodes', Node::findXML($query = $this->getQuery($options), $this->ctx->db)); // Пусто: откатываемся на другой раздел, но только если в текущем разделе // вообще ничего нет, на несуществующей странице выводим пустой список. if (empty($result)) { $count = $query->getCount($this->ctx->db); if (!$count and 'empty' == $this->fallbackmode and $this->fixed) { $options['section']['id'] = $this->fixed; $result = html::wrap('nodes', Node::findXML($query = $this->getQuery($options), $this->ctx->db)); $count = null; } } if (!empty($result)) { // Добавляем информацию о разделе. if ($this->showpath and !empty($options['section'])) { $tmp = ''; $section = Node::load($options['section'], $this->ctx->db); foreach ($section->getParents() as $node) { $tmp .= $node->push('section'); } if (!empty($tmp)) { $result .= html::em('path', $tmp); } } if ($this->pager and !empty($options['limit'])) { if (null === $count) { $count = $query->getCount($this->ctx->db); } $result .= $this->getPager($count, $options['page'], $options['limit']); } } return $result; }
/** * Обработка GET-запроса. */ public function onGet(array $options) { $nodes = Node::findXML(array('class' => $options['classes'], 'tagged' => $options['doc'], 'published' => 1, 'deleted' => 0, '#sort' => $options['sort']), $this->ctx->db); return $nodes; }