Documentation is available at indexer.php
- <?php
- /**
- * @package midcom.services
- * @author The Midgard Project, http://www.midgard-project.org
- * @version $Id: indexer.php,v 1.20.2.3 2005/07/06 13:36:52 torben Exp $
- * @copyright The Midgard Project, http://www.midgard-project.org
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
- */
- // First, load dependant classes:
- require('indexer/backend.php');
- require('indexer/filter.php');
- require('indexer/filter_date.php');
- require('indexer/document.php');
- // Load inherited classes
- // TODO: Find some more dynamic way for this.
- require('indexer/document_midcom.php');
- require('indexer/document_datamanager.php');
- require('indexer/document_attachment.php');
- /**
- * This class is the main access point into the MidCOM Indexer subsystem.
- *
- * It allows you to maintain and query the MidCOM document index.
- *
- * Do not instantinate this class directly. Instead use the get_service
- * method on midcom_application using the service name 'indexer' to obtain
- * a running instance. You <i>must</i> honor the reference of that call.
- *
- *
- *
- * @package midcom.services
- * @see midcom_services_indexer_document
- * @see midcom_services_indexer_backend
- * @see midcom_services_indexer_filter
- *
- * @todo Batch indexing support
- * @todo Write code examples
- * @todo More elaborate class introduction.
- */
- class midcom_services_indexer
- {
- /**
- * The backend indexer implementation
- *
- * @access private
- * @var midcom_services_indexer_backend
- */
- var $_backend = null;
- /**
- * Flag for disabled indexing, set by the constructor.
- *
- * @access private
- * @var bool
- */
- var $_disabled = false;
- /**
- * Initialization
- *
- * The constructor will initialize the indexer backend using the MidCOM
- * configuration by default. If you need a different indexer backend, you
- * can always explicitly instantinate a backend and pass it ot the
- * constructor. In that case you have to load the corresponding PHP file
- * manually.
- *
- * @param midcom_services_indexer_backend $backend An explicit indexer to initialize with.
- */
- function midcom_services_indexer($backend = null)
- {
- if ($GLOBALS['midcom_config']['indexer_backend'] == false)
- {
- $this->_disabled = true;
- return;
- }
- if (is_null($backend))
- {
- require_once("indexer/backend_{$GLOBALS['midcom_config']['indexer_backend']}.php");
- $class = "midcom_services_indexer_backend_{$GLOBALS['midcom_config']['indexer_backend']}";
- $this->_backend = new $class();
- }
- else
- {
- $this->_backend = $backend;
- }
- }
- /**
- * Adds a document to the index.
- *
- * A finished document object must be passed to this object. If the index
- * already contains a record with the same Resource Identifier, the record
- * is replaced.
- *
- * Support of batch-indexing using an Array of documents instead of a single
- * document is possible (and strongly advised for performance reasons).
- *
- *
- *
- * @param mixed $documents One or more documents to be indexed, so this is either a
- * midcom_services_indexer_document or an Array of these objects.
- * @return bool Indicating success.
- */
- function index ($documents)
- {
- if ($this->_disabled)
- {
- return true;
- }
- if (! is_array($documents))
- {
- $documents = Array($documents);
- }
- if (count($documents) == 0)
- {
- // Nothing to do.
- return true;
- }
- foreach ($documents as $key => $value)
- {
- // Process the document, if neccessary, create the corresponding object first.
- if (is_a($documents[$key], 'midcom_helper_datamanager'))
- {
- // Make a copy, as the document is created by-reference and this might make problems during the iterations.
- $datamanager = $value;
- $datamanager->reindex_autoindex_blobs();
- $documents[$key] = $this->new_document($datamanager);
- $datamanager->destroy();
- }
- if (! is_a($documents[$key], 'midcom_services_indexer_document'))
- {
- debug_push('midcom_services_indexer:index');
- debug_add("Encountered an unknown class while processing the document {$key}, aborting. See the debug messages for details.",
- MIDCOM_LOG_ERROR);
- debug_print_r("The document at type {$key} is invalid:", $document[$key]);
- debug_pop();
- $GLOBALS['midcom']->generate_error(MIDCOM_ERRCRIT, "Encountered an unknown class while processing the document {$key}");
- }
- $documents[$key]->members_to_fields();
- }
- return $this->_backend->index($documents);
- }
- /**
- * Removes the document with the given resource identifier from the index.
- *
- * @param string $RI The resource identifier of the document that should be deleted.
- * @return bool Indicating success.
- */
- function delete ($RI)
- {
- if ($this->_disabled)
- {
- return true;
- }
- return $this->_backend->delete($RI);
- }
- /**
- * Clear the index completly.
- *
- * This will drop the current index.
- *
- * @return bool Indicating success.
- */
- function delete_all()
- {
- if ($this->_disabled)
- {
- return true;
- }
- return $this->_backend->delete_all();
- }
- /**
- * 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 dependant on the backend. Refer to its documentation
- * how queries should be built.
- *
- * Each result node is looked up in NAP/Metadata to verify its visibility.
- *
- * @param string $query The query, which must suite 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 arary of documents matching the query, or false on a failure.
- */
- function query ($query, $filter = null)
- {
- if ($this->_disabled)
- {
- return false;
- }
- global $midcom_config;
- // Do charset translations
- $i18n =& $GLOBALS['midcom']->get_service('i18n');
- $query = $i18n->convert_to_utf8($query);
- $nav = new midcom_helper_nav();
- $result_raw = $this->_backend->query ($query, $filter);
- 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();
- // Permission checks
- debug_add("Doing Permission and Visibility Checks for {$document->title}");
- // Topic visibility
- $node = null;
- $topic = null;
- if ($document->topic_guid != '')
- {
- // Try to get a NAP object to verify visibility and access permissions.
- $node = $nav->resolve_guid($document->topic_guid);
- if ($node === false)
- {
- // Skip document, this topic is hidden.
- debug_add("Skipping the document {$document->title}, its topic {$document->topic_guid} seems to be invisible");
- continue;
- }
- $topic = $node[MIDCOM_NAV_OBJECT];
- }
- // For all midcom doucments, check the metadata visibility state given by the source object.
- if ($document->is_a('midcom'))
- {
- $metadata =& midcom_helper_metadata::retrieve($document->source);
- if (is_object($metadata))
- {
- if ( (! $midcom_config['show_hidden_objects'] && ! $metadata->is_visible())
- || (! $midcom_config['show_unapproved_objects'] && ! $metadata->is_approved()))
- {
- debug_add("Skipping the document {$document->title}, the metadata of the source document {$document->source} indicate no visibility.");
- debug_add("show_hidden_objects: {$midcom_config['show_hidden_objects']}; got: " . $metadata->is_visible());
- debug_add("show_unapproved_objects: {$midcom_config['show_unapproved_objects']}; got: " . $metadata->is_approved());
- continue;
- }
- }
- else
- {
- debug_add("Failed tor retrieve Metadata for {$document->title} using {$document->source}, doing no checks for this object.");
- }
- // Drop the reference again.
- unset($metadata);
- }
- // Check for additional security checks by the component or a custom callback
- $component_loader =& $GLOBALS['midcom']->get_component_loader();
- $security = explode(':', $document->security, 2);
- switch ($security[0])
- {
- case 'component':
- // Component security, get the interface base class, if it exists, and
- // execute the corresponding handler.
- debug_add('Doing additional component-level security check');
- $interface =& $component_loader->get_interface_class($document->component);
- if ( ! is_null($interface)
- && ! is_null($node)
- && ! $interface->check_document_permissions($document, $topic))
- {
- debug_add('Skipping the document, the callee returned false.');
- continue;
- }
- break;
- case 'function':
- // Execute a custom callback to ascertain visbility.
- debug_add("We are in function security mode, executing the callback {$security[1]}.");
- if (! $security[1]($document, $topic))
- {
- debug_add('Skipping the document, the callee returned false.');
- continue;
- }
- break;
- case 'class':
- // Execute a custom callback to ascertain visbility.
- debug_add("We are in function security mode, executing the callback {$security[1]}.");
- $instance =& $class->get_instance();
- if (! $instance->check_document_permissions($document, $topic))
- {
- debug_add('Skipping the document, the callee returned false.');
- continue;
- }
- break;
- }
- $result[] = $document;
- }
- return $result;
- }
- function _check_permissions_topic($document)
- {
- }
- /**
- * This function tries to instantinate the most specific document class
- * for the object given in the parameter.
- *
- * This class will not return empty document base class instances if nothing
- * specific can be found. If you are in this situation, you need to instantinate
- * an appropriate document manually and populate it.
- *
- * The checking sequence is like this right now:
- *
- * 1. If a datamanager instance is passed, it is transformed into a midcom_services_indexer_document_datamanager.
- * 2. If a Metadata object is passed, it is transformed into a midcom_services_indexer_document_midcom.
- * 3. Finally, the method tries to retrieve a MidCOM Metadata object using the parameter directly. If successful,
- * again a midcom_services_indexer_document_midcom is returned.
- *
- * This factory method will work even if the indexer is disabled. You therefore
- * need to protect your code by checking against the configuration option
- * indexer_backend !== false.
- *
- * @param object $object The object for which a document instance is required, passed by reference.
- * @return midcom_services_indexer_document A valid document class as specific as possible. Returns
- * false on error or if no specific class match could be found.
- */
- function new_document(&$object)
- {
- debug_push('midcom_services_indexer::new_document');
- debug_print_type('Searching an instance for this object type:', $object);
- // Scan for datamanager instances.
- if (is_a($object, 'midcom_helper_datamanager'))
- {
- debug_add('This is a document_datamanager');
- debug_pop();
- return new midcom_services_indexer_document_datamanager($object);
- }
- // Maybe we have a metadata object...
- if (is_a($object, 'midcom_helper_metadata'))
- {
- debug_add('This is a metadata document, built from a metadata object.');
- debug_pop();
- return new midcom_services_indexer_document_midcom($object);
- }
- // Try to get a metadata object for the argument passed
- $metadata =& midcom_helper_metadata::retrieve($object);
- if ($metadata !== false)
- {
- debug_add('Successfully fetched a Metadata object for the argument.');
- debug_pop();
- return new midcom_services_indexer_document_midcom($metadata);
- }
- // No specific match found.
- debug_add('No match found for this type.');
- debug_pop();
- return false;
- }
- }
- ?>
Documentation generated on Mon, 21 Nov 2005 18:16:24 +0100 by phpDocumentor 1.3.0RC3