/** * Displays an article edit view. * * Note, that the article for non-index mode operation is automatically determined in the can_handle * phase. * * If create privileges apply, we relocate to the index creation article * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_create($handler_id, array $args, array &$data) { $this->_content_topic->require_do('midgard:create'); $this->_schema = $args[0]; if ($handler_id == 'createindex') { $this->_indexmode = true; } $data['controller'] = $this->get_controller('create'); switch ($data['controller']->process_form()) { case 'save': // #809 should have taken care of this, but see same place in n.n.static if (strlen($this->_article->name) == 0) { // Generate something to avoid empty "/" links in case of failures $this->_article->name = time(); $this->_article->update(); } // Index the article $indexer = midcom::get('indexer'); net_nehmer_blog_viewer::index($data['controller']->datamanager, $indexer, $this->_content_topic); // *** FALL THROUGH *** // *** FALL THROUGH *** case 'cancel': return new midcom_response_relocate(''); } $this->_prepare_request_data(); $title = sprintf($this->_l10n_midcom->get('create %s'), $this->_schemadb[$this->_schema]->description); midcom::get('head')->set_pagetitle("{$this->_topic->extra}: {$title}"); $this->add_breadcrumb("create/{$this->_schema}/", sprintf($this->_l10n_midcom->get('create %s'), $this->_schemadb[$this->_schema]->description)); }
function _load_objects() { $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic', '=', $this->_request_data['content_topic']->id); $articles = $qb->execute(); return $articles; }
/** * Displays an article edit view. * * Note, that the article for non-index mode operation is automatically determined in the can_handle * phase. * * If create privileges apply, we relocate to the index creation article * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_create($handler_id, array $args, array &$data) { $this->_content_topic->require_do('midgard:create'); $this->_schema = $args[0]; if ($handler_id == 'createindex') { $this->_indexmode = true; } $data['controller'] = $this->get_controller('create'); switch ($data['controller']->process_form()) { case 'save': /** * http://trac.midgard-project.org/ticket/809 should have taken care of this. * BUT: to be extra careful, let's do this sanity-check anyway. */ if (strlen($this->_article->name) == 0) { // Generate something to avoid empty "/" links in case of failures $this->_article->name = time(); $this->_article->update(); } // Index the article $indexer = midcom::get('indexer'); net_nehmer_static_viewer::index($data['controller']->datamanager, $indexer, $this->_content_topic); if ($this->_article->name === 'index') { return new midcom_response_relocate(''); } return new midcom_response_relocate("{$this->_article->name}/"); case 'cancel': return new midcom_response_relocate(''); } $this->_prepare_request_data(); $title = sprintf($this->_l10n_midcom->get('create %s'), $this->_schemadb[$this->_schema]->description); midcom::get('head')->set_pagetitle("{$this->_topic->extra}: {$title}"); $this->add_breadcrumb("create/{$this->_schema}/", sprintf($this->_l10n_midcom->get('create %s'), $this->_schemadb[$this->_schema]->description)); }
/** * Returns all leaves for the current content topic. * * It will hide the index leaf from the NAP information unless we are in Autoindex * mode. The leaves' title are used as a description within NAP, and the toolbar will * contain edit and delete links. */ public function get_leaves() { $leaves = array(); if ($this->_config->get('hide_navigation')) { return $leaves; } // Get the required information with midgard_collector $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('up', '=', 0); // Check whether to include the linked articles to navigation list if (!$this->_config->get('enable_article_links')) { $qb->add_constraint('topic', '=', $this->_content_topic->id); } else { // Get the linked articles as well $mc = net_nehmer_static_link_dba::new_collector('topic', $this->_content_topic->id); $mc->add_constraint('topic', '=', $this->_content_topic->id); $links = $mc->get_values('article'); $qb->begin_group('OR'); if (count($links) > 0) { $qb->add_constraint('id', 'IN', $links); } $qb->add_constraint('topic', '=', $this->_content_topic->id); $qb->end_group(); } $qb->add_constraint('metadata.navnoentry', '=', 0); $qb->add_constraint('name', '<>', ''); // Unless in Auto-Index mode or the index article is hidden, we skip the index article. if (!$this->_config->get('autoindex') && !$this->_config->get('indexinnav')) { $qb->add_constraint('name', '<>', 'index'); } $sort_order = 'ASC'; $sort_property = $this->_config->get('sort_order'); if (strpos($sort_property, 'reverse ') === 0) { $sort_order = 'DESC'; $sort_property = substr($sort_property, strlen('reverse ')); } if (strpos($sort_property, 'metadata.') === false) { $article = new midgard_article(); if (!property_exists($article, $sort_property)) { $sort_property = 'metadata.' . $sort_property; } } $qb->add_order($sort_property, $sort_order); // Sort items with the same primary sort key by title. $qb->add_order('title'); $articles = $qb->execute(); foreach ($articles as $article) { $article_url = "{$article->name}/"; if ($article->name == 'index') { $article_url = ''; } $leaves[$article->id] = array(MIDCOM_NAV_URL => $article_url, MIDCOM_NAV_NAME => $article->title ? $article->title : $article->name, MIDCOM_NAV_GUID => $article->guid, MIDCOM_NAV_OBJECT => $article); } return $leaves; }
function _on_execute() { if (!$this->_config->get('atom_comments_import_enable')) { debug_add('Import of Atom comment feeds disabled, aborting', MIDCOM_LOG_INFO); return; } if (!midcom::get('auth')->request_sudo('net.nehmer.comments')) { debug_add('Could not get sudo, aborting operation', MIDCOM_LOG_ERROR); return; } // Get 50 latest articles so we can look for those $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic.guid', '=', $this->_config->get('atom_comments_topic')); $qb->add_order('metadata.published', 'DESC'); $qb->set_limit(50); $articles = $qb->execute(); foreach ($articles as $article) { $replies_url = $article->get_parameter('net.nemein.rss', 'replies_url'); if (empty($replies_url)) { // no replies-url for this article. skipping continue; } // fetch and parse Feed from URL $comments = net_nemein_rss_fetch::raw_fetch($replies_url)->items; foreach ($comments as $comment) { $qb = net_nehmer_comments_comment::new_query_builder(); $qb->add_constraint('remoteid', '=', $comment['guid']); $db_comments = $qb->execute(); if (count($db_comments) > 0) { $db_comment = $db_comments[0]; $db_comment->title = $comment['title']; $db_comment->content = $comment['description']; $db_comment->update(); } else { $author_info = net_nemein_rss_fetch::parse_item_author($comment); $db_comment = new net_nehmer_comments_comment(); $db_comment->objectguid = $article->guid; $db_comment->metadata->published = $comment['published']; $db_comment->author = isset($author_info['full_name']) ? $author_info['full_name'] : $author_info['username']; $db_comment->status = $this->_config->get('atom_comments_initial_status'); $db_comment->remoteid = $comment['guid']; $db_comment->title = $comment['title']; $db_comment->content = $comment['description']; $db_comment->create(); } } // <-- comments } // <-- articles midcom::get('auth')->drop_sudo(); debug_add('Done'); }
public function testHandler_create() { midcom::get('auth')->request_sudo('net.nehmer.blog'); $data = $this->run_handler(self::$_topic, array('create', 'default')); $this->assertEquals('create', $data['handler_id']); $this->show_handler($data); $formdata = array('title' => __CLASS__ . microtime(), 'content' => '<p>TEST</p>'); $url = $this->submit_dm2_form('controller', $formdata, self::$_topic, array('create', 'default')); $this->assertEquals('', $url); $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('title', '=', $formdata['title']); $results = $qb->execute(); $this->register_objects($results); $this->assertEquals(1, sizeof($results)); midcom::get('auth')->drop_sudo(); }
/** * Displays an article delete confirmation view. * * Note, that the article for non-index mode operation is automatically determined in the can_handle * phase. * * If create privileges apply, we relocate to the index creation article * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_delete($handler_id, array $args, array &$data) { $this->_article = new midcom_db_article($args[0]); // Relocate to delete the link instead of the article itself if ($this->_article->topic !== $this->_content_topic->id) { return new midcom_response_relocate("delete/link/{$args[0]}/"); } $this->_article->require_do('midgard:delete'); $this->_load_datamanager(); if (array_key_exists('net_nehmer_blog_deleteok', $_REQUEST)) { $title = $this->_article->title; // Deletion confirmed. if (!$this->_article->delete()) { throw new midcom_error("Failed to delete article {$args[0]}, last Midgard error was: " . midcom_connection::get_error_string()); } // Delete all the links pointing to the article $qb = net_nehmer_blog_link_dba::new_query_builder(); $qb->add_constraint('article', '=', $this->_article->id); $links = $qb->execute_unchecked(); midcom::get('auth')->request_sudo('net.nehmer.blog'); foreach ($links as $link) { $link->delete(); } midcom::get('auth')->drop_sudo(); // Update the index $indexer = midcom::get('indexer'); $indexer->delete($this->_article->guid); // Show user interface message midcom::get('uimessages')->add($this->_l10n->get('net.nehmer.blog'), sprintf($this->_l10n->get('article %s deleted'), $title)); // Delete ok, relocating to welcome. return new midcom_response_relocate(''); } if (array_key_exists('net_nehmer_blog_deletecancel', $_REQUEST)) { midcom::get('uimessages')->add($this->_l10n->get('net.nehmer.blog'), $this->_l10n->get('delete cancelled')); // Redirect to view page. if ($this->_config->get('view_in_url')) { return new midcom_response_relocate("view/{$this->_article->name}/"); } else { return new midcom_response_relocate("{$this->_article->name}/"); } } $this->_prepare_request_data(); midcom::get('metadata')->set_request_metadata($this->_article->metadata->revised, $this->_article->guid); $this->_view_toolbar->bind_to($this->_article); midcom::get('head')->set_pagetitle("{$this->_topic->extra}: {$this->_article->title}"); $this->_update_breadcrumb_line($handler_id); }
/** * Can-Handle check against the article name. We have to do this explicitly * in can_handle already, otherwise we would hide all subtopics as the request switch * accepts all argument count matches unconditionally. * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. * @return boolean True if the request can be handled, false otherwise. */ public function _can_handle_view($handler_id, array $args, array &$data) { $qb = midcom_db_article::new_query_builder(); net_nehmer_blog_viewer::article_qb_constraints($qb, $data, $handler_id); $qb->begin_group('OR'); $qb->add_constraint('name', '=', $args[0]); $qb->add_constraint('guid', '=', $args[0]); $qb->end_group(); $articles = $qb->execute(); if (count($articles) > 0) { $this->_article = $articles[0]; } if (!$this->_article) { return false; // This will 404 } return true; }
/** * Displays an article delete confirmation view. * * Note, that the article for non-index mode operation is automatically determined in the can_handle * phase. * * If create privileges apply, we relocate to the index creation article * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_delete($handler_id, array $args, array &$data) { $this->_article = new midcom_db_article($args[0]); // Relocate to delete the link instead of the article itself if ($this->_article->topic !== $this->_content_topic->id) { return new midcom_response_relocate("delete/link/{$args[0]}/"); } $this->_article->require_do('midgard:delete'); $this->_load_datamanager(); if (array_key_exists('net_nehmer_static_deleteok', $_REQUEST)) { // Deletion confirmed. if (!$this->_article->delete()) { throw new midcom_error("Failed to delete article {$args[0]}, last Midgard error was: " . midcom_connection::get_error_string()); } // Delete all the links pointing to the article $qb = net_nehmer_static_link_dba::new_query_builder(); $qb->add_constraint('article', '=', $this->_article->id); $links = $qb->execute_unchecked(); midcom::get('auth')->request_sudo('net.nehmer.static'); foreach ($links as $link) { $link->delete(); } midcom::get('auth')->drop_sudo(); // Update the index $indexer = midcom::get('indexer'); $indexer->delete($this->_article->guid); // Delete ok, relocating to welcome. return new midcom_response_relocate(''); } if (array_key_exists('net_nehmer_static_deletecancel', $_REQUEST)) { // Redirect to view page. return new midcom_response_relocate("{$this->_article->name}/"); } $this->_prepare_request_data(); $this->bind_view_to_object($this->_article, $this->_datamanager->schema->name); midcom::get('style')->append_substyle('admin'); midcom::get('metadata')->set_request_metadata($this->_article->metadata->revised, $this->_article->guid); midcom::get('head')->set_pagetitle("{$this->_topic->extra}: {$this->_article->title}"); $this->set_active_leaf($this->_article->id); $this->_update_breadcrumb_line($handler_id); }
/** * @todo This function does nothing (and would throw notices if it did) */ private function _add_attachment($att) { return false; $attobj = $this->_article->create_attachment($att['name'], $att['name'], $att['mimetype']); if (!$attobj) { //Could not create attachment debug_add("Could not create attachment '{$att['name']}', errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); continue; } $fp = @$attobj->open('w'); if (!$fp) { //Could not open for writing, clean up and continue debug_add("Could not open attachment {$attobj->guid} for writing, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); $attobj->delete(); continue; } if (!fwrite($fp, $att['content'], strlen($att['content']))) { //Could not write, clean up and continue debug_add("Error when writing attachment {$attobj->guid}, errstr: " . midcom_connection::get_error_string(), MIDCOM_LOG_ERROR); fclose($fp); $attobj->delete(); continue; } fclose($fp); if (isset($att['part']) && isset($att['part']->headers) && isset($att['part']->headers['content-id'])) { //Attachment is embed, add tag to end of note if (!$embeds_added) { $this->_article->content .= "<p>"; $embeds_added = true; } $this->_article->content .= "<a href=\"" . midcom_connection::get_url('self') . "midcom-serveattachmentguid-{$attobj->guid}/{$attobj->name}\">{$attobj->title}</a><br />"; } else { //Add normal attachments as links to end of note if (!$attachments_added) { //We hope the client handles these so that embeds come first and attachments then so we can avoid double pass over this array $this->_article->content .= "\n\n"; $attachments_added = true; } $this->_article->content .= "[{$attobj->title}](" . midcom_connection::get_url('self') . "midcom-serveattachmentguid-{$attobj->guid}/{$attobj->name}), "; } }
/** * Shows the autoindex list. Nothing to do in the handle phase except setting last modified * dates. * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_feed($handler_id, array $args, array &$data) { midcom::get('componentloader')->load_library('de.bitfolge.feedcreator'); midcom::get('cache')->content->content_type("text/xml; charset=UTF-8"); midcom::get()->header("Content-type: text/xml; charset=UTF-8"); midcom::get()->skip_page_style = true; // Prepare control structures $this->_datamanager = new midcom_helper_datamanager2_datamanager($this->_request_data['schemadb']); // Get the articles, $qb = midcom_db_article::new_query_builder(); net_nehmer_blog_viewer::article_qb_constraints($qb, $data, $handler_id); $qb->add_order('metadata.published', 'DESC'); if ($handler_id == 'feed-category-rss2') { if (!in_array($args[0], $this->_request_data['categories'])) { // This is not a predefined category from configuration, check if site maintainer allows us to show it if (!$this->_config->get('categories_custom_enable')) { throw new midcom_error('Custom category support is disabled'); } } // TODO: Check for ".xml" suffix $this->_request_data['category'] = trim(strip_tags($args[0])); $multiple_categories = true; // TODO: check schema storage to get fieldname if (isset($this->_request_data['schemadb']['default']->fields['categories']) && array_key_exists('allow_multiple', $this->_request_data['schemadb']['default']->fields['categories']['type_config']) && !$this->_request_data['schemadb']['default']->fields['categories']['type_config']['allow_multiple']) { $multiple_categories = false; } debug_add("multiple_categories={$multiple_categories}"); if ($multiple_categories) { $qb->add_constraint('extra1', 'LIKE', "%|{$this->_request_data['category']}|%"); } else { $qb->add_constraint('extra1', '=', (string) $this->_request_data['category']); } } $qb->set_limit($this->_config->get('rss_count')); $this->_articles = $qb->execute(); // Prepare the feed (this will also validate the handler_id) $this->_create_feed($handler_id); midcom::get('metadata')->set_request_metadata(net_nehmer_blog_viewer::get_last_modified($this->_topic, $this->_content_topic), $this->_topic->guid); }
/** * Get the leaves set to be displayed in navigation * * @return array */ public function get_leaves() { // Get the required information with midgard_collector $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic', '=', $this->_topic->id); $qb->add_constraint('view', '=', 1); // Set the order of navigation $qb->add_order('metadata.score', 'DESC'); $qb->add_order('title'); $qb->add_order('name'); // Return an empty result set if ($qb->count() === 0) { return array(); } $leaves = array(); // Get the leaves foreach ($qb->execute() as $article) { $leaves[$article->id] = array(MIDCOM_NAV_URL => $article->name, MIDCOM_NAV_NAME => $article->title ? $article->title : $article->name, MIDCOM_NAV_GUID => $article->guid, MIDCOM_NAV_OBJECT => $article); } // Finally return the leaves return $leaves; }
/** * Get latest 'n' comments that are posted to blogs * @param string GUID of the blog topic * @param integer the last 'n' number of comments to be fetched */ public function _get_last_blog_comments($number = -1) { $_comments = array(); $qb = net_nehmer_comments_comment::new_query_builder(); $qb->add_constraint('status', '>=', 4); $_res = $qb->execute(); foreach ($_res as $comment) { $qb2 = midcom_db_article::new_query_builder(); $qb2->add_constraint('guid', '=', $comment->objectguid); $qb2->add_constraint('topic', '=', $this->_config->get('blog_topic_id')); $_res2 = $qb2->execute(); if (count($_res2)) { $_comments[$comment->metadata->created]['type'] = 'blog'; $_comments[$comment->metadata->created]['object'] = $comment; krsort($_comments); } } if (isset($number) && $number != -1 && count($_comments) > $number) { $_comments = array_splice($_comments, 0, $number); } return $_comments; }
/** * Get article guid statically * * used by get_parent_guid_uncached_static * * @param int $parent_id id of topic to get the guid for */ private static function _get_parent_guid_uncached_static_article($parent_id) { if (empty($parent_id)) { return null; } $mc_parent = midcom_db_article::new_collector('id', $parent_id); if (!$mc_parent->execute()) { // Error return null; } $mc_parent_keys = $mc_parent->list_keys(); $parent_guid = key($mc_parent_keys); if ($parent_guid === false) { // Error return null; } return $parent_guid; }
$qb->add_constraint('metadata.navnoentry', '=', 1); $qb->end_group(); $qb->add_order('name'); $topics = $qb->execute(); unset($qb); echo "<h2>Topics</h2>\n"; foreach ($topics as $topic) { $node =& $nap->get_node($topic->id); $crumbs =& $nap->get_breadcrumb_data($node[MIDCOM_NAV_ID]); $n_crumbs = count($crumbs); $i = 0; render_breadcrumb($crumbs); echo " (<a href='{$host_prefix}__mfa/asgard/object/view/{$topic->guid}'>in Asgard</a>)<br/>\n"; } echo "<h2>Articles</h2>\n"; $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic', 'INTREE', $site_root->id); $qb->begin_group('OR'); $qb->add_constraint('metadata.hidden', '=', 1); $qb->add_constraint('metadata.navnoentry', '=', 1); $qb->end_group(); $qb->add_order('name'); $articles = $qb->execute(); unset($qb); foreach ($articles as $article) { $node =& $nap->get_node($article->topic); /* FIXME correct way to figure out leaf id ? $leaf =& $nap->get_leaf($article->id); $crumbs =& $nap->get_breadcrumb_data($leaf[MIDCOM_NAV_ID]); render_breadcrumb($crumbs); */
public function _on_updated() { parent::_on_updated(); $this->_update_watchers(); $this->_update_link_cache(); }
/** * Shows the archive. Depending on the selected handler various constraints are added to * the QB. See the add_*_constraint methods for details. * * @param mixed $handler_id The ID of the handler. * @param Array $args The argument list. * @param Array &$data The local request data. */ public function _handler_list($handler_id, array $args, array &$data) { // Get Articles, distinguish by handler. $qb = midcom_db_article::new_query_builder(); net_nehmer_blog_viewer::article_qb_constraints($qb, $data, $handler_id); // Use helper functions to determine start/end switch ($handler_id) { case 'archive-year-category': if (!$this->_config->get('archive_years_enable')) { throw new midcom_error_notfound('Year archive not allowed'); } $data['category'] = trim(strip_tags($args[1])); $multiple_categories = true; if (isset($data['schemadb']['default']->fields['categories']) && array_key_exists('allow_multiple', $data['schemadb']['default']->fields['categories']['type_config']) && !$data['schemadb']['default']->fields['categories']['type_config']['allow_multiple']) { $multiple_categories = false; } if ($multiple_categories) { $qb->add_constraint('extra1', 'LIKE', "%|{$this->_request_data['category']}|%"); } else { $qb->add_constraint('extra1', '=', (string) $data['category']); } case 'archive-year': if (!$this->_config->get('archive_years_enable')) { throw new midcom_error_notfound('Year archive not allowed'); } $this->_set_startend_from_year($args[0]); break; case 'archive-month': $this->_set_startend_from_month($args[0], $args[1]); break; default: throw new midcom_error("The request handler {$handler_id} is not supported."); } $qb->add_constraint('metadata.published', '>=', $this->_start->format('Y-m-d H:i:s')); $qb->add_constraint('metadata.published', '<', $this->_end->format('Y-m-d H:i:s')); $qb->add_order('metadata.published', $this->_config->get('archive_item_order')); $this->_articles = $qb->execute(); $this->_datamanager = new midcom_helper_datamanager2_datamanager($this->_request_data['schemadb']); // Move end date one day backwards for display purposes. $now = new DateTime(); if ($now < $this->_end) { $this->_end = $now; } else { $this->_end->modify('-1 day'); } $start = $this->_start->format($this->_l10n_midcom->get('short date')); $end = $this->_end->format($this->_l10n_midcom->get('short date')); $this->add_breadcrumb("archive/year/{$args[0]}/", "{$start} - {$end}"); $this->_prepare_request_data(); if ($this->_config->get('archive_in_navigation')) { $this->set_active_leaf($this->_topic->id . '_ARCHIVE'); } else { $this->set_active_leaf($this->_topic->id . '_ARCHIVE_' . $args[0]); } midcom::get('metadata')->set_request_metadata(net_nehmer_blog_viewer::get_last_modified($this->_topic, $this->_content_topic), $this->_topic->guid); midcom::get('head')->set_pagetitle("{$this->_topic->extra}: {$start} - {$end}"); }
private function read_structure($structure, $parent_id = 0) { if ($parent_id == 0) { $topic = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ROOTTOPIC); } else { $object_qb = midcom_db_topic::new_query_builder(); $object_qb->add_constraint('up', '=', $parent_id); $object_qb->add_constraint('name', '=', $structure['name']); if ($object_qb->count() == 0) { // New style $topic = new midcom_db_topic(); $topic->up = $parent_id; $topic->name = $structure['name']; $topic->extra = $structure['title']; $topic->title = $structure['title']; $topic->component = $structure['component']; if (!$topic->create()) { return false; } if (!empty($structure['create_index'])) { // Create index article for n.n.static $article = new midcom_db_article(); $article->name = 'index'; $article->title = $structure['title']; $article->topic = $topic->id; $article->create(); } } else { $topics = $object_qb->execute(); $topic = $topics[0]; } } // Update this folder properly $updated = false; if ($topic->extra != $structure['title']) { $topic->extra = $structure['title']; $topic->title = $structure['title']; $updated = true; } if ($topic->component != $structure['component']) { $topic->component = $structure['component']; $updated = true; } if ($topic->style != $structure['style']) { $topic->style = $structure['style']; $updated = true; } if ($topic->styleInherit != $structure['style_inherit']) { $topic->styleInherit = $structure['style_inherit']; $updated = true; } if ($updated) { $topic->update(); } // Remove parameters that are not in the topic $existing_params = $topic->list_parameters(); foreach ($existing_params as $domain => $params) { foreach ($params as $name => $value) { if (!isset($structure['parameters'][$domain]) || !isset($structure['parameters'][$domain][$name])) { $topic->set_parameter($domain, $name, ''); } } } // Set all new parameters foreach ($structure['parameters'] as $domain => $params) { foreach ($params as $name => $value) { $topic->set_parameter($domain, $name, $value); } } // FIXME: Implement ACLs // Handle subdirectories $foldernames = array(); foreach ($structure['nodes'] as $child_structure) { $this->read_structure($child_structure, $topic->id); $foldernames[] = $child_structure['name']; } if ($this->delete_missing) { // Then delete files and folders that are in DB but not in the importing folder $this->delete_missing_folders($foldernames, $topic->id); } }
/** * Cleans up old, removed items from feeds * @param Array $item Feed item as provided by MagpieRSS */ function clean($items) { if ($this->_feed->keepremoved) { // This feed is set up so that we retain items removed from array return false; } // Create array of item GUIDs $item_guids = array(); foreach ($items as $item) { $item_guids[] = $item['guid']; } // Find articles resulting from this feed $qb = midcom_db_article::new_query_builder(); $feed_category = md5($this->_feed->url); $qb->add_constraint('extra1', 'LIKE', "%|feed:{$feed_category}|%"); $local_items = $qb->execute_unchecked(); $guid_property = $this->_guid_property; $purge_guids = array(); foreach ($local_items as $item) { if (!in_array($item->{$guid_property}, $item_guids)) { // This item has been removed from the feed. if (midcom::get('componentloader')->is_installed('net.nemein.favourites') && midcom::get('componentloader')->load_graceful('net.nemein.favourites')) { // If it has been favorited keep it $qb = net_nemein_favourites_favourite_dba::new_query_builder(); $qb->add_constraint('objectGuid', '=', $item->guid); if ($qb->count_unchecked() > 0) { continue; // Skip deleting this one } } $purge_guids[] = $item->guid; $item->delete(); } } midcom_baseclasses_core_dbobject::purge($purge_guids, 'midgard_article'); return true; }
function import_file($file, $parent_id) { $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic', '=', $parent_id); $qb->add_constraint('name', '=', $file->name); $existing = $qb->execute(); if (count($existing) > 0 && $existing[0]->topic == $parent_id) { $article = $existing[0]; echo "Using existing article {$article->name} (#{$article->id}) from #{$article->topic}\n"; } else { $article = new midcom_db_article(); $article->topic = $parent_id; $article->name = $file->name; if (!$article->create()) { echo "Failed to create article {$article->name}: " . midcom_connection::get_error_string() . "\n"; return false; } echo "Created article {$article->name} (#{$article->id}) under #{$article->topic}\n"; } $article->title = $file->title; $article->content = $file->content; return $article->update(); }
/** * List topic contents * * @param int $id Topic ID */ public static function list_children($id) { try { $topic = new midcom_db_topic($id); $children = self::_get_child_objects($topic); if ($children === false) { $children = array(); } } catch (midcom_error $e) { $children = array(); } $qb_topic = midcom_db_topic::new_query_builder(); $qb_topic->add_constraint('up', '=', $id); $qb_article = midcom_db_article::new_query_builder(); $qb_article->add_constraint('topic', '=', $id); if ($qb_topic->count() === 0 && $qb_article->count() === 0 && !$children) { return false; } echo "<ul class=\"folder_list\">\n"; foreach ($qb_topic->execute_unchecked() as $topic) { $topic_title = $topic->extra; if (!$topic_title) { $topic_title = $topic->name; } echo " <li class=\"node\">\n"; echo " <img src=\"" . MIDCOM_STATIC_URL . "/stock-icons/16x16/stock_folder.png\" alt=\"\" /> {$topic_title}\n"; self::list_children($topic->id); echo " </li>\n"; } foreach ($qb_article->execute_unchecked() as $article) { echo " <li class=\"leaf article\">\n"; echo " <img src=\"" . MIDCOM_STATIC_URL . "/stock-icons/16x16/document.png\" alt=\"\" /> {$article->title}\n"; // Check for the reply articles $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('up', '=', $article->id); if ($qb->count() > 0) { $reply_ul = false; foreach ($qb->execute_unchecked() as $reply) { if (!$reply_ul) { echo " <ul>\n"; $reply_ul = true; } echo " <li class=\"leaf_child reply_article\">{$reply->title}\n"; self::_list_leaf_children($reply); echo " </li>\n"; } if ($reply_ul) { echo " </ul>\n"; } } self::_list_leaf_children($article, array('midgard_article')); echo " </li>\n"; } foreach ($children as $class => $objects) { if ($class == 'midgard_topic' || $class == 'midgard_article') { continue; } $style = ""; if ($class == 'net_nemein_tag_link') { $style = "style=\"display: none;\""; } foreach ($objects as $object) { $title = midcom_helper_reflector::get($class)->get_object_label($object); echo " <li class=\"leaf {$class}\"{$style}>\n"; echo " <img src=\"" . MIDCOM_STATIC_URL . "/stock-icons/16x16/document.png\" alt=\"\" /> {$title}\n"; self::_list_leaf_children($object); echo " </li>\n"; } } echo "</ul>\n"; }
/** * Simple helper, gets the last modified timestamp of the topic/content_topic combination * specified. * * @param midcom_db_topic $topic The base topic to use. * @param mdicom_db_topic $content_topic The topic where the articles are stored. */ public static function get_last_modified($topic, $content_topic) { // Get last modified timestamp $qb = midcom_db_article::new_query_builder(); // FIXME: use the constraints method below $qb->add_constraint('topic', '=', $content_topic->id); $qb->add_order('metadata.revised', 'DESC'); $qb->set_limit(1); $articles = $qb->execute(); if ($articles) { if (array_key_exists(0, $articles)) { return max($topic->metadata->revised, $articles[0]->metadata->revised); } return $topic->metadata->revised; } else { return $topic->metadata->revised; } }
private function _load_index_article() { $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('name', '=', 'index'); $qb->set_limit(1); // Include the article links to the indexes if enabled if ($this->_config->get('enable_article_links')) { $mc = net_nehmer_static_link_dba::new_collector('topic', $this->_content_topic->id); $mc->add_constraint('topic', '=', $this->_content_topic->id); $links = $mc->get_values('article'); $qb->begin_group('OR'); if (count($links) > 0) { $qb->add_constraint('id', 'IN', $links); } $qb->add_constraint('topic', '=', $this->_content_topic->id); $qb->end_group(); } else { $qb->add_constraint('topic', '=', $this->_content_topic->id); } $result = $qb->execute(); if (empty($result)) { if ($this->_content_topic->can_do('midgard:create')) { // Check via non-ACLd QB that the topic really doesn't have index article before relocating $index_qb = midcom_db_article::new_query_builder(); $index_qb->add_constraint('topic', '=', $this->_content_topic->id); $index_qb->add_constraint('name', '=', 'index'); if ($index_qb->count_unchecked() == 0) { $schemas = array_keys($this->_request_data['schemadb']); midcom::get()->relocate("createindex/{$schemas[0]}/"); // This will exit. } } throw new midcom_error_forbidden('Directory index forbidden'); } $this->_article = $result[0]; }
function deletePost($message) { $args = $this->_params_to_args($message); if (count($args) != 5) { return new XML_RPC_Response(0, midcom_connection::get_error(), 'Invalid arguments.'); } if (!midcom::get('auth')->login($args[2], $args[3])) { return new XML_RPC_Response(0, midcom_connection::get_error(), 'Authentication failed.'); } midcom::get('auth')->initialize(); try { $article = new midcom_db_article($args[1]); } catch (midcom_error $e) { return new XML_RPC_Response(0, midcom_connection::get_error(), 'Article not found: ' . $e->getMessage()); } if (!$article->delete()) { return new XML_RPC_Response(0, midcom_connection::get_error(), 'Failed to delete article: ' . midgard_connection::get_error_string()); } // Update the index $indexer = midcom::get('indexer'); $indexer->delete($article->guid); return new XML_RPC_Response(new XML_RPC_Value(true, 'boolean')); }
/** * This helper function goes over the topic and loads all available objects for displaying * in the autoindex. * * It will populate the request data key 'create_urls' as well. See the view handler for * further details. * * The computed array has the following keys: * * - string name: The name of the object. * - string url: The full URL to the object. * - string size: The formatted size of the document. This is only populated for attachments. * - string desc: The object title/description. * - string type: The MIME Type of the object. * - string lastmod: The localized last modified date. * * @return Array Autoindex objects as outlined above */ private function _load_autoindex_data() { $view = array(); $datamanager = new midcom_helper_datamanager2_datamanager($this->_request_data['schemadb']); $qb = midcom_db_article::new_query_builder(); $sort_order = 'ASC'; $sort_property = $this->_config->get('sort_order'); if (strpos($sort_property, 'reverse ') === 0) { $sort_order = 'DESC'; $sort_property = substr($sort_property, strlen('reverse ')); } if (strpos($sort_property, 'metadata.') === false) { $article = new midgard_article(); if (!property_exists($article, $sort_property)) { $sort_property = 'metadata.' . $sort_property; } } $qb->add_order($sort_property, $sort_order); $qb->add_order('title'); $qb->add_order('name'); // Include the article links to the indexes if enabled if ($this->_config->get('enable_article_links')) { $mc = net_nehmer_static_link_dba::new_collector('topic', $this->_content_topic->id); $mc->add_constraint('topic', '=', $this->_content_topic->id); $links = $mc->get_values('article'); $qb->begin_group('OR'); if (count($links) > 0) { $qb->add_constraint('id', 'IN', $links); } $qb->add_constraint('topic', '=', $this->_content_topic->id); $qb->end_group(); } else { $qb->add_constraint('topic', '=', $this->_content_topic->id); } $result = $qb->execute(); foreach ($result as $article) { if (!$datamanager->autoset_storage($article)) { debug_add("The datamanager for article {$article->id} could not be initialized, skipping it."); debug_print_r('Object was:', $article); continue; } $this->_process_datamanager($datamanager, $article, $view); } return $view; }
function _on_execute() { debug_add('_on_execute called'); if (!$this->_config->get('qaiku_enable')) { debug_add('Qaiku import disabled, aborting', MIDCOM_LOG_INFO); return; } if (!midcom::get('auth')->request_sudo('net.nehmer.comments')) { debug_add('Could not get sudo, aborting operation', MIDCOM_LOG_ERROR); return; } // Get 50 latest articles so we can look for those $articles_by_url = array(); $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic.guid', '=', $this->_config->get('qaiku_topic')); $qb->add_order('metadata.published', 'DESC'); $qb->set_limit(20); $articles = $qb->execute(); foreach ($articles as $article) { $articles_by_url[midcom::get('permalinks')->resolve_permalink($article->guid)] = $article; } unset($articles); foreach ($articles_by_url as $article_url => $article) { // Get the Qaiku JSON feed for article $url = "http://www.qaiku.com/api/statuses/replies/byurl.json?external_url=" . urlencode($article_url) . "&apikey=" . $this->_config->get('qaiku_apikey'); $json_file = @file_get_contents($url); if (!$json_file) { continue; } $comments = json_decode($json_file); if (empty($comments)) { continue; } foreach ($comments as $entry) { $article->set_parameter('net.nehmer.comments', 'qaiku_url', $entry->in_reply_to_status_url); $entry_published = strtotime($entry->created_at); // Check this comment isn't there yet $qb = net_nehmer_comments_comment::new_query_builder(); $qb->add_constraint('author', '=', (string) $entry->user->name); $qb->add_constraint('metadata.published', '=', gmstrftime('%Y-%m-%d %T', $entry_published)); $qb->add_constraint('objectguid', '=', $article->guid); $comments = $qb->execute(); if (count($comments) > 0) { // Update comment as needed $comment = $comments[0]; if ($comment->content != $entry->html) { // Entry has been updated $comment->content = (string) $entry->html; $comment->update(); } unset($comments); continue; } $comment = new net_nehmer_comments_comment(); $comment->objectguid = $article->guid; $comment->author = $entry->user->name; $comment->content = $entry->html; $comment->metadata->published = $entry_published; $comment->status = $this->_config->get('qaiku_initial_status'); $comment->create(); } } midcom::get('auth')->drop_sudo(); debug_add('Done'); }
private function _add_pseudo_leaves(&$leaves) { if ($this->_config->get('archive_enable') && $this->_config->get('archive_in_navigation')) { $leaves["{$this->_topic->id}_ARCHIVE"] = array(MIDCOM_NAV_URL => "archive/", MIDCOM_NAV_NAME => $this->_l10n->get('archive')); } if ($this->_config->get('rss_enable') && $this->_config->get('feeds_in_navigation')) { $leaves[NET_NEHMER_BLOG_LEAFID_FEEDS] = array(MIDCOM_NAV_URL => "feeds/", MIDCOM_NAV_NAME => $this->_l10n->get('available feeds')); } if ($this->_config->get('categories_in_navigation') && $this->_config->get('categories') != '') { $categories = explode(',', $this->_config->get('categories')); foreach ($categories as $category) { $leaves["{$this->_topic->id}_CAT_{$category}"] = array(MIDCOM_NAV_URL => "category/{$category}/", MIDCOM_NAV_NAME => $category); } } if ($this->_config->get('archive_years_in_navigation') && $this->_config->get('archive_years_enable')) { $qb = midcom_db_article::new_query_builder(); $qb->add_constraint('topic', '=', $this->_content_topic->id); // Hide the articles that have the publish time in the future and if // the user is not administrator if ($this->_config->get('enable_scheduled_publishing') && !midcom::get('auth')->admin) { // Show the article only if the publishing time has passed or the viewer // is the author $qb->begin_group('OR'); $qb->add_constraint('metadata.published', '<', gmdate('Y-m-d H:i:s')); if (midcom::get('auth')->user && isset(midcom::get('auth')->user->guid)) { $qb->add_constraint('metadata.authors', 'LIKE', '|' . midcom::get('auth')->user->guid . '|'); } $qb->end_group(); } $qb->add_order('metadata.published'); $qb->set_limit(1); $result = $qb->execute_unchecked(); if (count($result) == 0) { return $leaves; } $first_year = (int) gmdate('Y', (int) $result[0]->metadata->published); $year = $first_year; $this_year = (int) gmdate('Y', time()); while ($year <= $this_year) { $leaves["{$this->_topic->id}_ARCHIVE_{$year}"] = array(MIDCOM_NAV_URL => "archive/year/{$year}/", MIDCOM_NAV_NAME => $year); $year = $year + 1; } $leaves = array_reverse($leaves); } }