public static function initialize_index_article($topic) { $page = new net_nemein_wiki_wikipage(); $page->topic = $topic->id; $page->name = 'index'; $page->title = $topic->extra; $page->content = midcom::get('i18n')->get_string('wiki default page content', 'net.nemein.wiki'); $page->author = midcom_connection::get_user(); if ($page->create()) { return $page; } return false; }
/** * * @param mixed $handler_id The ID of the handler. * @param array &$data The local request data. */ public function _show_rss($handler_id, array &$data) { $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic.component', '=', midcom_core_context::get()->get_key(MIDCOM_CONTEXT_COMPONENT)); $qb->add_constraint('topic', 'INTREE', $this->_topic->id); $qb->add_order('metadata.revised', 'DESC'); $qb->set_limit($this->_config->get('rss_count')); $result = $qb->execute(); foreach ($result as $wikipage) { if ($wikipage->topic == $this->_topic->id) { $node = $data['node']; } else { $node = $data['nap']->get_node($wikipage->topic); } $item = new FeedItem(); $item->title = $wikipage->title; if ($wikipage->name == 'index') { $item->link = "{$node[MIDCOM_NAV_FULLURL]}"; } else { $item->link = "{$node[MIDCOM_NAV_FULLURL]}{$wikipage->name}/"; } $item->date = $wikipage->metadata->revised; try { $author = new midcom_db_person($wikipage->metadata->revisor); $item->author = $author->name; } catch (midcom_error $e) { $e->log(); } $parser = new net_nemein_wiki_parser($wikipage); $item->description = $parser->get_html(); $data['rss_creator']->addItem($item); } $data['rss'] = $data['rss_creator']->createFeed('RSS2.0'); echo $data['rss']; }
/** * List all items updated with then given timeframe */ private function _seek_updated($from, $to = null) { if (is_null($to)) { $to = time(); } $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic.component', '=', 'net.nemein.wiki'); $qb->add_constraint('topic', 'INTREE', $this->_topic->id); $qb->add_constraint('metadata.revised', '<=', date('Y-m-d H:i:s', $to)); $qb->add_constraint('metadata.revised', '>=', date('Y-m-d H:i:s', $from)); $qb->add_order('metadata.revised', 'DESC'); $result = $qb->execute(); $rcs = midcom::get('rcs'); foreach ($result as $page) { $rcs_handler = $rcs->load_handler($page); if (!$rcs_handler) { // Skip this one continue; } // Get object history $history = $rcs_handler->list_history(); foreach ($history as $version => $history) { if ($this->_updated_pages >= $this->_max_pages) { // End here return; } if ($history['date'] < $from || $history['date'] > $to) { // We can ignore revisions outside the timeframe continue; } $history['object'] = $page; $this->_add_history_entry($version, $history); } } }
/** * @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_change($handler_id, array $args, array &$data) { if ($_SERVER['REQUEST_METHOD'] != 'POST') { throw new midcom_error_forbidden('Only POST requests are allowed here.'); } $this->_page = $this->_master->load_page($args[0]); $this->_page->require_do('midgard:update'); // Change schema to redirect $this->_page->parameter('midcom.helper.datamanager2', 'schema_name', $_POST['change_to']); // Redirect to editing return new midcom_response_relocate("edit/{$this->_page->name}/"); }
public function testCRUD() { midcom::get('auth')->request_sudo('net.nemein.wiki'); $page = new net_nemein_wiki_wikipage(); $topic = $this->get_component_node('net.nemein.wiki'); $page->topic = $topic->id; $page->title = 'TEST TITLE'; $stat = $page->create(); $this->assertTrue($stat, midcom_connection::get_error_string()); $this->register_object($page); $page->refresh(); $this->assertEquals('test-title', $page->name); $page->title = 'Test Title 2'; $stat = $page->update(); $this->assertTrue($stat); $page->refresh(); $this->assertEquals('Test Title 2', $page->title); $stat = $page->delete(); $this->assertTrue($stat); midcom::get('auth')->drop_sudo(); }
/** * @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, $args, &$data, $delete_mode = true) { $this->_page = $this->_master->load_page($args[0]); $this->_page->require_do('midgard:delete'); if (array_key_exists('net_nemein_wiki_deleteok', $_POST)) { $wikiword = $this->_page->title; if ($this->_page->delete()) { midcom::get('uimessages')->add($this->_request_data['l10n']->get('net.nemein.wiki'), sprintf($this->_request_data['l10n']->get('page %s deleted'), $wikiword), 'ok'); // Update the index $indexer = midcom::get('indexer'); $indexer->delete($this->_page->guid); return new midcom_response_relocate(midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX)); } else { throw new midcom_error("Failed to delete wikipage, reason " . midcom_connection::get_error_string()); } } $this->_load_datamanager(); $this->_view_toolbar->add_item(array(MIDCOM_TOOLBAR_URL => "{$this->_page->name}/", MIDCOM_TOOLBAR_LABEL => $this->_request_data['l10n_midcom']->get('cancel'), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/cancel.png')); $this->_view_toolbar->bind_to($this->_page); $this->add_breadcrumb("{$this->_page->name}/", $this->_page->title); $this->add_breadcrumb("delete/{$this->_page->name}/", $this->_l10n_midcom->get('delete')); midcom::get('head')->set_pagetitle($this->_page->title); }
public function _on_creating() { if ($this->title == '' || !$this->topic) { // We must have wikiword and topic at this stage return false; } // Check for duplicates $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $this->topic); $qb->add_constraint('title', '=', $this->title); $result = $qb->execute(); if (count($result) > 0) { midcom_connection::set_error(MGD_ERR_OBJECT_NAME_EXISTS); return false; } // Generate URL-clean name if ($this->name != 'index') { $this->name = midcom_helper_misc::generate_urlname_from_string($this->title); } return true; }
/** * Iterate over all wiki pages and create index record using the datamanager2 indexer * method. */ public function _on_reindex($topic, $config, &$indexer) { $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $topic->id); $result = $qb->execute(); if ($result) { $schemadb = midcom_helper_datamanager2_schema::load_database($config->get('schemadb')); $datamanager = new midcom_helper_datamanager2_datamanager($schemadb); if (!$datamanager) { debug_add('Warning, failed to create a datamanager instance with this schemapath:' . $config->get('schemadb'), MIDCOM_LOG_WARN); continue; } foreach ($result as $wikipage) { if (!$datamanager->autoset_storage($wikipage)) { debug_add("Warning, failed to initialize datamanager for Wiki page {$wikipage->id}. Skipping it.", MIDCOM_LOG_WARN); continue; } net_nemein_wiki_viewer::index($datamanager, $indexer, $topic); } } return true; }
/** * @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_orphan($handler_id, array $args, array &$data) { $data['wiki_name'] = $this->_topic->extra; $data['view_title'] = sprintf($this->_l10n->get('orphaned pages in wiki %s'), $data['wiki_name']); midcom::get('head')->set_pagetitle($data['view_title']); $this->_node_toolbar->hide_item('orphans/'); $data['orphans'] = array(); $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $this->_topic->id); $qb->add_constraint('name', '<>', 'index'); $qb->add_order('name'); $wikipages = $qb->execute(); foreach ($wikipages as $wikipage) { $link_qb = net_nemein_wiki_link_dba::new_query_builder(); $link_qb->add_constraint('topage', '=', $wikipage->title); $links = $link_qb->count_unchecked(); if ($links == 0) { $data['orphans'][] = $wikipage; } } $this->add_breadcrumb('orphans/', $data['view_title']); }
/** * @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_tagged($handler_id, array $args, array &$data) { $data['tag'] = $args[0]; // Get wiki page GUIDs from tag links $mc = net_nemein_tag_link_dba::new_collector('metadata.deleted', false); $mc->add_constraint('fromClass', '=', 'net_nemein_wiki_wikipage'); $mc->add_constraint('tag.tag', '=', $data['tag']); $wikipage_guids = $mc->get_values('fromGuid'); if (empty($wikipage_guids)) { throw new midcom_error_notfound("No wiki pages tagged with {$data['tag']}"); } $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', 'INTREE', $this->_topic->id); $qb->add_constraint('guid', 'IN', $wikipage_guids); $qb->add_order('metadata.score', 'DESC'); $data['wikipages'] = $qb->execute(); if (count($data['wikipages']) == 0) { throw new midcom_error_notfound("No wiki pages tagged with {$data['tag']}"); } $data['view_title'] = sprintf($this->_request_data['l10n']->get('pages tagged with %s in %s'), $data['tag'], $this->_topic->extra); midcom::get('head')->set_pagetitle($data['view_title']); $this->add_breadcrumb("tags/{$data['tag']}/", $data['view_title']); }
/** * @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_notfound($handler_id, array $args, array &$data) { $data['wikiword'] = $args[0]; $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $this->_topic->id); $qb->add_constraint('title', '=', $data['wikiword']); $result = $qb->execute(); if (count($result) > 0) { // This wiki page actually exists, so go there as "Permanent Redirect" return new midcom_response_relocate("{$result[0]->name}/", 301); } // This is a custom "not found" page, send appropriate headers to prevent indexing midcom::get()->header('Not found', 404); midcom::get('head')->set_pagetitle(sprintf($this->_l10n->get('"%s" not found'), $data['wikiword'])); // TODO: List pages containing the wikiword via indexer $data['wiki_name'] = $this->_topic->extra; // Populate toolbar for actions available $data['wiki_tools'] = new midcom_helper_toolbar(); $data['wiki_tools']->add_item(array(MIDCOM_TOOLBAR_URL => 'create/?wikiword=' . rawurlencode($data['wikiword']), MIDCOM_TOOLBAR_LABEL => sprintf($this->_l10n->get('create page %s'), $data['wikiword']), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/new-html.png', MIDCOM_TOOLBAR_ENABLED => $this->_topic->can_do('midgard:create'))); $data['wiki_tools']->add_item(array(MIDCOM_TOOLBAR_URL => 'create/redirect/?wikiword=' . rawurlencode($data['wikiword']), MIDCOM_TOOLBAR_LABEL => sprintf($this->_l10n->get('create redirection page %s'), $data['wikiword']), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/new-html.png', MIDCOM_TOOLBAR_ENABLED => $this->_topic->can_do('midgard:create'))); $data['wiki_tools']->add_item(array(MIDCOM_TOOLBAR_URL => 'http://' . midcom::get('i18n')->get_current_language() . '.wikipedia.org/wiki/' . rawurlencode($data['wikiword']), MIDCOM_TOOLBAR_LABEL => sprintf($this->_l10n->get('look for %s in wikipedia'), $data['wikiword']), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/search.png', MIDCOM_TOOLBAR_OPTIONS => array('rel' => 'directlink'))); $this->add_breadcrumb('notfound/' . rawurlencode($data['wikiword']), $data['wikiword']); }
/** * @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_emailimport($handler_id, array $args, array &$data) { //Content-Type midcom::get()->skip_page_style = true; midcom::get('cache')->content->content_type('text/plain'); //Make sure we have the components we use and the Mail_mimeDecode package if (!class_exists('org_openpsa_mail_decoder')) { throw new midcom_error('org.openpsa.mail decoder could not be loaded.'); } if (!class_exists('Mail_mimeDecode')) { throw new midcom_error('Cannot decode attachments, aborting.'); } //Make sure the message_source is POSTed if (!array_key_exists('message_source', $_POST) || empty($_POST['message_source'])) { throw new midcom_error('_POST[\'message_source\'] not present or empty.'); } $decoder = new org_openpsa_mail_decoder(); $decoder->mime_decode($_POST['message_source']); //Parse email addresses $regex = '/<?([a-zA-Z0-9_.-]+?@[a-zA-Z0-9_.-]+)>?[ ,]?/'; $emails = array(); if (preg_match_all($regex, $decoder->headers['To'], $matches_to)) { foreach ($matches_to[1] as $email) { //Each address only once $emails[$email] = $email; } } if (preg_match_all($regex, $decoder->headers['Cc'], $matches_cc)) { foreach ($matches_cc[1] as $email) { //Each address only once $emails[$email] = $email; } } $from = false; if (preg_match_all($regex, $decoder->headers['From'], $matches_from)) { foreach ($matches_from[1] as $email) { //Each address only once $emails[$email] = $email; //It's unlikely that we'd get multiple matches in From, but we use the latest $from = $email; } } midcom::get('auth')->request_sudo(); //TODO: Create wikinote $wikipage = new net_nemein_wiki_wikipage(); $wikipage->topic = $this->_topic->id; //PONDER: add from, to & subject into the body ?? $wikipage->content = $decoder->body; $title_format = $this->_config->get('emailimport_title_format'); $wikipage->title = sprintf($title_format, $decoder->subject, $from, strftime('%x', time())); //Check for duplicate title(s) $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $wikipage->topic); $qb->add_constraint('title', 'LIKE', $wikipage->title . '%'); $results = $qb->execute_unchecked(); if (($found = count($results)) > 0) { foreach ($results as $foundpage) { if ($foundpage->content == $wikipage->content) { //Content exact duplicate, abort import debug_print_r("duplicate content with page '{$wikipage->title}", $wikipage->content); throw new midcom_error('Duplicate content with an existing page with similar title.'); } } //In theory this should be recursive but we'll leave it at this for now $wikipage->title .= ' ' . ($found + 1); } //Figure out author $author = $this->emailimport_find_person($from); $wikipage->author = $author->id; if (!$wikipage->author) { //Default to first user in the db $qb = midcom_db_person::new_query_builder(); $qb->add_constraint('username', '<>', ''); $results = $qb->execute_unchecked(); if (empty($results)) { //No users found throw new midcom_error('Cannot set any author for the wikipage'); } $wikipage->author = $results[0]->id; } if (!$wikipage->create()) { throw new midcom_error('wikipage->create returned failure, errstr: ' . midcom_connection::get_error_string()); } //Mark as email $wikipage->parameter('net.nemein.wiki:emailimport', 'is_email', time()); $embeds_added = false; $attachments_added = false; foreach ($decoder->attachments as $att) { debug_add("processing attachment {$att['name']}"); $attobj = $wikipage->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) { $wikipage->content .= "\n\n"; $embeds_added = true; } $wikipage->content .= "![{$attobj->title}](" . midcom_connection::get_url('self') . "midcom-serveattachmentguid-{$attobj->guid}/{$attobj->name})\n\n"; } 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 $wikipage->content .= "\n\n"; $attachments_added = true; } $wikipage->content .= "[{$attobj->title}](" . midcom_connection::get_url('self') . "midcom-serveattachmentguid-{$attobj->guid}/{$attobj->name}), "; } } if ($embeds_added || $attachments_added) { $wikipage->update(); } // Store recipients of the email to the page for possible later use reset($emails); foreach ($emails as $email) { $wikipage->parameter('net.nemein.wiki:emailimport_recipients', $email, time()); debug_add("Processing email address {$email} for related-to links"); $person = $this->emailimport_find_person($email); if (!$person) { $group = $this->emailimport_find_group($email); if (!$group) { debug_add("Could not find person or group for email {$email}, cannot link, storing email for future reference", MIDCOM_LOG_WARN); $wikipage->parameter('net.nemein.wiki:emailimport_notlinked', $email, time()); continue; } continue; } } midcom::get('auth')->drop_sudo(); }
/** * @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_view($handler_id, $args, &$data, $view_mode = true) { if (!$this->_page) { throw new midcom_error_notfound('The requested page could not be found.'); } $this->_load_datamanager(); if ($this->_datamanager->schema->name == 'redirect') { $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic.component', '=', 'net.nemein.wiki'); $qb->add_constraint('title', '=', $this->_page->url); $result = $qb->execute(); if (count($result) == 0) { // No matching redirection page found, relocate to editing // TODO: Add UI message return new midcom_response_relocate("edit/{$this->_page->name}/"); } if ($result[0]->topic == $this->_topic->id) { return new midcom_response_relocate("{$result[0]->name}/"); } else { return new midcom_response_relocate(midcom::get('permalinks')->create_permalink($result[0]->guid)); } } $this->_populate_toolbar(); $this->_view_toolbar->hide_item("{$this->_page->name}/"); if ($this->_page->name != 'index') { $this->add_breadcrumb("{$this->_page->name}/", $this->_page->title); } midcom::get('head')->set_pagetitle($this->_page->title); midcom::get('metadata')->set_request_metadata($this->_page->metadata->revised, $this->_page->guid); }
function import_file($title, $revision_path) { if (!is_readable($revision_path)) { return false; } if (!is_object($this->root_topic) || empty($this->root_topic->id)) { return false; } if (!$this->_datamanager) { return false; } if (!$this->_l10n) { return false; } $resolver = net_nemein_wiki_resolver($this->root_topic->id); // Make sure this is clean $this->add_parameters = array(); $content = trim(file_get_contents($revision_path)) . "\n"; $content = $this->moinmoin2markdown($content, $title); $resolved = $resolver->path_to_wikipage($title, true); echo "INFO: Importing '{$revision_path}' into '{$title}'<br/>\n"; if (!empty($resolved['latest_parent'])) { $to_node =& $resolved['latest_parent']; } else { $to_node =& $resolved['folder']; } $created_page = false; switch (true) { case strstr($resolved['remaining_path'], '/'): // One or more namespaces left, find first, create it and recurse $paths = explode('/', $resolved['remaining_path']); $folder_title = array_shift($paths); echo "NOTICE: Creating new wiki topic '{$folder_title}' under #{$to_node[MIDCOM_NAV_ID]}<br/>\n"; $topic = new midcom_db_topic(); $topic->up = $to_node[MIDCOM_NAV_ID]; $topic->extra = $folder_title; $topic->title = $folder_title; $topic->name = midcom_helper_misc::generate_urlname_from_string($folder_title); $topic->component = 'net.nemein.wiki'; if (!$topic->create()) { throw new midcom_error("could not create topic, error: " . midcom_connection::get_error_string()); } $topic = new midcom_db_topic($topic->id); // Set the component $topic->parameter('midcom', 'component', 'net.nemein.wiki'); // See if we have article with same title in immediate parent $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('title', '=', $folder_title); $qb->add_constraint('topic', '=', $topic->up); $results = $qb->execute(); if (is_array($results) && count($results) == 1) { echo "INFO: Found page with same title in parent, moving to be index of this new topic<br/>\n"; $article =& $results[0]; $article->name = 'index'; $article->topic = $topic->id; if (!$article->update()) { // Could not move article, do something ? echo "FAILURE: Could not move the page, errstr: " . midcom_connection::get_error_string() . "<br/>\n"; } } else { $page = new net_nemein_wiki_wikipage(); $page->topic = $topic->id; $page->name = 'index'; $page->title = $topic->extra; $page->content = $this->_l10n->get('wiki default page content'); $page->author = midcom_connection::get_user(); if (!$page->create()) { // Could not create index $topic->delete(); throw new midcom_error("Could not create index for new topic, errstr: " . midcom_connection::get_error_string()); } } // We have created a new topic, now recurse to create the rest of the path. echo "INFO: New topic created with id #{$topic->id}, now recursing the import to process next levels<br/>\n"; return $this->import_file($title, $revision_path); break; case is_object($resolved['wikipage']): // Page exists, create new revision echo "INFO: Updating wikipage #{$resolved['wikipage']->id}<br/>\n"; $wikipage =& $resolved['wikipage']; break; default: // No more namespaces left, create the page to latest parent echo "INFO: Creating new wikipage '{$resolved['remaining_path']}' in topic #{$to_node[MIDCOM_NAV_ID]} <br/>\n"; $wikipage = new net_nemein_wiki_wikipage(); $wikipage->title = $resolved['remaining_path']; $wikipage->name = midcom_helper_misc::generate_urlname_from_string($resolved['remaining_path']); $wikipage->topic = $to_node[MIDCOM_NAV_ID]; $wikipage->author = midcom_connection::get_user(); if (!$wikipage->create()) { echo "FAILURE: could not create wikipage object, error: " . midcom_connection::get_error_string() . "<br/>\n"; return false; } $wikipage = new net_nemein_wiki_wikipage($wikipage->id); $created_page =& $wikipage; $wikipage->set_parameter('midcom.helper.datamanager2', 'schema_name', 'default'); break; } if (!$this->_datamanager->autoset_storage($wikipage)) { // DM2 initialization failure echo "FAILURE: Could not initialize DM2<br/>\n"; if (is_object($created_page)) { // Clean up the just created page $created_page->delete(); } return false; } $this->_datamanager->types['content']->value = $content; if (!$this->_datamanager->save()) { // DM2 save failure echo "FAILURE: DM2->save() failed, errstr: " . midcom_connection::get_error_string() . "<br/>\n"; if (is_object($created_page)) { // Clean up the just created page $created_page->delete(); } return false; } // Handle $this->add_object_parameters if (!empty($this->add_object_parameters)) { foreach ($this->add_object_parameters as $param) { $wikipage->set_parameter($param['domain'], $param['name'], $param['value']); } } echo "INFO: file imported OK<br/>\n"; return true; }
/** * table of contents for the current pages node */ private function _run_macro_nodetoc($macro_content, $fulltag, $after) { $text = trim($macro_content); $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $this->_page->topic); $qb->add_constraint('name', '<>', $this->_page->name); $qb->add_order('title', 'ASC'); $pages = $qb->execute(); if (!is_array($pages)) { // QB error return false; } $nap = new midcom_helper_nav(); $node = $nap->get_node($this->_page->topic); $ret = "\n<ul class=\"node-toc\">\n"; if (!empty($text)) { $ret .= " \n<lh>{$text}</lh>\n"; } foreach ($pages as $page) { $url = $node[MIDCOM_NAV_FULLURL] . "{$page->name}/"; $ret .= " <li class=\"page\"><a href=\"{$url}\">{$page->title}</a></li>\n"; } $ret .= "</ul>\n"; return $ret . $after; }
/** * Traverse hierarchy of wiki folders or "name spaces" to figure out * if a page exists * * @return array containing midcom_db_topic and net_nemein_wiki_wikipage objects if found */ function path_to_wikipage($path, $force_resolve_folder_tree = false, $force_as_root = false) { $matches = array('wikipage' => null, 'folder' => null, 'latest_parent' => null, 'remaining_path' => $path); // Namespaced handling if (strstr($path, '/')) { /* We store the Wiki folder hierarchy in a static array that is populated only once, and even then only the first time we encounter a namespaced wikilink */ static $folder_tree = array(); if (count($folder_tree) == 0 || $force_resolve_folder_tree) { $folder_tree = $this->_resolve_folder_tree($force_as_root); } if (substr($path, 0, 1) != '/') { // This is a relative path, expand to full path foreach ($folder_tree as $prefix => $folder) { if ($folder[MIDCOM_NAV_ID] == $this->_topic) { $path = "{$prefix}{$path}"; break; } } } if (array_key_exists($path, $folder_tree)) { // This is a direct link to a folder, return the index article $matches['folder'] = $folder_tree[$path]; $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $folder_tree[$path][MIDCOM_NAV_ID]); $qb->add_constraint('name', '=', 'index'); $wikipages = $qb->execute(); if (count($wikipages) == 0) { $matches['remaining_path'] = $folder_tree[$path][MIDCOM_NAV_NAME]; return $matches; } $matches['wikipage'] = $wikipages[0]; return $matches; } // Resolve topic from path $directory = dirname($path); if (!array_key_exists($directory, $folder_tree)) { // Wiki folder is missing, go to create // Walk path downwards to locate latest parent $localpath = $path; $matches['latest_parent'] = $folder_tree['/']; while ($localpath && $localpath != '/') { $localpath = dirname($localpath); if (array_key_exists($localpath, $folder_tree)) { $matches['latest_parent'] = $folder_tree[$localpath]; $matches['remaining_path'] = substr($path, strlen($localpath)); if (substr($matches['remaining_path'], 0, 1) == '/') { $matches['remaining_path'] = substr($matches['remaining_path'], 1); } break; } } return $matches; } $folder = $folder_tree[$directory]; $matches['remaining_path'] = substr($path, strlen($directory) + 1); } else { // The linked page is in same namespace $nap = new midcom_helper_nav(); $folder = $nap->get_node($this->_topic); } if (empty($folder)) { return null; } // Check if the wikipage exists $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('title', '=', basename($path)); $qb->add_constraint('topic', '=', $folder[MIDCOM_NAV_ID]); $wikipages = $qb->execute(); if (count($wikipages) == 0) { // No page found, go to create $matches['folder'] = $folder; return $matches; } $matches['wikipage'] = $wikipages[0]; return $matches; }
private function _check_unique_wikiword($wikiword) { $resolver = new net_nemein_wiki_resolver($this->_topic->id); $resolved = $resolver->path_to_wikipage($wikiword, true, true); if (!empty($resolved['latest_parent'])) { $to_node =& $resolved['latest_parent']; } else { $to_node =& $resolved['folder']; } $created_page = false; switch (true) { case strstr($resolved['remaining_path'], '/'): // One or more namespaces left, find first, create it and recurse $paths = explode('/', $resolved['remaining_path']); $folder_title = array_shift($paths); $topic = new midcom_db_topic(); $topic->up = $to_node[MIDCOM_NAV_ID]; $topic->extra = $folder_title; $topic->title = $folder_title; $topic->name = midcom_helper_misc::generate_urlname_from_string($folder_title); $topic->component = 'net.nemein.wiki'; if (!$topic->create()) { throw new midcom_error("Could not create wiki namespace '{$folder_title}', last Midgard error was: " . midcom_connection::get_error_string()); } // refresh $topic = new midcom_db_topic($topic->id); // See if we have article with same title in immediate parent $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('title', '=', $folder_title); $qb->add_constraint('topic', '=', $topic->up); $results = $qb->execute(); if (is_array($results) && count($results) == 1) { $article =& $results[0]; $article->name = 'index'; $article->topic = $topic->id; if (!$article->update()) { // Could not move article, do something ? } } else { $created_page = net_nemein_wiki_viewer::initialize_index_article($topic); if (!$created_page) { // Could not create index $topic->delete(); throw new midcom_error("Could not create index for new topic, errstr: " . midcom_connection::get_error_string()); } } // We have created a new topic, now recurse to create the rest of the path. return $this->_check_unique_wikiword($wikiword); break; case is_object($resolved['wikipage']): // Page exists throw new midcom_error('Wiki page with that name already exists.'); break; default: // No more namespaces left, create the page to latest parent if ($to_node[MIDCOM_NAV_ID] != $this->_topic->id) { // Last parent is not this topic, redirect there $wikiword_url = rawurlencode($resolved['remaining_path']); midcom::get()->relocate($to_node[MIDCOM_NAV_FULLURL] . "create/{$this->_schema}?wikiword={$wikiword_url}"); // This will exit() } break; } return true; }
function populate_toolbar(&$toolbar) { $enable_creation = false; if ($this->wiki[MIDCOM_NAV_OBJECT]->can_do('midgard:create') && $this->new_wikipage) { $enable_creation = true; // Check for duplicates $qb = net_nemein_wiki_wikipage::new_query_builder(); $qb->add_constraint('topic', '=', $this->wiki[MIDCOM_NAV_OBJECT]->id); $qb->add_constraint('title', '=', rawurldecode($this->new_wikipage)); $result = $qb->execute(); if (count($result) > 0) { $enable_creation = false; } } $toolbar->add_item(array(MIDCOM_TOOLBAR_URL => "{$this->wiki[MIDCOM_NAV_FULLURL]}create/{$this->new_wikipage}/{$this->target_node[MIDCOM_NAV_GUID]}/{$this->target->guid}/", MIDCOM_TOOLBAR_LABEL => $this->_l10n->get('create note'), MIDCOM_TOOLBAR_ICON => 'stock-icons/16x16/new-text.png', MIDCOM_TOOLBAR_ENABLED => $enable_creation, MIDCOM_TOOLBAR_OPTIONS => array('target' => 'wiki'))); }