13ad9c1eaSAndreas Gohr<?php 2d6d97f60SAnna Dabrowska 33ad9c1eaSAndreas Gohr/** 43ad9c1eaSAndreas Gohr * DokuWiki Plugin struct (Action Component) 53ad9c1eaSAndreas Gohr * 63ad9c1eaSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 73ad9c1eaSAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 83ad9c1eaSAndreas Gohr */ 93ad9c1eaSAndreas Gohr 10f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable; 119fc5ecc2SMichael Grosseuse dokuwiki\plugin\struct\meta\Assignments; 12ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema; 13345c3838SSzymon Olewniczakuse dokuwiki\plugin\struct\meta\Search; 14e46eaffdSSzymon Olewniczakuse dokuwiki\plugin\struct\types\Lookup; 153ad9c1eaSAndreas Gohr 163ad9c1eaSAndreas Gohr/** 17cfe2b908SAndreas Gohr * Handles bureaucracy additions 183ad9c1eaSAndreas Gohr * 193ad9c1eaSAndreas Gohr * This registers to the template action of the bureaucracy plugin and saves all struct data 20cfe2b908SAndreas Gohr * submitted through the bureaucracy form to all newly created pages (if the schema applies). 21cfe2b908SAndreas Gohr * 22cfe2b908SAndreas Gohr * It also registers the struct_schema type for bureaucracy which will add all fields of the 23cfe2b908SAndreas Gohr * schema to the form. The struct_field type is added through standard naming convention - see 24cfe2b908SAndreas Gohr * helper/fiels.php for that. 253ad9c1eaSAndreas Gohr */ 26d6d97f60SAnna Dabrowskaclass action_plugin_struct_bureaucracy extends DokuWiki_Action_Plugin 27d6d97f60SAnna Dabrowska{ 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 */ 35d6d97f60SAnna Dabrowska public function register(Doku_Event_Handler $controller) 36d6d97f60SAnna Dabrowska { 37*e0f75a3fSAnna Dabrowska $controller->register_hook('PLUGIN_BUREAUCRACY_PAGENAME', 'BEFORE', $this, 'handleLookupFields'); 38748e747fSAnna Dabrowska $controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'AFTER', $this, 'handleSave'); 39748e747fSAnna Dabrowska $controller->register_hook('PLUGIN_BUREAUCRACY_FIELD_UNKNOWN', 'BEFORE', $this, 'handleSchema'); 40cfe2b908SAndreas Gohr } 41cfe2b908SAndreas Gohr 42cfe2b908SAndreas Gohr /** 43cfe2b908SAndreas Gohr * Load a whole schema as fields 44cfe2b908SAndreas Gohr * 45cfe2b908SAndreas Gohr * @param Doku_Event $event event object by reference 46cfe2b908SAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 47cfe2b908SAndreas Gohr * handler was registered] 48cfe2b908SAndreas Gohr * @return bool 49cfe2b908SAndreas Gohr */ 50748e747fSAnna Dabrowska public function handleSchema(Doku_Event $event, $param) 51d6d97f60SAnna Dabrowska { 52cfe2b908SAndreas Gohr $args = $event->data['args']; 5393ca6f4fSAndreas Gohr if ($args[0] != 'struct_schema') return false; 54cfe2b908SAndreas Gohr $event->preventDefault(); 55cfe2b908SAndreas Gohr $event->stopPropagation(); 56cfe2b908SAndreas Gohr 57cfe2b908SAndreas Gohr /** @var helper_plugin_bureaucracy_field $helper */ 58cfe2b908SAndreas Gohr $helper = plugin_load('helper', 'bureaucracy_field'); 59cfe2b908SAndreas Gohr $helper->initialize($args); 60cfe2b908SAndreas Gohr 61cfe2b908SAndreas Gohr $schema = new Schema($helper->opt['label']); 62cfe2b908SAndreas Gohr if (!$schema->getId()) { 63cfe2b908SAndreas Gohr msg('This schema does not exist', -1); 6493ca6f4fSAndreas Gohr return false; 65cfe2b908SAndreas Gohr } 66cfe2b908SAndreas Gohr 67cfe2b908SAndreas Gohr foreach ($schema->getColumns(false) as $column) { 68cfe2b908SAndreas Gohr /** @var helper_plugin_struct_field $field */ 69cfe2b908SAndreas Gohr $field = plugin_load('helper', 'struct_field'); 70cfe2b908SAndreas Gohr // we don't initialize the field but set the appropriate values 71cfe2b908SAndreas Gohr $field->opt = $helper->opt; // copy all the settings to each field 72cfe2b908SAndreas Gohr $field->opt['label'] = $column->getFullQualifiedLabel(); 73cfe2b908SAndreas Gohr $field->column = $column; 74cfe2b908SAndreas Gohr $event->data['fields'][] = $field; 75cfe2b908SAndreas Gohr } 7693ca6f4fSAndreas Gohr return true; 773ad9c1eaSAndreas Gohr } 783ad9c1eaSAndreas Gohr 793ad9c1eaSAndreas Gohr /** 80345c3838SSzymon Olewniczak * Replace lookup fields placeholder's values 81345c3838SSzymon Olewniczak * 82345c3838SSzymon Olewniczak * @param Doku_Event $event event object by reference 83345c3838SSzymon Olewniczak * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 84345c3838SSzymon Olewniczak * handler was registered] 85345c3838SSzymon Olewniczak * @return bool 86345c3838SSzymon Olewniczak */ 87748e747fSAnna Dabrowska public function handleLookupFields(Doku_Event $event, $param) 88d6d97f60SAnna Dabrowska { 89345c3838SSzymon Olewniczak foreach ($event->data['fields'] as $field) { 90345c3838SSzymon Olewniczak if (!is_a($field, 'helper_plugin_struct_field')) continue; 91e46eaffdSSzymon Olewniczak if (!$field->column->getType() instanceof Lookup) continue; 92345c3838SSzymon Olewniczak 93987ccc7fSSzymon Olewniczak $value = $field->getParam('value'); 94987ccc7fSSzymon Olewniczak if (!is_array($value)) $value = array($value); 95987ccc7fSSzymon Olewniczak 96345c3838SSzymon Olewniczak $config = $field->column->getType()->getConfig(); 97345c3838SSzymon Olewniczak 98345c3838SSzymon Olewniczak // find proper value 99345c3838SSzymon Olewniczak // current Search implementation doesn't allow doing it using SQL 100345c3838SSzymon Olewniczak $search = new Search(); 101345c3838SSzymon Olewniczak $search->addSchema($config['schema']); 102345c3838SSzymon Olewniczak $search->addColumn($config['field']); 103345c3838SSzymon Olewniczak $result = $search->execute(); 104345c3838SSzymon Olewniczak $pids = $search->getPids(); 10517308e28SAnna Dabrowska $rids = $search->getRids(); 106345c3838SSzymon Olewniczak 107987ccc7fSSzymon Olewniczak $field->opt['struct_pids'] = array(); 108987ccc7fSSzymon Olewniczak $new_value = array(); 109987ccc7fSSzymon Olewniczak foreach ($value as $pid) { 110987ccc7fSSzymon Olewniczak for ($i = 0; $i < count($result); $i++) { 11117308e28SAnna Dabrowska // lookups can reference pages or global data, so check both pid and rid 11217308e28SAnna Dabrowska $pid = json_decode($pid)[0] ?: $pid; 11317308e28SAnna Dabrowska $rid = json_decode($pid)[1]; 11417308e28SAnna Dabrowska if (($pid && $pids[$i] === $pid) || ($rid && $rids[$i] === (string)$rid)) { 115987ccc7fSSzymon Olewniczak $field->opt['struct_pids'][] = $pid; 116987ccc7fSSzymon Olewniczak $new_value[] = $result[$i][0]->getDisplayValue(); 117987ccc7fSSzymon Olewniczak } 118345c3838SSzymon Olewniczak } 119345c3838SSzymon Olewniczak } 120345c3838SSzymon Olewniczak 121345c3838SSzymon Olewniczak //replace previous value 122987ccc7fSSzymon Olewniczak if ($field->column->isMulti()) { 123987ccc7fSSzymon Olewniczak $field->opt['value'] = $new_value; 124987ccc7fSSzymon Olewniczak } else { 125987ccc7fSSzymon Olewniczak $event->data['values'][$field->column->getFullQualifiedLabel()] = $new_value[0]; 126345c3838SSzymon Olewniczak } 127345c3838SSzymon Olewniczak } 128345c3838SSzymon Olewniczak return true; 129345c3838SSzymon Olewniczak } 130345c3838SSzymon Olewniczak 131345c3838SSzymon Olewniczak /** 1323ad9c1eaSAndreas Gohr * Save the struct data 1333ad9c1eaSAndreas Gohr * 1343ad9c1eaSAndreas Gohr * @param Doku_Event $event event object by reference 1353ad9c1eaSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 1363ad9c1eaSAndreas Gohr * handler was registered] 1373ad9c1eaSAndreas Gohr * @return bool 1383ad9c1eaSAndreas Gohr */ 139748e747fSAnna Dabrowska public function handleSave(Doku_Event $event, $param) 140d6d97f60SAnna Dabrowska { 1413ad9c1eaSAndreas Gohr // get all struct values and their associated schemas 1423ad9c1eaSAndreas Gohr $tosave = array(); 1433ad9c1eaSAndreas Gohr foreach ($event->data['fields'] as $field) { 1443ad9c1eaSAndreas Gohr if (!is_a($field, 'helper_plugin_struct_field')) continue; 1453ad9c1eaSAndreas Gohr /** @var helper_plugin_struct_field $field */ 1463ad9c1eaSAndreas Gohr $tbl = $field->column->getTable(); 1473ad9c1eaSAndreas Gohr $lbl = $field->column->getLabel(); 1483ad9c1eaSAndreas Gohr if (!isset($tosave[$tbl])) $tosave[$tbl] = array(); 149987ccc7fSSzymon Olewniczak 150e46eaffdSSzymon Olewniczak if ($field->column->isMulti() && $field->column->getType() instanceof Lookup) { 151987ccc7fSSzymon Olewniczak $tosave[$tbl][$lbl] = $field->opt['struct_pids']; 152987ccc7fSSzymon Olewniczak } else { 1533ad9c1eaSAndreas Gohr $tosave[$tbl][$lbl] = $field->getParam('value'); 1543ad9c1eaSAndreas Gohr } 155987ccc7fSSzymon Olewniczak } 1563ad9c1eaSAndreas Gohr 1573ad9c1eaSAndreas Gohr // save all the struct data of assigned schemas 1583ad9c1eaSAndreas Gohr $id = $event->data['id']; 1593ad9c1eaSAndreas Gohr $time = filemtime(wikiFN($id)); 1609fc5ecc2SMichael Grosse 161025cb9daSAndreas Gohr $assignments = Assignments::getInstance(); 16293ca6f4fSAndreas Gohr $assigned = $assignments->getPageAssignments($id); 16393ca6f4fSAndreas Gohr foreach ($tosave as $table => $data) { 16493ca6f4fSAndreas Gohr if (!in_array($table, $assigned)) continue; 1654cd5cc28SAnna Dabrowska $access = AccessTable::getPageAccess($table, $id, $time); 16693ca6f4fSAndreas Gohr $validator = $access->getValidator($data); 16793ca6f4fSAndreas Gohr if ($validator->validate()) { 16893ca6f4fSAndreas Gohr $validator->saveData($time); 1695c5d9fe5SMichael Grosse 1705c5d9fe5SMichael Grosse // make sure this schema is assigned 1715c5d9fe5SMichael Grosse $assignments->assignPageSchema( 1725c5d9fe5SMichael Grosse $id, 1735c5d9fe5SMichael Grosse $validator->getAccessTable()->getSchema()->getTable() 1745c5d9fe5SMichael Grosse ); 1750e120badSMichael Grosse 1760e120badSMichael Grosse // trigger meta data rendering to set page title 1772a09b9b1SAnna Dabrowska p_get_metadata($id); 17893ca6f4fSAndreas Gohr } 1793ad9c1eaSAndreas Gohr } 1803ad9c1eaSAndreas Gohr 1813ad9c1eaSAndreas Gohr return true; 1823ad9c1eaSAndreas Gohr } 1833ad9c1eaSAndreas Gohr} 1843ad9c1eaSAndreas Gohr 1853ad9c1eaSAndreas Gohr// vim:ts=4:sw=4:et: 186