1<?php 2/** 3 * DokuWiki Plugin struct (Helper 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 10use dokuwiki\plugin\struct\meta\AccessTable; 11use dokuwiki\plugin\struct\meta\Assignments; 12use dokuwiki\plugin\struct\meta\Schema; 13use dokuwiki\plugin\struct\meta\AccessTableData; 14use dokuwiki\plugin\struct\meta\StructException; 15use dokuwiki\plugin\struct\meta\Validator; 16 17if(!defined('DOKU_INC')) die(); 18 19/** 20 * The public interface for the struct plugin 21 * 22 * 3rd party developers should always interact with struct data through this 23 * helper plugin only. If additionional interface functionality is needed, 24 * it should be added here. 25 * 26 * All functions will throw StructExceptions when something goes wrong. 27 * 28 * Remember to check permissions yourself! 29 */ 30class helper_plugin_struct extends DokuWiki_Plugin { 31 32 /** 33 * Get the structured data of a given page 34 * 35 * @param string $page The page to get data for 36 * @param string|null $schema The schema to use null for all 37 * @param int $time A timestamp if you want historic data (0 for now) 38 * @return array ('schema' => ( 'fieldlabel' => 'value', ...)) 39 * @throws StructException 40 */ 41 public function getData($page, $schema=null, $time=0) { 42 $page = cleanID($page); 43 44 if(is_null($schema)) { 45 $assignments = new Assignments(); 46 $schemas = $assignments->getPageAssignments($page, false); 47 } else { 48 $schemas = array($schema); 49 } 50 51 $result = array(); 52 foreach($schemas as $schema) { 53 $schemaData = AccessTable::byTableName($schema, $page, $time); 54 $result[$schema] = $schemaData->getDataArray(); 55 } 56 57 return $result; 58 } 59 60 /** 61 * Saves data for a given page (creates a new revision) 62 * 63 * If this call succeeds you can assume your data has either been saved or it was 64 * not necessary to save it because the data already existed in the wanted form or 65 * the given schemas are no longer assigned to that page. 66 * 67 * Important: You have to check write permissions for the given page before calling 68 * this function yourself! 69 * 70 * this duplicates a bit of code from entry.php - we could also fake post data and let 71 * entry handle it, but that would be rather unclean and might be problematic when multiple 72 * calls are done within the same request. 73 * 74 * @todo should this try to lock the page? 75 * 76 * 77 * @param string $page 78 * @param array $data ('schema' => ( 'fieldlabel' => 'value', ...)) 79 * @param string $summary 80 * @throws StructException 81 */ 82 public function saveData($page, $data, $summary='') { 83 $page = cleanID($page); 84 $summary = trim($summary); 85 if(!$summary) $summary = $this->getLang('summary'); 86 87 if(!page_exists($page)) throw new StructException("Page does not exist. You can not attach struct data"); 88 89 // validate and see if anything changes 90 $validator = new Validator(); 91 if(!$validator->validate($data, $page)) { 92 throw new StructException("Validation failed:\n%s", join("\n", $validator->getErrors())); 93 } 94 $data = $validator->getCleanedData(); 95 $tosave = $validator->getChangedSchemas(); 96 if(!$tosave) return; 97 98 $newrevision = self::createPageRevision($page, $summary); 99 100 // save the provided data 101 $assignments = new Assignments(); 102 foreach($tosave as $table) { 103 $schemaData = AccessTable::byTableName($table, $page, $newrevision); 104 $schemaData->saveData($data[$table]); 105 // make sure this schema is assigned 106 $assignments->assignPageSchema($page, $table); 107 } 108 } 109 110 /** 111 * Creates a new page revision with the same page content as before 112 * 113 * @param string $page 114 * @param string $summary 115 * @param bool $minor 116 * @return int the new revision 117 */ 118 static public function createPageRevision($page, $summary='', $minor=false) { 119 $summary = trim($summary); 120 // force a new page revision @see action_plugin_struct_entry::handle_pagesave_before() 121 $GLOBALS['struct_plugin_force_page_save'] = true; 122 saveWikiText($page, rawWiki($page), $summary, $minor); 123 unset($GLOBALS['struct_plugin_force_page_save']); 124 $file = wikiFN($page); 125 clearstatcache(false, $file); 126 return filemtime($file); 127 } 128 129 /** 130 * Get info about existing schemas 131 * 132 * @param string|null $schema the schema to query, null for all 133 * @return Schema[] 134 * @throws StructException 135 */ 136 public function getSchema($schema=null) { 137 if(is_null($schema)) { 138 $schemas = Schema::getAll(); 139 } else { 140 $schemas = array($schema); 141 } 142 143 $result = array(); 144 foreach($schemas as $table) { 145 $result[$table] = new Schema($table); 146 } 147 return $result; 148 } 149 150 /** 151 * Returns all pages known to the struct plugin 152 * 153 * That means all pages that have or had once struct data saved 154 * 155 * @param string|null $schema limit the result to a given schema 156 * @return array (page => (schema => true), ...) 157 * @throws StructException 158 */ 159 public function getPages($schema=null) { 160 $assignments = new Assignments(); 161 return $assignments->getPages($schema); 162 } 163 164} 165