PageRenderTime 52ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/admin-menu-editor/includes/shadow_plugin_framework.php

https://bitbucket.org/lgorence/quickpress
PHP | 341 lines | 170 code | 49 blank | 122 comment | 43 complexity | 2a01e32c1ce1692a07cf16a49013b7c7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-1.0
  1. <?php
  2. /**
  3. * @author W-Shadow
  4. * @copyright 2008-2011
  5. */
  6. //Load JSON functions for PHP < 5.2
  7. if ( !(function_exists('json_encode') && function_exists('json_decode')) && !(class_exists('Services_JSON') || class_exists('Moxiecode_JSON')) ){
  8. $class_json_path = ABSPATH.WPINC.'/class-json.php';
  9. $class_moxiecode_json_path = ABSPATH.WPINC.'/js/tinymce/plugins/spellchecker/classes/utils/JSON.php';
  10. if ( file_exists($class_json_path) ){
  11. require $class_json_path;
  12. } elseif ( file_exists($class_moxiecode_json_path) ) {
  13. require $class_moxiecode_json_path;
  14. }
  15. }
  16. class MenuEd_ShadowPluginFramework {
  17. public static $framework_version = '0.4.1';
  18. public $is_mu_plugin = null; //True if installed in the mu-plugins directory, false otherwise
  19. protected $options = array();
  20. public $option_name = ''; //should be set or overridden by the plugin
  21. protected $defaults = array(); //should be set or overridden by the plugin
  22. protected $sitewide_options = false; //WPMU only : save the setting in a site-wide option
  23. protected $serialize_with_json = false; //Use the JSON format for option storage
  24. public $plugin_file = ''; //Filename of the plugin.
  25. public $plugin_basename = ''; //Basename of the plugin, as returned by plugin_basename().
  26. public $plugin_dir_url = ''; //The URL of the plugin's folder
  27. protected $magic_hooks = false; //Automagically set up hooks for all methods named "hook_[hookname]" .
  28. protected $magic_hook_priority = 10; //Priority for magically set hooks.
  29. protected $settings_link = ''; //If set, this will be automatically added after "Deactivate"/"Edit".
  30. /**
  31. * Class constructor. Populates some internal fields, then calls the plugin's own
  32. * initializer (if any).
  33. *
  34. * @param string $plugin_file Plugin's filename. Usually you can just use __FILE__.
  35. * @param string $option_name
  36. */
  37. function __construct( $plugin_file = '', $option_name = null ){
  38. if ($plugin_file == ''){
  39. //Try to guess the name of the file that included this file.
  40. //Not implemented yet.
  41. }
  42. $this->option_name = $option_name;
  43. if ( is_null($this->is_mu_plugin) )
  44. $this->is_mu_plugin = $this->is_in_wpmu_plugin_dir($plugin_file);
  45. $this->plugin_file = $plugin_file;
  46. $this->plugin_basename = plugin_basename($this->plugin_file);
  47. $this->plugin_dir_url = rtrim(plugin_dir_url($this->plugin_file), '/');
  48. /************************************
  49. Add the default hooks
  50. ************************************/
  51. add_action('activate_'.$this->plugin_basename, array(&$this,'activate'));
  52. add_action('deactivate_'.$this->plugin_basename, array(&$this,'deactivate'));
  53. $this->init(); //Call the plugin's init() function
  54. $this->init_finish(); //Complete initialization by loading settings, etc
  55. }
  56. /**
  57. * Init the plugin. Should be overridden in a sub-class.
  58. * Called by the class constructor.
  59. *
  60. * @return void
  61. */
  62. function init(){
  63. //Do nothing.
  64. }
  65. /**
  66. * Initialize settings and set up magic hooks.
  67. *
  68. * @return void
  69. */
  70. function init_finish(){
  71. /************************************
  72. Load settings
  73. ************************************/
  74. //The provided $option_name overrides the default only if it is set to something useful
  75. if ( $this->option_name == '' ) {
  76. //Generate a unique name
  77. $this->option_name = 'plugin_'.md5($this->plugin_basename);
  78. }
  79. //Do we need to load the plugin's settings?
  80. if ($this->option_name != null){
  81. $this->load_options();
  82. }
  83. //Add a "Settings" action link
  84. if ($this->settings_link)
  85. add_filter('plugin_action_links', array(&$this, 'plugin_action_links'), 10, 2);
  86. if ($this->magic_hooks)
  87. $this->set_magic_hooks();
  88. }
  89. /**
  90. * Load the plugin's configuration.
  91. * Loads the specified option into $this->options, substituting defaults where necessary.
  92. *
  93. * @param string $option_name Optional. The slug of the option to load. If not set, the value of $this->option_name will be used instead.
  94. * @return boolean TRUE if options were loaded okay and FALSE otherwise.
  95. */
  96. function load_options($option_name = null){
  97. if ( empty($option_name) ){
  98. $option_name = $this->option_name;
  99. }
  100. if ( $this->sitewide_options ) {
  101. $this->options = get_site_option($option_name);
  102. } else {
  103. $this->options = get_option($option_name);
  104. }
  105. if ( $this->serialize_with_json || is_string($this->options) ){
  106. $this->options = $this->json_decode($this->options, true);
  107. }
  108. if(!is_array($this->options)){
  109. $this->options = $this->defaults;
  110. return false;
  111. } else {
  112. $this->options = array_merge($this->defaults, $this->options);
  113. return true;
  114. }
  115. }
  116. /**
  117. * ShadowPluginFramework::save_options()
  118. * Saves the $options array to the database.
  119. *
  120. * @return void
  121. */
  122. function save_options(){
  123. if ($this->option_name) {
  124. $stored_options = $this->options;
  125. if ( $this->serialize_with_json ){
  126. $stored_options = $this->json_encode($stored_options);
  127. }
  128. if ( $this->sitewide_options ) {
  129. update_site_option($this->option_name, $stored_options);
  130. } else {
  131. update_option($this->option_name, $stored_options);
  132. }
  133. }
  134. }
  135. /**
  136. * Backwards fompatible json_decode.
  137. *
  138. * @param string $data
  139. * @param bool $assoc Decode objects as associative arrays.
  140. * @return string
  141. */
  142. function json_decode($data, $assoc=false){
  143. if ( function_exists('json_decode') ){
  144. return json_decode($data, $assoc);
  145. }
  146. if ( class_exists('Services_JSON') ){
  147. $flag = $assoc?SERVICES_JSON_LOOSE_TYPE:0;
  148. $json = new Services_JSON($flag);
  149. return( $json->decode($data) );
  150. } elseif ( class_exists('Moxiecode_JSON') ){
  151. $json = new Moxiecode_JSON();
  152. return $json->decode($data);
  153. } else {
  154. trigger_error('No JSON parser available', E_USER_ERROR);
  155. }
  156. }
  157. /**
  158. * Backwards fompatible json_encode.
  159. *
  160. * @param mixed $data
  161. * @return string
  162. */
  163. function json_encode($data) {
  164. if ( function_exists('json_encode') ){
  165. return json_encode($data);
  166. }
  167. if ( class_exists('Services_JSON') ){
  168. $json = new Services_JSON();
  169. return( $json->encodeUnsafe($data) );
  170. } elseif ( class_exists('Moxiecode_JSON') ){
  171. $json = new Moxiecode_JSON();
  172. return $json->encode($data);
  173. } else {
  174. trigger_error('No JSON parser available', E_USER_ERROR);
  175. }
  176. }
  177. /**
  178. * ShadowPluginFramework::set_magic_hooks()
  179. * Automagically sets up hooks for all methods named "hook_[tag]". Uses the Reflection API.
  180. *
  181. * @return void
  182. */
  183. function set_magic_hooks(){
  184. $class = new ReflectionClass(get_class($this));
  185. $methods = $class->getMethods();
  186. foreach ($methods as $method){
  187. //Check if the method name starts with "hook_"
  188. if (strpos($method->name, 'hook_') === 0){
  189. //Get the hook's tag from the method name
  190. $hook = substr($method->name, 5);
  191. //Add the hook. Uses add_filter because add_action is simply a wrapper of the same.
  192. add_filter($hook, array(&$this, $method->name),
  193. $this->magic_hook_priority, $method->getNumberOfParameters());
  194. }
  195. }
  196. unset($class);
  197. }
  198. /**
  199. * ShadowPluginFramework::activate()
  200. * Stub function for the activation hook. Simply stores the default configuration.
  201. *
  202. * @return void
  203. */
  204. function activate(){
  205. $this->save_options();
  206. }
  207. /**
  208. * ShadowPluginFramework::deactivate()
  209. * Stub function for the deactivation hook. Does nothing.
  210. *
  211. * @return void
  212. */
  213. function deactivate(){
  214. }
  215. /**
  216. * ShadowPluginFramework::plugin_action_links()
  217. * Adds a "Settings" link to the plugin's action links. Default handler for the 'plugin_action_links' hook.
  218. *
  219. * @param array $links
  220. * @param string $file
  221. * @return array
  222. */
  223. function plugin_action_links($links, $file) {
  224. if ($file == $this->plugin_basename)
  225. $links[] = "<a href='" . $this->settings_link . "'>" . __('Settings') . "</a>";
  226. return $links;
  227. }
  228. /**
  229. * ShadowPluginFramework::uninstall()
  230. * Default uninstaller. Removes the plugins configuration record (if available).
  231. *
  232. * @return void
  233. */
  234. function uninstall(){
  235. if ($this->option_name)
  236. delete_option($this->option_name);
  237. }
  238. /**
  239. * Checks if the specified file is inside the mu-plugins directory.
  240. *
  241. * @param string $filename The filename to check. Leave blank to use the current plugin's filename.
  242. * @return bool
  243. */
  244. function is_in_wpmu_plugin_dir( $filename = '' ){
  245. if ( !defined('WPMU_PLUGIN_DIR') ) return false;
  246. if ( empty($filename) ){
  247. $filename = $this->plugin_file;
  248. }
  249. return (strpos( realpath($filename), realpath(WPMU_PLUGIN_DIR) ) !== false);
  250. }
  251. /**
  252. * Check if the plugin is active for the entire network.
  253. * Will return true when the plugin is installed in /mu-plugins/ (WPMU, pre-3.0)
  254. * or has been activated via "Network Activate" (WP 3.0+).
  255. *
  256. * Blame the ridiculous blog/site/network confusion perpetrated by
  257. * the WP API for the silly name.
  258. *
  259. * @return bool
  260. */
  261. function is_super_plugin(){
  262. if ( is_null($this->is_mu_plugin) ){
  263. $this->is_mu_plugin = $this->is_in_wpmu_plugin_dir($this->plugin_file);
  264. }
  265. if ( $this->is_mu_plugin ){
  266. return true;
  267. } else {
  268. return $this->is_plugin_active_for_network($this->plugin_basename);
  269. }
  270. }
  271. /**
  272. * Check whether the plugin is active for the entire network.
  273. *
  274. * Silly WP doesn't load the file that contains this native function until *after*
  275. * all plugins are loaded, so until then we use a copy-pasted version of the same.
  276. *
  277. * @param string $plugin
  278. * @return bool
  279. */
  280. function is_plugin_active_for_network( $plugin ) {
  281. if ( function_exists('is_plugin_active_for_network') ){
  282. return is_plugin_active_for_network($plugin);
  283. }
  284. if ( !is_multisite() )
  285. return false;
  286. $plugins = get_site_option( 'active_sitewide_plugins');
  287. if ( isset($plugins[$plugin]) )
  288. return true;
  289. return false;
  290. }
  291. }
  292. ?>