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_EMAIL_SEND', 'BEFORE', $this, 'handle_lookup_fields'); 39 $controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'AFTER', $this, 'handle_save'); 40 $controller->register_hook('PLUGIN_BUREAUCRACY_FIELD_UNKNOWN', 'BEFORE', $this, 'handle_schema'); 41 } 42 43 /** 44 * Load a whole schema as fields 45 * 46 * @param Doku_Event $event event object by reference 47 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 48 * handler was registered] 49 * @return bool 50 */ 51 public function handle_schema(Doku_Event $event, $param) { 52 $args = $event->data['args']; 53 if($args[0] != 'struct_schema') return false; 54 $event->preventDefault(); 55 $event->stopPropagation(); 56 57 /** @var helper_plugin_bureaucracy_field $helper */ 58 $helper = plugin_load('helper', 'bureaucracy_field'); 59 $helper->initialize($args); 60 61 $schema = new Schema($helper->opt['label']); 62 if(!$schema->getId()) { 63 msg('This schema does not exist', -1); 64 return false; 65 } 66 67 foreach($schema->getColumns(false) as $column) { 68 /** @var helper_plugin_struct_field $field */ 69 $field = plugin_load('helper', 'struct_field'); 70 // we don't initialize the field but set the appropriate values 71 $field->opt = $helper->opt; // copy all the settings to each field 72 $field->opt['label'] = $column->getFullQualifiedLabel(); 73 $field->column = $column; 74 $event->data['fields'][] = $field; 75 } 76 return true; 77 } 78 79 /** 80 * Replace lookup fields placeholder's values 81 * 82 * @param Doku_Event $event event object by reference 83 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 84 * handler was registered] 85 * @return bool 86 */ 87 public function handle_lookup_fields(Doku_Event $event, $param) { 88 foreach($event->data['fields'] as $field) { 89 if(!is_a($field, 'helper_plugin_struct_field')) continue; 90 if(!$field->column->getType() instanceof Lookup) continue; 91 92 $value = $field->getParam('value'); 93 if (!is_array($value)) $value = array($value); 94 95 $config = $field->column->getType()->getConfig(); 96 97 // find proper value 98 // current Search implementation doesn't allow doing it using SQL 99 $search = new Search(); 100 $search->addSchema($config['schema']); 101 $search->addColumn($config['field']); 102 $result = $search->execute(); 103 $pids = $search->getPids(); 104 105 $field->opt['struct_pids'] = array(); 106 $new_value = array(); 107 foreach ($value as $pid) { 108 for($i = 0; $i < count($result); $i++) { 109 if ($pids[$i] == $pid) { 110 $field->opt['struct_pids'][] = $pid; 111 $new_value[] = $result[$i][0]->getDisplayValue(); 112 } 113 } 114 } 115 116 //replace previous value 117 if ($field->column->isMulti()) { 118 $field->opt['value'] = $new_value; 119 } else { 120 $event->data['values'][$field->column->getFullQualifiedLabel()] = $new_value[0]; 121 } 122 123 } 124 return true; 125 } 126 127 /** 128 * Save the struct data 129 * 130 * @param Doku_Event $event event object by reference 131 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 132 * handler was registered] 133 * @return bool 134 */ 135 public function handle_save(Doku_Event $event, $param) { 136 // get all struct values and their associated schemas 137 $tosave = array(); 138 foreach($event->data['fields'] as $field) { 139 if(!is_a($field, 'helper_plugin_struct_field')) continue; 140 /** @var helper_plugin_struct_field $field */ 141 $tbl = $field->column->getTable(); 142 $lbl = $field->column->getLabel(); 143 if(!isset($tosave[$tbl])) $tosave[$tbl] = array(); 144 145 if ($field->column->isMulti() && $field->column->getType() instanceof Lookup) { 146 $tosave[$tbl][$lbl] = $field->opt['struct_pids']; 147 } else { 148 $tosave[$tbl][$lbl] = $field->getParam('value'); 149 } 150 } 151 152 // save all the struct data of assigned schemas 153 $id = $event->data['id']; 154 $time = filemtime(wikiFN($id)); 155 156 $assignments = Assignments::getInstance(); 157 $assigned = $assignments->getPageAssignments($id); 158 foreach($tosave as $table => $data) { 159 if(!in_array($table, $assigned)) continue; 160 $access = AccessTable::byTableName($table, $id, $time); 161 $validator = $access->getValidator($data); 162 if($validator->validate()) { 163 $validator->saveData($time); 164 165 // make sure this schema is assigned 166 $assignments->assignPageSchema( 167 $id, 168 $validator->getAccessTable()->getSchema()->getTable() 169 ); 170 171 // trigger meta data rendering to set page title 172 p_get_metadata($id); 173 } 174 } 175 176 return true; 177 } 178 179} 180 181// vim:ts=4:sw=4:et: 182