xref: /plugin/struct/helper.php (revision 13eddb0f545f8f41b29b77f59e797a50081d9821)
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
10f411d872SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTable;
11ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments;
12ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema;
1394c9aa4cSAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTableData;
14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException;
15ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Validator;
1646ca39b7SAndreas Gohr
1746ca39b7SAndreas Gohrif(!defined('DOKU_INC')) die();
1846ca39b7SAndreas Gohr
1946ca39b7SAndreas Gohr/**
2046ca39b7SAndreas Gohr * The public interface for the struct plugin
2146ca39b7SAndreas Gohr *
227dac04ffSAndreas Gohr * 3rd party developers should always interact with struct data through this
237dac04ffSAndreas Gohr * helper plugin only. If additionional interface functionality is needed,
247dac04ffSAndreas Gohr * it should be added here.
2546ca39b7SAndreas Gohr *
2646ca39b7SAndreas Gohr * All functions will throw StructExceptions when something goes wrong.
277dac04ffSAndreas Gohr *
287dac04ffSAndreas Gohr * Remember to check permissions yourself!
2946ca39b7SAndreas Gohr */
3046ca39b7SAndreas Gohrclass helper_plugin_struct extends DokuWiki_Plugin {
3146ca39b7SAndreas Gohr
3246ca39b7SAndreas Gohr    /**
3346ca39b7SAndreas Gohr     * Get the structured data of a given page
3446ca39b7SAndreas Gohr     *
3546ca39b7SAndreas Gohr     * @param string $page The page to get data for
3646ca39b7SAndreas Gohr     * @param string|null $schema The schema to use null for all
3746ca39b7SAndreas Gohr     * @param int $time A timestamp if you want historic data (0 for now)
3846ca39b7SAndreas Gohr     * @return array ('schema' => ( 'fieldlabel' => 'value', ...))
3946ca39b7SAndreas Gohr     * @throws StructException
4046ca39b7SAndreas Gohr     */
4146ca39b7SAndreas Gohr    public function getData($page, $schema=null, $time=0) {
427dac04ffSAndreas Gohr        $page = cleanID($page);
4346ca39b7SAndreas Gohr
447dac04ffSAndreas Gohr        if(is_null($schema)) {
457dac04ffSAndreas Gohr            $assignments = new Assignments();
467dac04ffSAndreas Gohr            $schemas = $assignments->getPageAssignments($page, false);
477dac04ffSAndreas Gohr        } else {
487dac04ffSAndreas Gohr            $schemas = array($schema);
497dac04ffSAndreas Gohr        }
507dac04ffSAndreas Gohr
517dac04ffSAndreas Gohr        $result = array();
527dac04ffSAndreas Gohr        foreach($schemas as $schema) {
53f411d872SAndreas Gohr            $schemaData = AccessTable::byTableName($schema, $page, $time);
540dd23cefSAndreas Gohr            $result[$schema] = $schemaData->getDataArray();
557dac04ffSAndreas Gohr        }
567dac04ffSAndreas Gohr
577dac04ffSAndreas Gohr        return $result;
5846ca39b7SAndreas Gohr    }
5946ca39b7SAndreas Gohr
6046ca39b7SAndreas Gohr    /**
6146ca39b7SAndreas Gohr     * Saves data for a given page (creates a new revision)
6246ca39b7SAndreas Gohr     *
637dac04ffSAndreas Gohr     * If this call succeeds you can assume your data has either been saved or it was
647dac04ffSAndreas Gohr     * not necessary to save it because the data already existed in the wanted form or
657dac04ffSAndreas Gohr     * the given schemas are no longer assigned to that page.
667dac04ffSAndreas Gohr     *
677dac04ffSAndreas Gohr     * Important: You have to check write permissions for the given page before calling
687dac04ffSAndreas Gohr     * this function yourself!
697dac04ffSAndreas Gohr     *
707dac04ffSAndreas Gohr     * this duplicates a bit of code from entry.php - we could also fake post data and let
717dac04ffSAndreas Gohr     * entry handle it, but that would be rather unclean and might be problematic when multiple
727dac04ffSAndreas Gohr     * calls are done within the same request.
737dac04ffSAndreas Gohr     *
747dac04ffSAndreas Gohr     * @todo should this try to lock the page?
757dac04ffSAndreas Gohr     *
767dac04ffSAndreas Gohr     *
7746ca39b7SAndreas Gohr     * @param string $page
787dac04ffSAndreas Gohr     * @param array $data ('schema' => ( 'fieldlabel' => 'value', ...))
7946ca39b7SAndreas Gohr     * @param string $summary
8046ca39b7SAndreas Gohr     * @throws StructException
8146ca39b7SAndreas Gohr     */
827dac04ffSAndreas Gohr    public function saveData($page, $data, $summary='') {
837dac04ffSAndreas Gohr        $page = cleanID($page);
847dac04ffSAndreas Gohr        $summary = trim($summary);
857dac04ffSAndreas Gohr        if(!$summary) $summary = $this->getLang('summary');
8646ca39b7SAndreas Gohr
877dac04ffSAndreas Gohr        if(!page_exists($page)) throw new StructException("Page does not exist. You can not attach struct data");
887dac04ffSAndreas Gohr
897dac04ffSAndreas Gohr        // validate and see if anything changes
907dac04ffSAndreas Gohr        $validator = new Validator();
917dac04ffSAndreas Gohr        if(!$validator->validate($data, $page)) {
927dac04ffSAndreas Gohr            throw new StructException("Validation failed:\n%s", join("\n", $validator->getErrors()));
937dac04ffSAndreas Gohr        }
947dac04ffSAndreas Gohr        $data = $validator->getCleanedData();
957dac04ffSAndreas Gohr        $tosave = $validator->getChangedSchemas();
967dac04ffSAndreas Gohr        if(!$tosave) return;
977dac04ffSAndreas Gohr
98*13eddb0fSAndreas Gohr        $newrevision = self::createPageRevision($page, $summary);
997dac04ffSAndreas Gohr
1007dac04ffSAndreas Gohr        // save the provided data
1017dac04ffSAndreas Gohr        $assignments = new Assignments();
1027dac04ffSAndreas Gohr        foreach($tosave as $table) {
103f411d872SAndreas Gohr            $schemaData = AccessTable::byTableName($table, $page, $newrevision);
1047dac04ffSAndreas Gohr            $schemaData->saveData($data[$table]);
1057dac04ffSAndreas Gohr            // make sure this schema is assigned
1067dac04ffSAndreas Gohr            $assignments->assignPageSchema($page, $table);
1077dac04ffSAndreas Gohr        }
10846ca39b7SAndreas Gohr    }
10946ca39b7SAndreas Gohr
11046ca39b7SAndreas Gohr    /**
111*13eddb0fSAndreas Gohr     * Creates a new page revision with the same page content as before
112*13eddb0fSAndreas Gohr     *
113*13eddb0fSAndreas Gohr     * @param string $page
114*13eddb0fSAndreas Gohr     * @param string $summary
115*13eddb0fSAndreas Gohr     * @param bool $minor
116*13eddb0fSAndreas Gohr     * @return int the new revision
117*13eddb0fSAndreas Gohr     */
118*13eddb0fSAndreas Gohr    static public function createPageRevision($page, $summary='', $minor=false) {
119*13eddb0fSAndreas Gohr        $summary = trim($summary);
120*13eddb0fSAndreas Gohr        // force a new page revision @see action_plugin_struct_entry::handle_pagesave_before()
121*13eddb0fSAndreas Gohr        $GLOBALS['struct_plugin_force_page_save'] = true;
122*13eddb0fSAndreas Gohr        saveWikiText($page, rawWiki($page), $summary, $minor);
123*13eddb0fSAndreas Gohr        unset($GLOBALS['struct_plugin_force_page_save']);
124*13eddb0fSAndreas Gohr        $file = wikiFN($page);
125*13eddb0fSAndreas Gohr        clearstatcache(false, $file);
126*13eddb0fSAndreas Gohr        return filemtime($file);
127*13eddb0fSAndreas Gohr    }
128*13eddb0fSAndreas Gohr
129*13eddb0fSAndreas Gohr    /**
13046ca39b7SAndreas Gohr     * Get info about existing schemas
13146ca39b7SAndreas Gohr     *
13246ca39b7SAndreas Gohr     * @param string|null $schema the schema to query, null for all
1337dac04ffSAndreas Gohr     * @return Schema[]
13446ca39b7SAndreas Gohr     * @throws StructException
13546ca39b7SAndreas Gohr     */
13646ca39b7SAndreas Gohr    public function getSchema($schema=null) {
1377dac04ffSAndreas Gohr        if(is_null($schema)) {
1387dac04ffSAndreas Gohr            $schemas = Schema::getAll();
1397dac04ffSAndreas Gohr        } else {
1407dac04ffSAndreas Gohr            $schemas = array($schema);
1417dac04ffSAndreas Gohr        }
14246ca39b7SAndreas Gohr
1437dac04ffSAndreas Gohr        $result = array();
1447dac04ffSAndreas Gohr        foreach($schemas as $table) {
1457dac04ffSAndreas Gohr            $result[$table] = new Schema($table);
1467dac04ffSAndreas Gohr        }
1477dac04ffSAndreas Gohr        return $result;
14846ca39b7SAndreas Gohr    }
14946ca39b7SAndreas Gohr
15046ca39b7SAndreas Gohr    /**
15146ca39b7SAndreas Gohr     * Returns all pages known to the struct plugin
15246ca39b7SAndreas Gohr     *
15346ca39b7SAndreas Gohr     * That means all pages that have or had once struct data saved
15446ca39b7SAndreas Gohr     *
15546ca39b7SAndreas Gohr     * @param string|null $schema limit the result to a given schema
1567dac04ffSAndreas Gohr     * @return array (page => (schema => true), ...)
15746ca39b7SAndreas Gohr     * @throws StructException
15846ca39b7SAndreas Gohr     */
15946ca39b7SAndreas Gohr    public function getPages($schema=null) {
1607dac04ffSAndreas Gohr        $assignments = new Assignments();
1617dac04ffSAndreas Gohr        return $assignments->getPages($schema);
16246ca39b7SAndreas Gohr    }
16346ca39b7SAndreas Gohr
16446ca39b7SAndreas Gohr}
165