1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Class file for the Object_Sync_Sf_Activate class. |
4
|
|
|
* |
5
|
|
|
* @file |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
if ( ! class_exists( 'Object_Sync_Salesforce' ) ) { |
9
|
|
|
die(); |
10
|
|
|
} |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* What to do when the plugin is activated |
14
|
|
|
*/ |
15
|
|
|
class Object_Sync_Sf_Activate { |
16
|
|
|
|
17
|
|
|
protected $wpdb; |
18
|
|
|
protected $version; |
19
|
|
|
protected $slug; |
20
|
|
|
protected $option_prefix; |
21
|
|
|
protected $schedulable_classes; |
22
|
|
|
protected $queue; |
23
|
|
|
|
24
|
|
|
private $installed_version; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Constructor which sets up activate hooks |
28
|
|
|
* |
29
|
|
|
* @param object $wpdb |
30
|
|
|
* @param string $version |
31
|
|
|
* @param string $slug |
32
|
|
|
* @param string $option_prefix |
33
|
|
|
* @param array $schedulable_classes |
34
|
|
|
* @param object $queue |
35
|
|
|
* |
36
|
|
|
*/ |
37
|
|
|
public function __construct( $wpdb, $version, $slug, $option_prefix = '', $schedulable_classes = array(), $queue = '' ) { |
38
|
|
|
$this->wpdb = $wpdb; |
39
|
|
|
$this->version = $version; |
40
|
|
|
$this->slug = $slug; |
41
|
|
|
$this->option_prefix = isset( $option_prefix ) ? $option_prefix : 'object_sync_for_salesforce_'; |
42
|
|
|
$this->schedulable_classes = $schedulable_classes; |
43
|
|
|
$this->queue = $queue; |
44
|
|
|
|
45
|
|
|
$this->action_group_suffix = '_check_records'; |
46
|
|
|
$this->installed_version = get_option( $this->option_prefix . 'db_version', '' ); |
47
|
|
|
|
48
|
|
|
$this->add_actions(); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Activation hooks |
53
|
|
|
*/ |
54
|
|
|
private function add_actions() { |
55
|
|
|
|
56
|
|
|
// on initial activation, run these hooks |
57
|
|
|
register_activation_hook( dirname( __DIR__ ) . '/' . $this->slug . '.php', array( $this, 'php_requirements' ) ); |
58
|
|
|
register_activation_hook( dirname( __DIR__ ) . '/' . $this->slug . '.php', array( $this, 'wordpress_salesforce_tables' ) ); |
59
|
|
|
register_activation_hook( dirname( __DIR__ ) . '/' . $this->slug . '.php', array( $this, 'add_roles_capabilities' ) ); |
60
|
|
|
|
61
|
|
|
// make sure admin users have the installed version as a transient |
62
|
|
|
add_action( 'admin_init', array( $this, 'set_installed_version' ), 10 ); |
63
|
|
|
|
64
|
|
|
// this should run when the user is in the admin area to make sure the database gets updated |
65
|
|
|
add_action( 'admin_init', array( $this, 'wordpress_salesforce_update_db_check' ), 10 ); |
66
|
|
|
|
67
|
|
|
// when users upgrade the plugin, run these hooks |
68
|
|
|
add_action( 'upgrader_process_complete', array( $this, 'check_for_action_scheduler' ), 10, 2 ); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Check for the minimum required version of php |
73
|
|
|
*/ |
74
|
|
|
public function php_requirements() { |
75
|
|
|
if ( version_compare( PHP_VERSION, '5.5', '<' ) ) { |
76
|
|
|
deactivate_plugins( plugin_basename( __FILE__ ) ); |
77
|
|
|
wp_die( '<strong>This plugin requires PHP Version 5.5</strong> <br />Please contact your host to upgrade PHP on your server, and then retry activating the plugin.' ); |
78
|
|
|
} |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Create database tables for Salesforce |
83
|
|
|
* This creates tables for fieldmaps (between types of objects) and object maps (between indidual instances of objects) |
84
|
|
|
* |
85
|
|
|
*/ |
86
|
|
|
public function wordpress_salesforce_tables() { |
87
|
|
|
|
88
|
|
|
$charset_collate = $this->wpdb->get_charset_collate(); |
89
|
|
|
|
90
|
|
|
$field_map_table = $this->wpdb->prefix . 'object_sync_sf_field_map'; |
91
|
|
|
$field_map_sql = "CREATE TABLE $field_map_table ( |
92
|
|
|
id bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
93
|
|
|
label varchar(64) NOT NULL DEFAULT '', |
94
|
|
|
name varchar(64) NOT NULL DEFAULT '', |
95
|
|
|
wordpress_object varchar(128) NOT NULL DEFAULT '', |
96
|
|
|
salesforce_object varchar(255) NOT NULL DEFAULT '', |
97
|
|
|
salesforce_record_types_allowed longblob, |
98
|
|
|
salesforce_record_type_default varchar(255) NOT NULL DEFAULT '', |
99
|
|
|
fields longtext NOT NULL, |
100
|
|
|
pull_trigger_field varchar(128) NOT NULL DEFAULT 'LastModifiedDate', |
101
|
|
|
sync_triggers text NOT NULL, |
102
|
|
|
push_async tinyint(1) NOT NULL DEFAULT '0', |
103
|
|
|
push_drafts tinyint(1) NOT NULL DEFAULT '0', |
104
|
|
|
pull_to_drafts tinyint(1) NOT NULL DEFAULT '0', |
105
|
|
|
weight tinyint(1) NOT NULL DEFAULT '0', |
106
|
|
|
version varchar(255) NOT NULL DEFAULT '', |
107
|
|
|
PRIMARY KEY (id), |
108
|
|
|
UNIQUE KEY name (name), |
109
|
|
|
KEY name_sf_type_wordpress_type (wordpress_object,salesforce_object) |
110
|
|
|
) ENGINE=InnoDB $charset_collate"; |
111
|
|
|
|
112
|
|
|
$object_map_table = $this->wpdb->prefix . 'object_sync_sf_object_map'; |
113
|
|
|
$object_map_sql = "CREATE TABLE $object_map_table ( |
114
|
|
|
id bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
115
|
|
|
wordpress_id varchar(32) NOT NULL, |
116
|
|
|
salesforce_id varbinary(32) NOT NULL DEFAULT '', |
117
|
|
|
wordpress_object varchar(128) NOT NULL DEFAULT '', |
118
|
|
|
created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, |
119
|
|
|
object_updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, |
120
|
|
|
last_sync datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, |
121
|
|
|
last_sync_action varchar(128) DEFAULT NULL, |
122
|
|
|
last_sync_status tinyint(1) NOT NULL DEFAULT '0', |
123
|
|
|
last_sync_message varchar(255) DEFAULT NULL, |
124
|
|
|
PRIMARY KEY (id), |
125
|
|
|
KEY wordpress_object (wordpress_object,wordpress_id), |
126
|
|
|
KEY salesforce_object (salesforce_id) |
127
|
|
|
) $charset_collate"; |
128
|
|
|
|
129
|
|
|
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); |
130
|
|
|
|
131
|
|
|
// Note: see https://wordpress.stackexchange.com/questions/67345/how-to-implement-wordpress-plugin-update-that-modifies-the-database |
132
|
|
|
// When we run the dbDelta method below, "it checks if the table exists. What's more, it checks the column types. So if the table doesn't exist, it creates it, if it does, but some column types have changed it updates them, and if a column doesn't exists - it adds it." |
133
|
|
|
// This does not remove columns if we remove columns, so we'll need to expand beyond this in the future if that happens, although I think the schema is pretty solid now. |
134
|
|
|
dbDelta( $field_map_sql ); |
135
|
|
|
dbDelta( $object_map_sql ); |
136
|
|
|
|
137
|
|
|
update_option( $this->option_prefix . 'db_version', $this->version ); |
138
|
|
|
|
139
|
|
|
// store right now as the time for the plugin's activation |
140
|
|
|
update_option( $this->option_prefix . 'activate_time', current_time( 'timestamp', true ) ); |
141
|
|
|
|
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* Add roles and capabilities |
146
|
|
|
* This adds the configure_salesforce capability to the admin role |
147
|
|
|
* |
148
|
|
|
* It also allows other plugins to add the capability to other roles |
149
|
|
|
* |
150
|
|
|
*/ |
151
|
|
View Code Duplication |
public function add_roles_capabilities() { |
|
|
|
|
152
|
|
|
|
153
|
|
|
// by default, only administrators can configure the plugin |
154
|
|
|
$role = get_role( 'administrator' ); |
155
|
|
|
$role->add_cap( 'configure_salesforce' ); |
156
|
|
|
|
157
|
|
|
// hook that allows other roles to configure the plugin as well |
158
|
|
|
$roles = apply_filters( $this->option_prefix . 'roles_configure_salesforce', null ); |
159
|
|
|
|
160
|
|
|
// for each role that we have, give it the configure salesforce capability |
161
|
|
|
if ( null !== $roles ) { |
162
|
|
|
foreach ( $roles as $role ) { |
163
|
|
|
$role = get_role( $role ); |
164
|
|
|
$role->add_cap( 'configure_salesforce' ); |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Set the installed version |
172
|
|
|
*/ |
173
|
|
|
public function set_installed_version() { |
174
|
|
|
// Save the current plugin version in a transient |
175
|
|
|
set_transient( $this->option_prefix . 'installed_version', $this->installed_version ); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Check for database version |
180
|
|
|
* When the plugin is loaded in the admin, if the database version does not match the current version, perform these methods |
181
|
|
|
* |
182
|
|
|
*/ |
183
|
|
|
public function wordpress_salesforce_update_db_check() { |
184
|
|
|
// user is running a version less than the current one |
185
|
|
|
$previous_version = get_transient( $this->option_prefix . 'installed_version' ); |
186
|
|
|
if ( version_compare( $previous_version, $this->version, '<' ) ) { |
187
|
|
|
$this->wordpress_salesforce_tables(); |
188
|
|
|
delete_transient( $this->option_prefix . 'installed_version' ); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Check whether the user has action scheduler tasks when they upgrade |
194
|
|
|
* |
195
|
|
|
* @param object $upgrader_object |
196
|
|
|
* @param array $hook_extra |
197
|
|
|
* |
198
|
|
|
* See https://developer.wordpress.org/reference/hooks/upgrader_process_complete/ |
199
|
|
|
* |
200
|
|
|
*/ |
201
|
|
|
public function check_for_action_scheduler( $upgrader_object, $hook_extra ) { |
202
|
|
|
|
203
|
|
|
// skip if this action isn't this plugin being updated |
204
|
|
|
if ( 'plugin' !== $hook_extra['type'] && 'update' !== $hook_extra['action'] && $hook_extra['plugin'] !== $this->slug ) { |
205
|
|
|
return; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
// user is running a version less than 1.4.0 |
209
|
|
|
$action_scheduler_version = '1.4.0'; |
210
|
|
|
$previous_version = get_transient( $this->option_prefix . 'installed_version' ); |
211
|
|
|
if ( version_compare( $previous_version, $action_scheduler_version, '<' ) ) { |
212
|
|
|
// delete old options |
213
|
|
|
delete_option( $this->option_prefix . 'push_schedule_number' ); |
214
|
|
|
delete_option( $this->option_prefix . 'push_schedule_unit' ); |
215
|
|
|
delete_option( $this->option_prefix . 'salesforce_schedule_number' ); |
216
|
|
|
delete_option( $this->option_prefix . 'salesforce_schedule_unit' ); |
217
|
|
|
if ( '' === $this->queue ) { |
218
|
|
|
delete_transient( $this->option_prefix . 'installed_version' ); |
219
|
|
|
return; |
220
|
|
|
} |
221
|
|
|
foreach ( $this->schedulable_classes as $key => $schedule ) { |
222
|
|
|
$schedule_name = $key; |
223
|
|
|
$action_group_name = $schedule_name . $this->action_group_suffix; |
224
|
|
|
// exit if there is no initializer property on this schedule |
225
|
|
|
if ( ! isset( $this->schedulable_classes[ $schedule_name ]['initializer'] ) ) { |
226
|
|
|
continue; |
227
|
|
|
} |
228
|
|
|
// create new recurring task for action-scheduler to check for data to pull from Salesforce |
229
|
|
|
$this->queue->schedule_recurring( |
230
|
|
|
current_time( 'timestamp', true ), // plugin seems to expect UTC |
231
|
|
|
$this->queue->get_frequency( $schedule_name, 'seconds' ), |
232
|
|
|
$this->schedulable_classes[ $schedule_name ]['initializer'], |
233
|
|
|
array(), |
234
|
|
|
$action_group_name |
235
|
|
|
); |
236
|
|
|
} |
237
|
|
|
delete_transient( $this->option_prefix . 'installed_version' ); |
238
|
|
|
} |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
} |
242
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.