xref: /plugin/struct/helper.php (revision 178d399278ee8ee13b199ce2e25beaaf3845ac80)
146ca39b7SAndreas Gohr<?php
246ca39b7SAndreas Gohr/**
346ca39b7SAndreas Gohr * DokuWiki Plugin struct (Helper Component)
446ca39b7SAndreas Gohr *
546ca39b7SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
646ca39b7SAndreas Gohr * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
746ca39b7SAndreas Gohr */
846ca39b7SAndreas Gohr
946ca39b7SAndreas Gohr// must be run within Dokuwiki
1093ca6f4fSAndreas Gohruse dokuwiki\plugin\struct\meta\AccessDataValidator;
11f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable;
12ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments;
13ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema;
14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException;
1546ca39b7SAndreas Gohr
1646ca39b7SAndreas Gohrif(!defined('DOKU_INC')) die();
1746ca39b7SAndreas Gohr
1846ca39b7SAndreas Gohr/**
1946ca39b7SAndreas Gohr * The public interface for the struct plugin
2046ca39b7SAndreas Gohr *
217dac04ffSAndreas Gohr * 3rd party developers should always interact with struct data through this
227dac04ffSAndreas Gohr * helper plugin only. If additionional interface functionality is needed,
237dac04ffSAndreas Gohr * it should be added here.
2446ca39b7SAndreas Gohr *
2546ca39b7SAndreas Gohr * All functions will throw StructExceptions when something goes wrong.
267dac04ffSAndreas Gohr *
277dac04ffSAndreas Gohr * Remember to check permissions yourself!
2846ca39b7SAndreas Gohr */
2946ca39b7SAndreas Gohrclass helper_plugin_struct extends DokuWiki_Plugin {
3046ca39b7SAndreas Gohr
3146ca39b7SAndreas Gohr    /**
3246ca39b7SAndreas Gohr     * Get the structured data of a given page
3346ca39b7SAndreas Gohr     *
3446ca39b7SAndreas Gohr     * @param string $page The page to get data for
3546ca39b7SAndreas Gohr     * @param string|null $schema The schema to use null for all
3646ca39b7SAndreas Gohr     * @param int $time A timestamp if you want historic data (0 for now)
3746ca39b7SAndreas Gohr     * @return array ('schema' => ( 'fieldlabel' => 'value', ...))
3846ca39b7SAndreas Gohr     * @throws StructException
3946ca39b7SAndreas Gohr     */
4046ca39b7SAndreas Gohr    public function getData($page, $schema = null, $time = 0) {
417dac04ffSAndreas Gohr        $page = cleanID($page);
4246ca39b7SAndreas Gohr
437dac04ffSAndreas Gohr        if(is_null($schema)) {
44025cb9daSAndreas Gohr            $assignments = Assignments::getInstance();
457dac04ffSAndreas Gohr            $schemas = $assignments->getPageAssignments($page, false);
467dac04ffSAndreas Gohr        } else {
477dac04ffSAndreas Gohr            $schemas = array($schema);
487dac04ffSAndreas Gohr        }
497dac04ffSAndreas Gohr
507dac04ffSAndreas Gohr        $result = array();
517dac04ffSAndreas Gohr        foreach($schemas as $schema) {
52f411d872SAndreas Gohr            $schemaData = AccessTable::byTableName($schema, $page, $time);
530dd23cefSAndreas Gohr            $result[$schema] = $schemaData->getDataArray();
547dac04ffSAndreas Gohr        }
557dac04ffSAndreas Gohr
567dac04ffSAndreas Gohr        return $result;
5746ca39b7SAndreas Gohr    }
5846ca39b7SAndreas Gohr
5946ca39b7SAndreas Gohr    /**
6046ca39b7SAndreas Gohr     * Saves data for a given page (creates a new revision)
6146ca39b7SAndreas Gohr     *
627dac04ffSAndreas Gohr     * If this call succeeds you can assume your data has either been saved or it was
637dac04ffSAndreas Gohr     * not necessary to save it because the data already existed in the wanted form or
647dac04ffSAndreas Gohr     * the given schemas are no longer assigned to that page.
657dac04ffSAndreas Gohr     *
667dac04ffSAndreas Gohr     * Important: You have to check write permissions for the given page before calling
677dac04ffSAndreas Gohr     * this function yourself!
687dac04ffSAndreas Gohr     *
697dac04ffSAndreas Gohr     * this duplicates a bit of code from entry.php - we could also fake post data and let
707dac04ffSAndreas Gohr     * entry handle it, but that would be rather unclean and might be problematic when multiple
717dac04ffSAndreas Gohr     * calls are done within the same request.
727dac04ffSAndreas Gohr     *
737dac04ffSAndreas Gohr     * @todo should this try to lock the page?
747dac04ffSAndreas Gohr     *
757dac04ffSAndreas Gohr     *
7646ca39b7SAndreas Gohr     * @param string $page
777dac04ffSAndreas Gohr     * @param array $data ('schema' => ( 'fieldlabel' => 'value', ...))
7846ca39b7SAndreas Gohr     * @param string $summary
79*178d3992SElan Ruusamäe     * @param string $summary
8046ca39b7SAndreas Gohr     * @throws StructException
8146ca39b7SAndreas Gohr     */
82*178d3992SElan Ruusamäe    public function saveData($page, $data, $summary = '', $minor = false)
83*178d3992SElan Ruusamäe    {
847dac04ffSAndreas Gohr        $page = cleanID($page);
857dac04ffSAndreas Gohr        $summary = trim($summary);
867dac04ffSAndreas Gohr        if(!$summary) $summary = $this->getLang('summary');
8746ca39b7SAndreas Gohr
887dac04ffSAndreas Gohr        if(!page_exists($page)) throw new StructException("Page does not exist. You can not attach struct data");
897dac04ffSAndreas Gohr
907dac04ffSAndreas Gohr        // validate and see if anything changes
9193ca6f4fSAndreas Gohr        $valid = AccessDataValidator::validateDataForPage($data, $page, $errors);
9293ca6f4fSAndreas Gohr        if($valid === false) {
9393ca6f4fSAndreas Gohr            throw new StructException("Validation failed:\n%s", join("\n", $errors));
947dac04ffSAndreas Gohr        }
9593ca6f4fSAndreas Gohr        if(!$valid) return; // empty array when no changes were detected
967dac04ffSAndreas Gohr
97*178d3992SElan Ruusamäe        $newrevision = self::createPageRevision($page, $summary, $minor);
987dac04ffSAndreas Gohr
997dac04ffSAndreas Gohr        // save the provided data
100025cb9daSAndreas Gohr        $assignments = Assignments::getInstance();
10193ca6f4fSAndreas Gohr        foreach($valid as $v) {
10293ca6f4fSAndreas Gohr            $v->saveData($newrevision);
1037dac04ffSAndreas Gohr            // make sure this schema is assigned
10493ca6f4fSAndreas Gohr            $assignments->assignPageSchema($page, $v->getAccessTable()->getSchema()->getTable());
1057dac04ffSAndreas Gohr        }
10646ca39b7SAndreas Gohr    }
10746ca39b7SAndreas Gohr
10846ca39b7SAndreas Gohr    /**
109ff2afc7cSMichael Große     * Save data row for a lookup schema
110ff2afc7cSMichael Große     *
111ff2afc7cSMichael Große     * @param string $tablename the name of the lookup schema into which to save the data
112ff2afc7cSMichael Große     * @param array  $data data to be saved in the form of [columnName => 'data']
113ff2afc7cSMichael Große     */
114ff2afc7cSMichael Große    public function saveLookupData($tablename, $data)
115ff2afc7cSMichael Große    {
116ff2afc7cSMichael Große        $access = AccessTable::byTableName($tablename, 0, 0);
117ff2afc7cSMichael Große        if(!$access->getSchema()->isEditable()) {
118ff2afc7cSMichael Große            throw new StructException('lookup save error: no permission for schema');
119ff2afc7cSMichael Große        }
120ff2afc7cSMichael Große        $validator = $access->getValidator($data);
121ff2afc7cSMichael Große        if(!$validator->validate()) {
122ff2afc7cSMichael Große            throw new StructException("Validation failed:\n%s", implode("\n", $validator->getErrors()));
123ff2afc7cSMichael Große        }
124ff2afc7cSMichael Große        if(!$validator->saveData()) {
125ff2afc7cSMichael Große            throw new StructException('No data saved');
126ff2afc7cSMichael Große        }
127ff2afc7cSMichael Große    }
128ff2afc7cSMichael Große
129ff2afc7cSMichael Große    /**
13013eddb0fSAndreas Gohr     * Creates a new page revision with the same page content as before
13113eddb0fSAndreas Gohr     *
13213eddb0fSAndreas Gohr     * @param string $page
13313eddb0fSAndreas Gohr     * @param string $summary
13413eddb0fSAndreas Gohr     * @param bool $minor
13513eddb0fSAndreas Gohr     * @return int the new revision
13613eddb0fSAndreas Gohr     */
13713eddb0fSAndreas Gohr    static public function createPageRevision($page, $summary = '', $minor = false) {
13813eddb0fSAndreas Gohr        $summary = trim($summary);
13913eddb0fSAndreas Gohr        // force a new page revision @see action_plugin_struct_entry::handle_pagesave_before()
14013eddb0fSAndreas Gohr        $GLOBALS['struct_plugin_force_page_save'] = true;
14113eddb0fSAndreas Gohr        saveWikiText($page, rawWiki($page), $summary, $minor);
14213eddb0fSAndreas Gohr        unset($GLOBALS['struct_plugin_force_page_save']);
14313eddb0fSAndreas Gohr        $file = wikiFN($page);
14413eddb0fSAndreas Gohr        clearstatcache(false, $file);
14513eddb0fSAndreas Gohr        return filemtime($file);
14613eddb0fSAndreas Gohr    }
14713eddb0fSAndreas Gohr
14813eddb0fSAndreas Gohr    /**
14946ca39b7SAndreas Gohr     * Get info about existing schemas
15046ca39b7SAndreas Gohr     *
15146ca39b7SAndreas Gohr     * @param string|null $schema the schema to query, null for all
1527dac04ffSAndreas Gohr     * @return Schema[]
15346ca39b7SAndreas Gohr     * @throws StructException
15446ca39b7SAndreas Gohr     */
15546ca39b7SAndreas Gohr    public function getSchema($schema = null) {
1567dac04ffSAndreas Gohr        if(is_null($schema)) {
1577dac04ffSAndreas Gohr            $schemas = Schema::getAll();
1587dac04ffSAndreas Gohr        } else {
1597dac04ffSAndreas Gohr            $schemas = array($schema);
1607dac04ffSAndreas Gohr        }
16146ca39b7SAndreas Gohr
1627dac04ffSAndreas Gohr        $result = array();
1637dac04ffSAndreas Gohr        foreach($schemas as $table) {
1647dac04ffSAndreas Gohr            $result[$table] = new Schema($table);
1657dac04ffSAndreas Gohr        }
1667dac04ffSAndreas Gohr        return $result;
16746ca39b7SAndreas Gohr    }
16846ca39b7SAndreas Gohr
16946ca39b7SAndreas Gohr    /**
17046ca39b7SAndreas Gohr     * Returns all pages known to the struct plugin
17146ca39b7SAndreas Gohr     *
17246ca39b7SAndreas Gohr     * That means all pages that have or had once struct data saved
17346ca39b7SAndreas Gohr     *
17446ca39b7SAndreas Gohr     * @param string|null $schema limit the result to a given schema
1757dac04ffSAndreas Gohr     * @return array (page => (schema => true), ...)
17646ca39b7SAndreas Gohr     * @throws StructException
17746ca39b7SAndreas Gohr     */
17846ca39b7SAndreas Gohr    public function getPages($schema = null) {
179025cb9daSAndreas Gohr        $assignments = Assignments::getInstance();
1807dac04ffSAndreas Gohr        return $assignments->getPages($schema);
18146ca39b7SAndreas Gohr    }
18246ca39b7SAndreas Gohr
18346ca39b7SAndreas Gohr}
184