Capability Manager Enhanced - Version 1.4.1

Version Description

  • https compatibility: use content_url(), plugins_url()
    • Press Permit integration: if role definitions are reset to WP defaults, also repopulate PP capabilities (pp_manage_settings, etc.)
Download this release

Release Info

Developer kevinB
Plugin Icon 128x128 Capability Manager Enhanced
Version 1.4.1
Comparing to
See all releases

Version 1.4.1

Files changed (72) hide show
  1. admin.css +122 -0
  2. capsman-enhanced.php +107 -0
  3. framework/.htaccess +4 -0
  4. framework/classes/abstract/component.php +182 -0
  5. framework/classes/abstract/module.php +718 -0
  6. framework/classes/abstract/plugin.php +473 -0
  7. framework/classes/abstract/theme.php +273 -0
  8. framework/classes/admin-notices.php +70 -0
  9. framework/classes/settings.php +330 -0
  10. framework/classes/template.php +380 -0
  11. framework/init.php +127 -0
  12. framework/lang/bg_BG.mo +0 -0
  13. framework/lang/bg_BG.po +352 -0
  14. framework/lang/ca.mo +0 -0
  15. framework/lang/ca.po +315 -0
  16. framework/lang/es_ES.mo +0 -0
  17. framework/lang/es_ES.po +316 -0
  18. framework/lang/framework.pot +317 -0
  19. framework/lang/it_IT.mo +0 -0
  20. framework/lang/it_IT.po +417 -0
  21. framework/lib/filesystem.php +198 -0
  22. framework/lib/formating.php +179 -0
  23. framework/lib/modules.php +207 -0
  24. framework/lib/objects.php +110 -0
  25. framework/lib/plugins.php +33 -0
  26. framework/lib/system.php +36 -0
  27. framework/lib/themes.php +251 -0
  28. framework/lib/users.php +142 -0
  29. framework/license.txt +280 -0
  30. framework/loader.php +71 -0
  31. framework/samples/alkivia.ini +33 -0
  32. framework/samples/alkivia.php +42 -0
  33. framework/styles/.htaccess +4 -0
  34. framework/styles/admin.css +173 -0
  35. framework/styles/images/alkivia.png +0 -0
  36. framework/styles/images/dl-bg-gray.png +0 -0
  37. framework/styles/images/docs.png +0 -0
  38. framework/styles/images/help.png +0 -0
  39. framework/styles/images/paypal.png +0 -0
  40. framework/vendor/upload/class.upload.php +4752 -0
  41. images/capsman.png +0 -0
  42. images/cman32.png +0 -0
  43. includes/admin.php +578 -0
  44. includes/author-widget.php +40 -0
  45. includes/backup.php +81 -0
  46. includes/manager.php +704 -0
  47. lang/capsman-by_BY.mo +0 -0
  48. lang/capsman-by_BY.po +281 -0
  49. lang/capsman-ca.mo +0 -0
  50. lang/capsman-ca.po +384 -0
  51. lang/capsman-de_DE.mo +0 -0
  52. lang/capsman-de_DE.po +281 -0
  53. lang/capsman-es_ES.mo +0 -0
  54. lang/capsman-es_ES.po +392 -0
  55. lang/capsman-it_IT.mo +0 -0
  56. lang/capsman-it_IT.po +281 -0
  57. lang/capsman-ru_RU.mo +0 -0
  58. lang/capsman-ru_RU.po +281 -0
  59. lang/capsman-sv_SE.mo +0 -0
  60. lang/capsman-sv_SE.po +240 -0
  61. lang/capsman.mo +0 -0
  62. lang/capsman.po +854 -0
  63. lang/capsman.pot +738 -0
  64. readme.txt +165 -0
  65. samples/alkivia.ini +18 -0
  66. screenshot-1.jpg +0 -0
  67. screenshot-2.jpg +0 -0
  68. screenshot-3.jpg +0 -0
  69. screenshot-4.jpg +0 -0
  70. screenshot-5.jpg +0 -0
  71. screenshot-6.jpg +0 -0
  72. screenshot-7.png +0 -0
