1<?php 2/** 3 * DokuWiki Plugin struct (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12use dokuwiki\plugin\struct\meta\AccessTable; 13use dokuwiki\plugin\struct\meta\Assignments; 14use dokuwiki\plugin\struct\meta\Schema; 15use dokuwiki\plugin\struct\meta\Search; 16use dokuwiki\plugin\struct\types\Lookup; 17 18/** 19 * Handles bureaucracy additions 20 * 21 * This registers to the template action of the bureaucracy plugin and saves all struct data 22 * submitted through the bureaucracy form to all newly created pages (if the schema applies). 23 * 24 * It also registers the struct_schema type for bureaucracy which will add all fields of the 25 * schema to the form. The struct_field type is added through standard naming convention - see 26 * helper/fiels.php for that. 27 */ 28class action_plugin_struct_bureaucracy extends DokuWiki_Action_Plugin { 29 30 /** 31 * Registers a callback function for a given event 32 * 33 * @param Doku_Event_Handler $controller DokuWiki's event controller object 34 * @return void 35 */ 36 public function register(Doku_Event_Handler $controller) { 37 $controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'BEFORE', $this, 'handle_lookup_fields'); 38 $controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'AFTER', $this, 'handle_save'); 39 $controller->register_hook('PLUGIN_BUREAUCRACY_FIELD_UNKNOWN', 'BEFORE', $this, 'handle_schema'); 40 } 41 42 /** 43 * Load a whole schema as fields 44 * 45 * @param Doku_Event $event event object by reference 46 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 47 * handler was registered] 48 * @return bool 49 */ 50 public function handle_schema(Doku_Event $event, $param) { 51 $args = $event->data['args']; 52 if($args[0] != 'struct_schema') return false; 53 $event->preventDefault(); 54 $event->stopPropagation(); 55 56 /** @var helper_plugin_bureaucracy_field $helper */ 57 $helper = plugin_load('helper', 'bureaucracy_field'); 58 $helper->initialize($args); 59 60 $schema = new Schema($helper->opt['label']); 61 if(!$schema->getId()) { 62 msg('This schema does not exist', -1); 63 return false; 64 } 65 66 foreach($schema->getColumns(false) as $column) { 67 /** @var helper_plugin_struct_field $field */ 68 $field = plugin_load('helper', 'struct_field'); 69 // we don't initialize the field but set the appropriate values 70 $field->opt = $helper->opt; // copy all the settings to each field 71 $field->opt['label'] = $column->getFullQualifiedLabel(); 72 $field->column = $column; 73 $event->data['fields'][] = $field; 74 } 75 return true; 76 } 77 78 /** 79 * Replace lookup fields placeholder's values 80 * 81 * @param Doku_Event $event event object by reference 82 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 83 * handler was registered] 84 * @return bool 85 */ 86 public function handle_lookup_fields(Doku_Event $event, $param) { 87 foreach($event->data['fields'] as $field) { 88 if(!is_a($field, 'helper_plugin_struct_field')) continue; 89 if(!$field->column->getType() instanceof Lookup) continue; 90 91 $value = $field->getParam('value'); 92 if (!is_array($value)) $value = array($value); 93 94 $config = $field->column->getType()->getConfig(); 95 96 // find proper value 97 // current Search implementation doesn't allow doing it using SQL 98 $search = new Search(); 99 $search->addSchema($config['schema']); 100 $search->addColumn($config['field']); 101 $result = $search->execute(); 102 $pids = $search->getPids(); 103 104 $field->opt['struct_pids'] = array(); 105 $new_value = array(); 106 foreach ($value as $pid) { 107 for($i = 0; $i < count($result); $i++) { 108 if ($pids[$i] == $pid) { 109 $field->opt['struct_pids'][] = $pid; 110 $new_value[] = $result[$i][0]->getDisplayValue(); 111 } 112 } 113 } 114 115 //replace previous value 116 if ($field->column->isMulti()) { 117 $field->opt['value'] = $new_value; 118 } else { 119 $event->data['values'][$field->column->getFullQualifiedLabel()] = $new_value[0]; 120 } 121 122 } 123 return true; 124 } 125 126 /** 127 * Save the struct data 128 * 129 * @param Doku_Event $event event object by reference 130 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 131 * handler was registered] 132 * @return bool 133 */ 134 public function handle_save(Doku_Event $event, $param) { 135 // get all struct values and their associated schemas 136 $tosave = array(); 137 foreach($event->data['fields'] as $field) { 138 if(!is_a($field, 'helper_plugin_struct_field')) continue; 139 /** @var helper_plugin_struct_field $field */ 140 $tbl = $field->column->getTable(); 141 $lbl = $field->column->getLabel(); 142 if(!isset($tosave[$tbl])) $tosave[$tbl] = array(); 143 144 if ($field->column->isMulti() && $field->column->getType() instanceof Lookup) { 145 $tosave[$tbl][$lbl] = $field->opt['struct_pids']; 146 } else { 147 $tosave[$tbl][$lbl] = $field->getParam('value'); 148 } 149 } 150 151 // save all the struct data of assigned schemas 152 $id = $event->data['id']; 153 $time = filemtime(wikiFN($id)); 154 155 $assignments = Assignments::getInstance(); 156 $assigned = $assignments->getPageAssignments($id); 157 foreach($tosave as $table => $data) { 158 if(!in_array($table, $assigned)) continue; 159 $access = AccessTable::byTableName($table, $id, $time); 160 $validator = $access->getValidator($data); 161 if($validator->validate()) { 162 $validator->saveData($time); 163 164 // make sure this schema is assigned 165 $assignments->assignPageSchema( 166 $id, 167 $validator->getAccessTable()->getSchema()->getTable() 168 ); 169 170 // trigger meta data rendering to set page title 171 p_get_metadata($id); 172 } 173 } 174 175 return true; 176 } 177 178} 179 180// vim:ts=4:sw=4:et: 181