Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 206 additions & 34 deletions CollectionTreePlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
*/
class CollectionTreePlugin extends Omeka_Plugin_AbstractPlugin
{
/**
* @var array Hooks for the plugin.
*/
protected $_hooks = array(
'install',
'uninstall',
Expand All @@ -23,17 +26,35 @@ class CollectionTreePlugin extends Omeka_Plugin_AbstractPlugin
'before_save_collection',
'after_save_collection',
'after_delete_collection',
'collection_browse_sql',
'collections_browse_sql',
'items_browse_sql',
'admin_items_search',
'public_items_search',
'admin_collections_show',
'public_collections_show',
);

/**
* @var array Filters for the plugin.
*/
protected $_filters = array(
'admin_navigation_main',
'public_navigation_main',
'admin_collections_form_tabs',
'items_browse_params',
'collections_select_options',
);


/**
* @var array Options and their default values.
*/
protected $_options = array(
'collection_tree_alpha_order' => 0,
'collection_tree_browse_only_root' => 0,
'collection_tree_show_subcollections' => 0,
'collection_tree_search_descendant' => 0,
);

/**
* Install the plugin.
*
Expand All @@ -54,9 +75,9 @@ public function hookInstall()
UNIQUE KEY `collection_id` (`collection_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
$this->_db->query($sql);
set_option('collection_tree_alpha_order', '0');

$this->_installOptions();

// Save all collections in the collection_trees table.
$collectionTable = $this->_db->getTable('Collection');
$collections = $this->_db->fetchAll("SELECT id FROM {$this->_db->Collection}");
Expand All @@ -77,8 +98,8 @@ public function hookUninstall()
{
$sql = "DROP TABLE IF EXISTS {$this->_db->CollectionTree}";
$this->_db->query($sql);
delete_option('collection_tree_alpha_order');

$this->_uninstallOptions();
}

/**
Expand Down Expand Up @@ -122,35 +143,42 @@ public function hookUpgrade($args)
}
}
}

/**
* Display the config form.
*/
public function hookConfigForm()
public function hookConfigForm($args)
{
echo get_view()->partial('plugins/collection-tree-config-form.php');
$view = get_view();
echo $view->partial('plugins/collection-tree-config-form.php');
}

/**
* Handle the config form.
*/
public function hookConfig()
public function hookConfig($args)
{
set_option('collection_tree_alpha_order', $_POST['collection_tree_alpha_order']);
$post = $args['post'];
foreach ($this->_options as $optionKey => $optionValue) {
if (isset($post[$optionKey])) {
set_option($optionKey, $post[$optionKey]);
}
}
}

public function hookBeforeSaveCollection($args)
{
$collectionTree = $this->_db->getTable('CollectionTree')->findByCollectionId($args['record']->id);
$collection = $args['record'];
$collectionTree = $this->_db->getTable('CollectionTree')->findByCollectionId($collection->id);
if (!$collectionTree) {
return;
}

// Only validate the relationship during a form submission.
if (isset($args['post']['collection_tree_parent_collection_id'])) {
$collectionTree->parent_collection_id = $args['post']['collection_tree_parent_collection_id'];
if (!$collectionTree->isValid()) {
$args['record']->addErrorsFrom($collectionTree);
$collection->addErrorsFrom($collectionTree);
}
}
}
Expand All @@ -160,11 +188,12 @@ public function hookBeforeSaveCollection($args)
*/
public function hookAfterSaveCollection($args)
{
$collectionTree = $this->_db->getTable('CollectionTree')->findByCollectionId($args['record']->id);

$collection = $args['record'];
$collectionTree = $this->_db->getTable('CollectionTree')->findByCollectionId($collection->id);

if (!$collectionTree) {
$collectionTree = new CollectionTree;
$collectionTree->collection_id = $args['record']->id;
$collectionTree->collection_id = $collection->id;
$collectionTree->parent_collection_id = 0;
}

Expand All @@ -189,51 +218,144 @@ public function hookAfterSaveCollection($args)
*/
public function hookAfterDeleteCollection($args)
{
$collection = $args['record'];
$collectionTreeTable = $this->_db->getTable('CollectionTree');

// Delete the relationship with the parent collection.
$collectionTree = $collectionTreeTable->findByCollectionId($args['record']->id);
$collectionTree = $collectionTreeTable->findByCollectionId($collection->id);
if ($collectionTree) {
$collectionTree->delete();
}

// Move child collections to root level by deleting their relationships.
$collectionTrees = $collectionTreeTable->findByParentCollectionId($args['record']->id);
$collectionTrees = $collectionTreeTable->findByParentCollectionId($collection->id);
foreach ($collectionTrees as $collectionTree) {
$collectionTree->parent_collection_id = 0;
$collectionTree->save();
}
}

/**
* Omit all child collections from the collection browse.
* Hook for collections browse: omit all child collections from the collection
* browse.
*/
public function hookCollectionBrowseSql($args)
public function hookCollectionsBrowseSql($args)
{
if (!is_admin_theme()) {
if (!get_option('collection_tree_browse_only_root')) {
return;
}
$select = $args['select'];
$sql = "
c.id NOT IN (
SELECT ct.collection_id
FROM {$this->_db->CollectionTree} ct
collections.id NOT IN (
SELECT collection_trees.collection_id
FROM {$this->_db->CollectionTree} collection_trees
WHERE collection_trees.parent_collection_id != 0
)";
$args['select']->where($sql);
$select->where($sql);
}
}


/**
* Hook for items browse: search in collection's children and selected one.
*
* @param Omeka_Db_Select $select
* @param array $params
*/
public function hookItemsBrowseSql($args)
{
if (is_admin_theme()) {
return;
}

$params = $args['params'];
if (empty($params['descendant_or_self'])) {
return;
}

$collection = $params['descendant_or_self'] instanceof Collection
// Collection can be an object when not called from search form.
? $params['descendant_or_self']->id
// Else this should be an integer.
: (integer) $params['descendant_or_self'];

if (empty($collection)) {
return;
}

$select = $args['select'];

$collections = $this->_db->getTable('CollectionTree')
->getDescendantOrSelfCollections($collection);
$collections = array_keys($collections);

$select->joinInner(
array('collection_tree_collections' => $this->_db->Collection),
'items.collection_id = collection_tree_collections.id',
array());

// There are descendants.
if (count($collections) > 1) {
$select->where('collection_tree_collections.id IN (?)', $collections);
}
// There is only the collection itself or no collection.
else {
$select->where('collection_tree_collections.id = ?', reset($collections));
}
}

/**
* Hook for admin advanced search.
*
* @return string HTML
*/
public function hookAdminItemsSearch($args)
{
echo $this->_itemsSearch($args);
}

/**
* Hook for public advanced search.
*
* @return string HTML
*/
public function hookPublicItemsSearch($args)
{
echo $this->_itemsSearch($args);
}

/**
* Append items search checkbox to the advanced search page.
*
* @return string HTML
*/
protected function _itemsSearch($args)
{
$view = $args['view'];
$html = '<div id="search-subcollections" class="field">';
$html .= $view->formLabel('subcollections', __('Broaden to the sub-collections'));
$html .= '<div class="inputs">';
$html .= $view->formCheckbox('subcollections', null,
array('checked' => (bool) get_option('collection_tree_search_descendant')));
$html .= '</div>';
$html .= '</div>';
return $html;
}

/**
* Display the collection's parent collection and child collections.
*/
public function hookAdminCollectionsShow($args)
{
$this->_appendToCollectionsShow($args['collection']);
}

/**
* Display the collection's parent collection and child collections.
*/
public function hookPublicCollectionsShow()
public function hookPublicCollectionsShow($args)
{
$this->_appendToCollectionsShow(get_current_record('collection'));
$this->_appendToCollectionsShow($args['collection']);
}

protected function _appendToCollectionsShow($collection)
Expand Down Expand Up @@ -268,12 +390,13 @@ public function filterPublicNavigationMain($nav)
*/
public function filterAdminCollectionsFormTabs($tabs, $args)
{
$collection = $args['collection'];
$collectionTreeTable = $this->_db->getTable('CollectionTree');

$options = $collectionTreeTable->findPairsForSelectForm();
$options = array('0' => __('No parent collection')) + $options;
$collectionTree = $collectionTreeTable->findByCollectionId($args['collection']->id);

$collectionTree = $collectionTreeTable->findByCollectionId($collection->id);
if ($collectionTree) {
$parentCollectionId = $collectionTree->parent_collection_id;
} else {
Expand All @@ -285,4 +408,53 @@ public function filterAdminCollectionsFormTabs($tabs, $args)
);
return $tabs;
}


/**
* Filter items browse params to broaden the search to subcollections.
*
* @param array $params
* @return array
*/
public function filterItemsBrowseParams($params)
{
// Check if this is a direct query (not from advanced search).
if (!is_admin_theme()
&& !isset($params['subcollections'])
&& get_option('collection_tree_show_subcollections')
) {
$params['subcollections'] = 1;
}

if (!empty($params['subcollections'])) {
$collection = 0;
if (!empty($params['collection_id'])) {
$collection = $params['collection_id'];
$params['collection_id'] = '';
}
if (!empty($params['collection'])) {
$collection = $params['collection'];
$params['collection'] = '';
}
if ($collection) {
$params['descendant_or_self'] = $collection;
}
}

return $params;
}


/**
* Manage search options for collections.
*
* @param array Search options for collections.
* @return array Filtered search options for collections.
*/
public function filterCollectionsSelectOptions($options)
{
$treeOptions = $this->_db->getTable('CollectionTree')->findPairsForSelectForm();
// Keep only chosen collections, in case another filter removed some.
return array_intersect_key($treeOptions, $options);
}
}
Loading