13ad9c1eaSAndreas Gohr<?php 23ad9c1eaSAndreas Gohr/** 33ad9c1eaSAndreas Gohr * DokuWiki Plugin struct (Action Component) 43ad9c1eaSAndreas Gohr * 53ad9c1eaSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 63ad9c1eaSAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 73ad9c1eaSAndreas Gohr */ 83ad9c1eaSAndreas Gohr 93ad9c1eaSAndreas Gohr// must be run within Dokuwiki 103ad9c1eaSAndreas Gohrif(!defined('DOKU_INC')) die(); 113ad9c1eaSAndreas Gohr 12f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable; 139fc5ecc2SMichael Grosseuse dokuwiki\plugin\struct\meta\Assignments; 14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema; 15345c3838SSzymon Olewniczakuse dokuwiki\plugin\struct\meta\Search; 163ad9c1eaSAndreas Gohr 173ad9c1eaSAndreas Gohr/** 18cfe2b908SAndreas Gohr * Handles bureaucracy additions 193ad9c1eaSAndreas Gohr * 203ad9c1eaSAndreas Gohr * This registers to the template action of the bureaucracy plugin and saves all struct data 21cfe2b908SAndreas Gohr * submitted through the bureaucracy form to all newly created pages (if the schema applies). 22cfe2b908SAndreas Gohr * 23cfe2b908SAndreas Gohr * It also registers the struct_schema type for bureaucracy which will add all fields of the 24cfe2b908SAndreas Gohr * schema to the form. The struct_field type is added through standard naming convention - see 25cfe2b908SAndreas Gohr * helper/fiels.php for that. 263ad9c1eaSAndreas Gohr */ 273ad9c1eaSAndreas Gohrclass action_plugin_struct_bureaucracy extends DokuWiki_Action_Plugin { 283ad9c1eaSAndreas Gohr 293ad9c1eaSAndreas Gohr /** 303ad9c1eaSAndreas Gohr * Registers a callback function for a given event 313ad9c1eaSAndreas Gohr * 323ad9c1eaSAndreas Gohr * @param Doku_Event_Handler $controller DokuWiki's event controller object 333ad9c1eaSAndreas Gohr * @return void 343ad9c1eaSAndreas Gohr */ 353ad9c1eaSAndreas Gohr public function register(Doku_Event_Handler $controller) { 36345c3838SSzymon Olewniczak $controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'BEFORE', $this, 'handle_lookup_fields'); 373ad9c1eaSAndreas Gohr $controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'AFTER', $this, 'handle_save'); 38cfe2b908SAndreas Gohr $controller->register_hook('PLUGIN_BUREAUCRACY_FIELD_UNKNOWN', 'BEFORE', $this, 'handle_schema'); 39cfe2b908SAndreas Gohr } 40cfe2b908SAndreas Gohr 41cfe2b908SAndreas Gohr /** 42cfe2b908SAndreas Gohr * Load a whole schema as fields 43cfe2b908SAndreas Gohr * 44cfe2b908SAndreas Gohr * @param Doku_Event $event event object by reference 45cfe2b908SAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 46cfe2b908SAndreas Gohr * handler was registered] 47cfe2b908SAndreas Gohr * @return bool 48cfe2b908SAndreas Gohr */ 49cfe2b908SAndreas Gohr public function handle_schema(Doku_Event $event, $param) { 50cfe2b908SAndreas Gohr $args = $event->data['args']; 5193ca6f4fSAndreas Gohr if($args[0] != 'struct_schema') return false; 52cfe2b908SAndreas Gohr $event->preventDefault(); 53cfe2b908SAndreas Gohr $event->stopPropagation(); 54cfe2b908SAndreas Gohr 55cfe2b908SAndreas Gohr /** @var helper_plugin_bureaucracy_field $helper */ 56cfe2b908SAndreas Gohr $helper = plugin_load('helper', 'bureaucracy_field'); 57cfe2b908SAndreas Gohr $helper->initialize($args); 58cfe2b908SAndreas Gohr 59cfe2b908SAndreas Gohr $schema = new Schema($helper->opt['label']); 60cfe2b908SAndreas Gohr if(!$schema->getId()) { 61cfe2b908SAndreas Gohr msg('This schema does not exist', -1); 6293ca6f4fSAndreas Gohr return false; 63cfe2b908SAndreas Gohr } 64cfe2b908SAndreas Gohr 65cfe2b908SAndreas Gohr foreach($schema->getColumns(false) as $column) { 66cfe2b908SAndreas Gohr /** @var helper_plugin_struct_field $field */ 67cfe2b908SAndreas Gohr $field = plugin_load('helper', 'struct_field'); 68cfe2b908SAndreas Gohr // we don't initialize the field but set the appropriate values 69cfe2b908SAndreas Gohr $field->opt = $helper->opt; // copy all the settings to each field 70cfe2b908SAndreas Gohr $field->opt['label'] = $column->getFullQualifiedLabel(); 71cfe2b908SAndreas Gohr $field->column = $column; 72cfe2b908SAndreas Gohr $event->data['fields'][] = $field; 73cfe2b908SAndreas Gohr } 7493ca6f4fSAndreas Gohr return true; 753ad9c1eaSAndreas Gohr } 763ad9c1eaSAndreas Gohr 773ad9c1eaSAndreas Gohr /** 78345c3838SSzymon Olewniczak * Replace lookup fields placeholder's values 79345c3838SSzymon Olewniczak * 80345c3838SSzymon Olewniczak * @param Doku_Event $event event object by reference 81345c3838SSzymon Olewniczak * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 82345c3838SSzymon Olewniczak * handler was registered] 83345c3838SSzymon Olewniczak * @return bool 84345c3838SSzymon Olewniczak */ 85345c3838SSzymon Olewniczak public function handle_lookup_fields(Doku_Event $event, $param) { 86345c3838SSzymon Olewniczak foreach($event->data['fields'] as $field) { 87345c3838SSzymon Olewniczak if(!is_a($field, 'helper_plugin_struct_field')) continue; 88345c3838SSzymon Olewniczak if($field->column->getType()->getClass() != 'Lookup') continue; 89345c3838SSzymon Olewniczak 90*987ccc7fSSzymon Olewniczak $value = $field->getParam('value'); 91*987ccc7fSSzymon Olewniczak if (!is_array($value)) $value = array($value); 92*987ccc7fSSzymon Olewniczak 93345c3838SSzymon Olewniczak $config = $field->column->getType()->getConfig(); 94345c3838SSzymon Olewniczak 95345c3838SSzymon Olewniczak // find proper value 96345c3838SSzymon Olewniczak // current Search implementation doesn't allow doing it using SQL 97345c3838SSzymon Olewniczak $search = new Search(); 98345c3838SSzymon Olewniczak $search->addSchema($config['schema']); 99345c3838SSzymon Olewniczak $search->addColumn($config['field']); 100345c3838SSzymon Olewniczak $result = $search->execute(); 101345c3838SSzymon Olewniczak $pids = $search->getPids(); 102345c3838SSzymon Olewniczak 103*987ccc7fSSzymon Olewniczak $field->opt['struct_pids'] = array(); 104*987ccc7fSSzymon Olewniczak $new_value = array(); 105*987ccc7fSSzymon Olewniczak foreach ($value as $pid) { 106*987ccc7fSSzymon Olewniczak for($i = 0; $i < count($result); $i++) { 107345c3838SSzymon Olewniczak if ($pids[$i] == $pid) { 108*987ccc7fSSzymon Olewniczak $field->opt['struct_pids'][] = $pid; 109*987ccc7fSSzymon Olewniczak $new_value[] = $result[$i][0]->getDisplayValue(); 110*987ccc7fSSzymon Olewniczak } 111345c3838SSzymon Olewniczak } 112345c3838SSzymon Olewniczak } 113345c3838SSzymon Olewniczak 114345c3838SSzymon Olewniczak //replace previous value 115*987ccc7fSSzymon Olewniczak if ($field->column->isMulti()) { 116*987ccc7fSSzymon Olewniczak $field->opt['value'] = $new_value; 117*987ccc7fSSzymon Olewniczak } else { 118*987ccc7fSSzymon Olewniczak $event->data['values'][$field->column->getFullQualifiedLabel()] = $new_value[0]; 119345c3838SSzymon Olewniczak } 120*987ccc7fSSzymon Olewniczak 121345c3838SSzymon Olewniczak } 122345c3838SSzymon Olewniczak return true; 123345c3838SSzymon Olewniczak } 124345c3838SSzymon Olewniczak 125345c3838SSzymon Olewniczak /** 1263ad9c1eaSAndreas Gohr * Save the struct data 1273ad9c1eaSAndreas Gohr * 1283ad9c1eaSAndreas Gohr * @param Doku_Event $event event object by reference 1293ad9c1eaSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 1303ad9c1eaSAndreas Gohr * handler was registered] 1313ad9c1eaSAndreas Gohr * @return bool 1323ad9c1eaSAndreas Gohr */ 1333ad9c1eaSAndreas Gohr public function handle_save(Doku_Event $event, $param) { 1343ad9c1eaSAndreas Gohr // get all struct values and their associated schemas 1353ad9c1eaSAndreas Gohr $tosave = array(); 1363ad9c1eaSAndreas Gohr foreach($event->data['fields'] as $field) { 1373ad9c1eaSAndreas Gohr if(!is_a($field, 'helper_plugin_struct_field')) continue; 1383ad9c1eaSAndreas Gohr /** @var helper_plugin_struct_field $field */ 1393ad9c1eaSAndreas Gohr $tbl = $field->column->getTable(); 1403ad9c1eaSAndreas Gohr $lbl = $field->column->getLabel(); 1413ad9c1eaSAndreas Gohr if(!isset($tosave[$tbl])) $tosave[$tbl] = array(); 142*987ccc7fSSzymon Olewniczak 143*987ccc7fSSzymon Olewniczak if ($field->column->isMulti() && $field->column->getType()->getClass() == 'Lookup') { 144*987ccc7fSSzymon Olewniczak $tosave[$tbl][$lbl] = $field->opt['struct_pids']; 145*987ccc7fSSzymon Olewniczak } else { 1463ad9c1eaSAndreas Gohr $tosave[$tbl][$lbl] = $field->getParam('value'); 1473ad9c1eaSAndreas Gohr } 148*987ccc7fSSzymon Olewniczak } 1493ad9c1eaSAndreas Gohr 1503ad9c1eaSAndreas Gohr // save all the struct data of assigned schemas 1513ad9c1eaSAndreas Gohr $id = $event->data['id']; 1523ad9c1eaSAndreas Gohr $time = filemtime(wikiFN($id)); 1539fc5ecc2SMichael Grosse 154025cb9daSAndreas Gohr $assignments = Assignments::getInstance(); 15593ca6f4fSAndreas Gohr $assigned = $assignments->getPageAssignments($id); 15693ca6f4fSAndreas Gohr foreach($tosave as $table => $data) { 15793ca6f4fSAndreas Gohr if(!in_array($table, $assigned)) continue; 15893ca6f4fSAndreas Gohr $access = AccessTable::byTableName($table, $id, $time); 15993ca6f4fSAndreas Gohr $validator = $access->getValidator($data); 16093ca6f4fSAndreas Gohr if($validator->validate()) { 16193ca6f4fSAndreas Gohr $validator->saveData($time); 1625c5d9fe5SMichael Grosse 1635c5d9fe5SMichael Grosse // make sure this schema is assigned 1645c5d9fe5SMichael Grosse $assignments->assignPageSchema( 1655c5d9fe5SMichael Grosse $id, 1665c5d9fe5SMichael Grosse $validator->getAccessTable()->getSchema()->getTable() 1675c5d9fe5SMichael Grosse ); 1680e120badSMichael Grosse 1690e120badSMichael Grosse // trigger meta data rendering to set page title 170eaab469cSSzymon Olewniczak // expire the cache in order to correctly render the struct header on the first page visit 171eaab469cSSzymon Olewniczak p_get_metadata($id, array('cache' => 'expire')); 17293ca6f4fSAndreas Gohr } 1733ad9c1eaSAndreas Gohr } 1743ad9c1eaSAndreas Gohr 1753ad9c1eaSAndreas Gohr return true; 1763ad9c1eaSAndreas Gohr } 1773ad9c1eaSAndreas Gohr 1783ad9c1eaSAndreas Gohr} 1793ad9c1eaSAndreas Gohr 1803ad9c1eaSAndreas Gohr// vim:ts=4:sw=4:et: 181