diff options
author | ArthurHoaro <arthur@hoa.ro> | 2015-07-15 11:42:15 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2015-11-07 15:27:17 +0100 |
commit | 6fc14d530369740d27d6bd641369d4f5f5f04080 (patch) | |
tree | 2da553378e8f0ff367dcb677d6f519d1fb3e803c | |
parent | 38bedfbbcdd2a40e9f04f5753e0fd6f4fd513c21 (diff) | |
download | Shaarli-6fc14d530369740d27d6bd641369d4f5f5f04080.tar.gz Shaarli-6fc14d530369740d27d6bd641369d4f5f5f04080.tar.zst Shaarli-6fc14d530369740d27d6bd641369d4f5f5f04080.zip |
Plugin system - CORE
see shaarli/Shaarli#275
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r--[-rwxr-xr-x] | application/Config.php | 263 | ||||
-rw-r--r-- | application/PluginManager.php | 184 | ||||
-rw-r--r-- | application/Router.php | 105 | ||||
-rwxr-xr-x | index.php | 230 | ||||
-rwxr-xr-x | tests/PluginManagerTest.php | 66 | ||||
-rwxr-xr-x | tests/RouterTest.php | 515 | ||||
-rwxr-xr-x | tests/plugins/test/test.php | 21 |
8 files changed, 1190 insertions, 197 deletions
@@ -21,3 +21,6 @@ coverage | |||
21 | tests/datastore.php | 21 | tests/datastore.php |
22 | tests/dummycache/ | 22 | tests/dummycache/ |
23 | phpmd.html | 23 | phpmd.html |
24 | |||
25 | # Ignore user plugin configuration | ||
26 | plugins/*/config.php \ No newline at end of file | ||
diff --git a/application/Config.php b/application/Config.php index ec799d7f..c71ef68c 100755..100644 --- a/application/Config.php +++ b/application/Config.php | |||
@@ -1,129 +1,134 @@ | |||
1 | <?php | 1 | <?php |
2 | /** | 2 | /** |
3 | * Functions related to configuration management. | 3 | * Functions related to configuration management. |
4 | */ | 4 | */ |
5 | 5 | ||
6 | /** | 6 | /** |
7 | * Re-write configuration file according to given array. | 7 | * Re-write configuration file according to given array. |
8 | * Requires mandatory fields listed in $MANDATORY_FIELDS. | 8 | * Requires mandatory fields listed in $MANDATORY_FIELDS. |
9 | * | 9 | * |
10 | * @param array $config contains all configuration fields. | 10 | * @param array $config contains all configuration fields. |
11 | * @param bool $isLoggedIn true if user is logged in. | 11 | * @param bool $isLoggedIn true if user is logged in. |
12 | * | 12 | * |
13 | * @return void | 13 | * @return void |
14 | * | 14 | * |
15 | * @throws MissingFieldConfigException: a mandatory field has not been provided in $config. | 15 | * @throws MissingFieldConfigException: a mandatory field has not been provided in $config. |
16 | * @throws UnauthorizedConfigException: user is not authorize to change configuration. | 16 | * @throws UnauthorizedConfigException: user is not authorize to change configuration. |
17 | * @throws Exception: an error occured while writing the new config file. | 17 | * @throws Exception: an error occured while writing the new config file. |
18 | */ | 18 | */ |
19 | function writeConfig($config, $isLoggedIn) | 19 | function writeConfig($config, $isLoggedIn) |
20 | { | 20 | { |
21 | // These fields are required in configuration. | 21 | // These fields are required in configuration. |
22 | $MANDATORY_FIELDS = array( | 22 | $MANDATORY_FIELDS = array( |
23 | 'login', 'hash', 'salt', 'timezone', 'title', 'titleLink', | 23 | 'login', 'hash', 'salt', 'timezone', 'title', 'titleLink', |
24 | 'redirector', 'disablesessionprotection', 'privateLinkByDefault' | 24 | 'redirector', 'disablesessionprotection', 'privateLinkByDefault' |
25 | ); | 25 | ); |
26 | 26 | ||
27 | if (!isset($config['config']['CONFIG_FILE'])) { | 27 | if (!isset($config['config']['CONFIG_FILE'])) { |
28 | throw new MissingFieldConfigException('CONFIG_FILE'); | 28 | throw new MissingFieldConfigException('CONFIG_FILE'); |
29 | } | 29 | } |
30 | 30 | ||
31 | // Only logged in user can alter config. | 31 | // Only logged in user can alter config. |
32 | if (is_file($config['config']['CONFIG_FILE']) && !$isLoggedIn) { | 32 | if (is_file($config['config']['CONFIG_FILE']) && !$isLoggedIn) { |
33 | throw new UnauthorizedConfigException(); | 33 | throw new UnauthorizedConfigException(); |
34 | } | 34 | } |
35 | 35 | ||
36 | // Check that all mandatory fields are provided in $config. | 36 | // Check that all mandatory fields are provided in $config. |
37 | foreach ($MANDATORY_FIELDS as $field) { | 37 | foreach ($MANDATORY_FIELDS as $field) { |
38 | if (!isset($config[$field])) { | 38 | if (!isset($config[$field])) { |
39 | throw new MissingFieldConfigException($field); | 39 | throw new MissingFieldConfigException($field); |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
43 | $configStr = '<?php '. PHP_EOL; | 43 | $configStr = '<?php '. PHP_EOL; |
44 | $configStr .= '$GLOBALS[\'login\'] = '.var_export($config['login'], true).';'. PHP_EOL; | 44 | $configStr .= '$GLOBALS[\'login\'] = '.var_export($config['login'], true).';'. PHP_EOL; |
45 | $configStr .= '$GLOBALS[\'hash\'] = '.var_export($config['hash'], true).';'. PHP_EOL; | 45 | $configStr .= '$GLOBALS[\'hash\'] = '.var_export($config['hash'], true).';'. PHP_EOL; |
46 | $configStr .= '$GLOBALS[\'salt\'] = '.var_export($config['salt'], true).'; '. PHP_EOL; | 46 | $configStr .= '$GLOBALS[\'salt\'] = '.var_export($config['salt'], true).'; '. PHP_EOL; |
47 | $configStr .= '$GLOBALS[\'timezone\'] = '.var_export($config['timezone'], true).';'. PHP_EOL; | 47 | $configStr .= '$GLOBALS[\'timezone\'] = '.var_export($config['timezone'], true).';'. PHP_EOL; |
48 | $configStr .= 'date_default_timezone_set('.var_export($config['timezone'], true).');'. PHP_EOL; | 48 | $configStr .= 'date_default_timezone_set('.var_export($config['timezone'], true).');'. PHP_EOL; |
49 | $configStr .= '$GLOBALS[\'title\'] = '.var_export($config['title'], true).';'. PHP_EOL; | 49 | $configStr .= '$GLOBALS[\'title\'] = '.var_export($config['title'], true).';'. PHP_EOL; |
50 | $configStr .= '$GLOBALS[\'titleLink\'] = '.var_export($config['titleLink'], true).'; '. PHP_EOL; | 50 | $configStr .= '$GLOBALS[\'titleLink\'] = '.var_export($config['titleLink'], true).'; '. PHP_EOL; |
51 | $configStr .= '$GLOBALS[\'redirector\'] = '.var_export($config['redirector'], true).'; '. PHP_EOL; | 51 | $configStr .= '$GLOBALS[\'redirector\'] = '.var_export($config['redirector'], true).'; '. PHP_EOL; |
52 | $configStr .= '$GLOBALS[\'disablesessionprotection\'] = '.var_export($config['disablesessionprotection'], true).'; '. PHP_EOL; | 52 | $configStr .= '$GLOBALS[\'disablesessionprotection\'] = '.var_export($config['disablesessionprotection'], true).'; '. PHP_EOL; |
53 | $configStr .= '$GLOBALS[\'privateLinkByDefault\'] = '.var_export($config['privateLinkByDefault'], true).'; '. PHP_EOL; | 53 | $configStr .= '$GLOBALS[\'privateLinkByDefault\'] = '.var_export($config['privateLinkByDefault'], true).'; '. PHP_EOL; |
54 | 54 | ||
55 | // Store all $config['config'] | 55 | // Store all $config['config'] |
56 | foreach ($config['config'] as $key => $value) { | 56 | foreach ($config['config'] as $key => $value) { |
57 | $configStr .= '$GLOBALS[\'config\'][\''. $key .'\'] = '.var_export($config['config'][$key], true).';'. PHP_EOL; | 57 | $configStr .= '$GLOBALS[\'config\'][\''. $key .'\'] = '.var_export($config['config'][$key], true).';'. PHP_EOL; |
58 | } | 58 | } |
59 | $configStr .= '?>'; | 59 | |
60 | 60 | if (isset($config['plugins'])) { | |
61 | if (!file_put_contents($config['config']['CONFIG_FILE'], $configStr) | 61 | foreach ($config['plugins'] as $key => $value) { |
62 | || strcmp(file_get_contents($config['config']['CONFIG_FILE']), $configStr) != 0 | 62 | $configStr .= '$GLOBALS[\'plugins\'][\''. $key .'\'] = '.var_export($config['plugins'][$key], true).';'. PHP_EOL; |
63 | ) { | 63 | } |
64 | throw new Exception( | 64 | } |
65 | 'Shaarli could not create the config file. | 65 | |
66 | Please make sure Shaarli has the right to write in the folder is it installed in.' | 66 | if (!file_put_contents($config['config']['CONFIG_FILE'], $configStr) |
67 | ); | 67 | || strcmp(file_get_contents($config['config']['CONFIG_FILE']), $configStr) != 0 |
68 | } | 68 | ) { |
69 | } | 69 | throw new Exception( |
70 | 70 | 'Shaarli could not create the config file. | |
71 | /** | 71 | Please make sure Shaarli has the right to write in the folder is it installed in.' |
72 | * Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore. | 72 | ); |
73 | * ==> if user is loggedIn, merge its content with config.php, then delete options.php. | 73 | } |
74 | * | 74 | } |
75 | * @param array $config contains all configuration fields. | 75 | |
76 | * @param bool $isLoggedIn true if user is logged in. | 76 | /** |
77 | * | 77 | * Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore. |
78 | * @return void | 78 | * ==> if user is loggedIn, merge its content with config.php, then delete options.php. |
79 | */ | 79 | * |
80 | function mergeDeprecatedConfig($config, $isLoggedIn) | 80 | * @param array $config contains all configuration fields. |
81 | { | 81 | * @param bool $isLoggedIn true if user is logged in. |
82 | $config_file = $config['config']['CONFIG_FILE']; | 82 | * |
83 | 83 | * @return void | |
84 | if (is_file($config['config']['DATADIR'].'/options.php') && $isLoggedIn) { | 84 | */ |
85 | include $config['config']['DATADIR'].'/options.php'; | 85 | function mergeDeprecatedConfig($config, $isLoggedIn) |
86 | 86 | { | |
87 | // Load GLOBALS into config | 87 | $config_file = $config['config']['CONFIG_FILE']; |
88 | foreach ($GLOBALS as $key => $value) { | 88 | |
89 | $config[$key] = $value; | 89 | if (is_file($config['config']['DATADIR'].'/options.php') && $isLoggedIn) { |
90 | } | 90 | include $config['config']['DATADIR'].'/options.php'; |
91 | $config['config']['CONFIG_FILE'] = $config_file; | 91 | |
92 | writeConfig($config, $isLoggedIn); | 92 | // Load GLOBALS into config |
93 | 93 | foreach ($GLOBALS as $key => $value) { | |
94 | unlink($config['config']['DATADIR'].'/options.php'); | 94 | $config[$key] = $value; |
95 | } | 95 | } |
96 | } | 96 | $config['config']['CONFIG_FILE'] = $config_file; |
97 | 97 | writeConfig($config, $isLoggedIn); | |
98 | /** | 98 | |
99 | * Exception used if a mandatory field is missing in given configuration. | 99 | unlink($config['config']['DATADIR'].'/options.php'); |
100 | */ | 100 | } |
101 | class MissingFieldConfigException extends Exception | 101 | } |
102 | { | 102 | |
103 | public $field; | 103 | /** |
104 | 104 | * Exception used if a mandatory field is missing in given configuration. | |
105 | /** | 105 | */ |
106 | * Construct exception. | 106 | class MissingFieldConfigException extends Exception |
107 | * | 107 | { |
108 | * @param string $field field name missing. | 108 | public $field; |
109 | */ | 109 | |
110 | public function __construct($field) | 110 | /** |
111 | { | 111 | * Construct exception. |
112 | $this->field = $field; | 112 | * |
113 | $this->message = 'Configuration value is required for '. $this->field; | 113 | * @param string $field field name missing. |
114 | } | 114 | */ |
115 | } | 115 | public function __construct($field) |
116 | 116 | { | |
117 | /** | 117 | $this->field = $field; |
118 | * Exception used if an unauthorized attempt to edit configuration has been made. | 118 | $this->message = 'Configuration value is required for '. $this->field; |
119 | */ | 119 | } |
120 | class UnauthorizedConfigException extends Exception | 120 | } |
121 | { | 121 | |
122 | /** | 122 | /** |
123 | * Construct exception. | 123 | * Exception used if an unauthorized attempt to edit configuration has been made. |
124 | */ | 124 | */ |
125 | public function __construct() | 125 | class UnauthorizedConfigException extends Exception |
126 | { | 126 | { |
127 | $this->message = 'You are not authorized to alter config.'; | 127 | /** |
128 | } | 128 | * Construct exception. |
129 | } | 129 | */ |
130 | public function __construct() | ||
131 | { | ||
132 | $this->message = 'You are not authorized to alter config.'; | ||
133 | } | ||
134 | } | ||
diff --git a/application/PluginManager.php b/application/PluginManager.php new file mode 100644 index 00000000..e572ff7c --- /dev/null +++ b/application/PluginManager.php | |||
@@ -0,0 +1,184 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Class PluginManager | ||
5 | * | ||
6 | * Use to manage, load and execute plugins. | ||
7 | * | ||
8 | * Using Singleton design pattern. | ||
9 | */ | ||
10 | class PluginManager | ||
11 | { | ||
12 | /** | ||
13 | * PluginManager singleton instance. | ||
14 | * @var PluginManager $instance | ||
15 | */ | ||
16 | private static $instance; | ||
17 | |||
18 | /** | ||
19 | * List of authorized plugins from configuration file. | ||
20 | * @var array $authorizedPlugins | ||
21 | */ | ||
22 | private $authorizedPlugins; | ||
23 | |||
24 | /** | ||
25 | * List of loaded plugins. | ||
26 | * @var array $loadedPlugins | ||
27 | */ | ||
28 | private $loadedPlugins = array(); | ||
29 | |||
30 | /** | ||
31 | * Plugins subdirectory. | ||
32 | * @var string $PLUGINS_PATH | ||
33 | */ | ||
34 | public static $PLUGINS_PATH = 'plugins'; | ||
35 | |||
36 | /** | ||
37 | * Private constructor: new instances not allowed. | ||
38 | */ | ||
39 | private function __construct() | ||
40 | { | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Cloning isn't allowed either. | ||
45 | * | ||
46 | * @return void | ||
47 | */ | ||
48 | private function __clone() | ||
49 | { | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * Return existing instance of PluginManager, or create it. | ||
54 | * | ||
55 | * @return PluginManager instance. | ||
56 | */ | ||
57 | public static function getInstance() | ||
58 | { | ||
59 | if (!(self::$instance instanceof self)) { | ||
60 | self::$instance = new self(); | ||
61 | } | ||
62 | |||
63 | return self::$instance; | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Load plugins listed in $authorizedPlugins. | ||
68 | * | ||
69 | * @param array $authorizedPlugins Names of plugin authorized to be loaded. | ||
70 | * | ||
71 | * @return void | ||
72 | */ | ||
73 | public function load($authorizedPlugins) | ||
74 | { | ||
75 | $this->authorizedPlugins = $authorizedPlugins; | ||
76 | |||
77 | $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR); | ||
78 | $dirnames = array_map('basename', $dirs); | ||
79 | foreach ($this->authorizedPlugins as $plugin) { | ||
80 | $index = array_search($plugin, $dirnames); | ||
81 | |||
82 | // plugin authorized, but its folder isn't listed | ||
83 | if ($index === false) { | ||
84 | continue; | ||
85 | } | ||
86 | |||
87 | try { | ||
88 | $this->loadPlugin($dirs[$index], $plugin); | ||
89 | } | ||
90 | catch (PluginFileNotFoundException $e) { | ||
91 | error_log($e->getMessage()); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * Execute all plugins registered hook. | ||
98 | * | ||
99 | * @param string $hook name of the hook to trigger. | ||
100 | * @param array $data list of data to manipulate passed by reference. | ||
101 | * @param array $params additional parameters such as page target. | ||
102 | * | ||
103 | * @return void | ||
104 | */ | ||
105 | public function executeHooks($hook, &$data, $params = array()) | ||
106 | { | ||
107 | if (!empty($params['target'])) { | ||
108 | $data['_PAGE_'] = $params['target']; | ||
109 | } | ||
110 | |||
111 | if (isset($params['loggedin'])) { | ||
112 | $data['_LOGGEDIN_'] = $params['loggedin']; | ||
113 | } | ||
114 | |||
115 | foreach ($this->loadedPlugins as $plugin) { | ||
116 | $hookFunction = $this->buildHookName($hook, $plugin); | ||
117 | |||
118 | if (function_exists($hookFunction)) { | ||
119 | $data = call_user_func($hookFunction, $data); | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * Load a single plugin from its files. | ||
126 | * Add them in $loadedPlugins if successful. | ||
127 | * | ||
128 | * @param string $dir plugin's directory. | ||
129 | * @param string $pluginName plugin's name. | ||
130 | * | ||
131 | * @return void | ||
132 | * @throws PluginFileNotFoundException - plugin files not found. | ||
133 | */ | ||
134 | private function loadPlugin($dir, $pluginName) | ||
135 | { | ||
136 | if (!is_dir($dir)) { | ||
137 | throw new PluginFileNotFoundException($pluginName); | ||
138 | } | ||
139 | |||
140 | $pluginFilePath = $dir . '/' . $pluginName . '.php'; | ||
141 | if (!is_file($pluginFilePath)) { | ||
142 | throw new PluginFileNotFoundException($pluginName); | ||
143 | } | ||
144 | |||
145 | include_once $pluginFilePath; | ||
146 | |||
147 | $this->loadedPlugins[] = $pluginName; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * Construct normalize hook name for a specific plugin. | ||
152 | * | ||
153 | * Format: | ||
154 | * hook_<plugin_name>_<hook_name> | ||
155 | * | ||
156 | * @param string $hook hook name. | ||
157 | * @param string $pluginName plugin name. | ||
158 | * | ||
159 | * @return string - plugin's hook name. | ||
160 | */ | ||
161 | public function buildHookName($hook, $pluginName) | ||
162 | { | ||
163 | return 'hook_' . $pluginName . '_' . $hook; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Class PluginFileNotFoundException | ||
169 | * | ||
170 | * Raise when plugin files can't be found. | ||
171 | */ | ||
172 | class PluginFileNotFoundException extends Exception | ||
173 | { | ||
174 | /** | ||
175 | * Construct exception with plugin name. | ||
176 | * Generate message. | ||
177 | * | ||
178 | * @param string $pluginName name of the plugin not found | ||
179 | */ | ||
180 | public function __construct($pluginName) | ||
181 | { | ||
182 | $this->message = 'Plugin "'. $pluginName .'" files not found.'; | ||
183 | } | ||
184 | } \ No newline at end of file | ||
diff --git a/application/Router.php b/application/Router.php new file mode 100644 index 00000000..82b2b858 --- /dev/null +++ b/application/Router.php | |||
@@ -0,0 +1,105 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Class Router | ||
5 | * | ||
6 | * (only displayable pages here) | ||
7 | */ | ||
8 | class Router | ||
9 | { | ||
10 | public static $PAGE_LOGIN = 'login'; | ||
11 | |||
12 | public static $PAGE_PICWALL = 'picwall'; | ||
13 | |||
14 | public static $PAGE_TAGCLOUD = 'tagcloud'; | ||
15 | |||
16 | public static $PAGE_TOOLS = 'tools'; | ||
17 | |||
18 | public static $PAGE_CHANGEPASSWORD = 'changepasswd'; | ||
19 | |||
20 | public static $PAGE_CONFIGURE = 'configure'; | ||
21 | |||
22 | public static $PAGE_CHANGETAG = 'changetag'; | ||
23 | |||
24 | public static $PAGE_ADDLINK = 'addlink'; | ||
25 | |||
26 | public static $PAGE_EDITLINK = 'edit_link'; | ||
27 | |||
28 | public static $PAGE_EXPORT = 'export'; | ||
29 | |||
30 | public static $PAGE_IMPORT = 'import'; | ||
31 | |||
32 | public static $PAGE_LINKLIST = 'linklist'; | ||
33 | |||
34 | /** | ||
35 | * Reproducing renderPage() if hell, to avoid regression. | ||
36 | * | ||
37 | * This highlights how bad this needs to be rewrite, | ||
38 | * but let's focus on plugins for now. | ||
39 | * | ||
40 | * @param string $query $_SERVER['QUERY_STRING']. | ||
41 | * @param array $get $_SERVER['GET']. | ||
42 | * @param bool $loggedIn true if authenticated user. | ||
43 | * | ||
44 | * @return self::page found. | ||
45 | */ | ||
46 | public static function findPage($query, $get, $loggedIn) | ||
47 | { | ||
48 | $loggedIn = ($loggedIn === true) ? true : false; | ||
49 | |||
50 | if (empty($query) && !isset($get['edit_link']) && !isset($get['post'])) { | ||
51 | return self::$PAGE_LINKLIST; | ||
52 | } | ||
53 | |||
54 | if (startswith($query, 'do='. self::$PAGE_LOGIN) && $loggedIn === false) { | ||
55 | return self::$PAGE_LOGIN; | ||
56 | } | ||
57 | |||
58 | if (startswith($query, 'do='. self::$PAGE_PICWALL)) { | ||
59 | return self::$PAGE_PICWALL; | ||
60 | } | ||
61 | |||
62 | if (startswith($query, 'do='. self::$PAGE_TAGCLOUD)) { | ||
63 | return self::$PAGE_TAGCLOUD; | ||
64 | } | ||
65 | |||
66 | // At this point, only loggedin pages. | ||
67 | if (!$loggedIn) { | ||
68 | return self::$PAGE_LINKLIST; | ||
69 | } | ||
70 | |||
71 | if (startswith($query, 'do='. self::$PAGE_TOOLS)) { | ||
72 | return self::$PAGE_TOOLS; | ||
73 | } | ||
74 | |||
75 | if (startswith($query, 'do='. self::$PAGE_CHANGEPASSWORD)) { | ||
76 | return self::$PAGE_CHANGEPASSWORD; | ||
77 | } | ||
78 | |||
79 | if (startswith($query, 'do='. self::$PAGE_CONFIGURE)) { | ||
80 | return self::$PAGE_CONFIGURE; | ||
81 | } | ||
82 | |||
83 | if (startswith($query, 'do='. self::$PAGE_CHANGETAG)) { | ||
84 | return self::$PAGE_CHANGETAG; | ||
85 | } | ||
86 | |||
87 | if (startswith($query, 'do='. self::$PAGE_ADDLINK)) { | ||
88 | return self::$PAGE_ADDLINK; | ||
89 | } | ||
90 | |||
91 | if (isset($get['edit_link']) || isset($get['post'])) { | ||
92 | return self::$PAGE_EDITLINK; | ||
93 | } | ||
94 | |||
95 | if (startswith($query, 'do='. self::$PAGE_EXPORT)) { | ||
96 | return self::$PAGE_EXPORT; | ||
97 | } | ||
98 | |||
99 | if (startswith($query, 'do='. self::$PAGE_IMPORT)) { | ||
100 | return self::$PAGE_IMPORT; | ||
101 | } | ||
102 | |||
103 | return self::$PAGE_LINKLIST; | ||
104 | } | ||
105 | } \ No newline at end of file | ||
@@ -45,9 +45,18 @@ $GLOBALS['config']['RAINTPL_TPL'] = 'tpl/' ; // Raintpl template directory (keep | |||
45 | $GLOBALS['config']['UPDATECHECK_FILENAME'] = $GLOBALS['config']['DATADIR'].'/lastupdatecheck.txt'; // For updates check of Shaarli. | 45 | $GLOBALS['config']['UPDATECHECK_FILENAME'] = $GLOBALS['config']['DATADIR'].'/lastupdatecheck.txt'; // For updates check of Shaarli. |
46 | $GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400 ; // Updates check frequency for Shaarli. 86400 seconds=24 hours | 46 | $GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400 ; // Updates check frequency for Shaarli. 86400 seconds=24 hours |
47 | // Note: You must have publisher.php in the same directory as Shaarli index.php | 47 | // Note: You must have publisher.php in the same directory as Shaarli index.php |
48 | $GLOBALS['config']['ARCHIVE_ORG'] = false; // For each link, add a link to an archived version on archive.org | ||
49 | $GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = true; // Enable RSS permalinks by default. This corresponds to the default behavior of shaarli before this was added as an option. | 48 | $GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = true; // Enable RSS permalinks by default. This corresponds to the default behavior of shaarli before this was added as an option. |
50 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = false; | 49 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = false; |
50 | //$GLOBALS['config']['ENABLED_PLUGINS'] = array( | ||
51 | // 'qrcode', 'archiveorg', 'readityourself', 'demo_plugin', 'playvideos', | ||
52 | // 'wallabag', 'markdown', 'addlink_toolbar', | ||
53 | //); | ||
54 | // Warning: order matters. | ||
55 | $GLOBALS['config']['ENABLED_PLUGINS'] = array('qrcode'); | ||
56 | |||
57 | // Default plugins, default config - will be overriden by config.php and then plugin's config.php file. | ||
58 | $GLOBALS['plugins']['READITYOUSELF_URL'] = 'http://someurl.com'; | ||
59 | $GLOBALS['plugins']['WALLABAG_URL'] = 'https://demo.wallabag.org/'; | ||
51 | // ----------------------------------------------------------------------------------------------- | 60 | // ----------------------------------------------------------------------------------------------- |
52 | define('shaarli_version', '0.5.4'); | 61 | define('shaarli_version', '0.5.4'); |
53 | // http://server.com/x/shaarli --> /shaarli/ | 62 | // http://server.com/x/shaarli --> /shaarli/ |
@@ -75,6 +84,8 @@ require_once 'application/TimeZone.php'; | |||
75 | require_once 'application/Url.php'; | 84 | require_once 'application/Url.php'; |
76 | require_once 'application/Utils.php'; | 85 | require_once 'application/Utils.php'; |
77 | require_once 'application/Config.php'; | 86 | require_once 'application/Config.php'; |
87 | require_once 'application/PluginManager.php'; | ||
88 | require_once 'application/Router.php'; | ||
78 | 89 | ||
79 | // Ensure the PHP version is supported | 90 | // Ensure the PHP version is supported |
80 | try { | 91 | try { |
@@ -119,6 +130,9 @@ include "inc/rain.tpl.class.php"; //include Rain TPL | |||
119 | raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory | 130 | raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory |
120 | raintpl::$cache_dir = $GLOBALS['config']['RAINTPL_TMP']; // cache directory | 131 | raintpl::$cache_dir = $GLOBALS['config']['RAINTPL_TMP']; // cache directory |
121 | 132 | ||
133 | $pluginManager = PluginManager::getInstance(); | ||
134 | $pluginManager->load($GLOBALS['config']['ENABLED_PLUGINS']); | ||
135 | |||
122 | ob_start(); // Output buffering for the page cache. | 136 | ob_start(); // Output buffering for the page cache. |
123 | 137 | ||
124 | 138 | ||
@@ -962,16 +976,31 @@ function showDaily() | |||
962 | $fill[$index]+=$length; | 976 | $fill[$index]+=$length; |
963 | } | 977 | } |
964 | $PAGE = new pageBuilder; | 978 | $PAGE = new pageBuilder; |
965 | $PAGE->assign('linksToDisplay',$linksToDisplay); | 979 | $data = array( |
966 | $PAGE->assign('linkcount',count($LINKSDB)); | 980 | 'linksToDisplay' => $linksToDisplay, |
967 | $PAGE->assign('cols', $columns); | 981 | 'linkcount' => count($LINKSDB), |
968 | $PAGE->assign('day',linkdate2timestamp($day.'_000000')); | 982 | 'cols' => $columns, |
969 | $PAGE->assign('previousday',$previousday); | 983 | 'day' => linkdate2timestamp($day.'_000000'), |
970 | $PAGE->assign('nextday',$nextday); | 984 | 'previousday' => $previousday, |
985 | 'nextday' => $nextday, | ||
986 | ); | ||
987 | $pluginManager = PluginManager::getInstance(); | ||
988 | $pluginManager->executeHooks('render_daily', $data, array('loggedin' => isLoggedIn())); | ||
989 | |||
990 | foreach ($data as $key => $value) { | ||
991 | $PAGE->assign($key, $value); | ||
992 | } | ||
993 | |||
971 | $PAGE->renderPage('daily'); | 994 | $PAGE->renderPage('daily'); |
972 | exit; | 995 | exit; |
973 | } | 996 | } |
974 | 997 | ||
998 | // Renders the linklist | ||
999 | function showLinkList($PAGE, $LINKSDB) { | ||
1000 | buildLinkList($PAGE,$LINKSDB); // Compute list of links to display | ||
1001 | $PAGE->renderPage('linklist'); | ||
1002 | } | ||
1003 | |||
975 | 1004 | ||
976 | // ------------------------------------------------------------------------------------------ | 1005 | // ------------------------------------------------------------------------------------------ |
977 | // Render HTML page (according to URL parameters and user rights) | 1006 | // Render HTML page (according to URL parameters and user rights) |
@@ -983,12 +1012,36 @@ function renderPage() | |||
983 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'] | 1012 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'] |
984 | ); | 1013 | ); |
985 | 1014 | ||
1015 | $PAGE = new pageBuilder; | ||
1016 | |||
1017 | // Determine which page will be rendered. | ||
1018 | $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : ''; | ||
1019 | $targetPage = Router::findPage($query, $_GET, isLoggedIn()); | ||
1020 | |||
1021 | // Call plugin hooks for header, footer and includes, specifying which page will be rendered. | ||
1022 | // Then assign generated data to RainTPL. | ||
1023 | $common_hooks = array( | ||
1024 | 'header', | ||
1025 | 'footer', | ||
1026 | 'includes', | ||
1027 | ); | ||
1028 | $pluginManager = PluginManager::getInstance(); | ||
1029 | foreach($common_hooks as $name) { | ||
1030 | $plugin_data = array(); | ||
1031 | $pluginManager->executeHooks('render_' . $name, $plugin_data, | ||
1032 | array( | ||
1033 | 'target' => $targetPage, | ||
1034 | 'loggedin' => isLoggedIn() | ||
1035 | ) | ||
1036 | ); | ||
1037 | $PAGE->assign('plugins_' . $name, $plugin_data); | ||
1038 | } | ||
1039 | |||
986 | // -------- Display login form. | 1040 | // -------- Display login form. |
987 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=login')) | 1041 | if ($targetPage == Router::$PAGE_LOGIN) |
988 | { | 1042 | { |
989 | if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli | 1043 | if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli |
990 | $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful. | 1044 | $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful. |
991 | $PAGE = new pageBuilder; | ||
992 | $PAGE->assign('token',$token); | 1045 | $PAGE->assign('token',$token); |
993 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); | 1046 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); |
994 | $PAGE->renderPage('loginform'); | 1047 | $PAGE->renderPage('loginform'); |
@@ -1004,7 +1057,7 @@ function renderPage() | |||
1004 | } | 1057 | } |
1005 | 1058 | ||
1006 | // -------- Picture wall | 1059 | // -------- Picture wall |
1007 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=picwall')) | 1060 | if ($targetPage == Router::$PAGE_PICWALL) |
1008 | { | 1061 | { |
1009 | // Optionally filter the results: | 1062 | // Optionally filter the results: |
1010 | $links=array(); | 1063 | $links=array(); |
@@ -1027,15 +1080,22 @@ function renderPage() | |||
1027 | } | 1080 | } |
1028 | } | 1081 | } |
1029 | 1082 | ||
1030 | $PAGE = new pageBuilder; | 1083 | $data = array( |
1031 | $PAGE->assign('linkcount',count($LINKSDB)); | 1084 | 'linkcount' => count($LINKSDB), |
1032 | $PAGE->assign('linksToDisplay',$linksToDisplay); | 1085 | 'linksToDisplay' => $linksToDisplay, |
1086 | ); | ||
1087 | $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); | ||
1088 | |||
1089 | foreach ($data as $key => $value) { | ||
1090 | $PAGE->assign($key, $value); | ||
1091 | } | ||
1092 | |||
1033 | $PAGE->renderPage('picwall'); | 1093 | $PAGE->renderPage('picwall'); |
1034 | exit; | 1094 | exit; |
1035 | } | 1095 | } |
1036 | 1096 | ||
1037 | // -------- Tag cloud | 1097 | // -------- Tag cloud |
1038 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=tagcloud')) | 1098 | if ($targetPage == Router::$PAGE_TAGCLOUD) |
1039 | { | 1099 | { |
1040 | $tags= $LINKSDB->allTags(); | 1100 | $tags= $LINKSDB->allTags(); |
1041 | 1101 | ||
@@ -1049,9 +1109,17 @@ function renderPage() | |||
1049 | { | 1109 | { |
1050 | $tagList[$key] = array('count'=>$value,'size'=>log($value, 15) / log($maxcount, 30) * (22-6) + 6); | 1110 | $tagList[$key] = array('count'=>$value,'size'=>log($value, 15) / log($maxcount, 30) * (22-6) + 6); |
1051 | } | 1111 | } |
1052 | $PAGE = new pageBuilder; | 1112 | |
1053 | $PAGE->assign('linkcount',count($LINKSDB)); | 1113 | $data = array( |
1054 | $PAGE->assign('tags',$tagList); | 1114 | 'linkcount' => count($LINKSDB), |
1115 | 'tags' => $tagList, | ||
1116 | ); | ||
1117 | $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); | ||
1118 | |||
1119 | foreach ($data as $key => $value) { | ||
1120 | $PAGE->assign($key, $value); | ||
1121 | } | ||
1122 | |||
1055 | $PAGE->renderPage('tagcloud'); | 1123 | $PAGE->renderPage('tagcloud'); |
1056 | exit; | 1124 | exit; |
1057 | } | 1125 | } |
@@ -1164,32 +1232,36 @@ function renderPage() | |||
1164 | header('Location: ?do=login&post='); | 1232 | header('Location: ?do=login&post='); |
1165 | exit; | 1233 | exit; |
1166 | } | 1234 | } |
1167 | 1235 | showLinkList($PAGE, $LINKSDB); | |
1168 | if (isset($_GET['edit_link'])) { | 1236 | if (isset($_GET['edit_link'])) { |
1169 | header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); | 1237 | header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); |
1170 | exit; | 1238 | exit; |
1171 | } | 1239 | } |
1172 | 1240 | ||
1173 | $PAGE = new pageBuilder; | ||
1174 | buildLinkList($PAGE,$LINKSDB); // Compute list of links to display | ||
1175 | $PAGE->renderPage('linklist'); | ||
1176 | exit; // Never remove this one! All operations below are reserved for logged in user. | 1241 | exit; // Never remove this one! All operations below are reserved for logged in user. |
1177 | } | 1242 | } |
1178 | 1243 | ||
1179 | // -------- All other functions are reserved for the registered user: | 1244 | // -------- All other functions are reserved for the registered user: |
1180 | 1245 | ||
1181 | // -------- Display the Tools menu if requested (import/export/bookmarklet...) | 1246 | // -------- Display the Tools menu if requested (import/export/bookmarklet...) |
1182 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=tools')) | 1247 | if ($targetPage == Router::$PAGE_TOOLS) |
1183 | { | 1248 | { |
1184 | $PAGE = new pageBuilder; | 1249 | $data = array( |
1185 | $PAGE->assign('linkcount',count($LINKSDB)); | 1250 | 'linkcount' => count($LINKSDB), |
1186 | $PAGE->assign('pageabsaddr',index_url($_SERVER)); | 1251 | 'pageabsaddr' => index_url($_SERVER), |
1252 | ); | ||
1253 | $pluginManager->executeHooks('render_tools', $data); | ||
1254 | |||
1255 | foreach ($data as $key => $value) { | ||
1256 | $PAGE->assign($key, $value); | ||
1257 | } | ||
1258 | |||
1187 | $PAGE->renderPage('tools'); | 1259 | $PAGE->renderPage('tools'); |
1188 | exit; | 1260 | exit; |
1189 | } | 1261 | } |
1190 | 1262 | ||
1191 | // -------- User wants to change his/her password. | 1263 | // -------- User wants to change his/her password. |
1192 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=changepasswd')) | 1264 | if ($targetPage == Router::$PAGE_CHANGEPASSWORD) |
1193 | { | 1265 | { |
1194 | if ($GLOBALS['config']['OPEN_SHAARLI']) die('You are not supposed to change a password on an Open Shaarli.'); | 1266 | if ($GLOBALS['config']['OPEN_SHAARLI']) die('You are not supposed to change a password on an Open Shaarli.'); |
1195 | if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) | 1267 | if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) |
@@ -1220,7 +1292,6 @@ function renderPage() | |||
1220 | } | 1292 | } |
1221 | else // show the change password form. | 1293 | else // show the change password form. |
1222 | { | 1294 | { |
1223 | $PAGE = new pageBuilder; | ||
1224 | $PAGE->assign('linkcount',count($LINKSDB)); | 1295 | $PAGE->assign('linkcount',count($LINKSDB)); |
1225 | $PAGE->assign('token',getToken()); | 1296 | $PAGE->assign('token',getToken()); |
1226 | $PAGE->renderPage('changepassword'); | 1297 | $PAGE->renderPage('changepassword'); |
@@ -1229,7 +1300,7 @@ function renderPage() | |||
1229 | } | 1300 | } |
1230 | 1301 | ||
1231 | // -------- User wants to change configuration | 1302 | // -------- User wants to change configuration |
1232 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=configure')) | 1303 | if ($targetPage == Router::$PAGE_CONFIGURE) |
1233 | { | 1304 | { |
1234 | if (!empty($_POST['title']) ) | 1305 | if (!empty($_POST['title']) ) |
1235 | { | 1306 | { |
@@ -1265,7 +1336,6 @@ function renderPage() | |||
1265 | } | 1336 | } |
1266 | else // Show the configuration form. | 1337 | else // Show the configuration form. |
1267 | { | 1338 | { |
1268 | $PAGE = new pageBuilder; | ||
1269 | $PAGE->assign('linkcount',count($LINKSDB)); | 1339 | $PAGE->assign('linkcount',count($LINKSDB)); |
1270 | $PAGE->assign('token',getToken()); | 1340 | $PAGE->assign('token',getToken()); |
1271 | $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); | 1341 | $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); |
@@ -1279,11 +1349,10 @@ function renderPage() | |||
1279 | } | 1349 | } |
1280 | 1350 | ||
1281 | // -------- User wants to rename a tag or delete it | 1351 | // -------- User wants to rename a tag or delete it |
1282 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=changetag')) | 1352 | if ($targetPage == Router::$PAGE_CHANGETAG) |
1283 | { | 1353 | { |
1284 | if (empty($_POST['fromtag'])) | 1354 | if (empty($_POST['fromtag'])) |
1285 | { | 1355 | { |
1286 | $PAGE = new pageBuilder; | ||
1287 | $PAGE->assign('linkcount',count($LINKSDB)); | 1356 | $PAGE->assign('linkcount',count($LINKSDB)); |
1288 | $PAGE->assign('token',getToken()); | 1357 | $PAGE->assign('token',getToken()); |
1289 | $PAGE->assign('tags', $LINKSDB->allTags()); | 1358 | $PAGE->assign('tags', $LINKSDB->allTags()); |
@@ -1328,9 +1397,8 @@ function renderPage() | |||
1328 | } | 1397 | } |
1329 | 1398 | ||
1330 | // -------- User wants to add a link without using the bookmarklet: Show form. | 1399 | // -------- User wants to add a link without using the bookmarklet: Show form. |
1331 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=addlink')) | 1400 | if ($targetPage == Router::$PAGE_ADDLINK) |
1332 | { | 1401 | { |
1333 | $PAGE = new pageBuilder; | ||
1334 | $PAGE->assign('linkcount',count($LINKSDB)); | 1402 | $PAGE->assign('linkcount',count($LINKSDB)); |
1335 | $PAGE->renderPage('addlink'); | 1403 | $PAGE->renderPage('addlink'); |
1336 | exit; | 1404 | exit; |
@@ -1349,6 +1417,9 @@ function renderPage() | |||
1349 | $link = array('title'=>trim($_POST['lf_title']),'url'=>$url,'description'=>trim($_POST['lf_description']),'private'=>(isset($_POST['lf_private']) ? 1 : 0), | 1417 | $link = array('title'=>trim($_POST['lf_title']),'url'=>$url,'description'=>trim($_POST['lf_description']),'private'=>(isset($_POST['lf_private']) ? 1 : 0), |
1350 | 'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags)); | 1418 | 'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags)); |
1351 | if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. | 1419 | if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. |
1420 | |||
1421 | $pluginManager->executeHooks('save_link', $link); | ||
1422 | |||
1352 | $LINKSDB[$linkdate] = $link; | 1423 | $LINKSDB[$linkdate] = $link; |
1353 | $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. | 1424 | $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. |
1354 | pubsubhub(); | 1425 | pubsubhub(); |
@@ -1382,6 +1453,9 @@ function renderPage() | |||
1382 | // - confirmation is handled by JavaScript | 1453 | // - confirmation is handled by JavaScript |
1383 | // - we are protected from XSRF by the token. | 1454 | // - we are protected from XSRF by the token. |
1384 | $linkdate=$_POST['lf_linkdate']; | 1455 | $linkdate=$_POST['lf_linkdate']; |
1456 | |||
1457 | $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); | ||
1458 | |||
1385 | unset($LINKSDB[$linkdate]); | 1459 | unset($LINKSDB[$linkdate]); |
1386 | $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk | 1460 | $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk |
1387 | 1461 | ||
@@ -1423,13 +1497,20 @@ function renderPage() | |||
1423 | { | 1497 | { |
1424 | $link = $LINKSDB[$_GET['edit_link']]; // Read database | 1498 | $link = $LINKSDB[$_GET['edit_link']]; // Read database |
1425 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. | 1499 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. |
1426 | $PAGE = new pageBuilder; | 1500 | $data = array( |
1427 | $PAGE->assign('linkcount',count($LINKSDB)); | 1501 | 'linkcount' => count($LINKSDB), |
1428 | $PAGE->assign('link',$link); | 1502 | 'link' => $link, |
1429 | $PAGE->assign('link_is_new',false); | 1503 | 'link_is_new' => false, |
1430 | $PAGE->assign('token',getToken()); // XSRF protection. | 1504 | 'token' => getToken(), |
1431 | $PAGE->assign('http_referer',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '')); | 1505 | 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), |
1432 | $PAGE->assign('tags', $LINKSDB->allTags()); | 1506 | 'tags' => $LINKSDB->allTags(), |
1507 | ); | ||
1508 | $pluginManager->executeHooks('render_editlink', $data); | ||
1509 | |||
1510 | foreach ($data as $key => $value) { | ||
1511 | $PAGE->assign($key, $value); | ||
1512 | } | ||
1513 | |||
1433 | $PAGE->renderPage('editlink'); | 1514 | $PAGE->renderPage('editlink'); |
1434 | exit; | 1515 | exit; |
1435 | } | 1516 | } |
@@ -1493,24 +1574,30 @@ function renderPage() | |||
1493 | ); | 1574 | ); |
1494 | } | 1575 | } |
1495 | 1576 | ||
1496 | $PAGE = new pageBuilder; | 1577 | $data = array( |
1497 | $PAGE->assign('linkcount',count($LINKSDB)); | 1578 | 'linkcount' => count($LINKSDB), |
1498 | $PAGE->assign('link',$link); | 1579 | 'link' => $link, |
1499 | $PAGE->assign('link_is_new',$link_is_new); | 1580 | 'link_is_new' => $link_is_new, |
1500 | $PAGE->assign('token',getToken()); // XSRF protection. | 1581 | 'token' => getToken(), // XSRF protection. |
1501 | $PAGE->assign('http_referer',(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '')); | 1582 | 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), |
1502 | $PAGE->assign('source',(isset($_GET['source']) ? $_GET['source'] : '')); | 1583 | 'source' => (isset($_GET['source']) ? $_GET['source'] : ''), |
1503 | $PAGE->assign('tags', $LINKSDB->allTags()); | 1584 | 'tags' => $LINKSDB->allTags(), |
1585 | ); | ||
1586 | $pluginManager->executeHooks('render_editlink', $data); | ||
1587 | |||
1588 | foreach ($data as $key => $value) { | ||
1589 | $PAGE->assign($key, $value); | ||
1590 | } | ||
1591 | |||
1504 | $PAGE->renderPage('editlink'); | 1592 | $PAGE->renderPage('editlink'); |
1505 | exit; | 1593 | exit; |
1506 | } | 1594 | } |
1507 | 1595 | ||
1508 | // -------- Export as Netscape Bookmarks HTML file. | 1596 | // -------- Export as Netscape Bookmarks HTML file. |
1509 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=export')) | 1597 | if ($targetPage == Router::$PAGE_EXPORT) |
1510 | { | 1598 | { |
1511 | if (empty($_GET['what'])) | 1599 | if (empty($_GET['what'])) |
1512 | { | 1600 | { |
1513 | $PAGE = new pageBuilder; | ||
1514 | $PAGE->assign('linkcount',count($LINKSDB)); | 1601 | $PAGE->assign('linkcount',count($LINKSDB)); |
1515 | $PAGE->renderPage('export'); | 1602 | $PAGE->renderPage('export'); |
1516 | exit; | 1603 | exit; |
@@ -1562,9 +1649,8 @@ HTML; | |||
1562 | } | 1649 | } |
1563 | 1650 | ||
1564 | // -------- Show upload/import dialog: | 1651 | // -------- Show upload/import dialog: |
1565 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=import')) | 1652 | if ($targetPage == Router::$PAGE_IMPORT) |
1566 | { | 1653 | { |
1567 | $PAGE = new pageBuilder; | ||
1568 | $PAGE->assign('linkcount',count($LINKSDB)); | 1654 | $PAGE->assign('linkcount',count($LINKSDB)); |
1569 | $PAGE->assign('token',getToken()); | 1655 | $PAGE->assign('token',getToken()); |
1570 | $PAGE->assign('maxfilesize',getMaxFileSize()); | 1656 | $PAGE->assign('maxfilesize',getMaxFileSize()); |
@@ -1573,9 +1659,7 @@ HTML; | |||
1573 | } | 1659 | } |
1574 | 1660 | ||
1575 | // -------- Otherwise, simply display search form and links: | 1661 | // -------- Otherwise, simply display search form and links: |
1576 | $PAGE = new pageBuilder; | 1662 | showLinkList($PAGE, $LINKSDB); |
1577 | buildLinkList($PAGE,$LINKSDB); // Compute list of links to display | ||
1578 | $PAGE->renderPage('linklist'); | ||
1579 | exit; | 1663 | exit; |
1580 | } | 1664 | } |
1581 | 1665 | ||
@@ -1746,7 +1830,7 @@ function buildLinkList($PAGE,$LINKSDB) | |||
1746 | $taglist = explode(' ',$link['tags']); | 1830 | $taglist = explode(' ',$link['tags']); |
1747 | uasort($taglist, 'strcasecmp'); | 1831 | uasort($taglist, 'strcasecmp'); |
1748 | $link['taglist']=$taglist; | 1832 | $link['taglist']=$taglist; |
1749 | 1833 | $link['shorturl'] = smallHash($link['linkdate']); | |
1750 | if ($link["url"][0] === '?' && // Check for both signs of a note: starting with ? and 7 chars long. I doubt that you'll post any links that look like this. | 1834 | if ($link["url"][0] === '?' && // Check for both signs of a note: starting with ? and 7 chars long. I doubt that you'll post any links that look like this. |
1751 | strlen($link["url"]) === 7) { | 1835 | strlen($link["url"]) === 7) { |
1752 | $link["url"] = index_url($_SERVER) . $link["url"]; | 1836 | $link["url"] = index_url($_SERVER) . $link["url"]; |
@@ -1766,18 +1850,28 @@ function buildLinkList($PAGE,$LINKSDB) | |||
1766 | $token = ''; if (isLoggedIn()) $token=getToken(); | 1850 | $token = ''; if (isLoggedIn()) $token=getToken(); |
1767 | 1851 | ||
1768 | // Fill all template fields. | 1852 | // Fill all template fields. |
1769 | $PAGE->assign('linkcount',count($LINKSDB)); | 1853 | $data = array( |
1770 | $PAGE->assign('previous_page_url',$previous_page_url); | 1854 | 'linkcount' => count($LINKSDB), |
1771 | $PAGE->assign('next_page_url',$next_page_url); | 1855 | 'previous_page_url' => $previous_page_url, |
1772 | $PAGE->assign('page_current',$page); | 1856 | 'next_page_url' => $next_page_url, |
1773 | $PAGE->assign('page_max',$pagecount); | 1857 | 'page_current' => $page, |
1774 | $PAGE->assign('result_count',count($linksToDisplay)); | 1858 | 'page_max' => $pagecount, |
1775 | $PAGE->assign('search_type',$search_type); | 1859 | 'result_count' => count($linksToDisplay), |
1776 | $PAGE->assign('search_crits',$search_crits); | 1860 | 'search_type' => $search_type, |
1777 | $PAGE->assign('redirector',empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']); // Optional redirector URL. | 1861 | 'search_crits' => $search_crits, |
1778 | $PAGE->assign('token',$token); | 1862 | 'redirector' => empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'], // Optional redirector URL. |
1779 | $PAGE->assign('links',$linkDisp); | 1863 | 'token' => $token, |
1780 | $PAGE->assign('tags', $LINKSDB->allTags()); | 1864 | 'links' => $linkDisp, |
1865 | 'tags' => $LINKSDB->allTags(), | ||
1866 | ); | ||
1867 | |||
1868 | $pluginManager = PluginManager::getInstance(); | ||
1869 | $pluginManager->executeHooks('render_linklist', $data, array('loggedin' => isLoggedIn())); | ||
1870 | |||
1871 | foreach ($data as $key => $value) { | ||
1872 | $PAGE->assign($key, $value); | ||
1873 | } | ||
1874 | |||
1781 | return; | 1875 | return; |
1782 | } | 1876 | } |
1783 | 1877 | ||
diff --git a/tests/PluginManagerTest.php b/tests/PluginManagerTest.php new file mode 100755 index 00000000..749ce2b5 --- /dev/null +++ b/tests/PluginManagerTest.php | |||
@@ -0,0 +1,66 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Plugin Manager tests | ||
5 | */ | ||
6 | |||
7 | require_once 'application/PluginManager.php'; | ||
8 | |||
9 | /** | ||
10 | * Unit tests for Plugins | ||
11 | */ | ||
12 | class PluginManagerTest extends PHPUnit_Framework_TestCase | ||
13 | { | ||
14 | /** | ||
15 | * Path to tests plugin. | ||
16 | * @var string $_PLUGIN_PATH | ||
17 | */ | ||
18 | private static $_PLUGIN_PATH = 'tests/plugins'; | ||
19 | |||
20 | /** | ||
21 | * Test plugin. | ||
22 | * @var string $_PLUGIN_NAME | ||
23 | */ | ||
24 | private static $_PLUGIN_NAME = 'test'; | ||
25 | |||
26 | /** | ||
27 | * Test plugin loading and hook execution. | ||
28 | * | ||
29 | * @return void | ||
30 | */ | ||
31 | public function testPlugin() | ||
32 | { | ||
33 | $pluginManager = PluginManager::getInstance(); | ||
34 | |||
35 | PluginManager::$PLUGINS_PATH = self::$_PLUGIN_PATH; | ||
36 | $pluginManager->load(array(self::$_PLUGIN_NAME)); | ||
37 | |||
38 | $this->assertTrue(function_exists('hook_test_random')); | ||
39 | |||
40 | $data = array(0 => 'woot'); | ||
41 | $pluginManager->executeHooks('random', $data); | ||
42 | $this->assertEquals('woot', $data[1]); | ||
43 | |||
44 | $data = array(0 => 'woot'); | ||
45 | $pluginManager->executeHooks('random', $data, array('target' => 'test')); | ||
46 | $this->assertEquals('page test', $data[1]); | ||
47 | |||
48 | $data = array(0 => 'woot'); | ||
49 | $pluginManager->executeHooks('random', $data, array('loggedin' => true)); | ||
50 | $this->assertEquals('loggedin', $data[1]); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Test missing plugin loading. | ||
55 | * | ||
56 | * @return void | ||
57 | */ | ||
58 | public function testPluginNotFound() | ||
59 | { | ||
60 | $pluginManager = PluginManager::getInstance(); | ||
61 | |||
62 | $pluginManager->load(array()); | ||
63 | |||
64 | $pluginManager->load(array('nope', 'renope')); | ||
65 | } | ||
66 | } \ No newline at end of file | ||
diff --git a/tests/RouterTest.php b/tests/RouterTest.php new file mode 100755 index 00000000..8838bc8d --- /dev/null +++ b/tests/RouterTest.php | |||
@@ -0,0 +1,515 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Router tests | ||
5 | */ | ||
6 | |||
7 | require_once 'application/Router.php'; | ||
8 | |||
9 | /** | ||
10 | * Unit tests for Router | ||
11 | */ | ||
12 | class RouterTest extends PHPUnit_Framework_TestCase | ||
13 | { | ||
14 | /** | ||
15 | * Test findPage: login page output. | ||
16 | * Valid: page should be return. | ||
17 | * | ||
18 | * @return void | ||
19 | */ | ||
20 | public function testFindPageLoginValid() | ||
21 | { | ||
22 | $this->assertEquals( | ||
23 | Router::$PAGE_LOGIN, | ||
24 | Router::findPage('do=login', array(), false) | ||
25 | ); | ||
26 | |||
27 | $this->assertEquals( | ||
28 | Router::$PAGE_LOGIN, | ||
29 | Router::findPage('do=login', array(), 1) | ||
30 | ); | ||
31 | |||
32 | $this->assertEquals( | ||
33 | Router::$PAGE_LOGIN, | ||
34 | Router::findPage('do=login&stuff', array(), false) | ||
35 | ); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * Test findPage: login page output. | ||
40 | * Invalid: page shouldn't be return. | ||
41 | * | ||
42 | * @return void | ||
43 | */ | ||
44 | public function testFindPageLoginInvalid() | ||
45 | { | ||
46 | $this->assertNotEquals( | ||
47 | Router::$PAGE_LOGIN, | ||
48 | Router::findPage('do=login', array(), true) | ||
49 | ); | ||
50 | |||
51 | $this->assertNotEquals( | ||
52 | Router::$PAGE_LOGIN, | ||
53 | Router::findPage('do=other', array(), false) | ||
54 | ); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Test findPage: picwall page output. | ||
59 | * Valid: page should be return. | ||
60 | * | ||
61 | * @return void | ||
62 | */ | ||
63 | public function testFindPagePicwallValid() | ||
64 | { | ||
65 | $this->assertEquals( | ||
66 | Router::$PAGE_PICWALL, | ||
67 | Router::findPage('do=picwall', array(), false) | ||
68 | ); | ||
69 | |||
70 | $this->assertEquals( | ||
71 | Router::$PAGE_PICWALL, | ||
72 | Router::findPage('do=picwall', array(), true) | ||
73 | ); | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Test findPage: picwall page output. | ||
78 | * Invalid: page shouldn't be return. | ||
79 | * | ||
80 | * @return void | ||
81 | */ | ||
82 | public function testFindPagePicwallInvalid() | ||
83 | { | ||
84 | $this->assertEquals( | ||
85 | Router::$PAGE_PICWALL, | ||
86 | Router::findPage('do=picwall&stuff', array(), false) | ||
87 | ); | ||
88 | |||
89 | $this->assertNotEquals( | ||
90 | Router::$PAGE_PICWALL, | ||
91 | Router::findPage('do=other', array(), false) | ||
92 | ); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Test findPage: tagcloud page output. | ||
97 | * Valid: page should be return. | ||
98 | * | ||
99 | * @return void | ||
100 | */ | ||
101 | public function testFindPageTagcloudValid() | ||
102 | { | ||
103 | $this->assertEquals( | ||
104 | Router::$PAGE_TAGCLOUD, | ||
105 | Router::findPage('do=tagcloud', array(), false) | ||
106 | ); | ||
107 | |||
108 | $this->assertEquals( | ||
109 | Router::$PAGE_TAGCLOUD, | ||
110 | Router::findPage('do=tagcloud', array(), true) | ||
111 | ); | ||
112 | |||
113 | $this->assertEquals( | ||
114 | Router::$PAGE_TAGCLOUD, | ||
115 | Router::findPage('do=tagcloud&stuff', array(), false) | ||
116 | ); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Test findPage: tagcloud page output. | ||
121 | * Invalid: page shouldn't be return. | ||
122 | * | ||
123 | * @return void | ||
124 | */ | ||
125 | public function testFindPageTagcloudInvalid() | ||
126 | { | ||
127 | $this->assertNotEquals( | ||
128 | Router::$PAGE_TAGCLOUD, | ||
129 | Router::findPage('do=other', array(), false) | ||
130 | ); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * Test findPage: linklist page output. | ||
135 | * Valid: page should be return. | ||
136 | * | ||
137 | * @return void | ||
138 | */ | ||
139 | public function testFindPageLinklistValid() | ||
140 | { | ||
141 | $this->assertEquals( | ||
142 | Router::$PAGE_LINKLIST, | ||
143 | Router::findPage('', array(), true) | ||
144 | ); | ||
145 | |||
146 | $this->assertEquals( | ||
147 | Router::$PAGE_LINKLIST, | ||
148 | Router::findPage('whatever', array(), true) | ||
149 | ); | ||
150 | |||
151 | $this->assertEquals( | ||
152 | Router::$PAGE_LINKLIST, | ||
153 | Router::findPage('whatever', array(), false) | ||
154 | ); | ||
155 | |||
156 | $this->assertEquals( | ||
157 | Router::$PAGE_LINKLIST, | ||
158 | Router::findPage('do=tools', array(), false) | ||
159 | ); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * Test findPage: tools page output. | ||
164 | * Valid: page should be return. | ||
165 | * | ||
166 | * @return void | ||
167 | */ | ||
168 | public function testFindPageToolsValid() | ||
169 | { | ||
170 | $this->assertEquals( | ||
171 | Router::$PAGE_TOOLS, | ||
172 | Router::findPage('do=tools', array(), true) | ||
173 | ); | ||
174 | |||
175 | $this->assertEquals( | ||
176 | Router::$PAGE_TOOLS, | ||
177 | Router::findPage('do=tools&stuff', array(), true) | ||
178 | ); | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * Test findPage: tools page output. | ||
183 | * Invalid: page shouldn't be return. | ||
184 | * | ||
185 | * @return void | ||
186 | */ | ||
187 | public function testFindPageToolsInvalid() | ||
188 | { | ||
189 | $this->assertNotEquals( | ||
190 | Router::$PAGE_TOOLS, | ||
191 | Router::findPage('do=tools', array(), 1) | ||
192 | ); | ||
193 | |||
194 | $this->assertNotEquals( | ||
195 | Router::$PAGE_TOOLS, | ||
196 | Router::findPage('do=tools', array(), false) | ||
197 | ); | ||
198 | |||
199 | $this->assertNotEquals( | ||
200 | Router::$PAGE_TOOLS, | ||
201 | Router::findPage('do=other', array(), true) | ||
202 | ); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * Test findPage: changepasswd page output. | ||
207 | * Valid: page should be return. | ||
208 | * | ||
209 | * @return void | ||
210 | */ | ||
211 | public function testFindPageChangepasswdValid() | ||
212 | { | ||
213 | $this->assertEquals( | ||
214 | Router::$PAGE_CHANGEPASSWORD, | ||
215 | Router::findPage('do=changepasswd', array(), true) | ||
216 | ); | ||
217 | $this->assertEquals( | ||
218 | Router::$PAGE_CHANGEPASSWORD, | ||
219 | Router::findPage('do=changepasswd&stuff', array(), true) | ||
220 | ); | ||
221 | |||
222 | } | ||
223 | |||
224 | /** | ||
225 | * Test findPage: changepasswd page output. | ||
226 | * Invalid: page shouldn't be return. | ||
227 | * | ||
228 | * @return void | ||
229 | */ | ||
230 | public function testFindPageChangepasswdInvalid() | ||
231 | { | ||
232 | $this->assertNotEquals( | ||
233 | Router::$PAGE_CHANGEPASSWORD, | ||
234 | Router::findPage('do=changepasswd', array(), 1) | ||
235 | ); | ||
236 | |||
237 | $this->assertNotEquals( | ||
238 | Router::$PAGE_CHANGEPASSWORD, | ||
239 | Router::findPage('do=changepasswd', array(), false) | ||
240 | ); | ||
241 | |||
242 | $this->assertNotEquals( | ||
243 | Router::$PAGE_CHANGEPASSWORD, | ||
244 | Router::findPage('do=other', array(), true) | ||
245 | ); | ||
246 | } | ||
247 | /** | ||
248 | * Test findPage: configure page output. | ||
249 | * Valid: page should be return. | ||
250 | * | ||
251 | * @return void | ||
252 | */ | ||
253 | public function testFindPageConfigureValid() | ||
254 | { | ||
255 | $this->assertEquals( | ||
256 | Router::$PAGE_CONFIGURE, | ||
257 | Router::findPage('do=configure', array(), true) | ||
258 | ); | ||
259 | |||
260 | $this->assertEquals( | ||
261 | Router::$PAGE_CONFIGURE, | ||
262 | Router::findPage('do=configure&stuff', array(), true) | ||
263 | ); | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * Test findPage: configure page output. | ||
268 | * Invalid: page shouldn't be return. | ||
269 | * | ||
270 | * @return void | ||
271 | */ | ||
272 | public function testFindPageConfigureInvalid() | ||
273 | { | ||
274 | $this->assertNotEquals( | ||
275 | Router::$PAGE_CONFIGURE, | ||
276 | Router::findPage('do=configure', array(), 1) | ||
277 | ); | ||
278 | |||
279 | $this->assertNotEquals( | ||
280 | Router::$PAGE_CONFIGURE, | ||
281 | Router::findPage('do=configure', array(), false) | ||
282 | ); | ||
283 | |||
284 | $this->assertNotEquals( | ||
285 | Router::$PAGE_CONFIGURE, | ||
286 | Router::findPage('do=other', array(), true) | ||
287 | ); | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * Test findPage: changetag page output. | ||
292 | * Valid: page should be return. | ||
293 | * | ||
294 | * @return void | ||
295 | */ | ||
296 | public function testFindPageChangetagValid() | ||
297 | { | ||
298 | $this->assertEquals( | ||
299 | Router::$PAGE_CHANGETAG, | ||
300 | Router::findPage('do=changetag', array(), true) | ||
301 | ); | ||
302 | |||
303 | $this->assertEquals( | ||
304 | Router::$PAGE_CHANGETAG, | ||
305 | Router::findPage('do=changetag&stuff', array(), true) | ||
306 | ); | ||
307 | } | ||
308 | |||
309 | /** | ||
310 | * Test findPage: changetag page output. | ||
311 | * Invalid: page shouldn't be return. | ||
312 | * | ||
313 | * @return void | ||
314 | */ | ||
315 | public function testFindPageChangetagInvalid() | ||
316 | { | ||
317 | $this->assertNotEquals( | ||
318 | Router::$PAGE_CHANGETAG, | ||
319 | Router::findPage('do=changetag', array(), 1) | ||
320 | ); | ||
321 | |||
322 | $this->assertNotEquals( | ||
323 | Router::$PAGE_CHANGETAG, | ||
324 | Router::findPage('do=changetag', array(), false) | ||
325 | ); | ||
326 | |||
327 | $this->assertNotEquals( | ||
328 | Router::$PAGE_CHANGETAG, | ||
329 | Router::findPage('do=other', array(), true) | ||
330 | ); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * Test findPage: addlink page output. | ||
335 | * Valid: page should be return. | ||
336 | * | ||
337 | * @return void | ||
338 | */ | ||
339 | public function testFindPageAddlinkValid() | ||
340 | { | ||
341 | $this->assertEquals( | ||
342 | Router::$PAGE_ADDLINK, | ||
343 | Router::findPage('do=addlink', array(), true) | ||
344 | ); | ||
345 | |||
346 | $this->assertEquals( | ||
347 | Router::$PAGE_ADDLINK, | ||
348 | Router::findPage('do=addlink&stuff', array(), true) | ||
349 | ); | ||
350 | } | ||
351 | |||
352 | /** | ||
353 | * Test findPage: addlink page output. | ||
354 | * Invalid: page shouldn't be return. | ||
355 | * | ||
356 | * @return void | ||
357 | */ | ||
358 | public function testFindPageAddlinkInvalid() | ||
359 | { | ||
360 | $this->assertNotEquals( | ||
361 | Router::$PAGE_ADDLINK, | ||
362 | Router::findPage('do=addlink', array(), 1) | ||
363 | ); | ||
364 | |||
365 | $this->assertNotEquals( | ||
366 | Router::$PAGE_ADDLINK, | ||
367 | Router::findPage('do=addlink', array(), false) | ||
368 | ); | ||
369 | |||
370 | $this->assertNotEquals( | ||
371 | Router::$PAGE_ADDLINK, | ||
372 | Router::findPage('do=other', array(), true) | ||
373 | ); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Test findPage: export page output. | ||
378 | * Valid: page should be return. | ||
379 | * | ||
380 | * @return void | ||
381 | */ | ||
382 | public function testFindPageExportValid() | ||
383 | { | ||
384 | $this->assertEquals( | ||
385 | Router::$PAGE_EXPORT, | ||
386 | Router::findPage('do=export', array(), true) | ||
387 | ); | ||
388 | |||
389 | $this->assertEquals( | ||
390 | Router::$PAGE_EXPORT, | ||
391 | Router::findPage('do=export&stuff', array(), true) | ||
392 | ); | ||
393 | } | ||
394 | |||
395 | /** | ||
396 | * Test findPage: export page output. | ||
397 | * Invalid: page shouldn't be return. | ||
398 | * | ||
399 | * @return void | ||
400 | */ | ||
401 | public function testFindPageExportInvalid() | ||
402 | { | ||
403 | $this->assertNotEquals( | ||
404 | Router::$PAGE_EXPORT, | ||
405 | Router::findPage('do=export', array(), 1) | ||
406 | ); | ||
407 | |||
408 | $this->assertNotEquals( | ||
409 | Router::$PAGE_EXPORT, | ||
410 | Router::findPage('do=export', array(), false) | ||
411 | ); | ||
412 | |||
413 | $this->assertNotEquals( | ||
414 | Router::$PAGE_EXPORT, | ||
415 | Router::findPage('do=other', array(), true) | ||
416 | ); | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * Test findPage: import page output. | ||
421 | * Valid: page should be return. | ||
422 | * | ||
423 | * @return void | ||
424 | */ | ||
425 | public function testFindPageImportValid() | ||
426 | { | ||
427 | $this->assertEquals( | ||
428 | Router::$PAGE_IMPORT, | ||
429 | Router::findPage('do=import', array(), true) | ||
430 | ); | ||
431 | |||
432 | $this->assertEquals( | ||
433 | Router::$PAGE_IMPORT, | ||
434 | Router::findPage('do=import&stuff', array(), true) | ||
435 | ); | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * Test findPage: import page output. | ||
440 | * Invalid: page shouldn't be return. | ||
441 | * | ||
442 | * @return void | ||
443 | */ | ||
444 | public function testFindPageImportInvalid() | ||
445 | { | ||
446 | $this->assertNotEquals( | ||
447 | Router::$PAGE_IMPORT, | ||
448 | Router::findPage('do=import', array(), 1) | ||
449 | ); | ||
450 | |||
451 | $this->assertNotEquals( | ||
452 | Router::$PAGE_IMPORT, | ||
453 | Router::findPage('do=import', array(), false) | ||
454 | ); | ||
455 | |||
456 | $this->assertNotEquals( | ||
457 | Router::$PAGE_IMPORT, | ||
458 | Router::findPage('do=other', array(), true) | ||
459 | ); | ||
460 | } | ||
461 | |||
462 | /** | ||
463 | * Test findPage: editlink page output. | ||
464 | * Valid: page should be return. | ||
465 | * | ||
466 | * @return void | ||
467 | */ | ||
468 | public function testFindPageEditlinkValid() | ||
469 | { | ||
470 | $this->assertEquals( | ||
471 | Router::$PAGE_EDITLINK, | ||
472 | Router::findPage('whatever', array('edit_link' => 1), true) | ||
473 | ); | ||
474 | |||
475 | $this->assertEquals( | ||
476 | Router::$PAGE_EDITLINK, | ||
477 | Router::findPage('', array('edit_link' => 1), true) | ||
478 | ); | ||
479 | |||
480 | |||
481 | $this->assertEquals( | ||
482 | Router::$PAGE_EDITLINK, | ||
483 | Router::findPage('whatever', array('post' => 1), true) | ||
484 | ); | ||
485 | |||
486 | $this->assertEquals( | ||
487 | Router::$PAGE_EDITLINK, | ||
488 | Router::findPage('whatever', array('post' => 1, 'edit_link' => 1), true) | ||
489 | ); | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * Test findPage: editlink page output. | ||
494 | * Invalid: page shouldn't be return. | ||
495 | * | ||
496 | * @return void | ||
497 | */ | ||
498 | public function testFindPageEditlinkInvalid() | ||
499 | { | ||
500 | $this->assertNotEquals( | ||
501 | Router::$PAGE_EDITLINK, | ||
502 | Router::findPage('whatever', array('edit_link' => 1), false) | ||
503 | ); | ||
504 | |||
505 | $this->assertNotEquals( | ||
506 | Router::$PAGE_EDITLINK, | ||
507 | Router::findPage('whatever', array('edit_link' => 1), 1) | ||
508 | ); | ||
509 | |||
510 | $this->assertNotEquals( | ||
511 | Router::$PAGE_EDITLINK, | ||
512 | Router::findPage('whatever', array(), true) | ||
513 | ); | ||
514 | } | ||
515 | } \ No newline at end of file | ||
diff --git a/tests/plugins/test/test.php b/tests/plugins/test/test.php new file mode 100755 index 00000000..3d750c90 --- /dev/null +++ b/tests/plugins/test/test.php | |||
@@ -0,0 +1,21 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * Hook for test. | ||
5 | * | ||
6 | * @param array $data - data passed to plugin. | ||
7 | * | ||
8 | * @return mixed altered data. | ||
9 | */ | ||
10 | function hook_test_random($data) | ||
11 | { | ||
12 | if (isset($data['_PAGE_']) && $data['_PAGE_'] == 'test') { | ||
13 | $data[1] = 'page test'; | ||
14 | } else if (isset($data['_LOGGEDIN_']) && $data['_LOGGEDIN_'] === true) { | ||
15 | $data[1] = 'loggedin'; | ||
16 | } else { | ||
17 | $data[1] = $data[0]; | ||
18 | } | ||
19 | |||
20 | return $data; | ||
21 | } | ||