1<?php 2 3/** 4 * DokuWiki Plugin struct (Helper Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 8 */ 9 10use dokuwiki\Extension\Event; 11use dokuwiki\plugin\struct\meta\StructException; 12 13class helper_plugin_struct_db extends DokuWiki_Plugin 14{ 15 /** @var helper_plugin_sqlite */ 16 protected $sqlite; 17 18 /** 19 * helper_plugin_struct_db constructor. 20 */ 21 public function __construct() 22 { 23 $this->init(); 24 } 25 26 /** 27 * Initialize the database 28 * 29 * @throws Exception 30 */ 31 protected function init() 32 { 33 /** @var helper_plugin_sqlite $sqlite */ 34 $this->sqlite = plugin_load('helper', 'sqlite'); 35 if (!$this->sqlite) { 36 if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t load sqlite.'); 37 return; 38 } 39 40 if ($this->sqlite->getAdapter() === null) { 41 if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t load PDO sqlite.'); 42 $this->sqlite = null; 43 return; 44 } 45 46 if ($this->sqlite->getAdapter()->getName() != DOKU_EXT_PDO) { 47 if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t load PDO sqlite.'); 48 $this->sqlite = null; 49 return; 50 } 51 $this->sqlite->getAdapter()->setUseNativeAlter(true); 52 53 // initialize the database connection 54 if (!$this->sqlite->init('struct', DOKU_PLUGIN . 'struct/db/')) { 55 if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t init sqlite.'); 56 $this->sqlite = null; 57 return; 58 } 59 60 // register our JSON function with variable parameters 61 // todo this might be useful to be moved into the sqlite plugin 62 $this->sqlite->create_function('STRUCT_JSON', array($this, 'STRUCT_JSON'), -1); 63 64 // this function is meant to be overwritten by plugins 65 $this->sqlite->create_function('IS_PUBLISHER', array($this, 'IS_PUBLISHER'), -1); 66 67 // collect and register custom functions from other plugins 68 $functions = []; 69 Event::createAndTrigger('STRUCT_PLUGIN_SQLITE_FUNCTION', $functions); 70 foreach ($functions as $fn) { 71 if (isset($fn['obj']) && isset($fn['name']) && is_callable([$fn['obj'], $fn['name']])) { 72 $this->sqlite->create_function($fn['name'], [$fn['obj'], $fn['name']], -1); 73 } 74 } 75 } 76 77 /** 78 * @param bool $throw throw an Exception when sqlite not available? 79 * @return helper_plugin_sqlite|null 80 */ 81 public function getDB($throw = true) 82 { 83 global $conf; 84 $len = strlen($conf['metadir']); 85 if ($this->sqlite && $conf['metadir'] != substr($this->sqlite->getAdapter()->getDbFile(), 0, $len)) { 86 $this->init(); 87 } 88 if (!$this->sqlite && $throw) { 89 throw new StructException('no sqlite'); 90 } 91 return $this->sqlite; 92 } 93 94 /** 95 * Completely remove the database and reinitialize it 96 * 97 * You do not want to call this except for testing! 98 */ 99 public function resetDB() 100 { 101 if (!$this->sqlite) return; 102 $file = $this->sqlite->getAdapter()->getDbFile(); 103 if (!$file) return; 104 unlink($file); 105 clearstatcache(true, $file); 106 $this->init(); 107 } 108 109 /** 110 * Encodes all given arguments into a JSON encoded array 111 * 112 * @param string ... 113 * @return string 114 */ 115 public function STRUCT_JSON() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 116 { 117 $args = func_get_args(); 118 return json_encode($args); 119 } 120 121 /** 122 * This dummy implementation can be overwritten by a plugin 123 * 124 * @return bool 125 */ 126 public function IS_PUBLISHER() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps 127 { 128 return true; 129 } 130} 131 132// vim:ts=4:sw=4:et: 133