admin.css ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Settings for admin dashboard.
3
+ * Based on the styles for Maintenance Mode plugin by Michael Wöhrer
4
+ *
5
+ * @version $Rev: 198515 $
6
+ * @author Jordi Canals
7
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals
8
+ * @license GNU General Public License version 2
9
+ * @link http://alkivia.org
10
+ * @package Alkivia
11
+ * @subpackage CapsMan
12
+ *
13
+
14
+ Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License
18
+ version 2 as published by the Free Software Foundation.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+ */
28
+
29
+ /* =========================================================== SETTINGS */
30
+
31
+ #icon-capsman-admin {
32
+ background: transparent url('images/cman32.png') no-repeat;
33
+ }
34
+
35
+ /* ====================================================== SIDEBAR ICONS */
36
+
37
+ td.sidebar a.capsman {
38
+ background-image: url('images/capsman.png');
39
+ }
40
+
41
+ a.cap_type {
42
+ text-decoration: none;
43
+ }
44
+
45
+ a.cap_type:hover {
46
+ text-decoration: underline;
47
+ }
48
+
49
+ ul.cme-listhoriz li {
50
+ text-align: center;
51
+ padding-right: 2em;
52
+ }
53
+
54
+ ul.cme-listhoriz li table{
55
+ text-align: center;
56
+ }
57
+
58
+
59
+ ul.cme-listhoriz {
60
+ width: 100%;
61
+ clear: both;
62
+ float: left;
63
+ margin: 0;
64
+ padding: 0;
65
+ }
66
+
67
+ ul.cme-listhoriz li {
68
+ list-style: none;
69
+ float: left;
70
+ margin: 0;
71
+ }
72
+
73
+
74
+ div.cme-listhoriz h3 {
75
+ margin: 0.2em;
76
+ }
77
+
78
+ table .cme-typecaps {
79
+ border: 1px solid black;
80
+ }
81
+
82
+ table .cme-typecaps td {
83
+ text-align: center;
84
+ height: 2em;
85
+ }
86
+
87
+ table .cme-typecaps th {
88
+ padding-left: 0.5em;
89
+ padding-right: 0.5em;
90
+ }
91
+
92
+ td.cap_yes {
93
+ color:green;font-weight:bold;
94
+ }
95
+
96
+ td.cap_no {
97
+ color:red;
98
+ }
99
+
100
+ #akmin input.button {
101
+ margin-top: 5px;
102
+ }
103
+
104
+ #akmin td.sidebar {
105
+ width: 300px;
106
+ }
107
+
108
+ #akmin input.regular-text {
109
+ width: 200px;
110
+ }
111
+
112
+ .cme-subtext {
113
+ color: #686868;
114
+ font-style: italic;
115
+ margin-top:5px;
116
+ }
117
+
118
+ #wpbody-content{
119
+ padding-bottom: 30px;
120
+ }
121
+
122
+ /* EOF */
capsman-enhanced.php ADDED
@@ -0,0 +1,107 @@
1
+ <?php
2
+ /*
3
+ Plugin Name: Capability Manager Enhanced
4
+ Plugin URI: http://presspermit.com/capability-manager
5
+ Description: Manage WordPress role definitions. Organizes available capabilities by post type, status and source.
6
+ Version: 1.4.1
7
+ Author: Jordi Canals, Kevin Behrens
8
+ Author URI: http://agapetry.net
9
+ */
10
+
11
+ /**
12
+ * Capability Manager. Main Plugin File.
13
+ * Plugin to create and manage Roles and Capabilities.
14
+ *
15
+ * @author Jordi Canals, Kevin Behrens
16
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals; modifications Copyright (C) 2012 Kevin Behrens
17
+ * @license GNU General Public License version 3
18
+ * @link http://agapetry.net
19
+ *
20
+
21
+ Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
22
+ Modifications Copyright 2012, Kevin Behrens <kevin@agapetry.net>
23
+
24
+ This program is free software; you can redistribute it and/or
25
+ modify it under the terms of the GNU General Public License
26
+ version 3 as published by the Free Software Foundation.
27
+
28
+ This program is distributed in the hope that it will be useful,
29
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
30
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31
+ GNU General Public License for more details <http://www.gnu.org/licenses/>.
32
+ */
33
+
34
+ if ( ! defined( 'CAPSMAN_VERSION' ) ) {
35
+ define( 'CAPSMAN_VERSION', '1.4.1' );
36
+ define( 'CAPSMAN_ENH_VERSION', '1.4.1' );
37
+ }
38
+
39
+ if ( cme_is_plugin_active( 'capsman.php' ) ) {
40
+ $message = __( '<strong>Error:</strong> Capability Manager Extended cannot function because another copy of Capability Manager is active.', 'capsman' );
41
+ add_action('admin_notices', create_function('', 'echo \'<div id="message" class="error fade" style="color: black">' . $message . '</div>\';'));
42
+ return;
43
+ } else {
44
+ define ( 'AK_CMAN_PATH', dirname(__FILE__) );
45
+ define ( 'AK_CMAN_LIB', AK_CMAN_PATH . '/includes' );
46
+
47
+ /**
48
+ * Sets an admin warning regarding required PHP version.
49
+ *
50
+ * @hook action 'admin_notices'
51
+ * @return void
52
+ */
53
+ function _cman_php_warning() {
54
+ $data = get_plugin_data(__FILE__);
55
+ load_plugin_textdomain('capsman', false, basename(dirname(__FILE__)) .'/lang');
56
+
57
+ echo '<div class="error"><p><strong>' . __('Warning:', 'capsman') . '</strong> '
58
+ . sprintf(__('The active plugin %s is not compatible with your PHP version.', 'capsman') .'</p><p>',
59
+ '&laquo;' . $data['Name'] . ' ' . $data['Version'] . '&raquo;')
60
+ . sprintf(__('%s is required for this plugin.', 'capsman'), 'PHP-5 ')
61
+ . '</p></div>';
62
+ }
63
+
64
+ // ============================================ START PROCEDURE ==========
65
+
66
+ // Check required PHP version.
67
+ if ( version_compare(PHP_VERSION, '5.0.0', '<') ) {
68
+ // Send an armin warning
69
+ add_action('admin_notices', '_cman_php_warning');
70
+ } else {
71
+ if ( is_admin() && ( isset($_REQUEST['page']) && in_array( $_REQUEST['page'], array( 'capsman', 'capsman-tool' ) ) || ( ! empty($_SERVER['SCRIPT_NAME']) && strpos( $_SERVER['SCRIPT_NAME'], 'p-admin/plugins.php' ) && ! empty($_REQUEST['action'] ) ) || ( isset($_GET['action']) && 'reset-defaults' == $_GET['action']) ) ) {
72
+ // Run the plugin
73
+ include_once ( AK_CMAN_PATH . '/framework/loader.php' );
74
+ include ( AK_CMAN_LIB . '/manager.php' );
75
+ ak_create_object('capsman', new CapabilityManager(__FILE__, 'capsman'));
76
+ } else {
77
+ load_plugin_textdomain('capsman', false, basename(dirname(__FILE__)) .'/lang');
78
+ add_action( 'admin_menu', 'cme_submenus' );
79
+ }
80
+ }
81
+ }
82
+
83
+ // perf enchancement: display submenu links without loading framework and plugin code
84
+ function cme_submenus() {
85
+ if ( defined( 'PP_VERSION' ) ) // Press Permit integrates into Permissions menu
86
+ add_action( 'pp_permissions_menu', '_cme_pp_menu' );
87
+ else
88
+ add_users_page( __('Capability Manager', 'capsman'), __('Role Capabilities', 'capsman'), 'manage_capabilities', 'capsman', 'cme_fakefunc');
89
+
90
+ add_management_page(__('Capability Manager', 'capsman'), __('Capability Manager', 'capsman'), 'manage_capabilities', 'capsman' . '-tool', 'cme_fakefunc');
91
+ }
92
+
93
+ function _cme_pp_menu() {
94
+ add_submenu_page( $GLOBALS['pp_admin']->get_menu('options'), __('Capability Manager', 'capsman'), __('Role Capabilities', 'capsman'), 'manage_capabilities', 'capsman', 'cme_fakefunc' );
95
+ }
96
+
97
+ function cme_is_plugin_active($check_plugin_file) {
98
+ if ( ! $check_plugin_file )
99
+ return false;
100
+
101
+ $plugins = get_option('active_plugins');
102
+
103
+ foreach ( $plugins as $plugin_file ) {
104
+ if ( false !== strpos($plugin_file, $check_plugin_file) )
105
+ return $plugin_file;
106
+ }
107
+ }
framework/.htaccess ADDED
@@ -0,0 +1,4 @@
1
+ # Prevent running or accessing any file directly.
2
+
3
+ Order Deny,Allow
4
+ Deny from all
framework/classes/abstract/component.php ADDED
@@ -0,0 +1,182 @@
1
+ <?php
2
+ /**
3
+ * Class Component.
4
+ * Manages the main functionality for all components.
5
+ *
6
+ * @version $Rev: 203758 $
7
+ * @author Jordi Canals
8
+ * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
9
+ * @license GNU General Public License version 2
10
+ * @link http://alkivia.org
11
+ * @package Alkivia
12
+ * @subpackage Framework
13
+ *
14
+
15
+ Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ version 2 as published by the Free Software Foundation.
20
+
21
+ This program is distributed in the hope that it will be useful,
22
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ GNU General Public License for more details.
25
+
26
+ You should have received a copy of the GNU General Public License
27
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
28
+ */
29
+
30
+ require_once ( AK_CLASSES . '/abstract/module.php' );
31
+
32
+ /**
33
+ * Abtract class to be used as a component template.
34
+ * There are some special functions thay can declared in implementations to perform main actions:
35
+ * - componentActivate: (Protected) Actions to run when activating the component.
36
+ * - componentDeactivate: (Hook, must be public) Actions to run when deactivating the component.
37
+ * - componentUpdate: (Protected) Actions to update the component to a new version. (Updating version on DB is done after this).
38
+ * - componentsLoaded: (Protected) Actions to run when components initialization is performed (In plugins loaded).
39
+ * - registerWidgets: (Protected) Actions to init plugin widgets (In widgets_init).
40
+ *
41
+ * @since 0.7
42
+ * @author Jordi Canals
43
+ * @package AOC
44
+ * @subpackage Library
45
+ * @link http://alkivia.org
46
+ */
47
+ abstract class akComponentAbstract extends akModuleAbstract
48
+ {
49
+ /**
50
+ * Parent plugin slug.
51
+ * This is used on menus and form actions.
52
+ *
53
+ * @var string
54
+ */
55
+ protected $slug;
56
+
57
+ /**
58
+ * Class constructor.
59
+ * Calls the implementated method 'startUp' if it exists. This is done at plugins loading time.
60
+ * Prepares admin menus by seting an action for the implemented method '_adminMenus' if it exists.
61
+ *
62
+ * @param string $file The main file to run the component.
63
+ * @return aocComponent The component object.
64
+ */
65
+ final function __construct ( $file )
66
+ {
67
+ parent::__construct('component', '', $file);
68
+ $this->slug = ak_get_object($this->PID)->getSlug();
69
+
70
+ // Activating and deactivating hooks.
71
+ add_action('ak_activate_' . $this->ID, array($this, 'activate'));
72
+ add_action('ak_deactivate_' . $this->ID, array($this, 'componentDeactivate'));
73
+
74
+ add_action('ak_' . $this->PID . '_components_init', array($this, 'init'));
75
+ add_action('ak_' . $this->PID . '_widgets_init', array($this, 'widgetsInit'));
76
+ }
77
+
78
+ /**
79
+ * Fires on plugin activation.
80
+ * @return void
81
+ */
82
+ protected function componentActivate () {}
83
+
84
+ /**
85
+ * Fires on plugin deactivation.
86
+ * @return void
87
+ */
88
+ public function componentDeactivate () {}
89
+
90
+ /**
91
+ * Updates the plugin to a new version.
92
+ * @param string $version Old component version.
93
+ * @return void
94
+ */
95
+ protected function componentUpdate ( $version ) {}
96
+
97
+ /**
98
+ * Fires when plugins have been loaded.
99
+ * @return void
100
+ */
101
+ protected function componentsLoaded () {}
102
+
103
+ /**
104
+ * Fires on Widgets init.
105
+ * @return void
106
+ */
107
+ protected function registerWidgets () {}
108
+
109
+ /**
110
+ * Activates the Component.
111
+ * Sets the plugin version in the component settings to be saved to DB.
112
+ *
113
+ * @hook action aoc_activate_$component
114
+ * @access private
115
+ * @return void
116
+ */
117
+ final function activate()
118
+ {
119
+ $this->componentActivate();
120
+ add_option($this->ID . '_version', $this->version);
121
+ }
122
+
123
+ /**
124
+ * Inits the component.
125
+ * Here whe call the 'update' and 'init' functions. This is done after the components are loaded.
126
+ * Also the component version is updated here.
127
+ *
128
+ * @hook action aoc_components_init
129
+ * @access private
130
+ * @return void
131
+ */
132
+ final function init ()
133
+ {
134
+ if ( $this->needs_update ) {
135
+ $this->componentUpdate( $this->getOption('version') );
136
+ update_option($this->ID . '_version', $this->version);
137
+ }
138
+
139
+ // Call the custom init for the component.
140
+ $this->componentsLoaded();
141
+ }
142
+
143
+ /**
144
+ * Inits the widgets (In action 'widgets_init')
145
+ * Before loading the widgets, we check that standard sidebar is present.
146
+ *
147
+ * @hook action 'widgets_init'
148
+ * @return void
149
+ */
150
+ final function widgetsInit()
151
+ {
152
+ if ( class_exists('WP_Widget') && function_exists('register_widget') && function_exists('unregister_widget') ) {
153
+ $this->registerWidgets();
154
+ } else {
155
+ add_action('admin_notices', array($this, 'noSidebarWarning'));
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Loads component data.
161
+ * As it is a child component, data is loaded into akModuleAbstract::child_data
162
+ *
163
+ * @return void
164
+ */
165
+ final protected function loadData()
166
+ {
167
+ if ( empty( $this->child_data) ) {
168
+ $component_data = ak_component_data($this->mod_file, true);
169
+ $readme_data = ak_module_readme_data($this->mod_file);
170
+ $this->child_data = array_merge($readme_data, $component_data);
171
+
172
+ $this->PID = $this->child_data['Parent'];
173
+ $this->mod_data = ak_get_object($this->PID)->getModData();
174
+
175
+ if ( empty( $this->child_data['Version']) ) {
176
+ $this->version = $this->mod_data['Version'];
177
+ } else {
178
+ $this->version = $this->child_data['Version'];
179
+ }
180
+ }
181
+ }
182
+ }
framework/classes/abstract/module.php ADDED
@@ -0,0 +1,718 @@
1
+ <?php
2
+ /**
3
+ * Class for Modules management.
4
+ * Modules are Plugins, Themes and plugin components.
5
+ *
6
+ * @version $Rev: 203758 $
7
+ * @author Jordi Canals
8
+ * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
9
+ * @license GNU General Public License version 2
10
+ * @link http://alkivia.org
11
+ * @package Alkivia
12
+ * @subpackage Framework
13
+ *
14
+
15
+ Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ version 2 as published by the Free Software Foundation.
20
+
21
+ This program is distributed in the hope that it will be useful,
22
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ GNU General Public License for more details.
25
+
26
+ You should have received a copy of the GNU General Public License
27
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
28
+ */
29
+
30
+ /**
31
+ * Abtract class to be used as a theme template.
32
+ * Must be implemented before using this class.
33
+ * There are some special functions that have to be declared in implementations to perform main actions:
34
+ * - moduleLoad (Protected) Additional actions to be run at module load time.
35
+ * - defaultOptions (Protected) Returns the module default options.
36
+ * - widgetsInit (Public) Runs at 'widgets_init' action.
37
+ * - wpInit (Public) Runs at 'init' action.
38
+ * - adminMenus (Public) Runs at 'admin_menus' option, used to set admin menus and page options.
39
+ *
40
+ * @author Jordi Canals
41
+ * @package Alkivia
42
+ * @subpackage Framework
43
+ * @link http://wiki.alkivia.org/framework/classes/module
44
+ *
45
+ * @uses akSettings
46
+ */
47
+
48
+ abstract class akModuleAbstract
49
+ {
50
+ /**
51
+ * Module ID. Is the module internal short name.
52
+ * Filled in constructor (as a constructor param). Used for translations textdomain.
53
+ *
54
+ * @var string
55
+ */
56
+ public $ID;
57
+
58
+ /**
59
+ * Component parent ID.
60
+ * Used only for components.
61
+ *
62
+ * @var string
63
+ */
64
+ public $PID = '';
65
+
66
+ /**
67
+ * Module version number.
68
+ *
69
+ * @since 0.8
70
+ *
71
+ * @var string
72
+ */
73
+ public $version;
74
+
75
+ /**
76
+ * Module Type using a class constant: self::PLUGIN, self::COMPONENT, seelf::THEME, self::CHILD_THEME
77
+ * By default is set to 0 (unknown).
78
+ *
79
+ * @var int
80
+ */
81
+ protected $mod_type = 0;
82
+
83
+ /**
84
+ * Full path to module main file.
85
+ * Main file is 'style.css' for themes and the php file with data header for plugins and components.
86
+ *
87
+ * @var string
88
+ */
89
+ protected $mod_file;
90
+
91
+ /**
92
+ * URL to the module folder.
93
+ *
94
+ * @var string
95
+ */
96
+ protected $mod_url;
97
+
98
+ /**
99
+ * Module data. Readed from the main plugin file header and the readme file.
100
+ * Filled in loadModuleData(). Called in constructor.
101
+ * From the filename:
102
+ * - 'ID' - Module internal short name. Taken from main module's file name.
103
+ * From themes style.css file header:
104
+ * - 'Name' - Name of the theme.
105
+ * - 'Title' - Long title for the theme. As WP 2.8 is the same as 'Name'.
106
+ * - 'URI' - Theme's page URI.
107
+ * - 'Description' - Description of theme's features.
108
+ * - 'Author' - Author name and link (to author home).
109
+ * - 'Version' - Theme Version number.
110
+ * - 'Template' - The parent theme (If this is a child theme).
111
+ * - 'Tags' - An array of theme tags features.
112
+ * From plugins file header:
113
+ * - 'Name' - Name of the plugin, must be unique.
114
+ * - 'Title' - Title of the plugin and the link to the plugin's web site.
115
+ * - 'Description' - Description of what the plugin does and/or notes from the author.
116
+ * - 'Author' - The author's name
117
+ * - 'AuthorURI' - The author's web site address.
118
+ * - 'Version' - The plugin's version number.
119
+ * - 'PluginURI' - Plugin's web site address.
120
+ * - 'TextDomain' - Plugin's text domain for localization.
121
+ * - 'DomainPath' - Plugin's relative directory path to .mo files.
122
+ * From readme.txt file :
123
+ * - 'Contributors' - An array with all contributors nicknames.
124
+ * - 'Tags' - An array with all plugin tags.
125
+ * - 'DonateURI' - The donations page address.
126
+ * - 'Requires' - Minimum required WordPress version.
127
+ * - 'Tested' - Higher WordPress version this plugin has been tested.
128
+ * - 'Stable' - Last stable tag when this was released.
129
+ *
130
+ * @var array
131
+ */
132
+ protected $mod_data;
133
+
134
+ /**
135
+ * Same as $mod_data but for child themes and components.
136
+ *
137
+ * From the Component file:
138
+ * - 'File' - FileName of the component (relative to plugin's folder).
139
+ * From componets file header:
140
+ * - 'File' - The component filename, relative to the plugin folder.
141
+ * - 'Component' - The component short name or ID.
142
+ * - 'Name' - Descriptive name for the component.
143
+ * - 'Description' - A descriptive text about the component.
144
+ * - 'Author' - Component author name
145
+ * - 'URL' - Author homepage URL.
146
+ * - 'Link' - Author anchor to home page.
147
+ * - 'Core' - If this is a core compoment or not.
148
+ * - 'Version' - Component version number.
149
+ * From readme.txt file:
150
+ * - Same as seen on akModuleAbstract::mod_data.
151
+ * From child themes file header:
152
+ * - Same as seen on akModuleAbstract::mod_data for themes.
153
+ *
154
+ * @var array
155
+ */
156
+ protected $child_data = array();
157
+
158
+ /**
159
+ * Theme saved data.
160
+ * - 'post' - Saves the current post.
161
+ * - 'more' - Saves the read more status.
162
+ *
163
+ * @var array
164
+ */
165
+ protected $saved;
166
+
167
+ /**
168
+ * Holds a reference to the global 'settings' object.
169
+ * This object has been created on the framework loader.
170
+ *
171
+ * @var akSettings
172
+ */
173
+ protected $cfg;
174
+
175
+ /**
176
+ * Flag to see if we are installing (activating for first time) or reactivating the module.
177
+ *
178
+ * @var boolean
179
+ */
180
+ protected $installing = false;
181
+
182
+ /**
183
+ * Flag to see if module needs to be updated.
184
+ *
185
+ * @var boolean
186
+ */
187
+ protected $needs_update = false;
188
+
189
+ /** Constant used to define module as plugin. */
190
+ const PLUGIN = 10;
191
+
192
+ /** Constant used to define module as component. */
193
+ const COMPONENT = 15;
194
+
195
+ /** Constant used to define module as theme. */
196
+ const THEME = 20;
197
+
198
+ /** Constant used to define module as child theme. */
199
+ const CHILD_THEME = 25;
200
+
201
+ /**
202
+ * Class constructor.
203
+ * Calls the implementated method 'startUp' if it exists. This is done at theme's loading time.
204
+ * Prepares admin menus by setting an action for the implemented method '_adminMenus' if it exists.
205
+ *
206
+ * @param string $type Module type. Must be one of 'plugin', 'component', 'theme'. (child themes are detected).
207
+ * @param string $ID Theme internal short name (known as theme ID).
208
+ * @param string $file Module file. Only for plugins and components. (For themes style.css is always used).
209
+ * @return akTheme
210
+ */
211
+ public function __construct ( $type = '', $ID = '', $file = '' )
212
+ {
213
+ $this->cfg =& ak_settings_object();
214
+
215
+ switch ( strtolower($type) ) {
216
+ case 'plugin' :
217
+ $this->mod_type = self::PLUGIN;
218
+ $this->mod_file = trim($file);
219
+ break;
220
+ case 'component' :
221
+ $this->mod_type = self::COMPONENT;
222
+ $this->mod_file = trim($file);
223
+ break;
224
+ case 'theme' :
225
+ $this->mod_type = self::THEME;
226
+ $this->mod_file = STYLESHEETPATH . '/style.css';
227
+ break;
228
+ default:
229
+ $this->mod_type = 0; // Unknown.
230
+ }
231
+
232
+ $this->loadModuleData($ID);
233
+ if ( $this->isCompatible() ) {
234
+ add_action('init', array($this, 'systemInit'));
235
+ add_action('plugins_loaded', array($this, 'pluginsInit'));
236
+ add_action('widgets_init', array($this, 'widgetsInit'));
237
+
238
+ if ( ! apply_filters('ak_' . $this->ID . '_disable_admin', $this->getOption('disable-admin-page')) ) {
239
+ add_action('admin_menu', array($this, 'adminMenus'), 5); // execute prior to PP, to use menu hook
240
+ }
241
+
242
+ // Load styles
243
+ if ( is_admin() ) {
244
+ add_action('admin_print_styles', array($this, 'adminStyles'));
245
+ } else {
246
+ add_action('wp_print_styles', array($this, 'enqueueStyles'));
247
+ }
248
+
249
+ $this->moduleLoad();
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Executes as soon as module class is loaded.
255
+ *
256
+ * @return void
257
+ */
258
+ protected function moduleLoad() {}
259
+
260
+ /**
261
+ * Prepares and returns default module options.
262
+ *
263
+ * @return array Options array
264
+ */
265
+ protected function defaultOptions()
266
+ {
267
+ return array();
268
+ }
269
+
270
+ /**
271
+ * Fires at 'widgets_init' action hook
272
+ *.
273
+ * @return void
274
+ */
275
+ public function widgetsInit () {}
276
+
277
+ /**
278
+ * Fires at 'init' action hook.
279
+ *
280
+ * @return void
281
+ */
282
+ protected function wpInit () {}
283
+
284
+ /**
285
+ * Fires at 'admin_menus' action hook.
286
+ *
287
+ * @return void
288
+ */
289
+ public function adminMenus () {}
290
+
291
+ /**
292
+ * Dummy method provided to check additional WP compatibility on inplementations.
293
+ * This is mostly used on plugins to check for WordPress required version.
294
+ *
295
+ * @return boolean
296
+ */
297
+ public function isCompatible ()
298
+ {
299
+ return true;
300
+ }
301
+
302
+ /**
303
+ * Loads module data.
304
+ * Loads different data for Plugin, Theme or Component.
305
+ *
306
+ * @return void
307
+ */
308
+ abstract protected function loadData ();
309
+
310
+ /**
311
+ * Functions to execute at system Init.
312
+ *
313
+ * @hook action 'init'
314
+ * @access private
315
+ *
316
+ * @return void
317
+ */
318
+ final function systemInit ()
319
+ {
320
+ switch ( $this->mod_type ) {
321
+ case self::CHILD_THEME :
322
+ load_theme_textdomain('akchild', STYLESHEETPATH . '/lang');
323
+ case self::THEME :
324
+ load_theme_textdomain('aktheme', TEMPLATEPATH . '/lang');
325
+ break;
326
+ }
327
+
328
+ $this->wpInit();
329
+ }
330
+
331
+ /**
332
+ * Functions to execute after loading plugins.
333
+ *
334
+ * @return void
335
+ */
336
+ final function pluginsInit ()
337
+ {
338
+ switch ( $this->mod_type ) {
339
+ case self::PLUGIN :
340
+ load_plugin_textdomain($this->ID, false, basename(dirname($this->mod_file)) . '/lang');
341
+ break;
342
+ case self::COMPONENT :
343
+ // TODO: Manage components translations.
344
+ break;
345
+ }
346
+
347
+ }
348
+
349
+ /**
350
+ * Enqueues additional administration styles.
351
+ * Send the framework admin.css file and additionally any other admin.css file
352
+ * found on the module direcotry.
353
+ *
354
+ * @hook action 'admin_print_styles'
355
+ * @uses apply_filters() Calls the 'ak_framework_style_admin' filter on the framework style url.
356
+ * @uses apply_filters() Calls the 'ak_<Mod_ID>_style_admin' filter on the style url.
357
+ * @access private
358
+ *
359
+ * @return void
360
+ */
361
+ final function adminStyles()
362
+ {
363
+ // FRAMEWORK admin styles.
364
+ $url = apply_filters('ak_framework_style_admin', AK_STYLES_URL . '/admin.css');
365
+ if ( ! empty($url) ) {
366
+ wp_register_style('ak_framework_admin', $url, false, get_option('ak_framework_version'));
367
+ wp_enqueue_style('ak_framework_admin');
368
+ }
369
+
370
+ // MODULE admin styles.
371
+ if ( $this->isChildTheme() && file_exists(STYLESHEETPATH . '/admin.css') ) {
372
+ $url = get_stylesheet_directory_uri() . '/admin.css';
373
+ } elseif ( $this->isTheme() && file_exists(TEMPLATEPATH . '/admin.css') ) {
374
+ $url = get_template_directory_uri() . '/admin.css';
375
+ } elseif ( file_exists(dirname($this->mod_file) . '/admin.css') ) {
376
+ $url = $this->mod_url . '/admin.css';
377
+ } else {
378
+ $url = '';
379
+ }
380
+
381
+ $url = apply_filters('ak_' . $this->ID . '_style_admin', $url);
382
+ if ( ! empty($url) ) {
383
+ wp_register_style('ak_' . $this->ID . '_admin', $url, array('ak_framework_admin'), $this->version);
384
+ wp_enqueue_style('ak_' . $this->ID . '_admin');
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Enqueues additional styles for plugins and components.
390
+ * For themes no styles are enqueued as them are already sent by WP.
391
+ *
392
+ * @hook action 'wp_print_styles'
393
+ * @uses apply_filters() Calls the 'ak_<Mod_ID>_style_url' filter on the style url.
394
+ * @access private
395
+ *
396
+ * @return void
397
+ */
398
+ final function enqueueStyles()
399
+ {
400
+ if ( $this->isTheme() || $this->getOption('disable-module-styles') ) {
401
+ return;
402
+ }
403
+
404
+ $url = $this->getOption('style-url', false);
405
+ if ( false === $url ) {
406
+ if ( file_exists(dirname($this->mod_file) . '/style.css') ) {
407
+ $url = $this->mod_url . '/style.css';
408
+ } else {
409
+ $url = '';
410
+ }
411
+ }
412
+
413
+ $url = apply_filters('ak_' . $this->ID . '_style_url', $url);
414
+ if ( ! empty($url) ) {
415
+ wp_register_style('ak_' . $this->ID, $url, false, $this->version);
416
+ wp_enqueue_style('ak_' . $this->ID);
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Checks if current module is a Plugin.
422
+ * @return boolean
423
+ */
424
+ final public function isPlugin()
425
+ {
426
+ return ( self::PLUGIN == $this->mod_type ) ? true : false;
427
+ }
428
+
429
+ /**
430
+ * Checks if current module is a Component.
431
+ * @return boolean
432
+ */
433
+ final public function isComponent()
434
+ {
435
+ return ( self::COMPONENT == $this->mod_type ) ? true : false;
436
+ }
437
+
438
+ /**
439
+ * Checks if current module is a Theme (or child)
440
+ * @return boolean
441
+ */
442
+ final public function isTheme()
443
+ {
444
+ return ( self::THEME == $this->mod_type || self::CHILD_THEME == $this->mod_type ) ? true : false;
445
+ }
446
+
447
+ /**
448
+ * Checks if current module is a child theme.
449
+ * @return boolean
450
+ */
451
+ final public function isChildTheme()
452
+ {
453
+ return ( self::CHILD_THEME == $this->mod_type ) ? true : false;
454
+ }
455
+
456
+ /**
457
+ * Returns a module option.
458
+ * If no specific option is requested, returns all options.
459
+ * If requested a non existent settings, returns $default.
460
+ *
461
+ * @param $name Name for the option to return.
462
+ * @param $default Default value to use if the option does not exists.
463
+ * @return mixed The option's value or an array with all options.
464
+ */
465
+ final public function getOption ( $name = '', $default = false )
466
+ {
467
+ return $this->cfg->getSetting($this->ID, $name, $default);
468
+ }
469
+
470
+ /**
471
+ * Updates a module option.
472
+ *
473
+ * @param string $name Option Name
474
+ * @param mixed $value Option value
475
+ * @return void
476
+ */
477
+ final public function updateOption ( $name, $value )
478
+ {
479
+ $this->cfg->updateOption($this->ID, $name, $value );
480
+ }
481
+
482
+ /**
483
+ * Deletes a module option.
484
+ *
485
+ * @param string $name Option Name
486
+ * @return void
487
+ */
488
+ final public function deleteOption( $name )
489
+ {
490
+ $this->cfg->deleteOption($this->ID, $name);
491
+ }
492
+
493
+ /**
494
+ * Merges new options into module settings.
495
+ * Replaces exsisting ones and adds new ones.
496
+ *
497
+ * @since 0.7
498
+ *
499
+ * @param array $options New options to merge into settings.
500
+ * @return void
501
+ */
502
+ final protected function mergeOptions ( $options )
503
+ {
504
+ $current = $this->cfg->getSetting($this->ID);
505
+ $new_opt = array_merge($current, $options);
506
+ $this->cfg->replaceOptions($this->ID, $new_opt);
507
+ }
508
+
509
+ /**
510
+ * Replaces ALL module options by new ones.
511
+ *
512
+ * @param array $options Array with all options pairs (name=>value)
513
+ * @return void
514
+ */
515
+ final public function setNewOptions ( $options )
516
+ {
517
+ $this->cfg->replaceOptions($this->ID, $options);
518
+ }
519
+
520
+ /**
521
+ * Returns current module default options.
522
+ *
523
+ * @since 0.7
524
+ *
525
+ * @return array Default module options.
526
+ */
527
+ final protected function getDefaults ()
528
+ {
529
+ $this->cfg->getDefaults($this->ID);
530
+ }
531
+
532
+ /**
533
+ * Replaces current module defaults by new ones.
534
+ *
535
+ * @since 0.7
536
+ *
537
+ * @param array $options New default options-
538
+ * @return void
539
+ */
540
+ final protected function setDefaults ( $options )
541
+ {
542
+ $this->cfg->setDefaults($this->ID, $options);
543
+ }
544
+
545
+ /**
546
+ * Merges new options into module defaults.
547
+ * Replaces exsisting ones and adds new ones.
548
+ *
549
+ * @since 0.7
550
+ *
551
+ * @param array $options New options to merge into defaults.
552
+ * @return void
553
+ */
554
+ final protected function mergeDefaults ( $options )
555
+ {
556
+ $defaults = $this->cfg->getDefaults($this->ID);
557
+ $new_def = array_merge($defaults, $options);
558
+ $this->cfg->setDefaults($this->ID, $new_def);
559
+ }
560
+
561
+ /**
562
+ * Returns module data.
563
+ * This data is loaded from the main module file.
564
+ *
565
+ * @see akModuleAbstract::$mod_data
566
+ * @return mixed The parameter requested or an array wil all data.
567
+ */
568
+ final public function getModData ( $name = '' )
569
+ {
570
+ if ( empty($name) ) {
571
+ return $this->mod_data;
572
+ } elseif ( isset( $this->mod_data[$name]) ) {
573
+ return $this->mod_data[$name];
574
+ } else {
575
+ return false;
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Returns child module data.
581
+ * This data is loaded from the child module file.
582
+ *
583
+ * @see akModuleAbstract::$child_data
584
+ * @return mixed The parameter requested or an array wil all data.
585
+ */
586
+ final public function getChildData ( $name = '' )
587
+ {
588
+ if ( empty($name) ) {
589
+ return $this->child_data;
590
+ } elseif ( isset( $this->child_data[$name]) ) {
591
+ return $this->child_data[$name];
592
+ } else {
593
+ return false;
594
+ }
595
+ }
596
+
597
+ /**
598
+ * Checks if an option can be maneged on settings page.
599
+ * Looks at the alkivia.ini file and if set there, the option will be disabled.
600
+ *
601
+ * @param string|array $options Options names.
602
+ * @param boolean $show_notice Show a notice if disabled.
603
+ * @return boolean If administration is allowed or not.
604
+ */
605
+ final public function allowAdmin( $options, $show_notice = true )
606
+ {
607
+ foreach ( (array) $options as $option ) {
608
+ if ( ! $this->cfg->isForced($this->ID, $option) ) {
609
+ return true;
610
+ }
611
+ }
612
+
613
+ if ( $show_notice ) {
614
+ echo '<em>' . __('Option blocked by administrator.', 'akfw') . '</em>';
615
+ }
616
+ return false;
617
+ }
618
+
619
+ /**
620
+ * Loads module data and settings.
621
+ * Data is loaded from the module file headers. Settings from Database and alkivia.ini.
622
+ *
623
+ * @return void
624
+ */
625
+ final private function loadModuleData ( $id )
626
+ {
627
+ $this->loadData();
628
+ switch ( $this->mod_type ) {
629
+ case self::PLUGIN :
630
+ $this->mod_url = plugins_url() . '/' . basename(dirname($this->mod_file));
631
+ $this->ID = ( empty($id) ) ? strtolower(basename($this->mod_file, '.php')) : trim($id) ;
632
+ break;
633
+ case self::THEME :
634
+ case self::CHILD_THEME :
635
+ $this->mod_url = get_stylesheet_directory_uri();
636
+ $this->ID = ( empty($id) ) ? strtolower(basename(TEMPLATEPATH)) : trim($id) ;
637
+ break;
638
+ case self::COMPONENT :
639
+ $this->mod_url = ak_get_object($this->PID)->getUrl() . 'components/' . basename(dirname($this->mod_file));
640
+ $this->ID = $this->PID . '_' . $this->child_data['Component'];
641
+ break;
642
+ }
643
+ $this->cfg->setDefaults($this->ID, $this->defaultOptions());
644
+
645
+ $old_version = get_option($this->ID . '_version');
646
+ if ( false === $old_version ) {
647
+ $this->installing = true;
648
+ } elseif ( version_compare($old_version, $this->version, 'ne') ) {
649
+ $this->needs_update = true;
650
+ }
651
+ }
652
+
653
+ /**
654
+ * Saves the current post state.
655
+ * Used if we are looping a new query to reset previous state.
656
+ *
657
+ * @return void
658
+ */
659
+ final public function savePost()
660
+ {
661
+ global $post, $more;
662
+
663
+ $this->saved['post'] = $post;
664
+ $this->saved['more'] = $more;
665
+ }
666
+
667
+ /**
668
+ * Restores the current post state.
669
+ * Saved in savePost()
670
+ *
671
+ * @return void
672
+ */
673
+ final public function restorePost()
674
+ {
675
+ global $post, $more;
676
+
677
+ $more = $this->saved['more'];
678
+ $post = $this->saved['post'];
679
+ if ( $post ) {
680
+ setup_postdata($post);
681
+ }
682
+ }
683
+
684
+ /**
685
+ * Returns the URL to the module folder.
686
+ *
687
+ * @return string Absolute URL to the module folder.
688
+ */
689
+ final public function getURL()
690
+ {
691
+ return trailingslashit($this->mod_url);
692
+ }
693
+
694
+ /**
695
+ * Returns the absolute path to module direcotory.
696
+ *
697
+ * @since 0.7
698
+ *
699
+ * @return string Full absolute path to module directory.
700
+ */
701
+ final public function getPath()
702
+ {
703
+ return trailingslashit(dirname($this->mod_file));
704
+ }
705
+
706
+ /**
707
+ * Returns the basename for the plugin folder.
708
+ *
709
+ * @since 0.7
710
+ *
711
+ * @return string Plugin folder name (Relative to wp-content/plugins or wp-content/themes.
712
+ */
713
+ final public function getSlug()
714
+ {
715
+ $folder = basename(dirname($this->mod_file));
716
+ return $folder;
717
+ }
718
+ }
framework/classes/abstract/plugin.php ADDED
@@ -0,0 +1,473 @@
1
+ <?php
2
+ /**
3
+ * Plugins related functions and classes.
4
+ *
5
+ * @version $Rev: 203758 $
6
+ * @author Jordi Canals
7
+ * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
8
+ * @license GNU General Public License version 2
9
+ * @link http://alkivia.org
10
+ * @package Alkivia
11
+ * @subpackage Framework
12
+ *
13
+
14
+ Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License
18
+ version 2 as published by the Free Software Foundation.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+ */
28
+
29
+ require_once ( AK_CLASSES . '/abstract/module.php' );
30
+
31
+ /**
32
+ * Abtract class to be used as a plugin template.
33
+ * Must be implemented before using this class and it's recommended to prefix the class to prevent collissions.
34
+ * There are some special functions that have to be declared in implementations to perform main actions:
35
+ * - pluginActivate (Protected) Actions to run when activating the plugin.
36
+ * - pluginDeactivate (Protected) Actions to run when deactivating the plugin.
37
+ * - pluginUpdate (Protected) Actions to update the plugin to a new version. (Updating version on DB is done after this).
38
+ * Takes plugin running version as a parameter.
39
+ * - pluginsLoaded (Protected) Runs at 'plugins_loaded' action hook.
40
+ * - registerWidgets (Protected) Runs at 'widgets_init' action hook.
41
+ *
42
+ * @author Jordi Canals
43
+ * @package Alkivia
44
+ * @subpackage Framework
45
+ * @link http://wiki.alkivia.org/framework/classes/plugin
46
+ */
47
+ abstract class akPluginAbstract extends akModuleAbstract
48
+ {
49
+ /**
50
+ * Holds the installed and active components.
51
+ * @var array
52
+ */
53
+ private $components = false;
54
+
55
+ /**
56
+ * Class constructor.
57
+ * Calls the implementated method 'startUp' if it exists. This is done at plugins loading time.
58
+ * Prepares admin menus by seting an action for the implemented method '_adminMenus' if it exists.
59
+ *
60
+ * @param string $mod_file Full main plugin's filename (absolute to root).
61
+ * @param string $ID Plugin short name (known as plugin ID).
62
+ * @return spostsPlugin|false The plugin object or false if not compatible.
63
+ */
64
+ public function __construct( $mod_file, $ID = '' )
65
+ {
66
+ parent::__construct('plugin', $ID, $mod_file);
67
+
68
+ if ( $this->isCompatible() ) {
69
+ // Activation and deactivation hooks.
70
+ register_activation_hook($this->mod_file, array($this, 'activate'));
71
+ register_deactivation_hook($this->mod_file, array($this, 'deactivate'));
72
+
73
+ add_action('plugins_loaded', array($this, 'init'));
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Fires on plugin activation.
79
+ * @return void
80
+ */
81
+ protected function pluginActivate () {}
82
+
83
+ /**
84
+ * Fires on plugin deactivation.
85
+ * @return void
86
+ */
87
+ protected function pluginDeactivate () {}
88
+
89
+ /**
90
+ * Updates the plugin to a new version.
91
+ * @param string $version Old plugin version.
92
+ * @return void
93
+ */
94
+ protected function pluginUpdate ( $version ) {}
95
+
96
+ /**
97
+ * Fires when plugins have been loaded.
98
+ * @return void
99
+ */
100
+ protected function pluginsLoaded () {}
101
+
102
+ /**
103
+ * Fires on Widgets init.
104
+ * @return void
105
+ */
106
+ protected function registerWidgets () {}
107
+
108
+ /**
109
+ * Allows to check if plugin is ready to load components on implementations.
110
+ * Overwrite this method and return true to load components, false to omit components load.
111
+ *
112
+ * @return boolean If components can be loaded or not.
113
+ */
114
+ protected function readyForComponents ()
115
+ {
116
+ return false;
117
+ }
118
+
119
+ /**
120
+ * Activates the plugin. Only runs on first activation.
121
+ * Saves the plugin version in DB, and calls the 'pluginActivate' method.
122
+ *
123
+ * @uses do_action() Calls 'ak_activate_<modID>_plugin' action hook.
124
+ * @hook register_activation_hook
125
+ * @access private
126
+ * @return void
127
+ */
128
+ final function activate()
129
+ {
130
+ $this->pluginActivate();
131
+
132
+ // Save options and version
133
+ $this->cfg->saveOptions($this->ID);
134
+ add_option($this->ID . '_version', $this->version);
135
+
136
+ // Load and activate plugin components.
137
+ $this->components = ak_get_installed_components($this->componentsPath(), true);
138
+ if ( empty($this->components) ) {
139
+ $this->components = false;
140
+ } else {
141
+ foreach ( $this->components as $id => $component ) {
142
+ if ( $component['Core'] ) {
143
+ require_once( $component['File'] );
144
+ do_action('ak_activate_' . $this->ID . '_' . $id);
145
+ $this->components[$id]['active'] = 1;
146
+ } else {
147
+ $this->components[$id]['active'] = 0;
148
+ }
149
+ }
150
+ update_option($this->ID . '_components', $this->components);
151
+ }
152
+
153
+ // Do activated hook.
154
+ do_action('ak_activate_' . $this->ID . '_plugin');
155
+ }
156
+
157
+ /**
158
+ * Deactivates the plugin.
159
+ *
160
+ * @uses do_action() Calls 'ak_deactivate_<modID>_plugin' action hook.
161
+ * @hook register_deactivation_hook
162
+ * @access private
163
+ * @return void
164
+ */
165
+ final function deactivate()
166
+ {
167
+ $this->pluginDeactivate();
168
+ do_action('ak_deactivate_' . $this->ID . '_plugin');
169
+ }
170
+
171
+ /**
172
+ * Init the plugin (In action 'plugins_loaded')
173
+ * Here whe call the 'pluginUpdate' and 'pluginsLoaded' methods.
174
+ * Also the plugin version and settings are updated here.
175
+ *
176
+ * @hook action plugins_loaded
177
+ * @uses do_action() Calls the 'ak_<modID>_updated' action hook.
178
+ *
179
+ * @access private
180
+ * @return void
181
+ */
182
+ final function init()
183
+ {
184
+ // First, check if the plugin needs to be updated.
185
+ if ( $this->needs_update ) {
186
+ $version = get_option($this->ID . '_version');
187
+ $this->pluginUpdate($version);
188
+
189
+ $this->cfg->saveOptions($this->ID);
190
+ update_option($this->ID . '_version', $this->version);
191
+
192
+ $this->searchNewComponents();
193
+ do_action('ak_' . $this->ID . '_updated');
194
+ }
195
+
196
+ $this->pluginsLoaded();
197
+ $this->loadComponents();
198
+ }
199
+
200
+ /**
201
+ * Loads plugin components if found.
202
+ *
203
+ * @return void
204
+ */
205
+ final function loadComponents()
206
+ {
207
+ if ( ! $this->readyForComponents() ) {
208
+ return;
209
+ }
210
+
211
+ $this->components = get_option($this->ID . '_components');
212
+ if ( ! is_array($this->components) ) {
213
+ return;
214
+ }
215
+
216
+ foreach ( $this->components as $component ) {
217
+ if ( $component['active'] ) {
218
+ require_once ( $component['File']);
219
+ }
220
+ }
221
+
222
+ do_action('ak_' . $this->ID . '_components_init');
223
+ }
224
+
225
+ /**
226
+ * Reloads and updates installed components.
227
+ * If a new core component is found, it will be activated automatically.
228
+ *
229
+ * @return void
230
+ */
231
+ private function searchNewComponents ()
232
+ {
233
+ $components = ak_get_installed_components($this->componentsPath(), true);
234
+ if ( empty($components) ) {
235
+ $this->components = false;
236
+ return;
237
+ }
238
+
239
+ $installed = array();
240
+ $core = array();
241
+ $optional = array();
242
+
243
+ // Sort components by core and optional. Then by name.
244
+ foreach ( $components as $id => $component ) {
245
+ if ( $component['Core'] ) {
246
+ $core[$id] = $component;
247
+ } else {
248
+ $optional[$id] = $component;
249
+ }
250
+ }
251
+ ksort($core); ksort($optional); // Sort components by ID.
252
+ $components = array_merge($core, $optional);
253
+
254
+ // Now, activate new core components, and set activation for optional.
255
+ $this->components = get_option($this->ID . '_components');
256
+ foreach ( $components as $id => $component ) {
257
+ $installed[$id] = $component;
258
+ if ( $component['Core'] ) {
259
+ $installed[$id]['active'] = 1;
260
+ if ( ! isset($this->components[$id]) || ! $this->components[$id]['active'] ) {
261
+ require_once( $component['File']);
262
+ do_action('ak_activate_' . $this->ID . '_' . $id);
263
+ }
264
+ } else {
265
+ if ( isset($this->components[$id]['active']) ) {
266
+ $installed[$id]['active'] = $this->components[$id]['active'];
267
+ } else {
268
+ $installed[$id]['active'] = 0;
269
+ }
270
+ }
271
+ }
272
+
273
+ $this->components = $installed;
274
+ update_option($this->ID . '_components', $this->components);
275
+ }
276
+
277
+ /**
278
+ * Checks if a component is installed and active.
279
+ *
280
+ * @return boolean If the component is active or not.
281
+ */
282
+ public function activeComponent ( $name )
283
+ {
284
+ if ( ! is_array($this->components) ) {
285
+ return false;
286
+ }
287
+
288
+ $name = strtolower($name);
289
+ if ( isset($this->components[$name]) && $this->components[$name]['active'] ) {
290
+ return true;
291
+ } else {
292
+ return false;
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Inits the widgets (In action 'widgets_init')
298
+ * Before loading the widgets, we check that standard sidebar is present.
299
+ *
300
+ * @hook action 'widgets_init'
301
+ * @return void
302
+ */
303
+ final function widgetsInit()
304
+ {
305
+ if ( class_exists('WP_Widget') && function_exists('register_widget') && function_exists('unregister_widget') ) {
306
+ $this->registerWidgets();
307
+ do_action('ak_' . $this->ID . '_widgets_init');
308
+ } else {
309
+ add_action('admin_notices', array($this, 'noSidebarWarning'));
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Checks if the plugin is compatible with the current WordPress version.
315
+ * If it's not compatible, sets an admin warning.
316
+ *
317
+ * @return boolean Plugin is compatible with this WordPress version or not.
318
+ */
319
+ final public function isCompatible()
320
+ {
321
+ global $wp_version;
322
+
323
+ if ( version_compare($wp_version, $this->mod_data['Requires'] , '>=') ) {
324
+ return true;
325
+ } elseif ( ! has_action('admin_notices', array($this, 'noCompatibleWarning')) ) {
326
+ add_action('admin_notices', array($this, 'noCompatibleWarning'));
327
+ }
328
+
329
+ return false;
330
+ }
331
+
332
+ /**
333
+ * Shows a warning message when the plugin is not compatible with current WordPress version.
334
+ * This is used by calling the action 'admin_notices' in isCompatible()
335
+ *
336
+ * @hook action admin_notices
337
+ * @access private
338
+ * @return void
339
+ */
340
+ final function noCompatibleWarning()
341
+ {
342
+ $this->loadTranslations(); // We have not loaded translations yet.
343
+
344
+ echo '<div class="error"><p><strong>' . __('Warning:', 'akfw') . '</strong> '
345
+ . sprintf(__('The active plugin %s is not compatible with your WordPress version.', 'akfw'),
346
+ '&laquo;' . $this->mod_data['Name'] . ' ' . $this->version . '&raquo;')
347
+ . '</p><p>' . sprintf(__('WordPress %s is required to run this plugin.', 'akfw'), $this->mod_data['Requires'])
348
+ . '</p></div>';
349
+ }
350
+
351
+ /**
352
+ * Shows an admin warning when not using the WordPress standard sidebar.
353
+ * This is done by calling the action 'admin_notices' in isStandardSidebar()
354
+ *
355
+ * @hook action admin_notices
356
+ * @access private
357
+ * @return void
358
+ */
359
+ final function noSidebarWarning()
360
+ {
361
+ $this->loadTranslations(); // We have not loaded translations yet.
362
+
363
+ echo '<div class="error"><p><strong>' . __('Warning:', $this->ID) . '</strong> '
364
+ . __('Standard sidebar functions are not present.', $this->ID) . '</p><p>'
365
+ . sprintf(__('It is required to use the standard sidebar to run %s', $this->ID),
366
+ '&laquo;' . $this->mod_data['Name'] . ' ' . $this->version . '&raquo;')
367
+ . '</p></div>';
368
+ }
369
+
370
+ /**
371
+ * Loads plugins data.
372
+ *
373
+ * @return void
374
+ */
375
+ final protected function loadData()
376
+ {
377
+ if ( empty($this->mod_data) ) {
378
+ if ( ! function_exists('get_plugin_data') ) {
379
+ require_once ( ABSPATH . 'wp-admin/includes/plugin.php' );
380
+ }
381
+
382
+ $plugin_data = get_plugin_data($this->mod_file);
383
+ $readme_data = ak_module_readme_data($this->mod_file);
384
+ $this->mod_data = array_merge($readme_data, $plugin_data);
385
+
386
+ $this->version = $this->mod_data['Version'];
387
+ }
388
+ }
389
+
390
+ /**
391
+ * Returns the path to plugin components.
392
+ *
393
+ * @uses apply_filters() Applies the ak_<plugin>_components_path filter on default path.
394
+ * @return string Path to components directory.
395
+ */
396
+ final protected function componentsPath ()
397
+ {
398
+ $path = dirname($this->mod_file) . '/components';
399
+ return apply_filters('ak_' . $this->ID . '_components_path', $path);
400
+ }
401
+
402
+ /**
403
+ * Form part to activate/deactivate plugin components.
404
+ * To be included on other configuration or settings form.
405
+ * String for component name and description have to be included on plugin text_domain.
406
+ *
407
+ * @return void
408
+ */
409
+ final protected function componentActivationForm ()
410
+ {
411
+ if ( $this->getOption('disable-components-activation') ) {
412
+ return;
413
+ }
414
+
415
+ $this->searchNewComponents();
416
+ ?>
417
+ <dl>
418
+ <dt><?php _e('Activate Components', 'akfw'); ?></dt>
419
+ <dd>
420
+ <?php wp_nonce_field('ak-component-activation', '_aknonce', false); ?>
421
+ <table width="100%" class="form-table">
422
+ <?php foreach ( $this->components as $c) :
423
+ if ( ! $c['Core'] ) : ?>
424
+ <tr>
425
+ <th scope="row"><?php _e($c['Name'], $this->ID) ?>:</th>
426
+ <td>
427
+ <input type="radio" name="components[<?php echo $c['Component']; ?>]" value="1" <?php checked(1, $c['active']); ?> /> <?php _e('Yes', 'akfw'); ?> &nbsp;&nbsp;
428
+ <input type="radio" name="components[<?php echo $c['Component']; ?>]" value="0" <?php checked(0, $c['active']); ?> /> <?php _e('No', 'akfw'); ?> &nbsp;&nbsp;
429
+ <span class="setting-description"><?php _e($c['Description'], $this->ID); ?></span>
430
+ </td>
431
+ </tr>
432
+ <?php endif;
433
+ endforeach; ?>
434
+ </table>
435
+ </dd>
436
+ </dl>
437
+ <?php
438
+ }
439
+
440
+ /**
441
+ * Saves data from componets activation form.
442
+ * Activates or deactivates components as requested by user.
443
+ *
444
+ * @return void
445
+ */
446
+ final protected function saveActivationForm ()
447
+ {
448
+ if ( $this->getOption('disable-components-activation') ) {
449
+ return;
450
+ }
451
+
452
+ check_admin_referer('ak-component-activation', '_aknonce');
453
+ if ( isset($_POST['action']) && 'update' == $_POST['action'] ) {
454
+ $post = stripslashes_deep($_POST['components'] );
455
+ $this->components = get_option($this->ID . '_components');
456
+ $this->searchNewComponents();
457
+
458
+ foreach ( $post as $name => $activate ) {
459
+ if ( $activate && ! $this->components[$name]['active'] ) {
460
+ require_once( $this->components[$name]['File']);
461
+ do_action('ak_activate_' . $this->ID . '_' . $name);
462
+ } elseif ( ! $activate && $this->components[$name]['active'] ) {
463
+ require_once( $this->components[$name]['File']);
464
+ do_action('ak_deactivate_' . $this->ID . '_' . $name);
465
+ }
466
+ $this->components[$name]['active'] = $activate;
467
+ }
468
+ update_option($this->ID . '_components', $this->components);
469
+ } else {
470
+ wp_die('Bad form received.', $this->ID);
471
+ }
472
+ }
473
+ }
framework/classes/abstract/theme.php ADDED
@@ -0,0 +1,273 @@
1
+ <?php
2
+ /**
3
+ * Class for Themes management.
4
+ *
5
+ * @version $Rev: 203758 $
6
+ * @author Jordi Canals
7
+ * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
8
+ * @license GNU General Public License version 2
9
+ * @link http://alkivia.org
10
+ * @package Alkivia
11
+ * @subpackage Framework
12
+ *
13
+
14
+ Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License
18
+ version 2 as published by the Free Software Foundation.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+ */
28
+
29
+ require_once ( AK_CLASSES . '/abstract/module.php' );
30
+
31
+ /**
32
+ * Abtract class to be used as a theme template.
33
+ * Must be implemented before using this class.
34
+ * There are some special functions that have to be declared in implementations to perform main actions:
35
+ * - themeInit (Protected) Runs as soon as theme has been loaded.
36
+ * - themeInstall (Protected) Runs at theme install time and fires on the 'init' action hook.
37
+ * - themeUpdate (Proetected) Runs at theme update and fires on the 'init' action hook.
38
+ * - themeSideBars (Protected) Runs at theme load time and used to register the theme sidebars.
39
+ *
40
+ * @author Jordi Canals
41
+ * @package Alkivia
42
+ * @subpackage Framework
43
+ * @link http://wiki.alkivia.org/framework/classes/theme
44
+ *
45
+ * @uses akSettings
46
+ */
47
+
48
+ abstract class akThemeAbstract extends akModuleAbstract
49
+ {
50
+ /**
51
+ * Class constructor.
52
+ * Calls the implementated method 'startUp' if it exists. This is done at theme's loading time.
53
+ * Prepares admin menus by setting an action for the implemented method '_adminMenus' if it exists.
54
+ *
55
+ * @uses do_action() Calls the 'ak_theme_loaded' action hook.
56
+ * @param string $ID Theme internal short name (known as theme ID).
57
+ * @return akTheme
58
+ */
59
+ public function __construct ( $ID = '' )
60
+ {
61
+ parent::__construct('theme', $ID);
62
+
63
+ if ( $this->installing ) {
64
+ $this->install();
65
+ }
66
+
67
+ if ( function_exists('register_sidebars') ) {
68
+ $this->themeSideBars();
69
+ }
70
+
71
+ $this->configureTheme();
72
+ do_action('ak_theme_loaded');
73
+ }
74
+
75
+ /**
76
+ * Inits the theme at WordPress 'init' action hook
77
+ * @return void
78
+ */
79
+ protected function themeInit () {}
80
+
81
+ /**
82
+ * Installs the theme.
83
+ * @return void
84
+ */
85
+ protected function themeInstall () {}
86
+
87
+ /**
88
+ * Performs additional actions to update the theme.
89
+ * @param string $version Theme current installed version.
90
+ * @return void
91
+ */
92
+ protected function themeUpdate ( $version ) {}
93
+
94
+ /**
95
+ * Registers and sets theme sidebars.
96
+ * @return void
97
+ */
98
+ protected function themeSideBars () {}
99
+
100
+ /**
101
+ * Configure the theme based on theme settings.
102
+ *
103
+ * @uses do_action() Calls the 'ak_theme_options_set' action hook.
104
+ * @return void
105
+ */
106
+ final private function configureTheme()
107
+ {
108
+ // Set metatags
109
+ add_action('wp_head', array($this, 'metaTags') );
110
+
111
+ // Set the theme favicon
112
+ if ( ! $this->getOption('disable-favicon') ) {
113
+ add_action('wp_head', array($this, 'favicon'));
114
+ add_action('admin_head', array($this, 'favicon'));
115
+ }
116
+
117
+ // Enable self ping.
118
+ if ( ! $this->getOption('enable-selfping') ) {
119
+ add_action('pre_ping', array($this, 'disableSelfPing'));
120
+ }
121
+
122
+ do_action('ak_theme_options_set');
123
+ }
124
+
125
+ /**
126
+ * Installs the theme.
127
+ * Saves the theme version in DB, and calls the 'install' method.
128
+ *
129
+ * @uses do_action() Calls the 'ak_theme_installed' action hook.
130
+ * @return void
131
+ */
132
+ final private function install ()
133
+ {
134
+ // If there is an additional function to perform on installation.
135
+ $this->themeInstall();
136
+
137
+ // Save options and version
138
+ $this->cfg->saveOptions($this->ID);
139
+ add_option($this->ID . '_version', $this->version);
140
+
141
+ do_action('ak_theme_installed');
142
+ }
143
+
144
+ /**
145
+ * Init the theme (In action 'init')
146
+ * Here whe call the 'themeUpdate' and 'themeInit' methods. This is done after the plugins are loaded.
147
+ * Also the theme version and settings are updated here.
148
+ *
149
+ * @uses do_action() Calls the 'ak_theme_updated' action hook.
150
+ * @hook action 'init'
151
+ * @access private
152
+ * @return void
153
+ */
154
+ final function wpInit ()
155
+ {
156
+ // Check if the module needs to be updated.
157
+ if ( $this->needs_update ) {
158
+ $version = get_option($this->ID . '_version');
159
+ $this->themeUpdate($version);
160
+
161
+ $this->cfg->saveOptions($this->ID);
162
+ update_option($this->ID . '_version', $this->version);
163
+
164
+ do_action('ak_theme_updated');
165
+ }
166
+
167
+ // Call the custom init for the theme when system is loaded.
168
+ $this->themeInit();
169
+ }
170
+
171
+ /**
172
+ * Inits the widgets (In action 'widgets_init')
173
+ * In own themes standard sidebar always will be present (No check needed).
174
+ *
175
+ * @hook action 'widgets_init'
176
+ * @access private
177
+ * @return void
178
+ */
179
+ final function widgetsInit ()
180
+ {
181
+ do_action('ak_theme_widgets_init');
182
+ }
183
+
184
+ /**
185
+ * Disables self pings.
186
+ * This will disable sending pings to our own blog.
187
+ *
188
+ * @author Michael D. Adams
189
+ * @link http://blogwaffe.com/2006/10/04/421/
190
+ * @version 0.2
191
+ * @hook action 'pre_ping'
192
+ * @param array $links Link list of URLs to ping.
193
+ */
194
+ final function disableSelfPing( &$links )
195
+ {
196
+ $home = get_option( 'home' );
197
+ foreach ( $links as $l => $link ) {
198
+ if ( 0 === strpos( $link, $home ) ) {
199
+ unset($links[$l]);
200
+ }
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Sets the favicon for the theme.
206
+ *
207
+ * @uses apply_filters() Calls apply_filters with the 'ak_theme_favicon' hook and the favicon url as content.
208
+ * @hook actions 'wp_head' and 'admin_head'
209
+ * @access private
210
+ * @return void
211
+ */
212
+ final function favicon ()
213
+ {
214
+ $file = '/images/favicon.ico';
215
+ $favicon = $this->getOption('favicon-url');
216
+
217
+ if ( false === $favicon ) {
218
+ if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists(STYLESHEETPATH . $file) ) {
219
+ $favicon = get_stylesheet_directory_uri() . $file;
220
+ } elseif ( file_exists(TEMPLATEPATH . $file) ) {
221
+ $favicon = get_template_directory_uri() . $file;
222
+ } else {
223
+ $favicon = '';
224
+ }
225
+ }
226
+
227
+ $favicon = apply_filters('ak_theme_favicon', $favicon);
228
+ if ( ! empty($favicon) ) {
229
+ echo '<link rel="shortcut icon" href="' . $favicon . '" />' . PHP_EOL;
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Adds meta names for parent and child themes to head.
235
+ *
236
+ * @hook action 'wp_head'
237
+ * @access private
238
+ * @return void
239
+ */
240
+ final function metaTags()
241
+ {
242
+ echo '<meta name="theme" content="'
243
+ . $this->getModData('Name') . ' ' . $this->getModData('Version') . '" />' . PHP_EOL;
244
+
245
+ if ( $this->isChildTheme() ) {
246
+ echo '<meta name="child_theme" content="'
247
+ . $this->getChildData('Name') . ' ' . $this->getChildData('Version') . '" />' . PHP_EOL;
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Loads theme (and child) data.
253
+ *
254
+ * @return void
255
+ */
256
+ final protected function loadData()
257
+ {
258
+ $readme_data = ak_module_readme_data(TEMPLATEPATH . '/readme.txt');
259
+ if ( empty($this->mod_data) ) {
260
+ $theme_data = get_theme_data(TEMPLATEPATH . '/style.css');
261
+ $this->mod_data = array_merge($readme_data, $theme_data);
262
+ }
263
+
264
+ if ( TEMPLATEPATH !== STYLESHEETPATH && empty($this->child_data) ) {
265
+ $this->mod_type = self::CHILD_THEME;
266
+ $child_data = get_theme_data(STYLESHEETPATH . '/style.css');
267
+ $child_readme_data = ak_module_readme_data(STYLESHEETPATH . '/readme.txt');
268
+ $this->child_data = array_merge($readme_data, $child_readme_data, $child_data);
269
+ }
270
+
271
+ $this->version = $this->mod_data['Version'];
272
+ }
273
+ }
framework/classes/admin-notices.php ADDED
@@ -0,0 +1,70 @@
1
+ <?php
2
+ /**
3
+ * Admin notices (or warnings).
4
+ *
5
+ * @version $Rev: 198515 $
6
+ * @author Jordi Canals
7
+ * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
8
+ * @license GNU General Public License version 2
9
+ * @link http://alkivia.org
10
+ * @package Alkivia
11
+ * @subpackage Framework
12
+ *
13
+
14
+ Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License </