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