public function _on_updated() { // Invalidate topic in cache to refresh all views // TODO: Do this only on status changes $topic = midcom_db_topic::get_cached($this->topic); if ($topic->guid) { $_MIDCOM->cache->invalidate($topic->guid); } if (isset($GLOBALS['disable_activitystream'])) { return true; } if ($_MIDCOM->auth->request_sudo('midcom')) { $actor = midcom_db_person::get_cached($_MIDGARD['user']); $activity = new midcom_helper_activitystream_activity_dba(); $activity->target = $this->guid; $activity->application = 'fi.kilonkipinat.account'; $activity->actor = $actor->id; $activity->verb = 'http://activitystrea.ms/schema/1.0/post'; if ($this->id == $actor->id) { $activity->summary = sprintf('%s muokkasi omaa tunnustaan', $actor->name); } else { $tmp_name = $this->firstname . ' ' . $this->lastname; $activity->summary = sprintf('%s muokkasi %s:n tunnusta', $actor->name, $tmp_name); } $activity->create(); $_MIDCOM->auth->drop_sudo(); } 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_view($handler_id, array $args, array &$data) { midcom::get('auth')->require_valid_user(); $qb = org_openpsa_documents_document_dba::new_query_builder(); //check if there is another output-mode wanted if (isset($args[0])) { $this->_output_mode = $args[0]; } if (isset($args[1])) { $current_topic = midcom_db_topic::get_cached($args[1]); } else { $current_topic = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_CONTENTTOPIC); } switch ($this->_output_mode) { case 'xml': $current_component = $current_topic->component; $parent_link = ""; $prefix = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX); //check if id of a topic is passed if (isset($_POST['nodeid'])) { $root_topic = new midcom_db_topic((int) $_POST['nodeid']); while ($root_topic->get_parent()->component == $current_component && $root_topic->id != $current_topic->id) { $parent_link = $root_topic->name . "/" . $parent_link; $root_topic = $root_topic->get_parent(); } $root_topic = new midcom_db_topic((int) $_POST['nodeid']); $this->_request_data['parent_link'] = $parent_link; } else { $root_topic = $current_topic; $current_topic = $current_topic->get_parent(); if ($current_topic->get_parent()) { $this->_request_data['parent_directory'] = $current_topic; $parent_link = substr($prefix, 0, strlen($prefix) - (strlen($root_topic->name) + 1)); } $this->_request_data['parent_up_link'] = $parent_link; } //show only documents of the right topic $qb->add_constraint('topic', '=', $root_topic->id); //get needed directories $this->_prepare_directories($root_topic, $current_component); //set header & style for xml midcom::get()->header("Content-type: text/xml; charset=UTF-8"); midcom::get()->skip_page_style = true; break; //html //html default: $qb->add_constraint('orgOpenpsaObtype', '=', ORG_OPENPSA_OBTYPE_DOCUMENT); $qb->add_constraint('topic', '=', $this->_request_data['directory']->id); $this->_prepare_output(); break; } $this->_request_data['current_guid'] = $current_topic->guid; $qb->add_constraint('nextVersion', '=', 0); $qb->add_order('title'); $this->_documents = $qb->execute(); }
/** * Set the content topic to use. This will check against the configuration setting 'symlink_topic'. */ private function _determine_content_topic() { $guid = $this->_config->get('symlink_topic'); if (is_null($guid)) { // No symlink topic // Workaround, we should talk to a DBA object automatically here in fact. $this->_content_topic = midcom_db_topic::get_cached($this->_topic->id); return; } $this->_content_topic = midcom_db_topic::get_cached($guid); // Validate topic. if ($this->_content_topic->component != 'net.nehmer.static') { debug_print_r('Retrieved topic was:', $this->_content_topic); throw new midcom_error('Symlink content topic is invalid, see the debug level log for details.'); } }
public function _on_updated() { // Invalidate topic in cache to refresh all views // TODO: Do this only on status changes $topic = midcom_db_topic::get_cached($this->topic); if ($topic->guid) { $_MIDCOM->cache->invalidate($topic->guid); } if (isset($GLOBALS['disable_activitystream'])) { return true; } if ($_MIDCOM->auth->request_sudo('midcom')) { // This is here because creating an object calls create and update..... and we don't want duplicate entry's $qb = midcom_helper_activitystream_activity_dba::new_query_builder(); $qb->set_limit(1); $qb->add_constraint('application', '=', 'fi.kilonkipinat.account'); $qb->add_constraint('target', '=', $this->guid); $groups = $qb->execute(); if ($groups && is_array($groups) && count($groups) > 0) { $new_object = false; } else { $new_object = true; } $actor = midcom_db_person::get_cached($_MIDGARD['user']); $activity = new midcom_helper_activitystream_activity_dba(); $activity->target = $this->guid; $activity->application = 'fi.kilonkipinat.account'; $activity->actor = $actor->id; $activity->verb = 'http://activitystrea.ms/schema/1.0/post'; if ($new_object) { $activity->summary = sprintf('%s loi pestiryhmän %s', $actor->name, $this->title); } else { $activity->summary = sprintf('%s muokkasi pestiryhmää %s', $actor->name, $this->title); } $activity->create(); $_MIDCOM->auth->drop_sudo(); } return true; }
public static function get_component_node($component) { $siteconfig = org_openpsa_core_siteconfig::get_instance(); midcom::get('auth')->request_sudo($component); if ($topic_guid = $siteconfig->get_node_guid($component)) { $topic = new midcom_db_topic($topic_guid); } else { $qb = midcom_db_topic::new_query_builder(); $qb->add_constraint('component', '=', $component); $qb->set_limit(1); $qb->add_order('id'); $result = $qb->execute(); if (sizeof($result) == 1) { midcom::get('auth')->drop_sudo(); return $result[0]; } $root_topic = midcom_db_topic::get_cached($GLOBALS['midcom_config']['root_topic']); $topic_attributes = array('up' => $root_topic->id, 'component' => $component, 'name' => 'handler_test_' . time()); $topic = self::create_class_object('midcom_db_topic', $topic_attributes); } midcom::get('auth')->drop_sudo(); return $topic; }
/** * Main MidCOM initialization. * * Initialize the Application class. Sets all private variables to a predefined * state. $node should be set to the midcom root-node GUID. * $prefix can be a prefix, which is appended to midcom_connection::get_url('self') (i.e. the * Midgard Page URL). This may be needed when MidCOM is run by wrapper. */ public function initialize() { $this->_status = MIDCOM_STATUS_PREPARE; // Start-up some of the services midcom::get('dbclassloader')->load_classes('midcom', 'legacy_classes.inc', null, true); midcom::get('dbclassloader')->load_classes('midcom', 'core_classes.inc', null, true); midcom::get('componentloader')->load_all_manifests(); // Initialize Context Storage $context = new midcom_core_context(0); $context->set_current(); // Initialize Root Topic try { $root_node = midcom_db_topic::get_cached($GLOBALS['midcom_config']['midcom_root_topic_guid']); } catch (midcom_error $e) { if ($e instanceof midcom_error_forbidden) { throw new midcom_error_forbidden(midcom::get('i18n')->get_string('access denied', 'midcom')); } else { // Fall back to another topic so that admin has a chance to fix this midcom::get('auth')->require_admin_user("Root folder is misconfigured. Please log in as administrator and fix this in settings."); $qb = midcom_db_topic::new_query_builder(); $qb->add_constraint('up', '=', 0); $qb->add_constraint('component', '<>', ''); $topics = $qb->execute(); if (count($topics) == 0) { throw new midcom_error("Fatal error: Unable to load website root folder with GUID '{$GLOBALS['midcom_config']['midcom_root_topic_guid']}'.<br />" . 'Last Midgard Error was: ' . midcom_connection::get_error_string()); } $root_node = $topics[0]; } } $context->set_key(MIDCOM_CONTEXT_ROOTTOPIC, $root_node); $context->set_key(MIDCOM_CONTEXT_ROOTTOPICID, $root_node->id); // Check the midcom_config site prefix for absolute local urls if ($GLOBALS['midcom_config']['midcom_site_url'][0] == '/') { $GLOBALS['midcom_config']['midcom_site_url'] = $this->get_page_prefix() . substr($GLOBALS['midcom_config']['midcom_site_url'], 1); } }
private function _get_available_generators() { if (is_array($this->_available_generators)) { return $this->_available_generators; } $this->_available_generators = array(); $components = array('org.openpsa.projects' => midcom::get('i18n')->get_string('org.openpsa.projects', 'org.openpsa.projects'), 'org.openpsa.sales' => midcom::get('i18n')->get_string('org.openpsa.sales', 'org.openpsa.sales'), 'org.openpsa.invoices' => midcom::get('i18n')->get_string('org.openpsa.invoices', 'org.openpsa.invoices')); $siteconfig = org_openpsa_core_siteconfig::get_instance(); foreach ($components as $component => $loc) { $node_guid = $siteconfig->get_node_guid($component); try { $topic = midcom_db_topic::get_cached($node_guid); $this->_available_generators[$component] = $loc; } catch (midcom_error $e) { debug_add("topic for component '{$component}' not found or accessible"); } } $this->_available_generators = $components; return $this->_available_generators; }
<?php $document = $data['document']; $score = round($document->score * 100); try { $topic = midcom_db_topic::get_cached($document->topic_guid); } catch (midcom_error $e) { $e->log(); } ?> <div class="midcom_helper_search_result"> <h3><a href='&(document.document_url);'>&(document.title);</a></h3> <div class="midcom_helper_search_result_abstract"> &(document.abstract:h); </div> <div class="midcom_helper_search_result_metadata"> <?php if (isset($topic)) { ?> <span class="midcom_helper_search_result_topic"><?php echo $data['l10n_midcom']->get('topic'); ?> : &(topic.extra);</span>, <?php } ?> <span class="midcom_helper_search_result_score"><?php echo $data['l10n']->get('score'); ?> : &(score); %</span> </div>
/** * This function tries to resolve a guid into a NAP object. * * The code is optimized trying to avoid a full-scan if possible. To do this it * will treat topic and article guids specially: In both cases the system will * translate it using the topic id into a node id and scan only that part of the * tree non-recursively. * * A full scan of the NAP data is only done if another MidgardObject is used. * * Note: If you want to resolve a GUID you got from a Permalink, use the Permalinks * service within MidCOM, as it covers more objects then the NAP listings. * * @param string $guid The GUID of the object to be looked up. * @param boolean $node_is_sufficient if we could return a good guess of correct parent node but said node does not list the $guid in leaves return the node or try to do a full (and very expensive) NAP scan ? * @return mixed Either a node or leaf structure, distinguishable by MIDCOM_NAV_TYPE, or false on failure. * @see midcom_services_permalinks */ function resolve_guid($guid, $node_is_sufficient = false) { // First, check if the GUID is already known by the backend: $cached_result = $this->_backend->get_loaded_object_by_guid($guid); if (!is_null($cached_result)) { debug_add('The GUID was already known by the backend instance, returning the cached copy directly.', MIDCOM_LOG_INFO); return $cached_result; } // Fetch the object in question for a start, so that we know what to do (tm) // Note, that objects that cannot be resolved will still be processed using a full-scan of // the tree. This is, for example, used by the on-delete cache invalidation. try { $object = midcom::get('dbfactory')->get_object_by_guid($guid); if (is_a($object, 'midcom_db_topic')) { // Ok. This topic should be within the content tree, // we check this and return the node if everything is ok. if (!$this->is_node_in_tree($object->id, $this->get_root_node())) { debug_add("The GUID {$guid} leads to an unknown topic not in our tree.", MIDCOM_LOG_WARN); return false; } return $this->get_node($object->id); } if (is_a($object, 'midcom_db_article')) { // Ok, let's try to find the article using the topic in the tree. if (!$this->is_node_in_tree($object->topic, $this->get_root_node())) { debug_add("The GUID {$guid} leads to an unknown topic not in our tree.", MIDCOM_LOG_WARN); return false; } $topic = midcom_db_topic::get_cached($object->topic); $leaves = $this->list_leaves($object->topic, true); foreach ($leaves as $leafid) { $leaf = $this->get_leaf($leafid); if ($leaf[MIDCOM_NAV_GUID] == $guid) { return $leaf; } } debug_add("The Article GUID {$guid} is somehow hidden from the NAP data in its topic, no results shown.", MIDCOM_LOG_INFO); return false; } } catch (midcom_error $e) { debug_add("Could not load GUID {$guid}, trying to continue anyway. Last error was: " . $e->getMessage(), MIDCOM_LOG_WARN); } // Ok, unfortunately, this is not an immediate topic. We try to traverse // upwards in the object chain to find a topic. $topic = $this->_find_closest_topic($object); if ($topic !== null) { debug_add("Found topic #{$topic->id}, searching the leaves"); $leaves = $this->list_leaves($topic->id, true); foreach ($leaves as $leafid) { $leaf = $this->get_leaf($leafid); if ($leaf[MIDCOM_NAV_GUID] == $guid) { return $leaf; } } if ($node_is_sufficient) { debug_add("Could not find guid in leaves (maybe not listed?), but node is sufficient, returning node"); return $this->get_node($topic->id); } } // this is the rest of the lot, we need to traverse everything, unfortunately. // First, we traverse a list of nodes to be checked on by one, avoiding a recursive // function call. $unprocessed_node_ids = array($this->get_root_node()); while (count($unprocessed_node_ids) > 0) { $node_id = array_shift($unprocessed_node_ids); // Check leaves of this node first. $leaves = $this->list_leaves($node_id, true); foreach ($leaves as $leafid) { $leaf = $this->get_leaf($leafid); if ($leaf[MIDCOM_NAV_GUID] == $guid) { return $leaf; } } // Ok, append all subnodes to the queue. $unprocessed_node_ids = array_merge($unprocessed_node_ids, $this->list_nodes($node_id)); } debug_add("We were unable to find the GUID {$guid} in the MidCOM tree even with a full scan.", MIDCOM_LOG_INFO); return false; }
/** * Query the index and, if set, restrict the query by a given filter. * * The filter argument is optional and may be a subclass of indexer_filter. * The backend determines what filters are supported and how they are * treated. * * The query syntax is also dependent on the backend. Refer to its documentation * how queries should be built. * * @param string $query The query, which must suit the backends query syntax. It is assumed to be in the site charset. * @param midcom_services_indexer_filter $filter An optional filter used to restrict the query. * @return Array An array of documents matching the query, or false on a failure. * @todo Refactor into multiple methods */ function query($query, midcom_services_indexer_filter $filter = null) { if ($this->_disabled) { return false; } // Do charset translations $i18n = midcom::get('i18n'); $query = $i18n->convert_to_utf8($query); try { $result_raw = $this->_backend->query($query, $filter); } catch (Exception $e) { debug_add("Query error: " . $e->getMessage(), MIDCOM_LOG_ERROR); return false; } if ($result_raw === false) { debug_add("Failed to execute the query, aborting.", MIDCOM_LOG_INFO); return false; } $result = array(); foreach ($result_raw as $document) { $document->fields_to_members(); /** * FIXME: Rethink program flow and especially take into account that not all documents are * created by midcom or even served by midgard */ // midgard:read verification, we simply try to create an object instance // In the case, we distinguish between MidCOM documents, where we can check // the RI identified object directly, and pure documents, where we use the // topic instead. // Try to check topic only if the guid is actually set if (!empty($document->topic_guid)) { try { $topic = midcom_db_topic::get_cached($document->topic_guid); } catch (midcom_error $e) { // Skip document, the object is hidden. debug_add("Skipping the generic document {$document->title}, its topic seems to be invisible, we cannot proceed."); continue; } } // this checks acls! if ($document->is_a('midcom')) { // Try to retrieve object: // Strip language code from end of RI if it looks like "<GUID>_<LANG>" try { $object = midcom::get('dbfactory')->get_object_by_guid(preg_replace('/^([0-9a-f]{32,80})_[a-z]{2}$/', '\\1', $document->RI)); } catch (midcom_error $e) { // Skip document, the object is hidden, deleted or otherwise unavailable. //@todo Maybe nonexistant objects should be removed from index? continue; } } $result[] = $document; } return $result; }
/** * Return next object in URL path */ public function get_object() { if ($this->argc == 0) { // No arguments left return false; } if (empty($this->url)) { $object_url = "{$this->argv[0]}/"; } else { $object_url = "{$this->url}/{$this->argv[0]}/"; } if (array_key_exists($object_url, $this->objects)) { // Remove this component from path $this->argc -= 1; array_shift($this->argv); // Set as current object $this->url = $object_url; $this->current_object = $this->objects[$object_url]; return $this->objects[$object_url]; } $qb = midcom_db_topic::new_query_builder(); $qb->add_constraint('name', '=', $this->argv[0]); $qb->add_constraint('up', '=', $this->current_object->id); if ($qb->count() == 0) { //last load returned ACCESS DENIED, no sense to dig deeper if ($qb->denied > 0) { midcom_connection::set_error(MGD_ERR_ACCESS_DENIED); return false; } // No topics matching path, check for attachments $att_qb = midcom_db_attachment::new_query_builder(); $att_qb->add_constraint('name', '=', $this->argv[0]); $att_qb->add_constraint('parentguid', '=', $this->current_object->guid); if ($att_qb->count() == 0) { // allow for handler switches to work return false; } $atts = $att_qb->execute(); // Remove this component from path $this->argc -= 1; array_shift($this->argv); // Set as current object $this->url = $object_url; $this->current_object = $atts[0]; $this->objects[$object_url] = $this->current_object; return $this->objects[$object_url]; } $topics = $qb->execute(); // Set to current topic $this->current_object = $topics[0]; $this->objects[$object_url] = $this->current_object; if ($GLOBALS['midcom_config']['symlinks'] && !empty($this->current_object->symlink)) { try { $topic = midcom_db_topic::get_cached($this->current_object->symlink); $this->current_object = $topic; } catch (midcom_error $e) { debug_add("Could not get target for symlinked topic #{$this->current_object->id}: " . $e->getMessage(), MIDCOM_LOG_ERROR); } } // TODO: Remove $this->check_style_inheritance($this->current_object); // Remove this component from path $this->argc -= 1; array_shift($this->argv); $this->url .= $this->objects[$object_url]->name . '/'; return $this->objects[$object_url]; }
/** * Set the content topic to use. This will check against the configuration setting 'symlink_topic'. * We don't do sanity checking here for performance reasons, it is done when accessing the topic, * that should be enough. */ private function _determine_content_topic() { $guid = $this->_config->get('symlink_topic'); if (is_null($guid)) { // No symlink topic // Workaround, we should talk to a DBA object automatically here in fact. $this->_content_topic = midcom_db_topic::get_cached($this->_topic->id); return; } $this->_content_topic = midcom_db_topic::get_cached($guid); }