Toolset Types – Custom Post Types, Custom Fields and Taxonomies - Version 1.9

Version Description

  • Release date: 2016-02-17
  • New: Taxonomy term meta (custom fields for taxonomy).
  • Major upgrade to user interface.
  • Renamed "Custom Fields" to "Post Fields".
  • Added post arguments show_rest and rest_base to options on post type edit screen.
  • Added ability to rename built-in post types Posts, Pages and Media.
  • Added new filter "wpcf_exclude_meta_boxes_on_post_type" that allows to exclude own Post Types from wpcf_add_meta_boxes() function in order to avoid adding Types meta boxes to certain custom posts.
  • Added ability to modify the title placeholder, displayed when creating a new post, for each post type.
  • Added ability to deactivate built-in taxonomies.
  • CPTs can now be positioned anywhere in the admin menu.
  • Promotional messages can now be disabled in settings.
  • Fixed date fields so they properly display "hour" and "minutes" when they provide those options.
  • Fix wrong field type conversion options for checkboxes fields.
  • Avoid clearing the roles for the current user as global when editing a user by visiting its profile.
  • Properly escape data used as attributes on a javascript methods controlling the post types, taxonomies, Content Templates or user roles assigned to a field group.
  • Ensure a user creating children posts on a Fields Table table has the right capabilities to do so, including Access rights.
  • Extend meta queries coming from Views so they work with Types checkboxes fields for users and taxonomy terms. Also, allow filtering by checkbox value in addition to checkbox title.
  • Allow to filter checkboxes fields by a value that contains a comma in its title.
  • Fix pagination in the Fields Table of a parent post type: it was returning the posts per page setting to its default state of 5.
  • Fix the Next pagination button missing on Fields Tables when the table is set to show N children each time and you have N+1 children assigned to that parent.
  • Fix custom taxonomy export/import when it is attached to a post type whose slug starts with a number.
Download this release

Release Info

Developer christianglingener
Plugin Icon 128x128 Toolset Types – Custom Post Types, Custom Fields and Taxonomies
Version 1.9
Comparing to
See all releases

Code changes from version 1.8.11 to 1.9

Files changed (133) hide show
  1. admin.php +581 -384
  2. embedded/admin.php +58 -24
  3. embedded/bootstrap.php +84 -11
  4. embedded/classes/class.wpcf-post-types.php +2 -3
  5. embedded/classes/editor.php +57 -28
  6. embedded/classes/field.php +196 -3
  7. embedded/classes/field/accessor/abstract.php +81 -0
  8. embedded/classes/field/accessor/dummy.php +57 -0
  9. embedded/classes/field/accessor/termmeta.php +43 -0
  10. embedded/classes/field/accessor/termmeta_field.php +55 -0
  11. embedded/classes/field/data_saver.php +151 -0
  12. embedded/classes/field/datamapper/abstract.php +44 -0
  13. embedded/classes/field/datamapper/checkbox.php +27 -0
  14. embedded/classes/field/datamapper/checkboxes.php +68 -0
  15. embedded/classes/field/datamapper/identity.php +12 -0
  16. embedded/classes/field/definition.php +275 -0
  17. embedded/classes/field/definition_abstract.php +61 -0
  18. embedded/classes/field/definition_factory.php +455 -0
  19. embedded/classes/field/definition_generic.php +42 -0
  20. embedded/classes/field/definition_term.php +67 -0
  21. embedded/classes/field/group.php +338 -0
  22. embedded/classes/field/group_factory.php +259 -0
  23. embedded/classes/field/group_term.php +115 -0
  24. embedded/classes/field/group_term_factory.php +136 -0
  25. embedded/classes/field/hooks_api.php +31 -0
  26. embedded/classes/field/instance.php +124 -0
  27. embedded/classes/field/instance_abstract.php +66 -0
  28. embedded/classes/field/instance_term.php +216 -0
  29. embedded/classes/field/instance_unsaved.php +22 -0
  30. embedded/classes/field/renderer/abstract.php +21 -0
  31. embedded/classes/field/renderer/toolset_forms.php +81 -0
  32. embedded/classes/field/term_definition_factory.php +51 -0
  33. embedded/classes/field/type_definition.php +79 -0
  34. embedded/classes/field/type_definition_factory.php +127 -0
  35. embedded/classes/field/utils.php +66 -0
  36. embedded/classes/fields.php +8 -7
  37. embedded/classes/forms.php +135 -29
  38. embedded/classes/gui/term_field_editing.php +320 -0
  39. embedded/classes/helper.ajax.php +1 -1
  40. embedded/classes/loader.php +7 -5
  41. embedded/classes/post-types/messages.php +1 -1
  42. embedded/classes/relationship/form-child.php +23 -30
  43. embedded/classes/repeater.php +576 -0
  44. embedded/classes/usermeta_field.php +8 -6
  45. embedded/classes/utils.php +111 -0
  46. embedded/classes/validate.php +3 -460
  47. embedded/common/WPML/wpml-string-shortcode.php +0 -34
  48. embedded/common/Zip.php +0 -861
  49. embedded/common/array2xml.php +0 -55
  50. embedded/common/changelog.txt +0 -31
  51. embedded/common/classes/class-toolset-admin-bar-menu.php +0 -779
  52. embedded/common/classes/class.toolset.promo.php +0 -193
  53. embedded/common/classes/control_forms.php +0 -28
  54. embedded/common/classes/forms.php +0 -972
  55. embedded/common/classes/validate.php +0 -425
  56. embedded/common/classes/validation-cakephp.php +0 -1139
  57. embedded/common/debug/debug-information.php +0 -24
  58. embedded/common/debug/functions_debug_information.php +0 -160
  59. embedded/common/expression-parser/js/parser.js +0 -2923
  60. embedded/common/expression-parser/parser.php +0 -2892
  61. embedded/common/functions.php +0 -622
  62. embedded/common/localization/locale/orig/views.po +0 -4528
  63. embedded/common/localization/locale/views-ar.mo +0 -0
  64. embedded/common/localization/locale/views-bg_BG.mo +0 -0
  65. embedded/common/localization/locale/views-de_DE.mo +0 -0
  66. embedded/common/localization/locale/views-el.mo +0 -0
  67. embedded/common/localization/locale/views-es_ES.mo +0 -0
  68. embedded/common/localization/locale/views-fr_FR.mo +0 -0
  69. embedded/common/localization/locale/views-he_IL.mo +0 -0
  70. embedded/common/localization/locale/views-it_IT.mo +0 -0
  71. embedded/common/localization/locale/views-ja.mo +0 -0
  72. embedded/common/localization/locale/views-ko_KR.mo +0 -0
  73. embedded/common/localization/locale/views-nl_NL.mo +0 -0
  74. embedded/common/localization/locale/views-pl_PL.mo +0 -0
  75. embedded/common/localization/locale/views-pt_BR.mo +0 -0
  76. embedded/common/localization/locale/views-pt_PT.mo +0 -0
  77. embedded/common/localization/locale/views-ru_RU.mo +0 -0
  78. embedded/common/localization/locale/views-sv_SE.mo +0 -0
  79. embedded/common/localization/locale/views-uk.mo +0 -0
  80. embedded/common/localization/locale/views-vi.mo +0 -0
  81. embedded/common/localization/locale/views-zh_CN.mo +0 -0
  82. embedded/common/localization/locale/views-zh_TW.mo +0 -0
  83. embedded/common/localization/wpt-localization.php +0 -61
  84. embedded/common/res/css/colorbox.css +0 -88
  85. embedded/common/res/css/toolset-common.css +0 -74
  86. embedded/common/res/css/toolset-menu-icon.css +0 -29
  87. embedded/common/res/css/toolset-promotion.css +0 -164
  88. embedded/common/res/css/wpv-wp-pointer.css +0 -4
  89. embedded/common/res/images/question.png +0 -0
  90. embedded/common/res/images/toolset.promotion/full.jpg +0 -0
  91. embedded/common/res/images/toolset.promotion/icons.png +0 -0
  92. embedded/common/res/images/toolset.promotion/toolset.png +0 -0
  93. embedded/common/res/js/jquery.colorbox-min.js +0 -7
  94. embedded/common/res/js/toolset-promotion.js +0 -47
  95. embedded/common/res/js/wpv-wp-pointer.js +0 -17
  96. embedded/common/toolset-forms/api.php +0 -93
  97. embedded/common/toolset-forms/bootstrap.php +0 -300
  98. embedded/common/toolset-forms/classes/abstract.field.php +0 -34
  99. embedded/common/toolset-forms/classes/abstract.form.php +0 -48
  100. embedded/common/toolset-forms/classes/class.audio.php +0 -33
  101. embedded/common/toolset-forms/classes/class.button.php +0 -25
  102. embedded/common/toolset-forms/classes/class.checkbox.php +0 -66
  103. embedded/common/toolset-forms/classes/class.checkboxes.php +0 -90
  104. embedded/common/toolset-forms/classes/class.colorpicker.php +0 -106
  105. embedded/common/toolset-forms/classes/class.conditional.php +0 -534
  106. embedded/common/toolset-forms/classes/class.cred.php +0 -90
  107. embedded/common/toolset-forms/classes/class.credaudio.php +0 -24
  108. embedded/common/toolset-forms/classes/class.credfile.php +0 -186
  109. embedded/common/toolset-forms/classes/class.credimage.php +0 -22
  110. embedded/common/toolset-forms/classes/class.credvideo.php +0 -24
  111. embedded/common/toolset-forms/classes/class.date.php +0 -434
  112. embedded/common/toolset-forms/classes/class.date.scripts.php +0 -190
  113. embedded/common/toolset-forms/classes/class.eforms.php +0 -1226
  114. embedded/common/toolset-forms/classes/class.email.php +0 -12
  115. embedded/common/toolset-forms/classes/class.embed.php +0 -14
  116. embedded/common/toolset-forms/classes/class.field_factory.php +0 -166
  117. embedded/common/toolset-forms/classes/class.fieldconfig.php +0 -250
  118. embedded/common/toolset-forms/classes/class.file.php +0 -149
  119. embedded/common/toolset-forms/classes/class.form_factory.php +0 -482
  120. embedded/common/toolset-forms/classes/class.hidden.php +0 -20
  121. embedded/common/toolset-forms/classes/class.image.php +0 -43
  122. embedded/common/toolset-forms/classes/class.integer.php +0 -12
  123. embedded/common/toolset-forms/classes/class.numeric.php +0 -12
  124. embedded/common/toolset-forms/classes/class.password.php +0 -33
  125. embedded/common/toolset-forms/classes/class.phone.php +0 -12
  126. embedded/common/toolset-forms/classes/class.radios.php +0 -102
  127. embedded/common/toolset-forms/classes/class.recaptcha.php +0 -69
  128. embedded/common/toolset-forms/classes/class.repetitive.php +0 -41
  129. embedded/common/toolset-forms/classes/class.select.php +0 -87
  130. embedded/common/toolset-forms/classes/class.skype.php +0 -267
  131. embedded/common/toolset-forms/classes/class.submit.php +0 -37
  132. embedded/common/toolset-forms/classes/class.taxonomy.php +0 -219
  133. embedded/common/toolset-forms/classes/class.taxonomyhierarchical.php +0 -238
admin.php CHANGED
@@ -16,13 +16,74 @@ WPCF_Roles::getInstance();
16
  * TODO Revise it to change to 'admin_init'
17
  */
18
  add_action( 'admin_init', 'wpcf_admin_init_hook', 11 );
 
 
 
19
  add_action( 'admin_menu', 'wpcf_admin_menu_hook' );
20
  add_action( 'wpcf_admin_page_init', 'wpcf_enqueue_scripts' );
21
  add_action( 'admin_enqueue_scripts', 'wpcf_admin_enqueue_scripts' );
22
 
23
- wpcf_admin_load_teasers( array('types-access.php') );
24
  if ( defined( 'DOING_AJAX' ) ) {
25
  require_once WPCF_INC_ABSPATH . '/ajax.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
  include_once WPCF_ABSPATH.'/includes/classes/class.wpcf.marketing.messages.php';
28
  new WPCF_Types_Marketing_Messages();
@@ -50,48 +111,87 @@ function wpcf_admin_init_hook()
50
 
51
  wp_enqueue_style( 'wpcf-promo-tabs', WPCF_EMBEDDED_RES_RELPATH . '/css/tabs.css', array(), WPCF_VERSION );
52
  wp_enqueue_style('toolset-dashicons');
 
53
  }
54
 
 
55
  /**
56
- * admin_menu hook.
 
 
 
57
  */
58
- function wpcf_admin_menu_hook()
59
- {
60
- $wpcf_capability = apply_filters( 'wpcf_capability', WPCF_CUSTOM_POST_TYPE_VIEW);
61
 
62
- add_menu_page(
63
- __( 'Types', 'wpcf' ),
64
- __( 'Types', 'wpcf' ),
65
- $wpcf_capability,
66
- 'wpcf',
67
- 'wpcf_admin_menu_summary',
68
- 'none'
69
- );
 
 
 
 
 
 
 
 
 
 
 
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  $subpages = array();
72
 
73
- // Custom Post Types
 
 
 
 
 
 
 
 
 
74
  $subpages['wpcf-cpt'] = array(
75
  'menu_title' => __( 'Post Types', 'wpcf' ),
76
  'function' => 'wpcf_admin_menu_summary_cpt',
77
  'capability_filter' => 'wpcf_cpt_view',
78
  'capability' => WPCF_CUSTOM_POST_TYPE_VIEW,
 
79
  );
80
 
81
- // Custom Taxonomies
82
  $subpages['wpcf-ctt'] = array(
83
- 'menu_title' => __( 'Custom Taxonomies', 'wpcf' ),
84
  'function' => 'wpcf_admin_menu_summary_ctt',
85
  'capability_filter' => 'wpcf_ctt_view',
86
  'capability' => WPCF_CUSTOM_TAXONOMY_VIEW,
 
87
  );
88
 
89
  // Custom fields
90
  $subpages['wpcf-cf'] = array(
91
- 'menu_title' => __( 'Custom Fields', 'wpcf' ),
92
  'function' => 'wpcf_admin_menu_summary',
93
  'capability_filter' => 'wpcf_cf_view',
94
  'capability' => WPCF_CUSTOM_FIELD_VIEW,
 
95
  );
96
 
97
  // User Meta
@@ -100,192 +200,250 @@ function wpcf_admin_menu_hook()
100
  'function' => 'wpcf_usermeta_summary',
101
  'capability_filter' => 'wpcf_uf_view',
102
  'capability' => WPCF_USER_META_FIELD_VIEW,
 
103
  );
104
 
105
  // Settings
106
  $subpages['wpcf-custom-settings'] = array(
107
  'menu_title' => __( 'Settings', 'wpcf' ),
108
  'function' => 'wpcf_admin_menu_settings',
 
109
  );
110
 
111
- foreach( $subpages as $menu_slug => $menu ) {
112
- wpcf_admin_add_submenu_page($menu, $menu_slug);
113
- }
114
 
115
- if ( isset( $_GET['page'] ) ) {
116
- $current_page = $_GET['page'];
117
- switch ( $current_page ) {
118
- /**
119
- * User Fields Control
120
- */
121
- case 'wpcf-user-fields-control':
122
- wpcf_admin_add_submenu_page(
123
- array(
124
- 'menu_title' => __( 'User Fields Control', 'wpcf' ),
125
- 'function' => 'wpcf_admin_menu_user_fields_control',
126
- 'capability_filter' => 'wpcf_ufc_view',
127
- ),
128
- 'wpcf-user-fields-control'
129
- );
130
- break;
131
-
132
- /**
133
- * Custom Fields Control
134
- */
135
- case 'wpcf-custom-fields-control':
136
- wpcf_admin_add_submenu_page(
137
- array(
138
- 'menu_title' => __( 'Custom Fields Control', 'wpcf' ),
139
- 'function' => 'wpcf_admin_menu_custom_fields_control',
140
- 'capability_filter' => 'wpcf_cfc_view',
141
- ),
142
- 'wpcf-custom-fields-control'
143
- );
144
- break;
145
- /**
146
- * Import/Export
147
- */
148
- case 'wpcf-import-export':
149
- wpcf_admin_add_submenu_page(
150
- array(
151
- 'menu_title' => __( 'Import/Export', 'wpcf' ),
152
- 'function' => 'wpcf_admin_menu_import_export',
153
- ),
154
- 'wpcf-import-export'
155
- );
156
- break;
157
-
158
- /**
159
- * debug
160
- */
161
- case 'wpcf-debug-information':
162
- wpcf_admin_add_submenu_page(
163
- array(
164
- 'menu_title' => __( 'Debug Information', 'wpcf' ),
165
- 'function' => 'wpcf_admin_menu_debug_information',
166
- ),
167
- 'wpcf-debug-information'
168
- );
169
- break;
170
- /**
171
- * custom field grup
172
- */
173
- case 'wpcf-edit':
174
- $title = isset( $_GET['group_id'] ) ? __( 'Edit Group', 'wpcf' ) : __( 'Add New Custom Fields Group', 'wpcf' );
175
- $hook = wpcf_admin_add_submenu_page(
176
- array(
177
- 'menu_title' => $title,
178
- 'function' => 'wpcf_admin_menu_edit_fields',
179
- 'capability' => WPCF_CUSTOM_FIELD_VIEW
180
- ),
181
- $current_page
182
- );
183
- add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_fields_hook' );
184
- wpcf_admin_plugin_help( $hook, 'wpcf-edit' );
185
- break;
186
 
187
- case 'wpcf-view-custom-field':
188
- $hook = wpcf_admin_add_submenu_page(
189
- array(
190
- 'menu_title' => __('View Custom Fields Group', 'wpcf'),
191
- 'function' => 'wpcf_admin_menu_edit_fields',
192
- 'capability' => WPCF_CUSTOM_FIELD_VIEW
193
- ),
194
- $current_page
195
- );
196
- wpcf_admin_plugin_help( $hook, 'wpcf-edit' );
197
- break;
198
- /**
199
- * custom post
200
- */
201
- case 'wpcf-edit-type':
202
- $title = __( 'Add New Custom Post Type', 'wpcf' );
203
- if ( isset( $_GET['wpcf-post-type'] ) ) {
204
- $title = __( 'Edit Custom Post Type', 'wpcf' );
205
- if ( wpcf_is_builtin_post_types($_GET['wpcf-post-type']) ) {
206
- $title = __( 'Edit Post Type', 'wpcf' );
207
- }
208
- }
209
- $hook = wpcf_admin_add_submenu_page(
210
- array(
211
- 'menu_title' => $title,
212
- 'function' => 'wpcf_admin_menu_edit_type',
213
- 'capability' => WPCF_CUSTOM_FIELD_EDIT
214
- ),
215
- $current_page
216
- );
217
- add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_type_hook' );
218
- wpcf_admin_plugin_help( $hook, 'wpcf-edit-type' );
219
- break;
220
 
221
- case 'wpcf-view-type':
222
- $hook = wpcf_admin_add_submenu_page(
223
- array(
224
- 'menu_title' => __('View Custom Post Type', 'wpcf'),
225
- 'function' => 'wpcf_admin_menu_edit_type',
226
- 'capability' => WPCF_CUSTOM_FIELD_VIEW
227
- ),
228
- $current_page
229
- );
230
- add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_type_hook' );
231
- wpcf_admin_plugin_help( $hook, 'wpcf-edit-type' );
232
- break;
233
 
234
- case 'wpcf-edit-tax':
235
- $title = isset( $_GET['wpcf-tax'] ) ? __( 'Edit Custom Taxonomy', 'wpcf' ) : __( 'Add New Custom Taxonomy', 'wpcf' );
236
- $hook = wpcf_admin_add_submenu_page(
237
- array(
238
- 'menu_title' => $title,
239
- 'function' => 'wpcf_admin_menu_edit_tax',
240
- 'capability' => WPCF_CUSTOM_TAXONOMY_EDIT
241
- ),
242
- $current_page
243
- );
244
- add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_tax_hook' );
245
- wpcf_admin_plugin_help( $hook, 'wpcf-edit-tax' );
246
- break;
247
 
248
- case 'wpcf-view-tax':
249
- $hook = wpcf_admin_add_submenu_page(
250
- array(
251
- 'menu_title' => __('View Custom Taxonomy', 'wpcf'),
252
- 'function' => 'wpcf_admin_menu_edit_tax',
253
- 'capability' => WPCF_CUSTOM_TAXONOMY_VIEW
254
- ),
255
- $current_page
256
- );
257
- add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_tax_hook' );
258
- wpcf_admin_plugin_help( $hook, 'wpcf-edit-tax' );
259
- break;
260
 
261
- /**
262
- * user meta fields
263
- */
264
- case 'wpcf-edit-usermeta':
265
- $title = isset( $_GET['group_id'] ) ? __( 'Edit User Fields Group', 'wpcf' ) : __( 'Add New User Fields Group', 'wpcf' );
266
- $hook = wpcf_admin_add_submenu_page(
267
- array(
268
- 'menu_title' => $title,
269
- 'function' => 'wpcf_admin_menu_edit_user_fields',
270
- 'capability' => WPCF_USER_META_FIELD_EDIT,
271
- ),
272
- $current_page
273
- );
274
- wpcf_admin_plugin_help( $hook, 'wpcf-edit-usermeta' );
275
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
 
277
- case 'wpcf-view-usermeta':
278
- $hook = wpcf_admin_add_submenu_page(
279
- array(
280
- 'menu_title' => __('View User Fields Group', 'wpcf'),
281
- 'function' => 'wpcf_admin_menu_edit_user_fields',
282
- 'capability' => WPCF_USER_META_FIELD_VIEW,
283
- ),
284
- $current_page
285
- );
286
- wpcf_admin_plugin_help( $hook, 'wpcf-edit-usermeta' );
287
- break;
288
- }
289
  }
290
 
291
  // Check if migration from other plugin is needed
@@ -311,7 +469,28 @@ function wpcf_admin_menu_hook()
311
  */
312
  function wpcf_admin_menu_debug_information()
313
  {
314
- require_once WPCF_EMBEDDED_ABSPATH.'/common/debug/debug-information.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  }
316
 
317
  /**
@@ -331,7 +510,7 @@ function wpcf_admin_menu_summary_hook()
331
  {
332
  do_action( 'wpcf_admin_page_init' );
333
  wpcf_admin_load_collapsible();
334
- wpcf_admin_page_add_options('cf', __( 'Custom Fields', 'wpcf' ));
335
  }
336
 
337
  /**
@@ -339,7 +518,7 @@ function wpcf_admin_menu_summary_hook()
339
  */
340
  function wpcf_admin_menu_summary()
341
  {
342
- wpcf_add_admin_header( __( 'Custom Fields Groups', 'wpcf' ), array('page'=>'wpcf-edit'));
343
  require_once WPCF_INC_ABSPATH . '/fields.php';
344
  require_once WPCF_INC_ABSPATH . '/fields-list.php';
345
  $to_display = wpcf_admin_fields_get_fields();
@@ -350,70 +529,93 @@ function wpcf_admin_menu_summary()
350
  wpcf_add_admin_footer();
351
  }
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  /**
354
  * Menu page hook.
355
  */
356
  function wpcf_admin_menu_edit_fields_hook()
357
  {
358
- do_action( 'wpcf_admin_page_init' );
359
 
360
- /*
361
- * Enqueue scripts
362
- */
363
- // Group filter
364
- wp_enqueue_script( 'wpcf-filter-js',
365
- WPCF_EMBEDDED_RES_RELPATH
366
- . '/js/custom-fields-form-filter.js', array('jquery'), WPCF_VERSION );
367
- // Form
368
- wp_enqueue_script( 'wpcf-form-validation',
369
- WPCF_EMBEDDED_RES_RELPATH . '/js/'
370
- . 'jquery-form-validation/jquery.validate.min.js', array('jquery'),
371
- WPCF_VERSION );
372
- wp_enqueue_script( 'wpcf-form-validation-additional',
373
- WPCF_EMBEDDED_RES_RELPATH . '/js/'
374
- . 'jquery-form-validation/additional-methods.min.js',
375
- array('jquery'), WPCF_VERSION );
376
- // Scroll
377
- wp_enqueue_script( 'wpcf-scrollbar',
378
- WPCF_EMBEDDED_RELPATH . '/common/visual-editor/res/js/scrollbar.js',
379
- array('jquery') );
380
- wp_enqueue_script( 'wpcf-mousewheel',
381
- WPCF_EMBEDDED_RELPATH . '/common/visual-editor/res/js/mousewheel.js',
382
- array('wpcf-scrollbar') );
383
- // MAIN
384
- wp_enqueue_script( 'wpcf-fields-form',
385
- WPCF_EMBEDDED_RES_RELPATH
386
- . '/js/fields-form.js', array('wpcf-js') );
387
-
388
- /*
389
- * Enqueue styles
390
- */
391
- wp_enqueue_style( 'wpcf-scroll',
392
- WPCF_EMBEDDED_RELPATH . '/common/visual-editor/res/css/scroll.css' );
393
-
394
- //Css editor
395
- wp_enqueue_script( 'wpcf-form-codemirror' ,
396
- WPCF_RELPATH . '/resources/js/codemirror234/lib/codemirror.js', array('wpcf-js'));
397
- wp_enqueue_script( 'wpcf-form-codemirror-css-editor' ,
398
- WPCF_RELPATH . '/resources/js/codemirror234/mode/css/css.js', array('wpcf-js'));
399
- wp_enqueue_script( 'wpcf-form-codemirror-html-editor' ,
400
- WPCF_RELPATH . '/resources/js/codemirror234/mode/xml/xml.js', array('wpcf-js'));
401
- wp_enqueue_script( 'wpcf-form-codemirror-html-editor2' ,
402
- WPCF_RELPATH . '/resources/js/codemirror234/mode/htmlmixed/htmlmixed.js', array('wpcf-js'));
403
- wp_enqueue_script( 'wpcf-form-codemirror-editor-resize' ,
404
- WPCF_RELPATH . '/resources/js/jquery_ui/jquery.ui.resizable.min.js', array('wpcf-js'));
405
-
406
- wp_enqueue_style( 'wpcf-css-editor',
407
- WPCF_RELPATH . '/resources/js/codemirror234/lib/codemirror.css' );
408
- wp_enqueue_style( 'wpcf-css-editor-resize',
409
- WPCF_RELPATH . '/resources/js/jquery_ui/jquery.ui.theme.min.css' );
410
- wp_enqueue_style( 'wpcf-usermeta',
411
- WPCF_EMBEDDED_RES_RELPATH . '/css/usermeta.css' );
412
-
413
- add_action( 'admin_footer', 'wpcf_admin_fields_form_js_validation' );
414
  require_once WPCF_INC_ABSPATH . '/fields.php';
415
  require_once WPCF_INC_ABSPATH . '/fields-form.php';
416
- $form = wpcf_admin_fields_form();
 
 
 
 
417
  wpcf_form( 'wpcf_form_fields', $form );
418
  }
419
 
@@ -422,19 +624,24 @@ function wpcf_admin_menu_edit_fields_hook()
422
  */
423
  function wpcf_admin_menu_edit_fields()
424
  {
425
- $title = __('View Custom Fields Group', 'wpcf');
 
 
426
  if ( isset( $_GET['group_id'] ) ) {
427
- if ( WPCF_Roles::user_can_edit('custom-field', $_GET['group_id']) ) {
428
- $title = __( 'Edit Custom Fields Group', 'wpcf' );
 
 
 
429
  }
430
  } else if ( WPCF_Roles::user_can_create('custom-field')) {
431
- $title = __( 'Add New Custom Fields Group', 'wpcf' );
432
  }
433
- wpcf_add_admin_header( $title );
434
  wpcf_wpml_warning();
435
  $form = wpcf_form( 'wpcf_form_fields' );
436
  echo '<form method="post" action="" class="wpcf-fields-form wpcf-form-validate js-types-show-modal">';
437
- echo $form->renderForm();
438
  echo '</form>';
439
  wpcf_add_admin_footer();
440
  }
@@ -477,7 +684,7 @@ function wpcf_admin_menu_summary_cpt()
477
  wpcf_add_admin_header(
478
  __( 'Post Types', 'wpcf' ),
479
  array('page'=>'wpcf-edit-type'),
480
- __('Add New Custom Post Type', 'wpcf')
481
  );
482
  $to_display_posts = get_option( WPCF_OPTION_NAME_CUSTOM_TYPES, array() );
483
  $to_display_tax = get_option( WPCF_OPTION_NAME_CUSTOM_TAXONOMIES, array() );
@@ -494,7 +701,7 @@ function wpcf_admin_menu_summary_cpt()
494
  function wpcf_admin_menu_summary_ctt_hook()
495
  {
496
  wpcf_admin_menu_summary_cpt_ctt_hook();
497
- wpcf_admin_page_add_options('ctt', __( 'Custom Taxonomies', 'wpcf' ));
498
  }
499
 
500
  /**
@@ -502,7 +709,7 @@ function wpcf_admin_menu_summary_ctt_hook()
502
  */
503
  function wpcf_admin_menu_summary_ctt()
504
  {
505
- wpcf_add_admin_header( __( 'Custom Taxonomies', 'wpcf' ), array('page' => 'wpcf-edit-tax') );
506
  wpcf_admin_custom_taxonomies_list();
507
  do_action('wpcf_types_tax_list_table_after');
508
  wpcf_add_admin_footer();
@@ -513,13 +720,14 @@ function wpcf_admin_menu_summary_ctt()
513
  */
514
  function wpcf_admin_menu_edit_type_hook()
515
  {
 
516
  do_action( 'wpcf_admin_page_init' );
517
  require_once WPCF_EMBEDDED_INC_ABSPATH . '/custom-types.php';
518
  require_once WPCF_INC_ABSPATH . '/custom-types-form.php';
519
  require_once WPCF_INC_ABSPATH . '/post-relationship.php';
520
  wp_enqueue_script( 'wpcf-custom-types-form',
521
  WPCF_RES_RELPATH . '/js/'
522
- . 'custom-types-form.js', array('jquery'), WPCF_VERSION );
523
  wp_enqueue_script( 'wpcf-form-validation',
524
  WPCF_RES_RELPATH . '/js/'
525
  . 'jquery-form-validation/jquery.validate.min.js', array('jquery'),
@@ -528,9 +736,17 @@ function wpcf_admin_menu_edit_type_hook()
528
  WPCF_RES_RELPATH . '/js/'
529
  . 'jquery-form-validation/additional-methods.min.js',
530
  array('jquery'), WPCF_VERSION );
 
531
  add_action( 'admin_footer', 'wpcf_admin_types_form_js_validation' );
532
  wpcf_post_relationship_init();
533
- $form = wpcf_admin_custom_types_form();
 
 
 
 
 
 
 
534
  wpcf_form( 'wpcf_form_types', $form );
535
  }
536
 
@@ -539,13 +755,11 @@ function wpcf_admin_menu_edit_type_hook()
539
  */
540
  function wpcf_admin_menu_edit_type()
541
  {
542
- $title = __('View Custom Post Type', 'wpcf');
 
543
  if ( WPCF_Roles::user_can_edit('custom-post-type', array()) ) {
544
  if ( isset( $_GET['wpcf-post-type'] ) ) {
545
- $title = __( 'Edit Custom Post Type', 'wpcf' );
546
- if ( wpcf_is_builtin_post_types($_GET['wpcf-post-type']) ) {
547
- $title = __( 'Edit Post Type', 'wpcf' );
548
- }
549
  /**
550
  * add new CPT link
551
  */
@@ -555,14 +769,14 @@ function wpcf_admin_menu_edit_type()
555
  __('Add New', 'wpcf')
556
  );
557
  } else {
558
- $title = __( 'Add New Custom Post Type', 'wpcf' );
559
  }
560
  }
561
  wpcf_add_admin_header( $title );
562
  wpcf_wpml_warning();
563
  $form = wpcf_form( 'wpcf_form_types' );
564
  echo '<form method="post" action="" class="wpcf-types-form wpcf-form-validate js-types-do-not-show-modal">';
565
- echo $form->renderForm();
566
  echo '</form>';
567
  wpcf_add_admin_footer();
568
  }
@@ -581,10 +795,17 @@ function wpcf_admin_menu_edit_tax_hook()
581
  WPCF_RES_RELPATH . '/js/'
582
  . 'jquery-form-validation/additional-methods.min.js',
583
  array('jquery'), WPCF_VERSION );
 
 
 
584
  add_action( 'admin_footer', 'wpcf_admin_tax_form_js_validation' );
585
  require_once WPCF_EMBEDDED_INC_ABSPATH . '/custom-taxonomies.php';
586
  require_once WPCF_INC_ABSPATH . '/custom-taxonomies-form.php';
587
- $form = wpcf_admin_custom_taxonomies_form();
 
 
 
 
588
  wpcf_form( 'wpcf_form_tax', $form );
589
  }
590
 
@@ -593,18 +814,21 @@ function wpcf_admin_menu_edit_tax_hook()
593
  */
594
  function wpcf_admin_menu_edit_tax()
595
  {
596
- $title = __( 'View Custom Taxonomy', 'wpcf' );
 
 
597
  if ( WPCF_Roles::user_can_create('custom-taxonomy') ) {
598
- $title = __( 'Add New Custom Taxonomy', 'wpcf' );
599
  if ( isset( $_GET['wpcf-tax'] ) ) {
600
- $title = __( 'Edit Custom Taxonomy', 'wpcf' );
 
601
  }
602
  }
603
- wpcf_add_admin_header( $title, array('page' => 'wpcf-edit-tax' ));
604
  wpcf_wpml_warning();
605
  $form = wpcf_form( 'wpcf_form_tax' );
606
  echo '<form method="post" action="" class="wpcf-tax-form wpcf-form-validate js-types-show-modal">';
607
- echo $form->renderForm();
608
  echo '</form>';
609
  wpcf_add_admin_footer();
610
  }
@@ -642,37 +866,18 @@ function wpcf_admin_menu_import_export()
642
  */
643
  function wpcf_admin_menu_custom_fields_control_hook()
644
  {
645
- do_action( 'wpcf_admin_page_init' );
646
- add_action( 'admin_head', 'wpcf_admin_custom_fields_control_js' );
647
- add_thickbox();
648
- require_once WPCF_INC_ABSPATH . '/fields.php';
649
- require_once WPCF_EMBEDDED_INC_ABSPATH . '/fields.php';
650
  require_once WPCF_INC_ABSPATH . '/fields-control.php';
651
-
652
- if ( isset( $_REQUEST['_wpnonce'] )
653
- && wp_verify_nonce( $_REQUEST['_wpnonce'],
654
- 'custom_fields_control_bulk' )
655
- && (isset( $_POST['action'] ) || isset( $_POST['action2'] )) && !empty( $_POST['fields'] ) ) {
656
- $action = ( $_POST['action'] == '-1' ) ? sanitize_text_field( $_POST['action2'] ) : sanitize_text_field( $_POST['action'] );
657
- wpcf_admin_custom_fields_control_bulk_actions( $action );
658
- }
659
-
660
- global $wpcf_control_table;
661
- $wpcf_control_table = new WPCF_Custom_Fields_Control_Table( array(
662
- 'ajax' => true,
663
- 'singular' => __( 'Custom Field', 'wpcf' ),
664
- 'plural' => __( 'Custom Fields', 'wpcf' ),
665
- ) );
666
- $wpcf_control_table->prepare_items();
667
  }
668
 
 
669
  /**
670
  * Menu page display.
671
  */
672
  function wpcf_admin_menu_custom_fields_control()
673
  {
674
  global $wpcf_control_table;
675
- wpcf_add_admin_header( __( 'Custom Fields Control', 'wpcf' ) );
676
  echo '<form method="post" action="" id="wpcf-custom-fields-control-form" class="wpcf-custom-fields-control-form wpcf-form-validate" enctype="multipart/form-data">';
677
  echo wpcf_admin_custom_fields_control_form( $wpcf_control_table );
678
  wp_nonce_field( 'custom_fields_control_bulk' );
@@ -726,89 +931,16 @@ function wpcf_admin_menu_settings()
726
  {
727
  ob_start();
728
  wpcf_add_admin_header( __( 'Settings', 'wpcf' ) );
729
-
730
- ?>
731
  <form method="post" action="" id="wpcf-general-settings-form" class="wpcf-settings-form wpcf-form-validate">
732
- <?php
733
-
734
- $form = wpcf_form( 'wpcf_form_general_settings' );
735
- echo $form->renderForm();
736
-
737
- ?>
738
- </form>
739
- <table class="widefat" id="types-tools">
740
- <thead>
741
- <tr>
742
- <th><?php _e( 'Types tools', 'wpcf' ); ?></th>
743
- </tr>
744
- </thead>
745
- <tbody>
746
- <tr>
747
- <td>
748
  <?php
749
 
750
- $pages = array(
751
- 'wpcf-custom-fields-control' => array(
752
- 'page' => 'wpcf-custom-fields-control',
753
- 'name' => __('Custom Fields Control', 'wpcf'),
754
- 'description' => __('Allow to control custom fields.', 'wpcf'),
755
- ),
756
- 'wpcf-user-fields-control' => array(
757
- 'page' => 'wpcf-user-fields-control',
758
- 'name' => __('User Fields Control', 'wpcf'),
759
- 'description' => __('Allow to control user meta fields.', 'wpcf'),
760
- ),
761
- 'wpcf-import-export' => array(
762
- 'page' => 'wpcf-import-export',
763
- 'name' => __('Import/Export', 'wpcf'),
764
- 'description' => __('For import or export data from Types.', 'wpcf'),
765
- ),
766
- 'wpcf-access' => array(
767
- 'page' => 'wpcf-access',
768
- 'name' => __('Access', 'wpcf'),
769
- 'description' => __('Access lets you control what content types different users can read, edit and publish on your site and create custom roles.', 'wpcf'),
770
- ),
771
- 'installer' => array(
772
- 'page' => 'installer',
773
- 'name' => __('Installer', 'wpcf'),
774
- 'description' => __('This page lets you install plugins and update existing plugins.', 'wpcf'),
775
- ),
776
- 'wpcf-debug-information' => array(
777
- 'page' => 'wpcf-debug-information',
778
- 'name' => __('Debug Information', 'wpcf'),
779
- 'description' => __( 'For retrieving debug information if asked by a support person.', 'wpcf'),
780
- ),
781
- );
782
-
783
- /**
784
- * remove Access page if is a full version of Access
785
- * installer and running
786
- */
787
- if ( defined( 'WPCF_ACCESS_VERSION' ) ) {
788
- unset($pages['wpcf-access']);
789
- }
790
 
791
- echo '<ul>';
792
- foreach( $pages as $data ) {
793
- echo '<li>';
794
- printf(
795
- '<strong><a href="%s">%s</a></strong>',
796
- esc_url( admin_url(sprintf('admin.php?page=%s', $data['page']))),
797
- $data['name']
798
- );
799
- if ( isset($data['description']) && !empty($data['description'])) {
800
- echo ' - ';
801
- echo $data['description'];
802
- }
803
- echo '<li>';
804
- }
805
- echo '</ul>';
806
  ?>
807
- </td>
808
- </tr>
809
- </tbody>
810
- </table>
811
- <?php
812
  wpcf_add_admin_footer();
813
 
814
  echo ob_get_clean();
@@ -834,18 +966,21 @@ function wpcf_add_admin_header($title, $add_new = false, $add_new_title = false)
834
  * check user can?
835
  */
836
  switch($add_new['page']) {
837
- case 'wpcf-edit-type':
838
- $add_button = WPCF_Roles::user_can_create('custom-post-type');
839
- break;
840
- case 'wpcf-edit-tax':
841
- $add_button = WPCF_Roles::user_can_create('custom-taxonomy');
842
- break;
843
- case 'wpcf-edit':
844
- $add_button = WPCF_Roles::user_can_create('custom-field');
845
- break;
846
- case 'wpcf-edit-usermeta':
847
- $add_button = WPCF_Roles::user_can_create('user-meta-field');
848
- break;
 
 
 
849
  }
850
  if ( $add_button ) {
851
  printf(
@@ -1051,6 +1186,13 @@ function wpcf_admin_plugin_help($hook, $page)
1051
  case 'wpcf-edit-usermeta':
1052
  $call = 'user_fields_edit';
1053
  break;
 
 
 
 
 
 
 
1054
  }
1055
  }
1056
  if ( $call ) {
@@ -1266,13 +1408,17 @@ function wpcf_admin_add_submenu_page($menu, $menu_slug = null, $menu_parent = 'w
1266
  $menu_slug,
1267
  array_key_exists('function', $menu)? $menu['function']:null
1268
  );
 
 
 
 
1269
  if ( !empty($menu_slug) ) {
1270
  wpcf_admin_plugin_help( $hook, $menu_slug );
1271
  }
1272
  /**
1273
  * add action
1274
  */
1275
- if ( !array_key_exists('load_hook', $menu) && array_key_exists('function', $menu) ) {
1276
  $menu['load_hook'] = sprintf( '%s_hook', $menu['function'] );
1277
  }
1278
  if ( !empty($menu['load_hook']) && function_exists( $menu['load_hook'] ) ) {
@@ -1306,6 +1452,12 @@ function wpcf_usort_reorder($a,$b)
1306
  if ('title' == $orderby || !isset($a[$orderby])) {
1307
  $orderby = 'slug';
1308
  }
 
 
 
 
 
 
1309
  $result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
1310
  return ($order==='asc') ? $result : -$result; //Send final sort direction to usort
1311
  }
@@ -1316,3 +1468,48 @@ function wpcf_table_set_option($status, $option, $value)
1316
  return $value;
1317
  }
1318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * TODO Revise it to change to 'admin_init'
17
  */
18
  add_action( 'admin_init', 'wpcf_admin_init_hook', 11 );
19
+
20
+ add_action( 'init', 'wpcf_init_admin_pages' );
21
+
22
  add_action( 'admin_menu', 'wpcf_admin_menu_hook' );
23
  add_action( 'wpcf_admin_page_init', 'wpcf_enqueue_scripts' );
24
  add_action( 'admin_enqueue_scripts', 'wpcf_admin_enqueue_scripts' );
25
 
26
+ // OMG, why so early? At this point we don't even have embedded Types (with functions.php).
27
  if ( defined( 'DOING_AJAX' ) ) {
28
  require_once WPCF_INC_ABSPATH . '/ajax.php';
29
+ if ( isset($_REQUEST['action']) ) {
30
+ switch( $_REQUEST['action']){
31
+ /**
32
+ * post edit screen
33
+ */
34
+ case 'wpcf_edit_post_get_child_fields_screen':
35
+ case 'wpcf_edit_post_get_icons_list':
36
+ case 'wpcf_edit_post_save_child_fields':
37
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.edit.post.type.php';
38
+ new Types_Admin_Edit_Post_Type();
39
+ break;
40
+ /**
41
+ * custom fields group edit screen
42
+ */
43
+ case 'wpcf_ajax_filter':
44
+ case 'wpcf_edit_field_choose':
45
+ case 'wpcf_edit_field_insert':
46
+ case 'wpcf_edit_field_select':
47
+ case 'wpcf_edit_field_add_existed': {
48
+
49
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.edit.custom.fields.group.php';
50
+
51
+ // Be careful here. For some AJAX actions we rely on the fact that the page parameter is not set and/or
52
+ // that post and user fields can use the same handler (which is originally meant for post fields only).
53
+
54
+ // We don't have functions.php at this point, can't use wpcf_getpost().
55
+ $current_page = isset( $_REQUEST['page'] ) ? $_REQUEST['page'] : Types_Admin_Edit_Custom_Fields_Group::PAGE_NAME;
56
+ if( in_array( $current_page, array( Types_Admin_Edit_Custom_Fields_Group::PAGE_NAME, 'wpcf-edit-usermeta' ) ) ) {
57
+ new Types_Admin_Edit_Custom_Fields_Group();
58
+ }
59
+
60
+ // For other pages, we will initialize during the 'init' hook when the autoloader is already available.
61
+ // At this point we don't even have access to names of the pages.
62
+ // See wpcf_init_admin_pages().
63
+ break;
64
+ }
65
+ case 'wpcf_edit_field_condition_get':
66
+ case 'wpcf_edit_field_condition_get_row':
67
+ case 'wpcf_edit_field_condition_save':
68
+ case 'wpcf_edit_custom_field_group_get':
69
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.fields.conditional.php';
70
+ new Types_Fields_Conditional();
71
+ break;
72
+ case 'wpcf_edit_post_get_fields_box':
73
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.fields.php';
74
+ new Types_Admin_Fields();
75
+ break;
76
+ /**
77
+ * custom fields control screen
78
+ */
79
+ case 'wpcf_custom_fields_control_change_type':
80
+ case 'wpcf_custom_fields_control_get_groups':
81
+ case 'wpcf_usermeta_control_get_groups':
82
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.control.fields.php';
83
+ new Types_Admin_Control_Fields();
84
+ break;
85
+ }
86
+ }
87
  }
88
  include_once WPCF_ABSPATH.'/includes/classes/class.wpcf.marketing.messages.php';
89
  new WPCF_Types_Marketing_Messages();
111
 
112
  wp_enqueue_style( 'wpcf-promo-tabs', WPCF_EMBEDDED_RES_RELPATH . '/css/tabs.css', array(), WPCF_VERSION );
113
  wp_enqueue_style('toolset-dashicons');
114
+
115
  }
116
 
117
+
118
  /**
119
+ * Initialize admin pages.
120
+ *
121
+ * @todo This, also, needs a review very badly.
122
+ * @since 1.9
123
  */
124
+ function wpcf_init_admin_pages() {
 
 
125
 
126
+ if( is_admin() ) {
127
+ WPCF_Page_Listing_Termmeta::get_instance();
128
+ }
129
+
130
+ if( defined( 'DOING_AJAX' ) ) {
131
+ $action = wpcf_getpost( 'action' );
132
+ $current_page = wpcf_getpost( 'page' );
133
+
134
+ switch( $action ) {
135
+
136
+ case 'wpcf_edit_field_select':
137
+ case 'wpcf_ajax_filter': {
138
+ if( WPCF_Page_Edit_Termmeta::PAGE_NAME == $current_page ) {
139
+ WPCF_Page_Edit_Termmeta::get_instance()->initialize_ajax_handler();
140
+ }
141
+ break;
142
+ }
143
+ }
144
+ }
145
 
146
+
147
+ }
148
+
149
+
150
+ /**
151
+ * Get information about admin menu subpages.
152
+ *
153
+ * It is also being used as a source for dashboard items.
154
+ *
155
+ * @return array See the wpcf_admin_menu_get_subpages filter description.
156
+ */
157
+ function wpcf_admin_menu_get_subpages()
158
+ {
159
  $subpages = array();
160
 
161
+ // Dashboard
162
+ $subpages['wpcf-dashboard'] = array(
163
+ 'menu_title' => __( 'Dashboard', 'wpcf' ),
164
+ 'function' => 'wpcf_admin_menu_summary_dashboard',
165
+ 'capability_filter' => 'wpcf_cpt_view',
166
+ 'capability' => WPCF_CUSTOM_POST_TYPE_VIEW,
167
+ 'context' => 'menu_only',
168
+ );
169
+
170
+ // Post Types
171
  $subpages['wpcf-cpt'] = array(
172
  'menu_title' => __( 'Post Types', 'wpcf' ),
173
  'function' => 'wpcf_admin_menu_summary_cpt',
174
  'capability_filter' => 'wpcf_cpt_view',
175
  'capability' => WPCF_CUSTOM_POST_TYPE_VIEW,
176
+ 'toolset_icon' => 'dashicons dashicons-admin-post',
177
  );
178
 
179
+ // Taxonomies
180
  $subpages['wpcf-ctt'] = array(
181
+ 'menu_title' => __( 'Taxonomies', 'wpcf' ),
182
  'function' => 'wpcf_admin_menu_summary_ctt',
183
  'capability_filter' => 'wpcf_ctt_view',
184
  'capability' => WPCF_CUSTOM_TAXONOMY_VIEW,
185
+ 'toolset_icon' => 'dashicons dashicons-tag',
186
  );
187
 
188
  // Custom fields
189
  $subpages['wpcf-cf'] = array(
190
+ 'menu_title' => __( 'Post Fields', 'wpcf' ),
191
  'function' => 'wpcf_admin_menu_summary',
192
  'capability_filter' => 'wpcf_cf_view',
193
  'capability' => WPCF_CUSTOM_FIELD_VIEW,
194
+ 'toolset_icon' => 'dashicons dashicons-forms',
195
  );
196
 
197
  // User Meta
200
  'function' => 'wpcf_usermeta_summary',
201
  'capability_filter' => 'wpcf_uf_view',
202
  'capability' => WPCF_USER_META_FIELD_VIEW,
203
+ 'toolset_icon' => 'dashicons dashicons-id-alt',
204
  );
205
 
206
  // Settings
207
  $subpages['wpcf-custom-settings'] = array(
208
  'menu_title' => __( 'Settings', 'wpcf' ),
209
  'function' => 'wpcf_admin_menu_settings',
210
+ 'toolset_icon' => 'dashicons dashicons-admin-settings',
211
  );
212
 
 
 
 
213
 
214
+ /**
215
+ * Allow for adding more admin menu subpages.
216
+ *
217
+ * Each subpage definition is an associative with following elements:
218
+ *
219
+ * string $menu_title: Title to be displayed in the menu.
220
+ * string $function: Callback function name to render the page.
221
+ * string $capability_filter: Name of the filter that will be applied to the capability,
222
+ * see wpcf_admin_add_submenu_page() for details.
223
+ * string $capability: Capability required to access the page.
224
+ * string $context: Where to display this menu item. 'context_only'|'dashboard_only'|missing
225
+ *
226
+ * Key of the subpage definition is the page name.
227
+ */
228
+ $subpages = apply_filters( 'wpcf_admin_menu_get_subpages', $subpages );
229
+
230
+ return $subpages;
231
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
+ /**
234
+ * admin_menu hook.
235
+ */
236
+ function wpcf_admin_menu_hook()
237
+ {
238
+ $wpcf_capability = apply_filters( 'wpcf_capability', WPCF_CUSTOM_POST_TYPE_VIEW);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
+ add_menu_page(
241
+ __( 'Types', 'wpcf' ),
242
+ __( 'Types', 'wpcf' ),
243
+ $wpcf_capability,
244
+ 'wpcf',
245
+ 'wpcf_admin_menu_summary'
246
+ );
 
 
 
 
 
247
 
248
+ $subpages = wpcf_admin_menu_get_subpages();
 
 
 
 
 
 
 
 
 
 
 
 
249
 
250
+ foreach( $subpages as $menu_slug => $menu ) {
251
+ if ( isset($menu['context']) && 'dashboard_only' == $menu['context'] ) {
252
+ continue;
253
+ }
254
+ wpcf_admin_add_submenu_page($menu, $menu_slug);
255
+ }
 
 
 
 
 
 
256
 
257
+ if ( isset( $_GET['page'] ) ) {
258
+ $current_page = $_GET['page'];
259
+ switch ( $current_page ) {
260
+ /**
261
+ * User Fields Control
262
+ */
263
+ case 'wpcf-user-fields-control':
264
+ wpcf_admin_add_submenu_page(
265
+ array(
266
+ 'menu_title' => __( 'User Field Control', 'wpcf' ),
267
+ 'function' => 'wpcf_admin_menu_user_fields_control',
268
+ 'capability_filter' => 'wpcf_ufc_view',
269
+ ),
270
+ 'wpcf-user-fields-control'
271
+ );
272
+ break;
273
+
274
+ /**
275
+ * Post Fields Control
276
+ */
277
+ case 'wpcf-custom-fields-control':
278
+ wpcf_admin_add_submenu_page(
279
+ array(
280
+ 'menu_title' => __( 'Post Field Control', 'wpcf' ),
281
+ 'function' => 'wpcf_admin_menu_custom_fields_control',
282
+ 'capability_filter' => 'wpcf_cfc_view',
283
+ ),
284
+ 'wpcf-custom-fields-control'
285
+ );
286
+ break;
287
+ /**
288
+ * Import/Export
289
+ */
290
+ case 'wpcf-import-export':
291
+ wpcf_admin_add_submenu_page(
292
+ array(
293
+ 'menu_title' => __( 'Import/Export', 'wpcf' ),
294
+ 'function' => 'wpcf_admin_menu_import_export',
295
+ ),
296
+ 'wpcf-import-export'
297
+ );
298
+ break;
299
+
300
+ /**
301
+ * debug
302
+ */
303
+ case 'wpcf-debug-information':
304
+ wpcf_admin_add_submenu_page(
305
+ array(
306
+ 'menu_title' => __( 'Debug Information', 'wpcf' ),
307
+ 'function' => 'wpcf_admin_menu_debug_information',
308
+ ),
309
+ 'wpcf-debug-information'
310
+ );
311
+ break;
312
+ /**
313
+ * custom field grup
314
+ */
315
+ case 'wpcf-edit':
316
+ $title = isset( $_GET['group_id'] ) ? __( 'Edit Group', 'wpcf' ) : __( 'Add New Post Field Group', 'wpcf' );
317
+ $hook = wpcf_admin_add_submenu_page(
318
+ array(
319
+ 'menu_title' => $title,
320
+ 'function' => 'wpcf_admin_menu_edit_fields',
321
+ 'capability' => WPCF_CUSTOM_FIELD_VIEW
322
+ ),
323
+ $current_page
324
+ );
325
+ add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_fields_hook' );
326
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit' );
327
+ break;
328
+
329
+ case 'wpcf-view-custom-field':
330
+ $hook = wpcf_admin_add_submenu_page(
331
+ array(
332
+ 'menu_title' => __( 'View Post Field Group', 'wpcf' ),
333
+ 'function' => 'wpcf_admin_menu_edit_fields',
334
+ 'capability' => WPCF_CUSTOM_FIELD_VIEW
335
+ ),
336
+ $current_page
337
+ );
338
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit' );
339
+ break;
340
+ /**
341
+ * custom post
342
+ */
343
+ case 'wpcf-edit-type':
344
+ $title = __( 'Add New Post Type', 'wpcf' );
345
+ if ( isset( $_GET['wpcf-post-type'] ) ) {
346
+ $title = __( 'Edit Post Type', 'wpcf' );
347
+ }
348
+ $hook = wpcf_admin_add_submenu_page(
349
+ array(
350
+ 'menu_title' => $title,
351
+ 'function' => 'wpcf_admin_menu_edit_type',
352
+ 'capability' => WPCF_CUSTOM_FIELD_EDIT
353
+ ),
354
+ $current_page
355
+ );
356
+ add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_type_hook' );
357
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit-type' );
358
+ break;
359
+
360
+ case 'wpcf-view-type':
361
+ $hook = wpcf_admin_add_submenu_page(
362
+ array(
363
+ 'menu_title' => __( 'View Post Type', 'wpcf' ),
364
+ 'function' => 'wpcf_admin_menu_edit_type',
365
+ 'capability' => WPCF_CUSTOM_FIELD_VIEW
366
+ ),
367
+ $current_page
368
+ );
369
+ add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_type_hook' );
370
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit-type' );
371
+ break;
372
+
373
+ case 'wpcf-edit-tax':
374
+ $title = isset( $_GET['wpcf-tax'] ) ? __( 'Edit Taxonomy', 'wpcf' ) : __( 'Add New Taxonomy', 'wpcf' );
375
+ $hook = wpcf_admin_add_submenu_page(
376
+ array(
377
+ 'menu_title' => $title,
378
+ 'function' => 'wpcf_admin_menu_edit_tax',
379
+ 'capability' => WPCF_CUSTOM_TAXONOMY_EDIT
380
+ ),
381
+ $current_page
382
+ );
383
+ add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_tax_hook' );
384
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit-tax' );
385
+ break;
386
+
387
+ case 'wpcf-view-tax':
388
+ $hook = wpcf_admin_add_submenu_page(
389
+ array(
390
+ 'menu_title' => __( 'View Taxonomy', 'wpcf' ),
391
+ 'function' => 'wpcf_admin_menu_edit_tax',
392
+ 'capability' => WPCF_CUSTOM_TAXONOMY_VIEW
393
+ ),
394
+ $current_page
395
+ );
396
+ add_action( 'load-' . $hook, 'wpcf_admin_menu_edit_tax_hook' );
397
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit-tax' );
398
+ break;
399
+
400
+ /**
401
+ * user meta fields
402
+ */
403
+ case 'wpcf-edit-usermeta':
404
+ $title = isset( $_GET['group_id'] ) ? __( 'Edit User Field Group', 'wpcf' ) : __( 'Add New User Field Group', 'wpcf' );
405
+ $hook = wpcf_admin_add_submenu_page(
406
+ array(
407
+ 'menu_title' => $title,
408
+ 'function' => 'wpcf_admin_menu_edit_user_fields',
409
+ 'capability' => WPCF_USER_META_FIELD_EDIT,
410
+ ),
411
+ $current_page
412
+ );
413
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit-usermeta' );
414
+ break;
415
+
416
+ case 'wpcf-view-usermeta':
417
+ $hook = wpcf_admin_add_submenu_page(
418
+ array(
419
+ 'menu_title' => __( 'View User Field Group', 'wpcf' ),
420
+ 'function' => 'wpcf_admin_menu_edit_user_fields',
421
+ 'capability' => WPCF_USER_META_FIELD_VIEW,
422
+ ),
423
+ $current_page
424
+ );
425
+ wpcf_admin_plugin_help( $hook, 'wpcf-edit-usermeta' );
426
+ break;
427
+
428
+ case WPCF_Page_Edit_Termmeta::PAGE_NAME:
429
+
430
+ // Initialize the page.
431
+ /** @var WPCF_Page_Edit_Termmeta $termmeta_page */
432
+ $termmeta_page = WPCF_Page_Edit_Termmeta::get_instance();
433
+ $termmeta_page->initialize();
434
+
435
+ break;
436
+
437
+ case WPCF_Page_Control_Termmeta::PAGE_NAME:
438
+
439
+ // Initialize by creating an instance.
440
+ /** @var WPCF_Page_Control_Termmeta $term_field_control_page */
441
+ $term_field_control_page = WPCF_Page_Control_Termmeta::get_instance();
442
+ $term_field_control_page->initialize();
443
+ break;
444
+
445
+ }
446
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  }
448
 
449
  // Check if migration from other plugin is needed
469
  */
470
  function wpcf_admin_menu_debug_information()
471
  {
472
+ require_once WPCF_EMBEDDED_ABSPATH.'/toolset/toolset-common/debug/debug-information.php';
473
+ }
474
+
475
+ /**
476
+ * Types Dashboard
477
+ */
478
+ function wpcf_admin_menu_summary_dashboard_hook()
479
+ {
480
+ do_action( 'wpcf_admin_page_init' );
481
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.dashboard.php';
482
+ $wpcf_admin = new Types_Dashboard();
483
+ $form = $wpcf_admin->form();
484
+ wpcf_form( 'wpcf_form_dashboard', $form );
485
+ }
486
+
487
+ function wpcf_admin_menu_summary_dashboard()
488
+ {
489
+ $post_type = current_filter();
490
+ wpcf_add_admin_header( __( 'Dashboard', 'wpcf' ));
491
+ $form = wpcf_form( 'wpcf_form_dashboard' );
492
+ $form_output = $form->renderForm();
493
+ wpcf_admin_screen($post_type, $form_output);
494
  }
495
 
496
  /**
510
  {
511
  do_action( 'wpcf_admin_page_init' );
512
  wpcf_admin_load_collapsible();
513
+ wpcf_admin_page_add_options('cf', __( 'Post Fields', 'wpcf' ));
514
  }
515
 
516
  /**
518
  */
519
  function wpcf_admin_menu_summary()
520
  {
521
+ wpcf_add_admin_header( __( 'Post Field Groups', 'wpcf' ), array('page'=>'wpcf-edit'));
522
  require_once WPCF_INC_ABSPATH . '/fields.php';
523
  require_once WPCF_INC_ABSPATH . '/fields-list.php';
524
  $to_display = wpcf_admin_fields_get_fields();
529
  wpcf_add_admin_footer();
530
  }
531
 
532
+
533
+ function wpcf_admin_enqueue_group_edit_page_assets() {
534
+ do_action( 'wpcf_admin_page_init' );
535
+
536
+ /*
537
+ * Enqueue scripts
538
+ */
539
+ // Group filter
540
+ wp_enqueue_script( 'wpcf-filter-js',
541
+ WPCF_EMBEDDED_RES_RELPATH
542
+ . '/js/custom-fields-form-filter.js', array('jquery'), WPCF_VERSION );
543
+ // Form
544
+ wp_enqueue_script( 'wpcf-form-validation',
545
+ WPCF_EMBEDDED_RES_RELPATH . '/js/'
546
+ . 'jquery-form-validation/jquery.validate.min.js', array('jquery'),
547
+ WPCF_VERSION );
548
+ wp_enqueue_script( 'wpcf-form-validation-additional',
549
+ WPCF_EMBEDDED_RES_RELPATH . '/js/'
550
+ . 'jquery-form-validation/additional-methods.min.js',
551
+ array('jquery'), WPCF_VERSION );
552
+ // Scroll
553
+ wp_enqueue_script( 'wpcf-scrollbar',
554
+ WPCF_EMBEDDED_RELPATH . '/toolset/toolset-common/visual-editor/res/js/scrollbar.js',
555
+ array('jquery') );
556
+ wp_enqueue_script( 'wpcf-mousewheel',
557
+ WPCF_EMBEDDED_RELPATH . '/toolset/toolset-common/visual-editor/res/js/mousewheel.js',
558
+ array('wpcf-scrollbar') );
559
+ // MAIN
560
+ wp_enqueue_script(
561
+ 'wpcf-fields-form',
562
+ WPCF_EMBEDDED_RES_RELPATH.'/js/fields-form.js',
563
+ array( 'wpcf-js' ),
564
+ WPCF_VERSION
565
+ );
566
+ wp_enqueue_script(
567
+ 'wpcf-admin-fields-form',
568
+ WPCF_RES_RELPATH.'/js/fields-form.js',
569
+ array(),
570
+ WPCF_VERSION
571
+ );
572
+
573
+ /*
574
+ * Enqueue styles
575
+ */
576
+ wp_enqueue_style( 'wpcf-scroll',
577
+ WPCF_EMBEDDED_RELPATH . '/toolset/toolset-common/visual-editor/res/css/scroll.css' );
578
+
579
+ //Css editor
580
+ wp_enqueue_script( 'wpcf-form-codemirror' ,
581
+ WPCF_RELPATH . '/resources/js/codemirror234/lib/codemirror.js', array('wpcf-js'));
582
+ wp_enqueue_script( 'wpcf-form-codemirror-css-editor' ,
583
+ WPCF_RELPATH . '/resources/js/codemirror234/mode/css/css.js', array('wpcf-js'));
584
+ wp_enqueue_script( 'wpcf-form-codemirror-html-editor' ,
585
+ WPCF_RELPATH . '/resources/js/codemirror234/mode/xml/xml.js', array('wpcf-js'));
586
+ wp_enqueue_script( 'wpcf-form-codemirror-html-editor2' ,
587
+ WPCF_RELPATH . '/resources/js/codemirror234/mode/htmlmixed/htmlmixed.js', array('wpcf-js'));
588
+ wp_enqueue_script( 'wpcf-form-codemirror-editor-resize' ,
589
+ WPCF_RELPATH . '/resources/js/jquery_ui/jquery.ui.resizable.min.js', array('wpcf-js'));
590
+
591
+ wp_enqueue_style( 'wpcf-css-editor',
592
+ WPCF_RELPATH . '/resources/js/codemirror234/lib/codemirror.css' );
593
+ //wp_enqueue_style( 'wpcf-css-editor-resize',
594
+ // WPCF_RELPATH . '/resources/js/jquery_ui/jquery.ui.theme.min.css' );
595
+ wp_enqueue_style( 'wpcf-usermeta',
596
+ WPCF_EMBEDDED_RES_RELPATH . '/css/usermeta.css' );
597
+
598
+ wp_enqueue_style( 'font-awesome' );
599
+
600
+ add_action( 'admin_footer', 'wpcf_admin_fields_form_js_validation' );
601
+
602
+ }
603
+
604
+
605
  /**
606
  * Menu page hook.
607
  */
608
  function wpcf_admin_menu_edit_fields_hook()
609
  {
610
+ wpcf_admin_enqueue_group_edit_page_assets();
611
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612
  require_once WPCF_INC_ABSPATH . '/fields.php';
613
  require_once WPCF_INC_ABSPATH . '/fields-form.php';
614
+ // $form = wpcf_admin_fields_form();
615
+ //require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.edit.custom.fields.group.php';
616
+ $wpcf_admin = new Types_Admin_Edit_Custom_Fields_Group();
617
+ $wpcf_admin->init_admin();
618
+ $form = $wpcf_admin->form();
619
  wpcf_form( 'wpcf_form_fields', $form );
620
  }
621
 
624
  */
625
  function wpcf_admin_menu_edit_fields()
626
  {
627
+ $add_new = false;
628
+ $post_type = current_filter();
629
+ $title = __('View Post Field Group', 'wpcf');
630
  if ( isset( $_GET['group_id'] ) ) {
631
+ if ( WPCF_Roles::user_can_edit('custom-field', array('id' => $_GET['group_id']))) {
632
+ $title = __( 'Edit Post Field Group', 'wpcf' );
633
+ $add_new = array(
634
+ 'page' => 'wpcf-edit',
635
+ );
636
  }
637
  } else if ( WPCF_Roles::user_can_create('custom-field')) {
638
+ $title = __( 'Add New Post Field Group', 'wpcf' );
639
  }
640
+ wpcf_add_admin_header( $title, $add_new );
641
  wpcf_wpml_warning();
642
  $form = wpcf_form( 'wpcf_form_fields' );
643
  echo '<form method="post" action="" class="wpcf-fields-form wpcf-form-validate js-types-show-modal">';
644
+ wpcf_admin_screen($post_type, $form->renderForm());
645
  echo '</form>';
646
  wpcf_add_admin_footer();
647
  }
684
  wpcf_add_admin_header(
685
  __( 'Post Types', 'wpcf' ),
686
  array('page'=>'wpcf-edit-type'),
687
+ __('Add New', 'wpcf')
688
  );
689
  $to_display_posts = get_option( WPCF_OPTION_NAME_CUSTOM_TYPES, array() );
690
  $to_display_tax = get_option( WPCF_OPTION_NAME_CUSTOM_TAXONOMIES, array() );
701
  function wpcf_admin_menu_summary_ctt_hook()
702
  {
703
  wpcf_admin_menu_summary_cpt_ctt_hook();
704
+ wpcf_admin_page_add_options('ctt', __( 'Taxonomies', 'wpcf' ));
705
  }
706
 
707
  /**
709
  */
710
  function wpcf_admin_menu_summary_ctt()
711
  {
712
+ wpcf_add_admin_header( __( 'Taxonomies', 'wpcf' ), array('page' => 'wpcf-edit-tax') );
713
  wpcf_admin_custom_taxonomies_list();
714
  do_action('wpcf_types_tax_list_table_after');
715
  wpcf_add_admin_footer();
720
  */
721
  function wpcf_admin_menu_edit_type_hook()
722
  {
723
+ require_once WPCF_INC_ABSPATH . '/fields.php';
724
  do_action( 'wpcf_admin_page_init' );
725
  require_once WPCF_EMBEDDED_INC_ABSPATH . '/custom-types.php';
726
  require_once WPCF_INC_ABSPATH . '/custom-types-form.php';
727
  require_once WPCF_INC_ABSPATH . '/post-relationship.php';
728
  wp_enqueue_script( 'wpcf-custom-types-form',
729
  WPCF_RES_RELPATH . '/js/'
730
+ . 'custom-types-form.js', array('jquery', 'jquery-ui-dialog', 'jquery-masonry'), WPCF_VERSION );
731
  wp_enqueue_script( 'wpcf-form-validation',
732
  WPCF_RES_RELPATH . '/js/'
733
  . 'jquery-form-validation/jquery.validate.min.js', array('jquery'),
736
  WPCF_RES_RELPATH . '/js/'
737
  . 'jquery-form-validation/additional-methods.min.js',
738
  array('jquery'), WPCF_VERSION );
739
+ wp_enqueue_style('wp-jquery-ui-dialog');
740
  add_action( 'admin_footer', 'wpcf_admin_types_form_js_validation' );
741
  wpcf_post_relationship_init();
742
+ /**
743
+ * add form
744
+ */
745
+ // $form = wpcf_admin_custom_types_form();
746
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.edit.post.type.php';
747
+ $wpcf_admin = new Types_Admin_Edit_Post_Type();
748
+ $wpcf_admin->init_admin();
749
+ $form = $wpcf_admin->form();
750
  wpcf_form( 'wpcf_form_types', $form );
751
  }
752
 
755
  */
756
  function wpcf_admin_menu_edit_type()
757
  {
758
+ $post_type = current_filter();
759
+ $title = __('View Post Type', 'wpcf');
760
  if ( WPCF_Roles::user_can_edit('custom-post-type', array()) ) {
761
  if ( isset( $_GET['wpcf-post-type'] ) ) {
762
+ $title = __( 'Edit Post Type', 'wpcf' );
 
 
 
763
  /**
764
  * add new CPT link
765
  */
769
  __('Add New', 'wpcf')
770
  );
771
  } else {
772
+ $title = __( 'Add New Post Type', 'wpcf' );
773
  }
774
  }
775
  wpcf_add_admin_header( $title );
776
  wpcf_wpml_warning();
777
  $form = wpcf_form( 'wpcf_form_types' );
778
  echo '<form method="post" action="" class="wpcf-types-form wpcf-form-validate js-types-do-not-show-modal">';
779
+ wpcf_admin_screen($post_type, $form->renderForm());
780
  echo '</form>';
781
  wpcf_add_admin_footer();
782
  }
795
  WPCF_RES_RELPATH . '/js/'
796
  . 'jquery-form-validation/additional-methods.min.js',
797
  array('jquery'), WPCF_VERSION );
798
+ wp_enqueue_script( 'wpcf-taxonomy-form',
799
+ WPCF_RES_RELPATH . '/js/'
800
+ . 'taxonomy-form.js', array( 'jquery' ), WPCF_VERSION );
801
  add_action( 'admin_footer', 'wpcf_admin_tax_form_js_validation' );
802
  require_once WPCF_EMBEDDED_INC_ABSPATH . '/custom-taxonomies.php';
803
  require_once WPCF_INC_ABSPATH . '/custom-taxonomies-form.php';
804
+ // $form = wpcf_admin_custom_taxonomies_form();
805
+ require_once WPCF_INC_ABSPATH.'/classes/class.types.admin.edit.taxonomy.php';
806
+ $wpcf_admin = new Types_Admin_Edit_Taxonomy();
807
+ $wpcf_admin->init_admin();
808
+ $form = $wpcf_admin->form();
809
  wpcf_form( 'wpcf_form_tax', $form );
810
  }
811
 
814
  */
815
  function wpcf_admin_menu_edit_tax()
816
  {
817
+ $post_type = current_filter();
818
+ $title = __( 'View Taxonomy', 'wpcf' );
819
+ $add_new = false;
820
  if ( WPCF_Roles::user_can_create('custom-taxonomy') ) {
821
+ $title = __( 'Add New Taxonomy', 'wpcf' );
822
  if ( isset( $_GET['wpcf-tax'] ) ) {
823
+ $title = __( 'Edit Taxonomy', 'wpcf' );
824
+ $add_new = array('page' => 'wpcf-edit-tax' );
825
  }
826
  }
827
+ wpcf_add_admin_header( $title, $add_new);
828
  wpcf_wpml_warning();
829
  $form = wpcf_form( 'wpcf_form_tax' );
830
  echo '<form method="post" action="" class="wpcf-tax-form wpcf-form-validate js-types-show-modal">';
831
+ wpcf_admin_screen($post_type, $form->renderForm());
832
  echo '</form>';
833
  wpcf_add_admin_footer();
834
  }
866
  */
867
  function wpcf_admin_menu_custom_fields_control_hook()
868
  {
 
 
 
 
 
869
  require_once WPCF_INC_ABSPATH . '/fields-control.php';
870
+ wpcf_admin_menu_custom_fields_control_hook_helper();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871
  }
872
 
873
+
874
  /**
875
  * Menu page display.
876
  */
877
  function wpcf_admin_menu_custom_fields_control()
878
  {
879
  global $wpcf_control_table;
880
+ wpcf_add_admin_header( __( 'Post Field Control', 'wpcf' ) );
881
  echo '<form method="post" action="" id="wpcf-custom-fields-control-form" class="wpcf-custom-fields-control-form wpcf-form-validate" enctype="multipart/form-data">';
882
  echo wpcf_admin_custom_fields_control_form( $wpcf_control_table );
883
  wp_nonce_field( 'custom_fields_control_bulk' );
931
  {
932
  ob_start();
933
  wpcf_add_admin_header( __( 'Settings', 'wpcf' ) );
934
+ ?>
 
935
  <form method="post" action="" id="wpcf-general-settings-form" class="wpcf-settings-form wpcf-form-validate">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
  <?php
937
 
938
+ $form = wpcf_form( 'wpcf_form_general_settings' );
939
+ echo $form->renderForm();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
940
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
941
  ?>
942
+ </form>
943
+ <?php
 
 
 
944
  wpcf_add_admin_footer();
945
 
946
  echo ob_get_clean();
966
  * check user can?
967
  */
968
  switch($add_new['page']) {
969
+ case 'wpcf-edit-type':
970
+ $add_button = WPCF_Roles::user_can_create( 'custom-post-type' );
971
+ break;
972
+ case 'wpcf-edit-tax':
973
+ $add_button = WPCF_Roles::user_can_create( 'custom-taxonomy' );
974
+ break;
975
+ case 'wpcf-edit':
976
+ $add_button = WPCF_Roles::user_can_create( 'custom-field' );
977
+ break;
978
+ case 'wpcf-edit-usermeta':
979
+ $add_button = WPCF_Roles::user_can_create( 'user-meta-field' );
980
+ break;
981
+ case WPCF_Page_Edit_Termmeta::PAGE_NAME:
982
+ $add_button = WPCF_Roles::user_can_create( 'term-field' );
983
+ break;
984
  }
985
  if ( $add_button ) {
986
  printf(
1186
  case 'wpcf-edit-usermeta':
1187
  $call = 'user_fields_edit';
1188
  break;
1189
+
1190
+ case 'wpcf-termmeta-listing':
1191
+ $call = 'term_fields_list';
1192
+ break;
1193
+
1194
+ case WPCF_Page_Edit_Termmeta::PAGE_NAME:
1195
+ $call = 'edit_termmeta';
1196
  }
1197
  }
1198
  if ( $call ) {
1408
  $menu_slug,
1409
  array_key_exists('function', $menu)? $menu['function']:null
1410
  );
1411
+
1412
+ // For given menu slug, publish the final hook name in case we need it somewhere.
1413
+ do_action( "wpcf_admin_add_submenu_page_$menu_slug", $hook );
1414
+
1415
  if ( !empty($menu_slug) ) {
1416
  wpcf_admin_plugin_help( $hook, $menu_slug );
1417
  }
1418
  /**
1419
  * add action
1420
  */
1421
+ if ( !array_key_exists('load_hook', $menu) && array_key_exists('function', $menu) && is_string( $menu['function' ] ) ) {
1422
  $menu['load_hook'] = sprintf( '%s_hook', $menu['function'] );
1423
  }
1424
  if ( !empty($menu['load_hook']) && function_exists( $menu['load_hook'] ) ) {
1452
  if ('title' == $orderby || !isset($a[$orderby])) {
1453
  $orderby = 'slug';
1454
  }
1455
+ /**
1456
+ * sort by slug if sort field is the same
1457
+ */
1458
+ if ( $a[$orderby] == $b[$orderby] ) {
1459
+ $orderby = 'slug';
1460
+ }
1461
  $result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
1462
  return ($order==='asc') ? $result : -$result; //Send final sort direction to usort
1463
  }
1468
  return $value;
1469
  }
1470
 
1471
+ function wpcf_admin_screen( $post_type, $form_output = '')
1472
+ {
1473
+ ?>
1474
+ <div id="poststuff">
1475
+ <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
1476
+ <?php echo $form_output; ?>
1477
+ <div id="postbox-container-1" class="postbox-container">
1478
+ <?php do_meta_boxes($post_type, 'side', null); ?>
1479
+ </div>
1480
+ <div id="postbox-container-2" class="postbox-container">
1481
+ <?php
1482
+ do_meta_boxes($post_type, 'normal', null);
1483
+ do_meta_boxes($post_type, 'advanced', null);
1484
+ ?>
1485
+ </div>
1486
+ </div>
1487
+ </div>
1488
+ <?php
1489
+ }
1490
+
1491
+ /**
1492
+ * Add Usermeta Fields manager page.
1493
+ *
1494
+ * @author Gen gen.i@icanlocalize.com
1495
+ * @since Types 1.3
1496
+ */
1497
+ function wpcf_admin_menu_user_fields_control_hook()
1498
+ {
1499
+ require_once WPCF_INC_ABSPATH . '/usermeta-control.php';
1500
+ wpcf_admin_menu_user_fields_control_hook_helper();
1501
+ }
1502
+
1503
+ /**
1504
+ * Menu page display.
1505
+ */
1506
+ function wpcf_admin_menu_user_fields_control() {
1507
+ global $wpcf_control_table;
1508
+ wpcf_add_admin_header( __( 'User Field Control', 'wpcf' ) );
1509
+ echo '<form method="post" action="" id="wpcf-custom-fields-control-form" class="wpcf-custom-fields-control-form '
1510
+ . 'wpcf-form-validate" enctype="multipart/form-data">';
1511
+ echo wpcf_admin_custom_fields_control_form( $wpcf_control_table );
1512
+ wp_nonce_field( 'user_fields_control_bulk' );
1513
+ echo '</form>';
1514
+ wpcf_add_admin_footer();
1515
+ }
embedded/admin.php CHANGED
@@ -3,7 +3,7 @@
3
  *
4
  *
5
  */
6
- require_once(WPCF_EMBEDDED_ABSPATH . '/common/visual-editor/editor-addon.class.php');
7
  require_once WPCF_EMBEDDED_ABSPATH . '/includes/post-relationship.php';
8
 
9
  if ( defined( 'DOING_AJAX' ) ) {
@@ -161,24 +161,53 @@ function wpcf_admin_fields_postfields_styles(){
161
  }
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Initiates/returns specific form.
166
  *
167
  * @staticvar array $wpcf_forms
168
- * @param type $id
169
- * @param type $form
170
- * @return array
171
  */
172
  function wpcf_form( $id, $form = array() ) {
173
- static $wpcf_forms = array();
174
- if ( isset( $wpcf_forms[$id] ) ) {
175
- return $wpcf_forms[$id];
176
- }
177
- require_once WPCF_EMBEDDED_ABSPATH . '/classes/forms.php';
178
- $new_form = new Enlimbo_Forms_Wpcf();
179
- $new_form->autoHandle( $id, $form );
180
- $wpcf_forms[$id] = $new_form;
181
- return $wpcf_forms[$id];
 
 
 
 
 
 
182
  }
183
 
184
  /**
@@ -334,8 +363,9 @@ function wpcf_admin_message_sanitize( $message )
334
  /**
335
  * Adds admin notice.
336
  *
337
- * @param type $message
338
- * @param type $class
 
339
  */
340
  function wpcf_admin_message( $message, $class = 'updated', $mode = 'action' )
341
  {
@@ -346,7 +376,11 @@ function wpcf_admin_message( $message, $class = 'updated', $mode = 'action' )
346
  '$screen = get_current_screen(); if (!$screen->is_network) echo "<div class=\"message $class\"><p>" . wpcf_admin_message_sanitize ($message) . "</p></div>";' ) );
347
  } elseif ( 'echo' == $mode ) {
348
  printf(
349
- '<div class="message %s"><p>%s</p></div>',
 
 
 
 
350
  $class,
351
  wpcf_admin_message_sanitize($message)
352
  );
@@ -362,13 +396,14 @@ function wpcf_show_admin_messages($mode = 'action')
362
  $messages_for_user = isset( $messages[get_current_user_id()] ) ? $messages[get_current_user_id()] : array();
363
  $dismissed = get_option( 'wpcf_dismissed_messages', array() );
364
  if ( !empty( $messages_for_user ) && is_array( $messages_for_user ) ) {
365
- foreach ( $messages_for_user as $message_id => $message ) {
366
- if ( !in_array( $message['keep_id'], $dismissed ) ) {
367
  wpcf_admin_message( $message['message'], $message['class'], $mode );
368
  }
369
- if ( empty( $message['keep_id'] )
370
- || in_array( $message['keep_id'], $dismissed ) ) {
371
- unset( $messages[get_current_user_id()][$message_id] );
 
372
  }
373
  }
374
  }
@@ -378,9 +413,8 @@ function wpcf_show_admin_messages($mode = 'action')
378
  /**
379
  * Stores admin notices if redirection is performed.
380
  *
381
- * @param type $message
382
- * @param type $class
383
- * @return type
384
  */
385
  function wpcf_admin_message_store( $message, $class = 'updated', $keep_id = false )
386
  {
3
  *
4
  *
5
  */
6
+ require_once(WPCF_EMBEDDED_ABSPATH . '/toolset/toolset-common/visual-editor/editor-addon.class.php');
7
  require_once WPCF_EMBEDDED_ABSPATH . '/includes/post-relationship.php';
8
 
9
  if ( defined( 'DOING_AJAX' ) ) {
161
  }
162
  }
163
 
164
+ /**
165
+ * Add styles to userfields groups
166
+ */
167
+ function wpcf_admin_fields_userfields_styles(){
168
+
169
+ require_once WPCF_EMBEDDED_INC_ABSPATH . '/usermeta-post.php';
170
+
171
+
172
+ // $groups = wpcf_admin_fields_get_groups();
173
+ $groups = wpcf_admin_usermeta_get_groups_fields();
174
+
175
+ if ( !empty( $groups ) ) {
176
+ echo '<style type="text/css">';
177
+ foreach ( $groups as $key => $group ) {
178
+ echo str_replace( "}", "}\n",
179
+ wpcf_admin_get_groups_admin_styles_by_group( $group['id'] ) );
180
+ }
181
+ echo '</style>';
182
+ }
183
+ }
184
+
185
+ /** @noinspection PhpUndefinedClassInspection */
186
+
187
  /**
188
  * Initiates/returns specific form.
189
  *
190
  * @staticvar array $wpcf_forms
191
+ * @param string $id
192
+ * @param array $form
193
+ * @return Enlimbo_Forms_Wpcf
194
  */
195
  function wpcf_form( $id, $form = array() ) {
196
+ static $wpcf_forms = array();
197
+
198
+ if ( isset( $wpcf_forms[ $id ] ) ) {
199
+ return $wpcf_forms[ $id ];
200
+ }
201
+
202
+ require_once WPCF_EMBEDDED_ABSPATH . '/classes/forms.php';
203
+ /** @noinspection PhpUndefinedClassInspection */
204
+
205
+ $new_form = new Enlimbo_Forms_Wpcf();
206
+ $new_form->autoHandle( $id, $form );
207
+
208
+ $wpcf_forms[ $id ] = $new_form;
209
+
210
+ return $wpcf_forms[ $id ];
211
  }
212
 
213
  /**
363
  /**
364
  * Adds admin notice.
365
  *
366
+ * @param string $message
367
+ * @param string $class
368
+ * @param string $mode 'action'|'echo'
369
  */
370
  function wpcf_admin_message( $message, $class = 'updated', $mode = 'action' )
371
  {
376
  '$screen = get_current_screen(); if (!$screen->is_network) echo "<div class=\"message $class\"><p>" . wpcf_admin_message_sanitize ($message) . "</p></div>";' ) );
377
  } elseif ( 'echo' == $mode ) {
378
  printf(
379
+ '<div class="message %s is-dismissible"><p>%s</p> <button type="button" class="notice-dismiss">
380
+ <span class="screen-reader-text">
381
+ '. __( 'Dismiss this notice.' ) .'
382
+ </span>
383
+ </button></div>',
384
  $class,
385
  wpcf_admin_message_sanitize($message)
386
  );
396
  $messages_for_user = isset( $messages[get_current_user_id()] ) ? $messages[get_current_user_id()] : array();
397
  $dismissed = get_option( 'wpcf_dismissed_messages', array() );
398
  if ( !empty( $messages_for_user ) && is_array( $messages_for_user ) ) {
399
+ foreach( $messages_for_user as $message_id => $message ) {
400
+ if( ! in_array( $message['keep_id'], $dismissed ) ) {
401
  wpcf_admin_message( $message['message'], $message['class'], $mode );
402
  }
403
+ if( empty( $message['keep_id'] )
404
+ || in_array( $message['keep_id'], $dismissed )
405
+ ) {
406
+ unset( $messages[ get_current_user_id() ][ $message_id ] );
407
  }
408
  }
409
  }
413
  /**
414
  * Stores admin notices if redirection is performed.
415
  *
416
+ * @param string $message
417
+ * @param string $class
 
418
  */
419
  function wpcf_admin_message_store( $message, $class = 'updated', $keep_id = false )
420
  {
embedded/bootstrap.php CHANGED
@@ -43,6 +43,11 @@ define('TYPES_CUSTOM_FIELD_GROUP_CPT_NAME', 'wp-types-group');
43
  */
44
  define('TYPES_USER_META_FIELD_GROUP_CPT_NAME', 'wp-types-user-group');
45
 
 
 
 
 
 
46
  /**
47
  * default capability
48
  */
@@ -66,7 +71,14 @@ add_action( 'init', 'wpcf_embedded_init', TYPES_INIT_PRIORITY );
66
  * register_post_type & register_taxonomy - must be with default pririty to
67
  * handle defult taxonomies
68
  */
69
- add_action('init', 'wpcf_init_custom_types_taxonomies');
 
 
 
 
 
 
 
70
 
71
  /*
72
  *
@@ -93,7 +105,7 @@ if ( !defined( 'TYPES_DEBUG' ) ) {
93
  * Load common and local localization
94
  */
95
  if ( !defined( 'WPT_LOCALIZATION' ) ) {
96
- require_once( WPCF_EMBEDDED_ABSPATH . '/common/localization/wpt-localization.php' );
97
  }
98
  new WPToolset_Localization( 'wpcf', WPCF_EMBEDDED_ABSPATH . '/locale', 'types-%s' );
99
 
@@ -102,14 +114,14 @@ new WPToolset_Localization( 'wpcf', WPCF_EMBEDDED_ABSPATH . '/locale', 'types-%s
102
  * Include common code.
103
  */
104
  if ( !defined( 'ICL_COMMON_FUNCTIONS' ) ) {
105
- require_once WPCF_EMBEDDED_ABSPATH . '/common/functions.php';
106
  if ( !defined( 'WPTOOLSET_COMMON_PATH' ) ) {
107
- define( 'WPTOOLSET_COMMON_PATH', WPCF_EMBEDDED_ABSPATH . '/common' );
108
  }
109
  } else if ( !defined( 'WPTOOLSET_COMMON_PATH' ) ) {
110
  //$__types_common_reflection = new ReflectionFunction( 'wpv_condition' );
111
  //define( 'WPTOOLSET_COMMON_PATH', dirname( $__types_common_reflection->getFileName() ) );
112
- define( 'WPTOOLSET_COMMON_PATH', WPCF_EMBEDDED_ABSPATH . '/common' );
113
  }
114
  if ( !defined( 'WPTOOLSET_FORMS_VERSION' ) ) {
115
  require_once WPTOOLSET_COMMON_PATH . '/toolset-forms/bootstrap.php';
@@ -128,6 +140,26 @@ wpcf_embedded_after_setup_theme_hook();
128
  */
129
  $GLOBALS['wpcf'] = new stdClass();
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  /**
132
  * Main init hook.
133
  *
@@ -156,7 +188,7 @@ function wpcf_embedded_init() {
156
  // Define necessary constants if plugin is not present
157
  // This ones are skipped if used as embedded code!
158
  if ( !defined( 'WPCF_VERSION' ) ) {
159
- define( 'WPCF_VERSION', '1.8.11' );
160
  define( 'WPCF_META_PREFIX', 'wpcf-' );
161
  }
162
 
@@ -292,12 +324,18 @@ function wpcf_embedded_init() {
292
 
293
  // Set usermeta field object
294
  $wpcf->usermeta_field = new WPCF_Usermeta_Field();
 
 
 
 
 
 
295
 
296
- // Set repeater object
297
  $wpcf->usermeta_repeater = new WPCF_Usermeta_Repeater();
298
-
299
- // Set repeater object
300
- $wpcf->repeater = new WPCF_Repeater();
301
 
302
  // Set relationship object
303
  $wpcf->relationship = new WPCF_Relationship();
@@ -325,9 +363,10 @@ function wpcf_embedded_init() {
325
  // 'attachment' = Media
326
  //
327
  $wpcf->excluded_post_types = array(
328
- 'dd_layouts',
329
  'cred-form',
330
  'cred-user-form',
 
 
331
  'mediapage',
332
  'nav_menu_item',
333
  'revision',
@@ -337,6 +376,18 @@ function wpcf_embedded_init() {
337
  'wp-types-user-group',
338
  );
339
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  // Init loader
341
  WPCF_Loader::init();
342
 
@@ -353,6 +404,28 @@ function wpcf_embedded_init() {
353
  // Check if import/export request is going on
354
  wpcf_embedded_check_import();
355
 
 
 
 
 
356
  do_action( 'types_after_init' );
357
  do_action( 'wpcf_after_init' );
358
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  */
44
  define('TYPES_USER_META_FIELD_GROUP_CPT_NAME', 'wp-types-user-group');
45
 
46
+ /**
47
+ * user meta filed groups - post type
48
+ */
49
+ define('TYPES_TERM_META_FIELD_GROUP_CPT_NAME', 'wp-types-term-group');
50
+
51
  /**
52
  * default capability
53
  */
71
  * register_post_type & register_taxonomy - must be with default pririty to
72
  * handle defult taxonomies
73
  */
74
+ /**
75
+ * Priotity for wpcf_init_custom_types_taxonomies()
76
+ *
77
+ * Priotity for function wpcf_init_custom_types_taxonomies() in init WP
78
+ * action..
79
+ *
80
+ */
81
+ add_action( 'init', 'wpcf_init_custom_types_taxonomies', apply_filters('wpcf_init_custom_types_taxonomies', 10));
82
 
83
  /*
84
  *
105
  * Load common and local localization
106
  */
107
  if ( !defined( 'WPT_LOCALIZATION' ) ) {
108
+ require_once( WPCF_EMBEDDED_ABSPATH . '/toolset/toolset-common/localization/wpt-localization.php' );
109
  }
110
  new WPToolset_Localization( 'wpcf', WPCF_EMBEDDED_ABSPATH . '/locale', 'types-%s' );
111
 
114
  * Include common code.
115
  */
116
  if ( !defined( 'ICL_COMMON_FUNCTIONS' ) ) {
117
+ require_once WPCF_EMBEDDED_ABSPATH . '/toolset/toolset-common/functions.php';
118
  if ( !defined( 'WPTOOLSET_COMMON_PATH' ) ) {
119
+ define( 'WPTOOLSET_COMMON_PATH', WPCF_EMBEDDED_ABSPATH . '/toolset/toolset-common' );
120
  }
121
  } else if ( !defined( 'WPTOOLSET_COMMON_PATH' ) ) {
122
  //$__types_common_reflection = new ReflectionFunction( 'wpv_condition' );
123
  //define( 'WPTOOLSET_COMMON_PATH', dirname( $__types_common_reflection->getFileName() ) );
124
+ define( 'WPTOOLSET_COMMON_PATH', WPCF_EMBEDDED_ABSPATH . '/toolset/toolset-common' );
125
  }
126
  if ( !defined( 'WPTOOLSET_FORMS_VERSION' ) ) {
127
  require_once WPTOOLSET_COMMON_PATH . '/toolset-forms/bootstrap.php';
140
  */
141
  $GLOBALS['wpcf'] = new stdClass();
142
 
143
+
144
+
145
+ /**
146
+ * Initialize the autoloader (for newer parts of code).
147
+ */
148
+ function wpcf_initialize_autoloader_embedded() {
149
+ require_once WPCF_EMBEDDED_INC_ABSPATH . '/autoloader.php';
150
+ $autoloader = WPCF_Autoloader::get_instance();
151
+ $autoloader->add_prefix( 'WPCF' );
152
+
153
+ // This will trigger the loading mechanism for legacy classes.
154
+ $autoloader->add_prefix( 'Types' );
155
+ $autoloader->add_prefix( 'WPToolset' );
156
+
157
+ $autoloader->add_path( WPCF_EMBEDDED_ABSPATH . '/classes' );
158
+ }
159
+
160
+ wpcf_initialize_autoloader_embedded();
161
+
162
+
163
  /**
164
  * Main init hook.
165
  *
188
  // Define necessary constants if plugin is not present
189
  // This ones are skipped if used as embedded code!
190
  if ( !defined( 'WPCF_VERSION' ) ) {
191
+ define( 'WPCF_VERSION', '1.9' );
192
  define( 'WPCF_META_PREFIX', 'wpcf-' );
193
  }
194
 
324
 
325
  // Set usermeta field object
326
  $wpcf->usermeta_field = new WPCF_Usermeta_Field();
327
+
328
+ // Set termmeta field object
329
+ $wpcf->termmeta_field = new WPCF_Termmeta_Field();
330
+
331
+ // Set repeater object
332
+ $wpcf->repeater = new WPCF_Repeater();
333
 
334
+ // Set usermeta repeater object
335
  $wpcf->usermeta_repeater = new WPCF_Usermeta_Repeater();
336
+
337
+ // Set termmeta repeater object
338
+ $wpcf->termmeta_repeater = new WPCF_Termmeta_Repeater();
339
 
340
  // Set relationship object
341
  $wpcf->relationship = new WPCF_Relationship();
363
  // 'attachment' = Media
364
  //
365
  $wpcf->excluded_post_types = array(
 
366
  'cred-form',
367
  'cred-user-form',
368
+ 'dd_layouts',
369
+ 'deprecated_log',
370
  'mediapage',
371
  'nav_menu_item',
372
  'revision',
376
  'wp-types-user-group',
377
  );
378
 
379
+ /**
380
+ * Do use this CPT in Toolset "actions"
381
+ *
382
+ * Filter allow to add own post types which will be not used in
383
+ * Toolset plugins
384
+ *
385
+ * @since 1.9.0
386
+ *
387
+ * @param array $post_types array of post types slugs
388
+ */
389
+ $wpcf->excluded_post_types = apply_filters( 'toolset_filter_exclude_own_post_types', $wpcf->excluded_post_types );
390
+
391
  // Init loader
392
  WPCF_Loader::init();
393
 
404
  // Check if import/export request is going on
405
  wpcf_embedded_check_import();
406
 
407
+ // Initialize (new) parts of the GUI.
408
+ // Btw. current_screen is being fired during admin_init.
409
+ add_action( 'current_screen', 'wpcf_initialize_admin_gui' );
410
+
411
  do_action( 'types_after_init' );
412
  do_action( 'wpcf_after_init' );
413
  }
414
+
415
+
416
+ /**
417
+ * Initialize parts of GUI depending on current screen.
418
+ *
419
+ * @since 1.9
420
+ */
421
+ function wpcf_initialize_admin_gui() {
422
+
423
+ $screen = get_current_screen();
424
+
425
+ // Should be always true.
426
+ if( $screen instanceof WP_Screen ) {
427
+ if( in_array( $screen->base, array( 'edit-tags', 'term' ) ) ) {
428
+ WPCF_GUI_Term_Field_Editing::initialize();
429
+ }
430
+ }
431
+ }
embedded/classes/class.wpcf-post-types.php CHANGED
@@ -28,7 +28,7 @@ class WPCF_Post_Types
28
  function __construct()
29
  {
30
  add_action('admin_init', array($this, 'admin_init'));
31
- global $wp_version;
32
  if ( version_compare( $wp_version, '4.4' ) < 0 ) {
33
  add_action('admin_head-nav-menus.php', array($this, 'add_filters'));
34
  add_filter('wp_setup_nav_menu_item', array( $this, 'setup_archive_item'));
@@ -38,7 +38,7 @@ class WPCF_Post_Types
38
  /**
39
  * Check has some custom fields to display.
40
  *
41
- * Check custom post type for custom fields to display on custom post edit
42
  * screen.
43
  *
44
  * @since 1.7
@@ -199,7 +199,6 @@ class WPCF_Post_Types
199
  /**
200
  * turn of sorting for complex data
201
  */
202
- case 'date':
203
  case 'skype':
204
  $columns[$data['meta_key']] = false;;
205
  break;
28
  function __construct()
29
  {
30
  add_action('admin_init', array($this, 'admin_init'));
31
+ global $wp_version;
32
  if ( version_compare( $wp_version, '4.4' ) < 0 ) {
33
  add_action('admin_head-nav-menus.php', array($this, 'add_filters'));
34
  add_filter('wp_setup_nav_menu_item', array( $this, 'setup_archive_item'));
38
  /**
39
  * Check has some custom fields to display.
40
  *
41
+ * Check post type for custom fields to display on custom post edit
42
  * screen.
43
  *
44
  * @since 1.7
199
  /**
200
  * turn of sorting for complex data
201
  */
 
202
  case 'skype':
203
  $columns[$data['meta_key']] = false;;
204
  break;
embedded/classes/editor.php CHANGED
@@ -55,7 +55,7 @@ class WPCF_Editor
55
  array('jquery', 'types-knockout'), WPCF_VERSION, true );
56
  wp_register_style( 'types-editor',
57
  WPCF_EMBEDDED_RES_RELPATH . '/css/editor.css',
58
- array('admin-bar', 'wp-admin', 'buttons', 'media-views', 'toolset-font-awesome'),
59
  WPCF_VERSION );
60
  wp_register_style( 'types-editor-cloned',
61
  WPCF_EMBEDDED_RES_RELPATH . '/css/editor-cloned.css', array(),
@@ -87,7 +87,7 @@ class WPCF_Editor
87
  * @param string $shortcode
88
  */
89
  function frame( $field, $meta_type = 'postmeta', $post_id = -1,
90
- $shortcode = null, $callback = false, $views_usermeta = false ) {
91
 
92
  global $wp_version, $wpcf;
93
 
@@ -101,7 +101,7 @@ class WPCF_Editor
101
  wp_enqueue_script( 'wp-pointer' );
102
  wp_enqueue_style( 'types-editor' );
103
  wp_enqueue_style( 'wp-pointer' );
104
- wp_enqueue_style( 'toolset-font-awesome' );
105
 
106
  // Load cloned WP Media Modal CSS
107
  if ( version_compare( $wp_version, '3.5', '<' ) ) {
@@ -175,11 +175,16 @@ class WPCF_Editor
175
 
176
  // Add User ID form
177
  if ( $this->_meta_type == 'usermeta' ) {
178
- if ( !$views_usermeta ){
 
179
  $this->_data['user_form'] = wpcf_form_simple( wpcf_get_usermeta_form_addon( $this->_settings ) );
180
- $this->_data['supports'][] = 'user_id';
181
  }
182
-
 
 
 
 
 
183
  } else {
184
  // Add Post ID form
185
  $this->_data['supports'][] = 'post_id';
@@ -192,32 +197,53 @@ class WPCF_Editor
192
 
193
  // Set icons
194
  $icons = array(
195
- 'audio' => 'icon-music',
196
- 'checkbox' => 'icon-check',
197
- 'checkboxes' => 'icon-checkboxes',
198
- 'colorpicker' => 'icon-tint',
199
- 'date' => 'icon-calendar',
200
- 'email' => 'icon-envelope-alt',
201
- 'embed' => 'icon-youtube-play',
202
- 'file' => 'icon-file-alt',
203
- 'image' => 'icon-picture',
204
- 'map' => 'icon-map-marker',
205
- 'numeric' => 'icon-numeric',
206
- 'phone' => 'icon-phone',
207
- 'radio' => 'icon-radio-button',
208
- 'select' => 'icon-select-box',
209
- 'skype' => 'icon-skype',
210
- 'textarea' => 'icon-text-area',
211
- 'textfield' => 'icon-text-field',
212
- 'url' => 'icon-link',
213
- 'video' => 'icon-film',
214
- 'wysiwyg' => 'icon-wysiwyg',
215
  );
216
- $this->_data['icon_class'] = isset( $icons[$field['type']] ) ? $icons[$field['type']] : 'icon-text-field';
 
 
 
 
 
 
 
 
 
 
217
 
218
  // Is repetitive
219
  $this->_data['is_repetitive'] = (bool) types_is_repetitive( $field );
220
- if ( $this->_data['is_repetitive'] ) {
 
 
 
 
 
 
 
 
 
 
 
221
  $this->_data['supports'][] = 'separator';
222
  }
223
 
@@ -292,6 +318,9 @@ class WPCF_Editor
292
  if ( $this->_meta_type == 'usermeta' ) {
293
  $add = wpcf_get_usermeta_form_addon_submit();
294
  $shortcode = wpcf_usermeta_get_shortcode( $this->field, $add );
 
 
 
295
  } else {
296
  $shortcode = wpcf_fields_get_shortcode( $this->field );
297
  }
55
  array('jquery', 'types-knockout'), WPCF_VERSION, true );
56
  wp_register_style( 'types-editor',
57
  WPCF_EMBEDDED_RES_RELPATH . '/css/editor.css',
58
+ array('admin-bar', 'wp-admin', 'buttons', 'media-views', 'font-awesome'),
59
  WPCF_VERSION );
60
  wp_register_style( 'types-editor-cloned',
61
  WPCF_EMBEDDED_RES_RELPATH . '/css/editor-cloned.css', array(),
87
  * @param string $shortcode
88
  */
89
  function frame( $field, $meta_type = 'postmeta', $post_id = -1,
90
+ $shortcode = null, $callback = false, $views_meta = false ) {
91
 
92
  global $wp_version, $wpcf;
93
 
101
  wp_enqueue_script( 'wp-pointer' );
102
  wp_enqueue_style( 'types-editor' );
103
  wp_enqueue_style( 'wp-pointer' );
104
+ wp_enqueue_style( 'font-awesome' );
105
 
106
  // Load cloned WP Media Modal CSS
107
  if ( version_compare( $wp_version, '3.5', '<' ) ) {
175
 
176
  // Add User ID form
177
  if ( $this->_meta_type == 'usermeta' ) {
178
+ if ( ! $views_meta ) {
179
+ $this->_data['supports'][] = 'user_id';
180
  $this->_data['user_form'] = wpcf_form_simple( wpcf_get_usermeta_form_addon( $this->_settings ) );
 
181
  }
182
+ } elseif ( $this->_meta_type == 'termmeta' ) {
183
+ if ( ! $views_meta ) {
184
+ $this->_data['supports'][] = 'term_id';
185
+ //$this->_data['user_form'] = wpcf_form_simple( wpcf_get_usermeta_form_addon( $this->_settings ) );
186
+ //$this->_data['supports'][] = 'user_id';
187
+ }
188
  } else {
189
  // Add Post ID form
190
  $this->_data['supports'][] = 'post_id';
197
 
198
  // Set icons
199
  $icons = array(
200
+ 'audio' => 'music',
201
+ 'checkbox' => 'check',
202
+ 'checkboxes' => 'checkboxes',
203
+ 'colorpicker' => 'tint',
204
+ 'date' => 'calendar',
205
+ 'email' => 'envelope-alt',
206
+ 'embed' => 'youtube-play',
207
+ 'file' => 'file-alt',
208
+ 'image' => 'picture',
209
+ 'map' => 'map-marker',
210
+ 'numeric' => 'numeric',
211
+ 'phone' => 'phone',
212
+ 'radio' => 'radio-button',
213
+ 'select' => 'select-box',
214
+ 'skype' => 'skype',
215
+ 'textarea' => 'text-area',
216
+ 'textfield' => 'text-field',
217
+ 'url' => 'link',
218
+ 'video' => 'film',
219
+ 'wysiwyg' => 'wysiwyg',
220
  );
221
+ $this->_data['icon_class'] = 'fa ';
222
+ if ( isset( $icons[$field['type']] ) ) {
223
+ $this->_data['icon_class'] .= sprintf(
224
+ 'fa-%s icon-%s',
225
+ $icons[$field['type']],
226
+ $icons[$field['type']]
227
+ );
228
+ } else {
229
+ $filter = sprintf('toolset_editor_%s_icon_class', $field['type']);
230
+ $this->_data['icon_class'] .= apply_filters($filter, 'fa-text-field icon-text-field');
231
+ }
232
 
233
  // Is repetitive
234
  $this->_data['is_repetitive'] = (bool) types_is_repetitive( $field );
235
+ /**
236
+ * Show or hide separator.
237
+ *
238
+ * Filter allow to hide separator choosing tab when we do not need
239
+ * this tab in Types shortcode GUI
240
+ *
241
+ * @since 1.9.0
242
+ *
243
+ * @param boolean $show Show separator tab - default true.
244
+ */
245
+ $show_separator = apply_filters('toolset_editor_show_separator_'.$field['type'], true);
246
+ if ( $show_separator && $this->_data['is_repetitive'] ) {
247
  $this->_data['supports'][] = 'separator';
248
  }
249
 
318
  if ( $this->_meta_type == 'usermeta' ) {
319
  $add = wpcf_get_usermeta_form_addon_submit();
320
  $shortcode = wpcf_usermeta_get_shortcode( $this->field, $add );
321
+ } elseif ( $this->_meta_type == 'termmeta' ) {
322
+ $add = wpcf_get_termmeta_form_addon_submit();
323
+ $shortcode = wpcf_termmeta_get_shortcode( $this->field, $add );
324
  } else {
325
  $shortcode = wpcf_fields_get_shortcode( $this->field );
326
  }
embedded/classes/field.php CHANGED
@@ -417,6 +417,12 @@ class WPCF_Field
417
  $value = apply_filters( 'wpcf_fields_usermeta_value_save', $value, $this->cf['type'], $this->cf['slug'], $this->cf, $this );
418
  return $value;
419
  }
 
 
 
 
 
 
420
 
421
  /**
422
  * Use these hooks to add future functionality.
@@ -672,9 +678,10 @@ class WPCF_Field
672
  if ( !isset( $data_script['src'] ) ) {
673
  continue;
674
  }
675
- $deps = !empty( $data_script['deps'] ) ? $data_script['deps'] : array();
676
- wp_enqueue_script( $handle, $data_script['src'], $deps,
677
- WPCF_VERSION );
 
678
  }
679
  }
680
  }
@@ -795,3 +802,189 @@ class WPCF_Field
795
  }
796
 
797
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  $value = apply_filters( 'wpcf_fields_usermeta_value_save', $value, $this->cf['type'], $this->cf['slug'], $this->cf, $this );
418
  return $value;
419
  }
420
+
421
+ function _filter_save_termmeta_value( $value )
422
+ {
423
+ $value = apply_filters( 'wpcf_fields_termmeta_value_save', $value, $this->cf['type'], $this->cf['slug'], $this->cf, $this );
424
+ return $value;
425
+ }
426
 
427
  /**
428
  * Use these hooks to add future functionality.
678
  if ( !isset( $data_script['src'] ) ) {
679
  continue;
680
  }
681
+ $deps = isset($data_script['deps']) && !empty( $data_script['deps'] ) ? $data_script['deps'] : array();
682
+ $in_footer = isset($data_script['in_footer']) && $data_script['in_footer'];
683
+ $ver = !empty( $data_script['ver'] ) ? $data_script['ver'] : WPCF_VERSION;
684
+ wp_enqueue_script( $handle, $data_script['src'], $deps, $ver, $in_footer);
685
  }
686
  }
687
  }
802
  }
803
 
804
  }
805
+
806
+ /*
807
+ * Usermeta Field class extends Field.
808
+ */
809
+
810
+ //require_once WPCF_EMBEDDED_ABSPATH . '/classes/field.php';
811
+
812
+
813
+ class WPCF_Termmeta_Field extends WPCF_Field
814
+ {
815
+
816
+ /**
817
+ * Set current post and field.
818
+ *
819
+ * @param type $post
820
+ * @param type $cf
821
+ */
822
+ function set( $term_id, $cf ) {
823
+
824
+ global $wpcf;
825
+
826
+ /*
827
+ *
828
+ * Check if $cf is string
829
+ */
830
+ if ( is_string( $cf ) ) {
831
+ WPCF_Loader::loadInclude( 'fields' );
832
+ $cf = types_get_field( $this->__get_slug_no_prefix( $cf ), 'termmeta' );
833
+ if ( empty( $cf ) ) {
834
+ $this->_reset();
835
+ return false;
836
+ }
837
+ }
838
+
839
+ $this->term_id = $term_id;
840
+ $this->ID = $cf['id'];
841
+ $this->cf = $cf;
842
+ $this->slug = wpcf_types_get_meta_prefix( $this->cf ) . $this->cf['slug'];
843
+ $this->meta = $this->_get_meta();
844
+ $this->config = $this->_get_config();
845
+ $this->unique_id = wpcf_unique_id( serialize( (array) $this ) );
846
+ $this->cf['value'] = $this->meta;
847
+ // Debug
848
+ $wpcf->debug->fieds[$this->unique_id] = $this->cf;
849
+ $wpcf->debug->meta[$this->slug][] = $this->meta;
850
+
851
+ // Load files
852
+ if ( isset( $this->cf['type'] ) ) {
853
+ $file = WPCF_EMBEDDED_INC_ABSPATH . '/fields/' . $this->cf['type'] . '.php';
854
+ if ( file_exists( $file ) ) {
855
+ include_once $file;
856
+ }
857
+ if ( defined( 'WPCF_INC_ABSPATH' ) ) {
858
+ $file = WPCF_INC_ABSPATH . '/fields/' . $this->cf['type'] . '.php';
859
+ if ( file_exists( $file ) ) {
860
+ include_once $file;
861
+ }
862
+ }
863
+ }
864
+ }
865
+
866
+ /**
867
+ * Save usermeta field.
868
+ *
869
+ *
870
+ * @param type $value
871
+ */
872
+ function termmeta_save( $value = null ) {
873
+
874
+ // If $value null, look for submitted data
875
+ if ( is_null( $value ) ) {
876
+ $value = $this->get_submitted_data();
877
+ }
878
+ /*
879
+ *
880
+ *
881
+ * Since Types 1.2
882
+ * We completely rewrite meta.
883
+ * It has no impact on frontend and covers a lot of cases
884
+ * (e.g. user change mode from single to repetitive)
885
+ */
886
+
887
+ delete_term_meta( $this->term_id, $this->slug );
888
+
889
+
890
+ // Save
891
+ if ( !empty( $value ) || is_numeric( $value ) ) {
892
+
893
+ // Trim
894
+ if ( is_string( $value ) ) {
895
+ $value = trim( $value );
896
+ }
897
+
898
+ // Apply filters
899
+ $_value = $this->_filter_save_termmeta_value( $value );
900
+ $_value = $this->_filter_save_value( $_value );
901
+ if ( !empty( $_value ) || is_numeric( $_value ) ) {
902
+ // Save field
903
+ $mid = update_term_meta( $this->term_id, $this->slug, $_value );
904
+ $this->_action_save( $this->cf, $_value, $mid, $value );
905
+ }
906
+ }
907
+ }
908
+
909
+ /**
910
+ * Fetch and sort fields.
911
+ *
912
+ * @global object $wpdb
913
+ *
914
+ */
915
+ function _get_meta() {
916
+ global $wpdb;
917
+
918
+ $cache_key = md5( 'termmeta::_get_meta' . $this->term_id . $this->slug );
919
+ $cache_group = 'types_cache';
920
+ $cached_object = wp_cache_get( $cache_key, $cache_group );
921
+
922
+ if ( $this->use_cache ) {
923
+ if ( false != $cached_object && is_array( $cached_object ) && isset( $cached_object[0] ) ) {// WordPress cache
924
+ $r = $cached_object[0];
925
+ } else {
926
+ // Cache all the postmeta for this same user
927
+ $all_termmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->termmeta} WHERE term_id=%d", $this->term_id), OBJECT );
928
+ if ( !empty( $all_termmeta ) ) {
929
+ $cache_key_keys = array();
930
+ foreach ( $all_termmeta as $metarow ) {
931
+ $mpid = intval($metarow->term_id);
932
+ $mkey = $metarow->meta_key;
933
+ $cache_key_keys[$mpid . $mkey][] = $metarow;
934
+ $cache_key_looped = md5( 'termmeta::_get_meta' . $mpid . $mkey );
935
+ if ( $mkey == $this->slug ) {
936
+ $r = $metarow;
937
+ }
938
+ }
939
+ foreach ( $cache_key_keys as $single_meta_keys => $single_meta_values ) {
940
+ $cache_key_looped_new = md5( 'termmeta::_get_meta' . $single_meta_keys );
941
+ wp_cache_add( $cache_key_looped_new, $single_meta_values, $cache_group );// WordPress cache
942
+ }
943
+ }
944
+ }
945
+ } else {
946
+ // Get straight from DB single value
947
+ $r = $wpdb->get_row(
948
+ $wpdb->prepare(
949
+ "SELECT * FROM {$wpdb->termmeta}
950
+ WHERE term_id=%d
951
+ AND meta_key=%s",
952
+ $this->term_id, $this->slug )
953
+ );
954
+ // Cache it
955
+ wp_cache_add( $cache_key, array( $r ), $cache_group );// WordPress cache
956
+ }
957
+
958
+ // Sort meta
959
+ $meta = array();
960
+ if ( !empty( $r ) ) {
961
+ $meta = maybe_unserialize( $r->meta_value );
962
+ $this->meta_object = $r;
963
+ } else {
964
+ $meta = null;
965
+ $this->meta_object = new stdClass();
966
+ $this->meta_object->meta_id = null;
967
+ $this->meta_object->meta_key = null;
968
+ $this->meta_object->meta_value = null;
969
+ }
970
+
971
+ /*
972
+ * Secret public object :)
973
+ * Keeps original data
974
+ */
975
+ $this->__meta = $meta;
976
+
977
+ /*
978
+ *
979
+ * Apply filters
980
+ * !!! IMPORTANT !!!
981
+ * TODO Make this only place where field meta value is filtered
982
+ */
983
+ $meta = apply_filters( 'wpcf_fields_value_get', $meta, $this );
984
+ $meta = apply_filters( 'wpcf_fields_slug_' . $this->cf['slug'] . '_value_get', $meta, $this );
985
+ $meta = apply_filters( 'wpcf_fields_type_' . $this->cf['type'] . '_value_get', $meta, $this );
986
+ return $meta;
987
+ }
988
+
989
+ }
990
+
embedded/classes/field/accessor/abstract.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Abstract class for accessing a specific field value.
5
+ *
6
+ * It works with the raw value and performs no validation or sanitization whatsoever. The actual behaviour depends on
7
+ * the actual implementation, but it is safe to assume get_*_meta (& co.) functions will be used.
8
+ */
9
+ abstract class WPCF_Field_Accessor_Abstract {
10
+
11
+ /** @var int */
12
+ protected $object_id;
13
+
14
+ /** @var string */
15
+ protected $meta_key;
16
+
17
+ /** @var bool */
18
+ protected $is_single;
19
+
20
+
21
+ /**
22
+ * WPCF_Field_Accessor_Abstract constructor.
23
+ *
24
+ * @param int $object_id ID of the object to which the field belongs.
25
+ * @param string $meta_key Meta key used to store field value.
26
+ * @param bool $is_repetitive
27
+ */
28
+ public function __construct( $object_id, $meta_key, $is_repetitive = false ) {
29
+ $this->object_id = $object_id;
30
+ $this->meta_key = $meta_key;
31
+ $this->is_single = (bool) !$is_repetitive;
32
+ }
33
+
34
+
35
+ /**
36
+ * @return mixed Field value from the database.
37
+ */
38
+ public abstract function get_raw_value();
39
+
40
+
41
+ /**
42
+ * @param mixed $value New value to be saved to the database.
43
+ * @param mixed $prev_value Previous field value. Use if updating an item in a repetitive field.
44
+ * @return mixed
45
+ */
46
+ public abstract function update_raw_value( $value, $prev_value = '' );
47
+
48
+
49
+ /**
50
+ * Add new metadata. Note that if the accessor is set up for a repetitive field, the is_unique argument
51
+ * of add_*_meta should be false and otherwise it should be true.
52
+ *
53
+ * @link https://developer.wordpress.org/reference/functions/add_term_meta/
54
+ *
55
+ * @param mixed $value New value to be saved to the database
56
+ * @return mixed
57
+ */
58
+ public abstract function add_raw_value( $value );
59
+
60
+
61
+ /**
62
+ * @return bool True, if the value is not empty.
63
+ */
64
+ public function has_raw_value() {
65
+ $has_raw_value = $this->get_raw_value();
66
+ $has_raw_value = ! empty( $has_raw_value )
67
+ ? true
68
+ : false;
69
+
70
+ return $has_raw_value;
71
+ }
72
+
73
+
74
+ /**
75
+ * Delete field value from the database.
76
+ *
77
+ * @param string $value Specific value to be deleted. Use if deleting an item in a repetitive field.
78
+ * @return mixed
79
+ */
80
+ public abstract function delete_raw_value( $value = '' );
81
+ }
embedded/classes/field/accessor/dummy.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Dummy field accessor that does nothing and returns an empty string.
5
+ *
6
+ * Useful for unsaved field instances.
7
+ */
8
+ final class WPCF_Field_Accessor_Dummy extends WPCF_Field_Accessor_Abstract {
9
+
10
+
11
+ public function __construct() {
12
+ parent::__construct( 0, '', false );
13
+ }
14
+
15
+ /**
16
+ * @return mixed Field value from the database.
17
+ */
18
+ public function get_raw_value() {
19
+ return '';
20
+ }
21
+
22
+ /**
23
+ * @param mixed $value New value to be saved to the database.
24
+ * @param mixed $prev_value Previous field value. Use if updating an item in a repetitive field.
25
+ *
26
+ * @return mixed
27
+ */
28
+ public function update_raw_value( $value, $prev_value = '' ) {
29
+ // Nothing to do here, although this being called might indicate an error.
30
+ }
31
+
32
+ /**
33
+ * Delete field value from the database.
34
+ *
35
+ * @param string $value Specific value to be deleted. Use if deleting an item in a repetitive field.
36
+ *
37
+ * @return mixed
38
+ */
39
+ public function delete_raw_value( $value = '' ) {
40
+ // Nothing to do here, although this being called might indicate an error.
41
+ }
42
+
43
+ /**
44
+ * Add new metadata. Note that if the accessor is set up for a repetitive field, the is_unique argument
45
+ * of add_*_meta should be false and otherwise it should be true.
46
+ *
47
+ * @link https://developer.wordpress.org/reference/functions/add_term_meta/
48
+ *
49
+ * @param mixed $value New value to be saved to the database
50
+ *
51
+ * @return mixed
52
+ */
53
+ public function add_raw_value( $value ) {
54
+ // Nothing to do here, although this being called might indicate an error.
55
+ }
56
+
57
+ }
embedded/classes/field/accessor/termmeta.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Generic accessor to term meta.
5
+ *
6
+ * It can be used to provide access to generic term meta, but it never should be used for term fields (take
7
+ * a look at WPCF_Field_Accessor_Termmeta_Field instead).
8
+ *
9
+ * @since 1.9
10
+ */
11
+ class WPCF_Field_Accessor_Termmeta extends WPCF_Field_Accessor_Abstract {
12
+
13
+
14
+ public function get_raw_value() {
15
+ return get_term_meta( $this->object_id, $this->meta_key, $this->is_single );
16
+ }
17
+
18
+ public function update_raw_value( $value, $prev_value = '' ) {
19
+ return update_term_meta( $this->object_id, $this->meta_key, $value, $prev_value );
20
+ }
21
+
22
+
23
+ /**
24
+ * Add new metadata.
25
+ *
26
+ * @param mixed $value New value to be saved to the database
27
+ * @return mixed
28
+ */
29
+ public function add_raw_value( $value ) {
30
+ return add_term_meta( $this->object_id, $this->meta_key, $value, $this->is_single );
31
+ }
32
+
33
+ /**
34
+ * Delete field value from the database.
35
+ *
36
+ * @param string $value Specific value to be deleted.
37
+ * @return mixed
38
+ */
39
+ public function delete_raw_value( $value = '' ) {
40
+ return delete_term_meta( $this->object_id, $this->meta_key, $value );
41
+ }
42
+
43
+ }
embedded/classes/field/accessor/termmeta_field.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Field accessor for term meta.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ final class WPCF_Field_Accessor_Termmeta_Field extends WPCF_Field_Accessor_Termmeta {
9
+
10
+ /** @var WPCF_Field_Instance_Abstract */
11
+ private $field;
12
+
13
+
14
+ /**
15
+ * WPCF_Field_Accessor_Termmeta_Field constructor.
16
+ *
17
+ * @param int $object_id
18
+ * @param string $meta_key
19
+ * @param bool $is_repetitive
20
+ * @param WPCF_Field_Instance_Abstract $field_instance
21
+ * @throws InvalidArgumentException
22
+ */
23
+ public function __construct( $object_id, $meta_key, $is_repetitive, $field_instance ) {
24
+ parent::__construct( $object_id, $meta_key, $is_repetitive );
25
+ if( ! $field_instance instanceof WPCF_Field_Instance_Abstract ) {
26
+ throw new InvalidArgumentException( 'Field instance required.' );
27
+ }
28
+ $this->field = $field_instance;
29
+ }
30
+
31
+
32
+ public function delete_raw_value( $value = '' ) {
33
+
34
+ $action = ( $this->field->get_definition()->get_is_repetitive() ? 'delete_repetitive' : 'delete' );
35
+
36
+ do_action( "wpcf_termeta_before_{$action}", $this->field );
37
+
38
+ $result = delete_term_meta( $this->object_id, $this->meta_key, $value );
39
+
40
+ do_action( "wpcf_termmeta_after_{$action}", $this->field );
41
+
42
+ return $result;
43
+ }
44
+
45
+ /**
46
+ * Add new metadata.
47
+ *
48
+ * @param mixed $value New value to be saved to the database
49
+ * @return mixed
50
+ */
51
+ public function add_raw_value( $value ) {
52
+ return add_term_meta( $this->object_id, $this->meta_key, $value, $this->is_single );
53
+ }
54
+
55
+ }
embedded/classes/field/data_saver.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Handles processing POST data from a toolset-forms form and updates a single field.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ final class WPCF_Field_Data_Saver {
9
+
10
+
11
+ /** @var WPCF_Field_Instance */
12
+ private $field;
13
+
14
+
15
+ /** @var string */
16
+ private $form_id;
17
+
18
+
19
+ /**
20
+ * WPCF_Field_Data_Saver constructor.
21
+ *
22
+ * @param WPCF_Field_Instance $field_instance Field that should be updated.
23
+ * @param string $form_id ID attribute of the form element that is being read from.
24
+ * @throws InvalidArgumentException
25
+ */
26
+ public function __construct( $field_instance, $form_id ) {
27
+ if( ! $field_instance instanceof WPCF_Field_Instance ) {
28
+ throw new InvalidArgumentException( 'Invalid field instance (must be an field of existing object).' );
29
+ }
30
+
31
+ $this->field = $field_instance;
32
+ $this->form_id = $form_id;
33
+ }
34
+
35
+
36
+ private $field_values = null;
37
+
38
+
39
+ /**
40
+ * Read the field values from $_POST.
41
+ *
42
+ * @return array Values in the "intermediate" format (see WPCF_Field_DataMapper_Abstract). For non-repetitive values,
43
+ * it will be an array with a single item.
44
+ */
45
+ private function read_field_values() {
46
+
47
+ if( null == $this->field_values ) {
48
+ $definition = $this->field->get_definition();
49
+
50
+ $form_data = wpcf_ensarr( wpcf_getpost( 'wpcf' ) );
51
+
52
+ $values = wpcf_getarr( $form_data, $definition->get_slug() );
53
+
54
+ // Handle single fields.
55
+ if ( ! $definition->get_is_repetitive() ) {
56
+ $values = array( $values );
57
+ }
58
+
59
+ // Map POST values to intermediate format.
60
+ $this->field_values = array();
61
+ $data_mapper = $definition->get_data_mapper();
62
+ foreach( $values as $value ) {
63
+ $this->field_values[] = $data_mapper->post_to_intermediate( $value, $form_data );
64
+ }
65
+ }
66
+
67
+ return wpcf_ensarr( $this->field_values );
68
+ }
69
+
70
+
71
+ /**
72
+ * @return array Array of true and WP_Error, one for each field value.
73
+ */
74
+ public function validate_field_data() {
75
+
76
+ $field_config = WPCF_Field_Utils::get_toolset_forms_field_config( $this->field );
77
+
78
+ $this->toggle_adding_field_names_to_error_messages( false );
79
+
80
+ $values = $this->read_field_values();
81
+ $results = array();
82
+ foreach( $values as $key => $value ) {
83
+ $results[ $key ] = $this->validate_single_field_value( $field_config, $value );
84
+ }
85
+
86
+ $this->toggle_adding_field_names_to_error_messages( true );
87
+
88
+ return $results;
89
+ }
90
+
91
+
92
+ private function is_all_field_data_valid() {
93
+ $validation_results = $this->validate_field_data();
94
+ foreach( $validation_results as $validation_result ) {
95
+ if( $validation_result instanceof WP_Error ) {
96
+ return false;
97
+ }
98
+ }
99
+
100
+ return true;
101
+ }
102
+
103
+
104
+ /**
105
+ * Sets if toolset-forms will be adding field name to error messages (that will be returned as WP_Error objects).
106
+ *
107
+ * Default is to add field names, make sure you return to this state afterwards.
108
+ *
109
+ * @param bool $add_field_name True if field name should be added to error messages.
110
+ */
111
+ private function toggle_adding_field_names_to_error_messages( $add_field_name ) {
112
+ if( false == $add_field_name ) {
113
+ add_filter( 'toolset_common_validation_add_field_name_to_error', '__return_false' );
114
+ } else {
115
+ remove_filter( 'toolset_common_validation_add_field_name_to_error', '__return_false' );
116
+ }
117
+ }
118
+
119
+
120
+ /**
121
+ * @param $field_config
122
+ * @param $value
123
+ *
124
+ * @return true|WP_Error
125
+ */
126
+ private function validate_single_field_value( $field_config, $value ) {
127
+ return wptoolset_form_validate_field( $this->form_id, $field_config, $value );
128
+ }
129
+
130
+
131
+ /**
132
+ * Update field value if it is valid.
133
+ *
134
+ * @return bool|WP_Error True on success, false or WP_Error on failure.
135
+ */
136
+ public function save_field_data() {
137
+
138
+ if( !$this->is_all_field_data_valid() ) {
139
+ return new WP_Error( 'Attempt to save a field with invalid value.' );
140
+ }
141
+
142
+ $values = $this->read_field_values();
143
+
144
+ $is_success = $this->field->update_all_values( $values );
145
+
146
+ return $is_success;
147
+
148
+ }
149
+
150
+
151
+ }
embedded/classes/field/datamapper/abstract.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Data mapper object for translating field value between what comes from $_POST (toolset-forms, usually), what is used
5
+ * in Types internally and what is stored to database.
6
+ *
7
+ * These classes should (eventually) define all three formats for all the field types.
8
+ *
9
+ * The correct data mapper for a field is chosen in WPCF_Field_Definition::get_data_mapper().
10
+ *
11
+ * @since 1.9
12
+ */
13
+ abstract class WPCF_Field_DataMapper_Abstract {
14
+
15
+ protected $field_definition;
16
+
17
+ public function __construct( $field_definition ) {
18
+ if( ! $field_definition instanceof WPCF_Field_Definition_Abstract ) {
19
+ throw new InvalidArgumentException( 'Field instance expected.' );
20
+ }
21
+
22
+ $this->field_definition = $field_definition;
23
+ }
24
+
25
+
26
+ public function database_to_intermediate( $value ) {
27
+ return $value;
28
+ }
29
+
30
+ public function intermediate_to_database( $value ) {
31
+ return $value;
32
+ }
33
+
34
+
35
+ /**
36
+ * @param mixed $post_value Field value as obtained from the POST data.
37
+ * @param array $form_data Complete form data.
38
+ *
39
+ * @return mixed
40
+ */
41
+ public function post_to_intermediate( $post_value, /** @noinspection PhpUnusedParameterInspection */ $form_data ) {
42
+ return $post_value;
43
+ }
44
+ }
embedded/classes/field/datamapper/checkbox.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Data mapper for a checkbox field.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ class WPCF_Field_DataMapper_Checkbox extends WPCF_Field_DataMapper_Abstract {
9
+
10
+
11
+ /**
12
+ * If this is a checkbox field that is not set, we will set the value manually to false.
13
+ *
14
+ * @param mixed $post_value
15
+ * @param array $form_data
16
+ *
17
+ * @return bool|mixed
18
+ */
19
+ public function post_to_intermediate( $post_value, $form_data ) {
20
+ if( ! array_key_exists( $this->field_definition->get_slug(), $form_data ) ) {
21
+ $value = false;
22
+ } else {
23
+ $value = $post_value;
24
+ }
25
+ return $value;
26
+ }
27
+ }
embedded/classes/field/datamapper/checkboxes.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPCF_Field_DataMapper_Checkboxes extends WPCF_Field_DataMapper_Abstract {
4
+
5
+
6
+ /** @var WPCF_Field_Definition */
7
+ protected $field_definition;
8
+
9
+
10
+ /**
11
+ * @param WPCF_Field_Definition $field_definition Must be a definition of a checkboxes field.
12
+ */
13
+ public function __construct( $field_definition ) {
14
+ parent::__construct( $field_definition );
15
+
16
+ if( $field_definition->get_type()->get_slug() != WPCF_Field_Definition::TYPE_CHECKBOXES ) {
17
+ throw new InvalidArgumentException( 'Wrong field definition type.' );
18
+ }
19
+ }
20
+
21
+
22
+ /**
23
+ * Theoretically this should be placed in self::post_to_intermediate(), but toolset-forms & legacy code
24
+ * might expect the POST data instead what I think should be the intermediate format.
25
+ *
26
+ * First of all, $value is expected to be an array. If checkbox is checked, an element with its id as key and value
27
+ * will be present. In that case it will be stored in the same way. If it's not checked, we either store nothing
28
+ * or a zero, depending on the field definition setting "Save empty value".
29
+ *
30
+ * @param array|mixed $value
31
+ *
32
+ * @return array
33
+ */
34
+ public function intermediate_to_database( $value ) {
35
+
36
+ $options = $this->field_definition->get_field_options();
37
+
38
+ $result = array();
39
+
40
+ foreach( $options as $option_id => $ignored ) {
41
+ $option_is_checked = isset( $value[ $option_id ] );
42
+
43
+ if( $option_is_checked ) {
44
+ $result[ $option_id ] = $value[ $option_id ];
45
+ } else if( $this->field_definition->get_should_save_empty_value() ) {
46
+ $result[ $option_id ] = 0;
47
+ }
48
+
49
+ }
50
+
51
+ return $result;
52
+ }
53
+
54
+
55
+ /**
56
+ * Since meta data (for posts and users, anyway) was historically loaded by get_*_meta() with $single = false,
57
+ * it always returned an array even for single fields. New accessors don't do that - and we need to fix it
58
+ * especially for checkboxes.
59
+ *
60
+ * @param array|mixed $value Expected array of checkboxes states, like
61
+ * array( "unchecked_option_hash" => 0, "checked_option_hash" => array( 0 => "option_value" ) )
62
+ *
63
+ * @return array
64
+ */
65
+ public function database_to_intermediate( $value ) {
66
+ return array( $value );
67
+ }
68
+ }
embedded/classes/field/datamapper/identity.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Identity data mapper. Does nothing.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ class WPCF_Field_DataMapper_Identity extends WPCF_Field_DataMapper_Abstract {
9
+
10
+ // Nothing to do here.
11
+
12
+ }
embedded/classes/field/definition.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Definition of a field.
5
+ *
6
+ * Children of this class must be instantiated exclusively through a factory class inherited from WPCF_Field_Definition_Factory.
7
+ *
8
+ * Note about field definition identification: For historical reasons, there are several, possibly equal, values available:
9
+ * The field key (key in the associative array of field definitions), slug, id and meta_key. While the meta_key's role
10
+ * is clear - it determines how field's data are stored in postmeta -, the first three values seem to be completely
11
+ * identical. Since the slug is used to organize fields into groups, we will use that as the main unique identifier
12
+ * from now on.
13
+ *
14
+ * @since 1.9
15
+ */
16
+ abstract class WPCF_Field_Definition extends WPCF_Field_Definition_Abstract {
17
+
18
+
19
+ /**
20
+ * For a Types field, this is a default prefix to it's slug that defines the meta_key for storing this field's values.
21
+ * Note that other custom fields that are brought under Types control additionally don't have to use this prefix
22
+ * and can have completely arbitrary meta_keys.
23
+ */
24
+ const FIELD_META_KEY_PREFIX = 'wpcf-';
25
+
26
+
27
+ const TYPE_CHECKBOXES = 'checkboxes';
28
+
29
+ const TYPE_CHECKBOX = 'checkbox';
30
+
31
+
32
+ /**
33
+ * @var WPCF_Field_Type_Definition Type definition.
34
+ */
35
+ private $type;
36
+
37
+
38
+ /**
39
+ * @var array The underlying array with complete information about this field.
40
+ * @todo We need a specification of everything that can be in it.
41
+ */
42
+ /*
43
+
44
+ Example of an field definition:
45
+
46
+ array (
47
+ 'id' => 'field-1',
48
+ 'slug' => 'field-1',
49
+ 'type' => 'textfield',
50
+ 'name' => 'Field 1',
51
+ 'description' => '',
52
+ 'data' => array
53
+ (
54
+ 'placeholder' => '',
55
+ 'user_default_value' => '',
56
+ 'repetitive' => '0',
57
+ 'is_new' => '1',
58
+ 'conditional_display' => array
59
+ (
60
+ 'custom_use' => '0',
61
+ 'relation' => 'AND',
62
+ 'custom' => '',
63
+ ),
64
+ 'submit-key' => 'textfield-1955088717',
65
+ 'disabled_by_type' => 0,
66
+ 'set_value' => ... (optional, presence is relevant)
67
+ ),
68
+ 'meta_key' => 'wpcf-field-1',
69
+ 'meta_type' => 'postmeta',
70
+ ),
71
+ ); */
72
+ private $definition_array;
73
+
74
+
75
+ /**
76
+ * @var string Field slug.
77
+ */
78
+ private $slug;
79
+
80
+
81
+ /**
82
+ * @var string Name of the field that can be displayed to the user.
83
+ */
84
+ private $name;
85
+
86
+
87
+
88
+ /**
89
+ * WPCF_Field_Definition constructor.
90
+ *
91
+ * @param WPCF_Field_Type_Definition $type Field type definition.
92
+ * @param array $definition_array The underlying array with complete information about this field.
93
+ */
94
+ public function __construct( $type, $definition_array ) {
95
+ $this->type = $type;
96
+ $this->definition_array = $definition_array;
97
+
98
+ $this->slug = wpcf_getarr( $definition_array, 'slug' );
99
+ if( sanitize_title( $this->slug ) != $this->slug ) {
100
+ throw new InvalidArgumentException( 'Invalid slug.' );
101
+ }
102
+
103
+ $this->name = sanitize_text_field( wpcf_getarr( $definition_array, 'name', $this->get_slug() ) );
104
+ }
105
+
106
+
107
+
108
+ public function get_slug() { return $this->slug; }
109
+
110
+
111
+ public function get_name() { return $this->name; }
112
+
113
+
114
+ /**
115
+ * @return string Proper display name suitable for direct displaying to the user.
116
+ *
117
+ * Handles string translation and adds an asterisk if the field is required.
118
+ *
119
+ * @since 1.9
120
+ */
121
+ public function get_display_name() {
122
+
123
+ // Try to translate through standard toolset-forms method
124
+ $string_name = sprintf( 'field %s name', $this->get_slug() );
125
+ $display_name = WPToolset_Types::translate( $string_name, $this->get_name() );
126
+
127
+ // Add an asterisk if the field is required
128
+ if( $this->get_is_required() && !empty( $display_name ) ) {
129
+ $display_name .= '&#42;';
130
+ }
131
+ return $display_name;
132
+ }
133
+
134
+
135
+ /**
136
+ * @return string Field description as provided by the user. Sanitized.
137
+ */
138
+ public function get_description() { return sanitize_text_field( wpcf_getarr( $this->definition_array, 'description' ) ); }
139
+
140
+
141
+ /**
142
+ * Determine whether the field is currently under Types control.
143
+ *
144
+ * If it's not, we are only holding on to this definition in case user decides to return it to Types control in the
145
+ * future. In all other regards, such field definition should be handled as a generic one.
146
+ *
147
+ * @return bool
148
+ */
149
+ public function is_under_types_control() {
150
+ $is_disabled = (bool) wpcf_getnest( $this->definition_array, array( 'data', 'disabled' ), false );
151
+ return !$is_disabled;
152
+ }
153
+
154
+
155
+ private $meta_key = null;
156
+
157
+
158
+ /**
159
+ * @return string Meta_key use to store this field's values. Defaults to wpcf-$slug.
160
+ */
161
+ public function get_meta_key() {
162
+ if( null == $this->meta_key ) {
163
+ $this->meta_key = sanitize_title(
164
+ wpcf_getarr( $this->definition_array, 'meta_key', self::FIELD_META_KEY_PREFIX . $this->get_slug() )
165
+ );
166
+ }
167
+ return $this->meta_key;
168
+ }
169
+
170
+
171
+ private $is_repetitive = null;
172
+
173
+
174
+ /**
175
+ * @return bool True if the field is repetitive, false otherwise.
176
+ */
177
+ public function get_is_repetitive() {
178
+ if( null === $this->is_repetitive ) {
179
+ $this->is_repetitive = ( wpcf_getnest( $this->definition_array, array( 'data', 'repetitive' ), 0 ) != 0 );
180
+ }
181
+ return $this->is_repetitive;
182
+ }
183
+
184
+
185
+ /**
186
+ * Get the underlying field definition array.
187
+ *
188
+ * Usage of this method is strongly discouraged, consider writing a custom (and safe) getter instead.
189
+ *
190
+ * @return array
191
+ */
192
+ public function get_definition_array() { return $this->definition_array; }
193
+
194
+
195
+ public function get_type() { return $this->type; }
196
+
197
+
198
+ /**
199
+ * For binary fields (like checkbox), it is possible to specify a value that will be saved to the database
200
+ * if the field is checked/selected/whatever.
201
+ *
202
+ * Stored in $cf['data']['set_save'].
203
+ *
204
+ * @return mixed|null The value or null if none is defined (make sure to compare with ===).
205
+ */
206
+ public function get_forced_value() {
207
+ return wpcf_getnest( $this->definition_array, array( 'data', 'set_value' ), null );
208
+ }
209
+
210
+
211
+ public function has_forced_value() {
212
+ return ( null !== $this->get_forced_value() );
213
+ }
214
+
215
+
216
+ public function get_should_save_empty_value() {
217
+ return ( 'yes' == wpcf_getnest( $this->definition_array, array( 'data', 'save_empty' ), 'no' ) );
218
+ }
219
+
220
+
221
+ public function get_is_required() {
222
+ return ( 1 == wpcf_getnest( $this->definition_array, array( 'data', 'validate', 'required', 'active' ), 0 ) );
223
+ }
224
+
225
+
226
+ /**
227
+ * @return array An option_id => option_data array.
228
+ */
229
+ public function get_field_options() {
230
+ return wpcf_ensarr( wpcf_getnest( $this->definition_array, array( 'data', 'options' ) ) );
231
+ }
232
+
233
+
234
+
235
+ /**
236
+ * Get an accessor for a specific field instance.
237
+ *
238
+ * @param WPCF_Field_Instance $field_instance Instance of the field the accessor should access.
239
+ * @return WPCF_Field_Accessor_Abstract
240
+ */
241
+ public abstract function get_accessor( $field_instance );
242
+
243
+
244
+
245
+
246
+ /**
247
+ * Get a mapper object that helps translating field data between database and rest of Types.
248
+ *
249
+ * Note: This happens here and not in field type definition because the information about field type might not
250
+ * be enough in the future.
251
+ *
252
+ * @todo This should probably be provided by type definition, no switch should be here.
253
+ *
254
+ * @return WPCF_Field_DataMapper_Abstract
255
+ */
256
+ public function get_data_mapper() {
257
+ switch( $this->get_type()->get_slug() ) {
258
+ case self::TYPE_CHECKBOXES:
259
+ return new WPCF_Field_DataMapper_Checkboxes( $this );
260
+ case self::TYPE_CHECKBOX:
261
+ return new WPCF_Field_DataMapper_Checkbox( $this );
262
+ default:
263
+ return new WPCF_Field_DataMapper_Identity( $this );
264
+ }
265
+ }
266
+
267
+
268
+ /**
269
+ * Delete all field values!
270
+ *
271
+ * @return bool
272
+ */
273
+ public abstract function delete_all_fields();
274
+
275
+ }
embedded/classes/field/definition_abstract.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Abstract of a field definition (common interface and code for generic and Types field definitions).
5
+ */
6
+ abstract class WPCF_Field_Definition_Abstract {
7
+
8
+ /**
9
+ * @return string Field definition slug.
10
+ */
11
+ public abstract function get_slug();
12
+
13
+
14
+ /**
15
+ * @return string Field definition display name.
16
+ */
17
+ public abstract function get_name();
18
+
19
+
20
+ /**
21
+ * @return string Description provided by the user.
22
+ */
23
+ public abstract function get_description();
24
+
25
+
26
+ /**
27
+ * @return string Meta key used to store values of these fields.
28
+ */
29
+ public abstract function get_meta_key();
30
+
31
+ /**
32
+ * Determine whether the field is currently under Types control.
33
+ *
34
+ * @return mixed
35
+ */
36
+ public abstract function is_under_types_control();
37
+
38
+
39
+ /**
40
+ * @return WPCF_Field_Group[]
41
+ */
42
+ public abstract function get_associated_groups();
43
+
44
+
45
+ /**
46
+ * Does the field definition match a certain string?
47
+ *
48
+ * Searches it's name and slug.
49
+ *
50
+ * @param string $search_string
51
+ * @return bool
52
+ */
53
+ public function is_match( $search_string ) {
54
+ return (
55
+ WPCF_Utils::is_string_match( $search_string, $this->get_name() )
56
+ || WPCF_Utils::is_string_match( $search_string, $this->get_slug() )
57
+ );
58
+ }
59
+
60
+
61
+ }
embedded/classes/field/definition_factory.php ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Abstract factory for field definitions.
5
+ *
6
+ * Handles creation of the objects as well as their caching.
7
+ */
8
+ abstract class WPCF_Field_Definition_Factory {
9
+
10
+ /**
11
+ * Singleton parent.
12
+ *
13
+ * @link http://stackoverflow.com/questions/3126130/extending-singletons-in-php
14
+ * @return WPCF_Field_Definition_Factory Instance of calling class.
15
+ */
16
+ final public static function get_instance() {
17
+ static $instances = array();
18
+ $called_class = get_called_class();
19
+ if( !isset( $instances[ $called_class ] ) ) {
20
+ $instances[ $called_class ] = new $called_class();
21
+ }
22
+ return $instances[ $called_class ];
23
+ }
24
+
25
+
26
+ final private function __construct() { }
27
+
28
+
29
+ final private function __clone() { }
30
+
31
+
32
+ /**
33
+ * @return string Name of the option that should be used to obtain field definitions.
34
+ */
35
+ protected abstract function get_option_name();
36
+
37
+
38
+ /**
39
+ * @return string Name of the class that should be instantiated as a field definition. It MUST inherit from
40
+ * WPCF_Field_Definition.
41
+ */
42
+ protected abstract function get_class_name();
43
+
44
+
45
+ /**
46
+ * @var array Existing instances of field definitions indexed by field slugs.
47
+ */
48
+ private $field_definitions = array();
49
+
50
+
51
+ /**
52
+ * Load an existing field definition.
53
+ *
54
+ * For now, we're using legacy code to read fields from the options table.
55
+ *
56
+ * @param string $field_key Key used to store the field configuration in options, or field slug (which should be
57
+ * equal to the key).
58
+ * @return null|WPCF_Field_Definition Field definition or null if it can't be loaded.
59
+ */
60
+ final public function load_field_definition( $field_key ) {
61
+
62
+ if( !is_string( $field_key ) || empty( $field_key ) ) {
63
+ return null;
64
+ }
65
+
66
+ // Can we use cached version?
67
+ if( !in_array( $field_key, $this->field_definitions ) ) {
68
+
69
+ // Get all field definitions for the option name we're using. No performance worries, it uses caching.
70
+ $fields_from_options = $this->get_fields_from_options();
71
+ $field_configuration = null;
72
+ if( in_array( $field_key, array_keys( $fields_from_options ) ) ) {
73
+ $field_configuration = $fields_from_options[ $field_key ];
74
+ } else {
75
+
76
+ // Theoretically, the field key may differ from the field slug (we have no invariants defined anywhere).
77
+ // We can search the array and look for slugs.
78
+ foreach( $fields_from_options as $field_from_options ) {
79
+ if( wpcf_getarr( $field_from_options, 'slug' ) == $field_key ) {
80
+ $field_configuration = $fields_from_options;
81
+ break;
82
+ }
83
+ }
84
+
85
+ if( null == $field_configuration ) {
86
+ // No such field is defined.
87
+ return null;
88
+ }
89
+ }
90
+
91
+ // Prepare the field type information, fail if we can't.
92
+ $field_type_slug = wpcf_getarr( $field_configuration, 'type', null );
93
+ $field_type = WPCF_Field_Type_Definition_Factory::load( $field_type_slug );
94
+ if( null == $field_type ) {
95
+ return null;
96
+ }
97
+
98
+ // Create the object and save it to cache.
99
+ try {
100
+ $class_name = $this->get_class_name();
101
+ /** @var WPCF_Field_Definition $field_definition */
102
+ $field_definition = new $class_name( $field_type, $field_configuration );
103
+ } catch( Exception $e ) {
104
+ return null;
105
+ }
106
+
107
+ $this->field_definitions[ $field_key ] = $field_definition;
108
+ }
109
+
110
+ return $this->field_definitions[ $field_key ];
111
+ }
112
+
113
+
114
+ /**
115
+ * Note: Consider using the builder pattern.
116
+ */
117
+ /*final protected function create_field_definition( ) {
118
+
119
+ }*/
120
+
121
+
122
+ /**
123
+ * @return array Raw field definition data from the options.
124
+ */
125
+ private function get_fields_from_options() {
126
+ return wpcf_admin_fields_get_fields( false, false, false, $this->get_option_name() );
127
+ }
128
+
129
+
130
+ /**
131
+ * Removes a single field definition from the storage of existing instances.
132
+ *
133
+ * It also completely clears the cache of the (legacy) wpcf_admin_fields_get_fields.
134
+ * Note that this method is public only temporarily and that this is not a mere cache clearing.
135
+ *
136
+ * @param string|null $field_slug If null, the cache will be emptied completely.
137
+ */
138
+ public function clear_definition_storage( $field_slug = null ) {
139
+ if( null == $field_slug ) {
140
+ $this->field_definitions = array();
141
+ } else {
142
+ unset( $this->field_definitions[ $field_slug ] );
143
+ }
144
+
145
+ wpcf_admin_fields_get_fields( false, false, false, $this->get_option_name(), false, true );
146
+ }
147
+
148
+
149
+ /**
150
+ * Completely erase field definition from options and clear cache.
151
+ *
152
+ * @param string $field_slug
153
+ */
154
+ private function erase_field_definition_from_options( $field_slug ) {
155
+
156
+ $fields_from_options = $this->get_fields_from_options();
157
+ unset( $fields_from_options[ $field_slug ] );
158
+ wpcf_admin_fields_save_fields( $fields_from_options, true, $this->get_option_name() );
159
+
160
+ $this->clear_definition_storage( $field_slug );
161
+ }
162
+
163
+
164
+ /**
165
+ * @return string[] Slugs of fields that have a definition in Types.
166
+ */
167
+ private function get_types_field_slugs() {
168
+ $fields_from_options = $this->get_fields_from_options();
169
+ $field_slugs = array();
170
+ foreach ( $fields_from_options as $field_configuration ) {
171
+ $slug = wpcf_getarr( $field_configuration, 'slug' );
172
+ if( !empty( $slug ) ) {
173
+ $field_slugs[] = $slug;
174
+ }
175
+ }
176
+ return array_unique( $field_slugs );
177
+ }
178
+
179
+
180
+ /**
181
+ * @param string $meta_key
182
+ * @return bool True if there exists any Types field definition (within the domain) that uses this key.
183
+ */
184
+ private function meta_key_belongs_to_types_field( $meta_key ) {
185
+ $field_definitions = $this->load_types_field_definitions();
186
+ foreach( $field_definitions as $field_definition ) {
187
+ if( $field_definition->get_meta_key() == $meta_key ) {
188
+ return true;
189
+ }
190
+ }
191
+ return false;
192
+ }
193
+
194
+
195
+ /**
196
+ * @return WPCF_Field_Definition[] All existing Types field definitions.
197
+ */
198
+ private function load_types_field_definitions() {
199
+ $field_slugs = $this->get_types_field_slugs();
200
+ $field_definitions = array();
201
+
202
+ foreach ( $field_slugs as $slug ) {
203
+ $field_definition = $this->load_field_definition( $slug );
204
+ if ( null != $field_definition ) {
205
+ $field_definitions[] = $field_definition;
206
+ }
207
+ }
208
+
209
+ return $field_definitions;
210
+ }
211
+
212
+
213
+ /**
214
+ * @return string[] All meta keys that occur in the database (within the domain).
215
+ */
216
+ protected abstract function get_existing_meta_keys();
217
+
218
+
219
+ /**
220
+ * @var null|WPCF_Field_Definition_Generic[] Cache.
221
+ */
222
+ private $generic_field_definitions = null;
223
+
224
+
225
+ /**
226
+ * @return WPCF_Field_Definition_Generic[] Definitions of all generic fields that exist in the database within
227
+ * current domain.
228
+ */
229
+ public function load_generic_field_definitions() {
230
+
231
+ if( null == $this->generic_field_definitions ) {
232
+ $existing_meta_keys = $this->get_existing_meta_keys();
233
+
234
+ $results = array();
235
+ foreach( $existing_meta_keys as $meta_key ) {
236
+
237
+ if( $this->meta_key_belongs_to_types_field( $meta_key ) ) {
238
+ continue;
239
+ }
240
+
241
+ $results[] = new WPCF_Field_Definition_Generic( $meta_key );
242
+ }
243
+
244
+ $this->generic_field_definitions = $results;
245
+
246
+ }
247
+
248
+ return $this->generic_field_definitions;
249
+ }
250
+
251
+
252
+ /**
253
+ * @return WPCF_Field_Definition_Abstract[] All field definitions (generic and Types-controlled).
254
+ */
255
+ public function load_all_definitions() {
256
+ return array_merge( $this->load_types_field_definitions(), $this->load_generic_field_definitions() );
257
+ }
258
+
259
+
260
+ /**
261
+ * Reorder an array of field definitions.
262
+ *
263
+ * @param WPCF_Field_Definition_Abstract[] $definitions
264
+ * @param string $orderby 'name'|'slug'|'is_under_types_control'|'field_type'
265
+ * @param string $order 'asc'|'desc'
266
+ *
267
+ * @return WPCF_Field_Definition_Abstract[] Reordered array.
268
+ */
269
+ public function order_definitions( $definitions, $orderby = 'name', $order = 'asc' ) {
270
+
271
+ $orderby_to_comparison_function = array(
272
+ 'name' => 'compare_definitions_by_name',
273
+ 'slug' => 'compare_definitions_by_slug',
274
+ 'is_under_types_control' => 'compare_definition_by_types_control',
275
+ 'field_type' => 'compare_definitions_by_field_type'
276
+ );
277
+
278
+ usort( $definitions, array( $this, wpcf_getarr( $orderby_to_comparison_function, $orderby, 'compare_definitions_by_name' ) ) );
279
+
280
+ if( 'desc' == $order ) {
281
+ $definitions = array_reverse( $definitions );
282
+ }
283
+
284
+ return $definitions;
285
+ }
286
+
287
+
288
+ /**
289
+ * Compare function for ordering by name in order_definitions().
290
+ *
291
+ * @param $first WPCF_Field_Definition_Abstract
292
+ * @param $second WPCF_Field_Definition_Abstract
293
+ *
294
+ * @return int
295
+ */
296
+ public function compare_definitions_by_name( $first, $second ) {
297
+ return strcoll( strtolower( $first->get_name() ), strtolower( $second->get_name() ) );
298
+ }
299
+
300
+
301
+ /**
302
+ * Compare function for ordering by slug in order_definitions().
303
+ *
304
+ * @param $first WPCF_Field_Definition_Abstract
305
+ * @param $second WPCF_Field_Definition_Abstract
306
+ *
307
+ * @return int
308
+ */
309
+ public function compare_definitions_by_slug( $first, $second ) {
310
+ return strcmp( $first->get_slug(), $second->get_slug() );
311
+ }
312
+
313
+
314
+ /**
315
+ * Compare function for ordering by the Types control status in order_definitions().
316
+ *
317
+ * @param $first WPCF_Field_Definition_Abstract
318
+ * @param $second WPCF_Field_Definition_Abstract
319
+ *
320
+ * @return int
321
+ */
322
+ public function compare_definition_by_types_control( $first, $second ) {
323
+ if( $first->is_under_types_control() == $second->is_under_types_control() ) {
324
+ return 0;
325
+ } else {
326
+ return $first->is_under_types_control() ? 1 : -1;
327
+ }
328
+ }
329
+
330
+
331
+ /**
332
+ * Compare function for ordering by field type in order_definitions().
333
+ *
334
+ * @param $first WPCF_Field_Definition_Abstract
335
+ * @param $second WPCF_Field_Definition_Abstract
336
+ *
337
+ * @return int
338
+ */
339
+ public function compare_definitions_by_field_type( $first, $second ) {
340
+ if( $first->is_under_types_control() == $second->is_under_types_control() ) {
341
+ if( $first->is_under_types_control() ) {
342
+ // Both are under Types control, compare their field types
343
+ /** @var WPCF_Field_Definition $first_t */
344
+ $first_t = $first;
345
+ /** @var WPCF_Field_Definition $second_t */
346
+ $second_t = $second;
347
+ return strcmp( $first_t->get_type()->get_slug(), $second_t->get_type()->get_slug() );
348
+ } else {
349
+ // None are under Types control
350
+ return 0;
351
+ }
352
+ } else {
353
+ // The one that is under Types control wins.
354
+ return $first->is_under_types_control() ? -1 : 1;
355
+ }
356
+ }
357
+
358
+
359
+ /**
360
+ * Query field definitions.
361
+ *
362
+ * @param array $args Following arguments are recognized:
363
+ * - filter: What field definitions should be retrieved: 'types'|'generic'|'all'
364
+ * - orderby: 'name'|'slug'|'is_under_types_control'|'field_type'
365
+ * - order: 'asc'|'desc'
366
+ * - search: String for fulltext search.
367
+ *
368
+ * @return WPCF_Field_Definition_Abstract[] Field definitions that match query arguments.
369
+ */
370
+ public function query_definitions( $args ) {
371
+
372
+ $args = wp_parse_args( $args, array('filter' => 'all') );
373
+
374
+ // Get only certain type of field definitions (generic, Types or both)
375
+ switch( $args['filter'] ) {
376
+ case 'types':
377
+ $results = $this->load_types_field_definitions();
378
+ break;
379
+ case 'generic':
380
+ $results = $this->load_generic_field_definitions();
381
+ break;
382
+ case 'all':
383
+ $results = $this->load_all_definitions();
384
+ break;
385
+ default:
386
+ $results = array();
387
+ break;
388
+ }
389
+
390
+ // Perform fulltext search if needed
391
+ $search_string = wpcf_getarr( $args, 'search', '' );
392
+
393
+ if( !empty( $search_string ) ) {
394
+ $matches = array();
395
+ foreach( $results as $definition ) {
396
+ if( $definition->is_match( $search_string ) ) {
397
+ $matches[] = $definition;
398
+ }
399
+ }
400
+ $results = $matches;
401
+ }
402
+
403
+ // Sort results
404
+ $orderby = wpcf_getarr( $args, 'orderby', 'name' );
405
+ $order = wpcf_getarr( $args, 'order', 'asc', array( 'asc', 'desc' ) );
406
+
407
+ $results = $this->order_definitions( $results, $orderby, $order );
408
+
409
+ return $results;
410
+ }
411
+
412
+
413
+ /**
414
+ * Permanently delete field definition.
415
+ *
416
+ * That means:
417
+ * - remove it from all field groups,
418
+ * - delete field data from the database (sic!) and
419
+ * - delete the definition itself.
420
+ *
421
+ * After calling this method, the field definition object passed as parameter should never be used again.
422
+ *
423
+ * @param WPCF_Field_Definition $field_definiton
424
+ * @return bool
425
+ */
426
+ public function delete_definition( $field_definiton ) {
427
+
428
+ // We accept only fields that are under Types control
429
+ if( ! $field_definiton instanceof WPCF_Field_Definition ) {
430
+ return false;
431
+ }
432
+
433
+ if( ! $field_definiton->is_under_types_control() ) {
434
+ return false;
435
+ }
436
+
437
+ // Remove field from all groups
438
+ $associated_groups = $field_definiton->get_associated_groups();
439
+ foreach( $associated_groups as $group ) {
440
+ $group->remove_field_definition( $field_definiton );
441
+ }
442
+
443
+ // Delete field data
444
+ $is_success = $field_definiton->delete_all_fields();
445
+
446
+ // Delete the definition
447
+ $slug_to_delete = $field_definiton->get_slug();
448
+ $this->erase_field_definition_from_options( $slug_to_delete );
449
+
450
+ return $is_success;
451
+
452
+ }
453
+
454
+
455
+ }
embedded/classes/field/definition_generic.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Generic field definition.
5
+ *
6
+ * Represents basically a meta key that doesn't belong to any field known to Types.
7
+ */
8
+ class WPCF_Field_Definition_Generic extends WPCF_Field_Definition_Abstract {
9
+
10
+
11
+ private $meta_key = '';
12
+
13
+
14
+ public function __construct( $meta_key ) {
15
+ $this->meta_key = $meta_key;
16
+ }
17
+
18
+
19
+ public function get_slug() {
20
+ return $this->meta_key;
21
+ }
22
+
23
+ public function get_name() {
24
+ return $this->meta_key;
25
+ }
26
+
27
+ public function get_description() {
28
+ return '';
29
+ }
30
+
31
+ public function get_meta_key() {
32
+ return $this->meta_key;
33
+ }
34
+
35
+ public function is_under_types_control() {
36
+ return false;
37
+ }
38
+
39
+ public function get_associated_groups() {
40
+ return array();
41
+ }
42
+ }
embedded/classes/field/definition_term.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Field definition for term fields.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ final class WPCF_Field_Definition_Term extends WPCF_Field_Definition {
9
+
10
+
11
+ /**
12
+ * Get an accessor for a specific field instance.
13
+ *
14
+ * @param WPCF_Field_Instance $field_instance Instance of the field the accessor should access.
15
+ * @return WPCF_Field_Accessor_Termmeta_Field
16
+ */
17
+ public function get_accessor( $field_instance ) {
18
+ return new WPCF_Field_Accessor_Termmeta_Field(
19
+ $field_instance->get_object_id(),
20
+ $this->get_meta_key(),
21
+ $this->get_is_repetitive(),
22
+ $field_instance
23
+ );
24
+ }
25
+
26
+
27
+ /**
28
+ * @return WPCF_Field_Group[]
29
+ */
30
+ public function get_associated_groups() {
31
+ $term_field_groups = WPCF_Field_Group_Term_Factory::get_instance()->query_groups();
32
+ $associated_groups = array();
33
+ foreach ( $term_field_groups as $field_group ) {
34
+ if ( $field_group->contains_field_definition( $this ) ) {
35
+ $associated_groups[] = $field_group;
36
+ }
37
+ }
38
+
39
+ return $associated_groups;
40
+ }
41
+
42
+
43
+ /**
44
+ * Delete all field values!
45
+ *
46
+ * @return bool
47
+ */
48
+ public function delete_all_fields() {
49
+ global $wpdb;
50
+
51
+ $meta_key = $this->get_meta_key();
52
+
53
+ $termmeta_records = $wpdb->get_results(
54
+ $wpdb->prepare(
55
+ "SELECT term_id FROM $wpdb->termmeta WHERE meta_key = %s",
56
+ $meta_key
57
+ )
58
+ );
59
+
60
+ // Delete one by one because we (probably) want all the WP hooks to fire.
61
+ foreach ( $termmeta_records as $termmeta ) {
62
+ delete_term_meta( $termmeta->term_id, $meta_key );
63
+ }
64
+
65
+ return true;
66
+ }
67
+ }
embedded/classes/field/group.php ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Abstract representation of a field group (without defined type).
5
+ *
6
+ * Descendants of this class allways must be instantiated through appropriate factory class inheriting
7
+ * from WPCF_Field_Group_Factory.
8
+ *
9
+ * Any method that permanently changes any group data needs to call execute_group_updated_action() afterwards.
10
+ */
11
+ abstract class WPCF_Field_Group {
12
+
13
+ /**
14
+ * Stores the slugs of the fields that belong to this group, as a comma separated list.
15
+ */
16
+ const POSTMETA_FIELD_SLUGS_LIST = '_wp_types_group_fields';
17
+
18
+
19
+ const FIELD_SLUG_DELIMITER = ',';
20
+
21
+
22
+ /**
23
+ * @var WP_Post Post object that represents the field group.
24
+ */
25
+ private $post;
26
+
27
+
28
+ /**
29
+ * WPCF_Field_Group constructor.
30
+ *
31
+ * Note that it is protected - inheriting classes have to implement an override that should, additionally, check
32
+ * if the post has correct type.
33
+ *
34
+ * @param WP_Post $field_group_post Post object that represents the field group.
35
+ * @throws InvalidArgumentException
36
+ */
37
+ protected function __construct( $field_group_post ) {
38
+ if( ! $field_group_post instanceof WP_Post ) {
39
+ throw new InvalidArgumentException( 'First argument is not a post.' );
40
+ }
41
+ $this->post = $field_group_post;
42
+ }
43
+
44
+
45
+ /**
46
+ * @return WPCF_Field_Definition_Factory Field definition factory of the correct type.
47
+ */
48
+ protected abstract function get_field_definition_factory();
49
+
50
+
51
+ /**
52
+ * @return WP_Post Post object representing the field group.
53
+ */
54
+ protected function get_post() {
55
+ return $this->post;
56
+ }
57
+
58
+
59
+ /**
60
+ * @return int ID of the field group.
61
+ */
62
+ public function get_id() {
63
+ return $this->get_post()->ID;
64
+ }
65
+
66
+
67
+ /**
68
+ * @return string Unique name (post slug) of the field group.
69
+ */
70
+ public function get_slug() {
71
+ return sanitize_title( $this->get_post()->post_name );
72
+ }
73
+
74
+
75
+ /**
76
+ * @return string Field group description. Sanitized as a text field.
77
+ */
78
+ public function get_description() {
79
+ return sanitize_text_field( $this->get_post()->post_content );
80
+ }
81
+
82
+
83
+ /**
84
+ * Note that for displaying group name to the user you should use get_display_name() instead.
85
+ *
86
+ * @return string Field group title.
87
+ */
88
+ public function get_name() {
89
+ return sanitize_text_field( $this->get_post()->post_title );
90
+ }
91
+
92
+
93
+ /**
94
+ * Get group name as it should be displayed to the user.
95
+ *
96
+ * Handles string translation if applicable.
97
+ */
98
+ public function get_display_name() {
99
+ return wpcf_translate(
100
+ sprintf( 'group %d name', $this->get_id() ),
101
+ $this->get_name()
102
+ );
103
+ }
104
+
105
+
106
+ /**
107
+ * @return bool True if the field group is active, false if deactivated.
108
+ */
109
+ public function is_active() {
110
+ return ( $this->get_post()->post_status == 'publish' ? true : false );
111
+ }
112
+
113
+
114
+ /**
115
+ * @return string Status of the underlying post. Limited to 'publish'|'draft' (default).
116
+ */
117
+ public function get_post_status() {
118
+ return ( $this->is_active() ? 'publish' : 'draft' );
119
+ }
120
+
121
+
122
+ /**
123
+ * @return int ID of the user who edited the field group last.
124
+ */
125
+ public function get_author() {
126
+ return (int) $this->get_post()->post_author;
127
+ }
128
+
129
+
130
+ /*
131
+ * $group['meta_box_context'] = 'normal';
132
+ $group['meta_box_priority'] = 'high';
133
+ $group['filters_association'] = get_post_meta( $post->ID, '_wp_types_group_filters_association', true );
134
+ */
135
+
136
+
137
+ /**
138
+ * Change name of the field group.
139
+ *
140
+ * Do not confuse with the title. *All* changes of the name must happen through this method, otherwise
141
+ * unexpected behaviour of the WPCF_Field_Group_Factory can occur.
142
+ *
143
+ * @param string $value New value of the post name. Note that it may be further modified by WordPress before saving.
144
+ */
145
+ public function set_name( $value ) {
146
+ $updated_post_id = wp_update_post(
147
+ array( 'ID' => $this->get_id(), 'post_name' => sanitize_title( $value ) )
148
+ );
149
+ if( 0 !== $updated_post_id ) {
150
+ // Refresh the post object and notify about renaming field group.
151
+ $this->post = WP_Post::get_instance( $updated_post_id );
152
+ do_action( 'wpcf_field_group_renamed', $value, $this );
153
+ $this->execute_group_updated_action();
154
+ }
155
+ }
156
+
157
+
158
+ /**
159
+ * @return string The underlying post type of the post representing the field group.
160
+ */
161
+ public function get_post_type() {
162
+ return $this->post->post_type;
163
+ }
164
+
165
+
166
+ /**
167
+ * @var null|array Array of field slugs that belong to this field group, or null if it was not loaded from database yet.
168
+ */
169
+ private $field_slugs = null;
170
+
171
+
172
+ /**
173
+ * Check if a field slug is valid and can be stored in the database.
174
+ *
175
+ * @param string $field_slug
176
+ * @return bool True if the slug is valid.
177
+ */
178
+ public function is_valid_field_slug( $field_slug ) {
179
+ return !empty( $field_slug ) && is_string( $field_slug ) && ( sanitize_title( $field_slug ) == $field_slug );
180
+ }
181
+
182
+
183
+ /**
184
+ * Check if an array of field slugs is valid.
185
+ *
186
+ * @param array|mixed $field_slugs
187
+ * @return bool True if an array of valid field slugs was provided.
188
+ */
189
+ protected function validate_field_slugs( $field_slugs ) {
190
+ if( !is_array( $field_slugs ) ) {
191
+ return false;
192
+ }
193
+
194
+ // Every element needs to be valid
195
+ if( count( $field_slugs ) != count ( array_filter( $field_slugs, array( $this, 'is_valid_field_slug' ) ) ) ) {
196
+ return false;
197
+ }
198
+
199
+ return true;
200
+ }
201
+
202
+
203
+ /**
204
+ * @return array Slugs of fields that belong to this field group, or empty array when database doesn't contain
205
+ * valid data.
206
+ *
207
+ * Consider using get_field_definitions() instead.
208
+ */
209
+ public function get_field_slugs() {
210
+ if( null == $this->field_slugs ) {
211
+ $field_slug_list = get_post_meta( $this->get_id(), self::POSTMETA_FIELD_SLUGS_LIST, true );
212
+ $field_slugs = explode( self::FIELD_SLUG_DELIMITER, $field_slug_list );
213
+
214
+ // Remove empty slugs
215
+ foreach( $field_slugs as $key => $slug ) {
216
+ if( empty( $slug ) ) {
217
+ unset( $field_slugs[ $key ] );
218
+ }
219
+ }
220
+
221
+ $this->field_slugs = $this->validate_field_slugs( $field_slugs ) ? $field_slugs : array();
222
+ }
223
+ return $this->field_slugs;
224
+ }
225
+
226
+
227
+ /**
228
+ * Get all existing definitions of fields that belong to this group.
229
+ *
230
+ * @return WPCF_Field_Definition[]
231
+ */
232
+ public function get_field_definitions() {
233
+ $slugs = $this->get_field_slugs();
234
+ $field_definitions = array();
235
+ $factory = $this->get_field_definition_factory();
236
+ foreach( $slugs as $slug ) {
237
+ $field_definition = $factory->load_field_definition( $slug );
238
+ if( null != $field_definition ) {
239
+ $field_definitions[] = $field_definition;
240
+ }
241
+ }
242
+ return $field_definitions;
243
+ }
244
+
245
+
246
+ /**
247
+ * Update the set of field slugs that belong to this field group.
248
+ *
249
+ * @param array $field_slugs Array of valid field slugs.
250
+ * @return bool True if the database was updated successfully, false otherwise.
251
+ */
252
+ protected function set_field_slugs( $field_slugs ) {
253
+ if( !$this->validate_field_slugs( $field_slugs ) ) {
254
+ return false;
255
+ }
256
+
257
+ $this->field_slugs = $field_slugs;
258
+
259
+ $field_slug_list = implode( self::FIELD_SLUG_DELIMITER, $field_slugs );
260
+
261
+ $updated = update_post_meta( $this->get_id(), self::POSTMETA_FIELD_SLUGS_LIST, $field_slug_list );
262
+
263
+ $this->execute_group_updated_action();
264
+
265
+ return ( $updated != false );
266
+ }
267
+
268
+
269
+ /**
270
+ * Remove field definition from this group.
271
+ *
272
+ * @param WPCF_Field_Definition $field_definition
273
+ * @return bool
274
+ */
275
+ public function remove_field_definition( $field_definition ) {
276
+
277
+ $field_slugs = $this->get_field_slugs();
278
+
279
+ $slug_to_remove = $field_definition->get_slug();
280
+ $key = array_search( $slug_to_remove, $field_slugs );
281
+ if( $key !== false ) {
282
+ unset( $field_slugs[ $key ] );
283
+ }
284
+
285
+ $is_success = $this->set_field_slugs( $field_slugs );
286
+
287
+ return $is_success;
288
+ }
289
+
290
+
291
+ /**
292
+ * Check if a string is contained within the field group definition.
293
+ *
294
+ * Searches in ID, slug, title and description. Case insensitive.
295
+ *
296
+ * @param string $search_string String to look for.
297
+ * @return bool True if found.
298
+ */
299
+ public function is_match( $search_string ) {
300
+ return (
301
+ WPCF_Utils::is_string_match( $search_string, $this->get_id() )
302
+ || WPCF_Utils::is_string_match( $search_string, $this->get_slug() )
303
+ || WPCF_Utils::is_string_match( $search_string, $this->get_name() )
304
+ || WPCF_Utils::is_string_match( $search_string, $this->get_display_name() )
305
+ || WPCF_Utils::is_string_match( $search_string, $this->get_description() )
306
+ );
307
+ }
308
+
309
+
310
+ public function contains_field_definition( $field_definition ) {
311
+ if( $field_definition instanceof WPCF_Field_Definition ) {
312
+ return in_array( $field_definition, $this->get_field_definitions() );
313
+ } elseif( is_string( $field_definition ) ) {
314
+ return in_array( $field_definition, $this->get_field_slugs() );
315
+ } else {
316
+ return false;
317
+ }
318
+ }
319
+
320
+
321
+ /**
322
+ * Execute the wpcf_group_updated action.
323
+ *
324
+ * Needs to be called after each (permanent) change to a group.
325
+ */
326
+ public function execute_group_updated_action() {
327
+
328
+ /**
329
+ * Executed after a group has been updated in the database.
330
+ *
331
+ * @param int $id Group ID.
332
+ * @param WPCF_Field_Group $group The group object.
333
+ * @since 1.9
334
+ */
335
+ do_action( 'wpcf_group_updated', $this->get_id(), $this );
336
+ }
337
+
338
+ }
embedded/classes/field/group_factory.php ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Abstract factory for field group classes.
5
+ *
6
+ * It ensures that each field group is instantiated only once and it keeps returning that one instance.
7
+ *
8
+ * Note: Cache is indexed by slugs, so if a field group can change it's slug, it is necessary to do
9
+ * an 'wpcf_field_group_renamed' action immediately after renaming.
10
+ */
11
+ abstract class WPCF_Field_Group_Factory {
12
+
13
+
14
+ /**
15
+ * Singleton parent.
16
+ *
17
+ * @link http://stackoverflow.com/questions/3126130/extending-singletons-in-php
18
+ * @return WPCF_Field_Group_Factory Instance of calling class.
19
+ */
20
+ public static function get_instance() {
21
+ static $instances = array();
22
+ $called_class = get_called_class();
23
+ if( !isset( $instances[ $called_class ] ) ) {
24
+ $instances[ $called_class ] = new $called_class();
25
+ }
26
+ return $instances[ $called_class ];
27
+ }
28
+
29
+
30
+ protected function __construct() {
31
+ add_action( 'wpcf_field_group_renamed', array( $this, 'field_group_renamed' ), 10, 2 );
32
+ }
33
+
34
+
35
+ final private function __clone() { }
36
+
37
+
38
+ /**
39
+ * @return string Post type that holds information about this field group type.
40
+ */
41
+ abstract protected function get_post_type();
42
+
43
+
44
+ /**
45
+ * @return string Name of the class that represents this field group type (and that will be instantiated). It must
46
+ * be a child of WPCF_Field_Group.
47
+ */
48
+ abstract protected function get_field_group_class_name();
49
+
50
+
51
+ /**
52
+ * Get a post object that represents a field group.
53
+ *
54
+ * @param int|string|WP_Post $field_group Numeric ID of the post, post slug or a post object.
55
+ *
56
+ * @return null|WP_Post Requested post object when the post exists and has correct post type. Null otherwise.
57
+ */
58
+ final protected function get_post( $field_group ) {
59
+
60
+ $fg_post = null;
61
+
62
+ // http://stackoverflow.com/questions/2559923/shortest-way-to-check-if-a-variable-contains-positive-integer-using-php
63
+ if ( is_scalar( $field_group ) && ( $field_group == (int) $field_group ) && ( (int) $field_group > 0 ) ) {
64
+ $fg_post = WP_Post::get_instance( $field_group );
65
+ } else if ( is_string( $field_group ) ) {
66
+ $query = new WP_Query( array( 'post_type' => $this->get_post_type(), 'name' => $field_group, 'posts_per_page' => 1 ) );
67
+ if( $query->have_posts() ) {
68
+ $fg_post = $query->get_posts();
69
+ $fg_post = $fg_post[0];
70
+ }
71
+ } else {
72
+ $fg_post = $field_group;
73
+ }
74
+
75
+ if( $fg_post instanceof WP_Post && $this->get_post_type() == $fg_post->post_type ) {
76
+ return $fg_post;
77
+ } else {
78
+ return null;
79
+ }
80
+ }
81
+
82
+
83
+ /**
84
+ * @var array Array of field group instances for this post type, indexed by names (post slugs).
85
+ */
86
+ private $field_groups = array();
87
+
88
+
89
+ /**
90
+ * @param string $field_group_name Name of the field group.
91
+ * @return null|WPCF_Field_Group Field group instance or null if it's not cached.
92
+ */
93
+ private function get_from_cache( $field_group_name ) {
94
+ return wpcf_getarr( $this->field_groups, $field_group_name, null );
95
+ }
96
+
97
+
98
+ /**
99
+ * Save a field group instance to cache.
100
+ * @param WPCF_Field_Group $field_group
101
+ */
102
+ private function save_to_cache( $field_group ) {
103
+ $this->field_groups[ $field_group->get_slug() ] = $field_group;
104
+ }
105
+
106
+
107
+ /**
108
+ * Remove field group instance from cache.
109
+ * @param string $field_group_name
110
+ */
111
+ private function clear_from_cache( $field_group_name ) {
112
+ unset( $this->field_groups[ $field_group_name ] );
113
+ }
114
+
115
+
116
+ /**
117
+ * Load a field group instance.
118
+ *
119
+ * @param int|string|WP_Post $field_group_source Post ID of the field group, it's name or a WP_Post object.
120
+ *
121
+ * @return null|WPCF_Field_Group Field group or null if it can't be loaded.
122
+ */
123
+ final public function load_field_group( $field_group_source ) {
124
+
125
+ $post = null;
126
+
127
+ // If we didn't get a field group name, we first need to get the post so we can look into the cache.
128
+ if( !is_string( $field_group_source ) ) {
129
+ $post = $this->get_post( $field_group_source );
130
+ if( null == $post ) {
131
+ // There is no such post (or has wrong type).
132
+ return null;
133
+ }
134
+ $field_group_name = $post->post_name;
135
+ } else {
136
+ $field_group_name = $field_group_source;
137
+ }
138
+
139
+ // Try to get an existing instance.
140
+ $field_group = $this->get_from_cache( $field_group_name );
141
+ if( null != $field_group ) {
142
+ return $field_group;
143
+ }
144
+
145
+ // We might already have the post by now.
146
+ if( null == $post ) {
147
+ $post = $this->get_post( $field_group_source );
148
+ }
149
+
150
+ // There is no such post (or has wrong type).
151
+ if( null == $post ) {
152
+ return null;
153
+ }
154
+
155
+ // Create new field group instance
156
+ try {
157
+ $class_name = $this->get_field_group_class_name();
158
+ $field_group = new $class_name( $post );
159
+ } catch( Exception $e ) {
160
+ return null;
161
+ }
162
+
163
+ $this->save_to_cache( $field_group );
164
+ return $field_group;
165
+ }
166
+
167
+
168
+ /**
169
+ * Update cache after a field group is renamed.
170
+ *
171
+ * @param string $original_name The old name of the field group.
172
+ * @param WPCF_Field_Group $field_group The field group involved, with already updated name.
173
+ */
174
+ public function field_group_renamed( $original_name, $field_group ) {
175
+ if( $field_group->get_post_type() == $this->get_post_type() ) {
176
+ $this->clear_from_cache( $original_name );
177
+ $this->save_to_cache( $field_group );
178
+ }
179
+ }
180
+
181
+
182
+ /**
183
+ * Create new field group.
184
+ *
185
+ * @param string $name Sanitized field group name. Note that the final name may change when new post is inserted.
186
+ * @param string $title Field group title.
187
+ *
188
+ * @return null|WPCF_Field_Group The new field group or null on error.
189
+ */
190
+ final public function create_field_group( $name, $title = '' ) {
191
+
192
+ if( sanitize_title( $name ) != $name ) {
193
+ return null;
194
+ }
195
+
196
+ $title = wp_strip_all_tags( $title );
197
+
198
+ $post_id = wp_insert_post( array(
199
+ 'post_type' => $this->get_post_type(),
200
+ 'post_name' => $name,
201
+ 'post_title' => empty( $title ) ? $name : $title
202
+ ) );
203
+
204
+ if( 0 == $post_id ) {
205
+ return null;
206
+ }
207
+
208
+ // Store the mandatory postmeta, just to be safe. I'm not sure about invariants here.
209
+ update_post_meta( $post_id, WPCF_Field_Group::POSTMETA_FIELD_SLUGS_LIST, '' );
210
+
211
+ $field_group = $this->load_field_group( $post_id );
212
+
213
+ $field_group->execute_group_updated_action();
214
+
215
+ return $field_group;
216
+ }
217
+
218
+
219
+ /**
220
+ * Get field groups based on query arguments.
221
+ *
222
+ * @param array $query_args Optional. Arguments for the WP_Query that will be applied on the underlying posts.
223
+ * Post type query is added automatically.
224
+ * @param null|string $search_string String for extended search. See WPCF_Field_Group::is_match() for details.
225
+ * @return WPCF_Field_Group[]
226
+ */
227
+ public function query_groups( $query_args = array(), $search_string = null ) {
228
+
229
+ // Query posts
230
+ $query_args = array_merge( $query_args, array( 'post_type' => $this->get_post_type() ) );
231
+ $query = new WP_Query( $query_args );
232
+ $posts = $query->get_posts();
233
+
234
+ // Transform posts into WPCF_Field_Group
235
+ $all_groups = array();
236
+ foreach( $posts as $post ) {
237
+ $field_group = $this->load_field_group( $post );
238
+ if( null != $field_group ) {
239
+ $all_groups[] = $field_group;
240
+ }
241
+ }
242
+
243
+ // Filter groups by the search string.
244
+ $selected_groups = array();
245
+ if( empty( $search_string ) ) {
246
+ $selected_groups = $all_groups;
247
+ } else {
248
+ /** @var WPCF_Field_Group $group */
249
+ foreach ( $all_groups as $group ) {
250
+ if ( $group->is_match( $search_string ) ) {
251
+ $selected_groups[] = $group;
252
+ }
253
+ }
254
+ }
255
+
256
+ return $selected_groups;
257
+ }
258
+
259
+ }
embedded/classes/field/group_term.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Term field group.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ final class WPCF_Field_Group_Term extends WPCF_Field_Group {
9
+
10
+
11
+ const POST_TYPE = 'wp-types-term-group';
12
+
13
+
14
+ /**
15
+ * Key for postmeta that holds slugs of taxonomies associated with this group. This is a "plural" postmeta,
16
+ * each record contains one slug.
17
+ */
18
+ const POSTMETA_ASSOCIATED_TAXONOMY = '_wp_types_associated_taxonomy';
19
+
20
+
21
+ /**
22
+ * WPCF_Field_Group_Term constructor.
23
+ *
24
+ * @param WP_Post $field_group_post Post object representing a term field group.
25
+ * @throws InvalidArgumentException
26
+ */
27
+ public function __construct( $field_group_post ) {
28
+ parent::__construct( $field_group_post );
29
+ if( self::POST_TYPE != $field_group_post->post_type ) {
30
+ throw new InvalidArgumentException( 'incorrect post type' );
31
+ }
32
+ }
33
+
34
+
35
+ /**
36
+ * @return WPCF_Field_Definition_Factory Field definition factory of the correct type.
37
+ */
38
+ protected function get_field_definition_factory() {
39
+ return WPCF_Field_Term_Definition_Factory::get_instance();
40
+ }
41
+
42
+
43
+ /**
44
+ * Get taxonomies that are associated with this field group.
45
+ *
46
+ * @return string[] Taxonomy slugs. Empty array means that this group should be displayed with all taxonomies.
47
+ */
48
+ public function get_associated_taxonomies() {
49
+ $postmeta = get_post_meta( $this->get_id(), self::POSTMETA_ASSOCIATED_TAXONOMY, false );
50
+ return wpcf_ensarr( $postmeta );
51
+ }
52
+
53
+
54
+ /**
55
+ * Quickly determine whether given taxonomy is associated with this group.
56
+ *
57
+ * @param string $taxonomy_slug
58
+ * @return bool
59
+ */
60
+ public function has_associated_taxonomy( $taxonomy_slug ) {
61
+ $taxonomies = $this->get_associated_taxonomies();
62
+ return ( empty( $taxonomies ) || in_array( $taxonomy_slug, $taxonomies ) );
63
+ }
64
+
65
+
66
+ /**
67
+ * Remove association with a single taxonomy from the database.
68
+ *
69
+ * @param string $taxonomy_slug Slug of the taxonomy.
70
+ */
71
+ private function remove_associated_taxonomy( $taxonomy_slug ) {
72
+ if( empty( $taxonomy_slug ) ) {
73
+ return;
74
+ }
75
+ delete_post_meta( $this->get_id(), self::POSTMETA_ASSOCIATED_TAXONOMY, $taxonomy_slug );
76
+ $this->execute_group_updated_action();
77
+ }
78
+
79
+
80
+ /**
81
+ * Add an association with a single taxonomy to the database.
82
+ *
83
+ * @param string $taxonomy_slug Slug of the taxonomy. If empty or not sanitized, the function does nothing.
84
+ */
85
+ private function add_associated_taxonomy( $taxonomy_slug ) {
86
+ if( empty( $taxonomy_slug ) || $taxonomy_slug != sanitize_title( $taxonomy_slug )) {
87
+ return;
88
+ }
89
+ add_post_meta( $this->get_id(), self::POSTMETA_ASSOCIATED_TAXONOMY, $taxonomy_slug );
90
+ $this->execute_group_updated_action();
91
+ }
92
+
93
+
94
+ /**
95
+ * Update the set of taxonomies associated with this field group.
96
+ *
97
+ * @param string[] $taxonomy_slugs Array of (sanitized) taxonomy slugs.
98
+ */
99
+ public function update_associated_taxonomies( $taxonomy_slugs ) {
100
+ $current_taxonomies = $this->get_associated_taxonomies();
101
+
102
+ // Remove taxonomies that are associated but shouldn't be.
103
+ $to_remove = array_diff( $current_taxonomies, $taxonomy_slugs );
104
+ foreach( $to_remove as $taxonomy_slug ) {
105
+ $this->remove_associated_taxonomy( $taxonomy_slug );
106
+ }
107
+
108
+ // Add taxonomies that aren't associated but should be.
109
+ $to_add = array_diff( $taxonomy_slugs, $current_taxonomies );
110
+ foreach( $to_add as $taxonomy_slug ) {
111
+ $this->add_associated_taxonomy( $taxonomy_slug );
112
+ }
113
+ }
114
+
115
+ }
embedded/classes/field/group_term_factory.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Factory for the WPCF_Field_Group_Term class.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ final class WPCF_Field_Group_Term_Factory extends WPCF_Field_Group_Factory {
9
+
10
+
11
+ /**
12
+ * @return WPCF_Field_Group_Term_Factory
13
+ */
14
+ public static function get_instance() {
15
+ return parent::get_instance();
16
+ }
17
+
18
+ protected function __construct() {
19
+ parent::__construct();
20
+
21
+ add_action( 'wpcf_group_updated', array( $this, 'on_group_updated' ), 10, 2 );
22
+ }
23
+
24
+
25
+ /**
26
+ * Load a field group instance.
27
+ *
28
+ * @param int|string|WP_Post $field_group Post ID of the field group, it's name or a WP_Post object.
29
+ *
30
+ * @return null|WPCF_Field_Group_Term Field group or null if it can't be loaded.
31
+ */
32
+ public static function load( $field_group ) {
33
+ // we cannot use self::get_instance here, because of low PHP requirements and missing get_called_class function
34
+ // we have a fallback class for get_called_class but that scans files by debug_backtrace and return 'self'
35
+ // instead of WPCF_Field_Group_Term_Factory like the original get_called_class() function does
36
+ // ends in an error because of parents (abstract) $var = new self();
37
+ return WPCF_Field_Group_Term_Factory::get_instance()->load_field_group( $field_group );
38
+ }
39
+
40
+
41
+ /**
42
+ * Create new field group.
43
+ *
44
+ * @param string $name Sanitized field group name. Note that the final name may change when new post is inserted.
45
+ * @param string $title Field group title.
46
+ *
47
+ * @return null|WPCF_Field_Group The new field group or null on error.
48
+ */
49
+ public static function create( $name, $title = '' ) {
50
+ // we cannot use self::get_instance here, because of low PHP requirements and missing get_called_class function
51
+ // we have a fallback class for get_called_class but that scans files by debug_backtrace and return 'self'
52
+ // instead of WPCF_Field_Group_Term_Factory like the original get_called_class() function does
53
+ // ends in an error because of parents (abstract) $var = new self();
54
+ return WPCF_Field_Group_Term_Factory::get_instance()->create_field_group( $name, $title );
55
+ }
56
+
57
+
58
+ protected function get_post_type() {
59
+ return WPCF_Field_Group_Term::POST_TYPE;
60
+ }
61
+
62
+
63
+ protected function get_field_group_class_name() {
64
+ return 'WPCF_Field_Group_Term';
65
+ }
66
+
67
+
68
+ /**
69
+ * @var null|WPCF_Field_Group_Term[][] Cache for the get_groups_by_taxonomies() method.
70
+ */
71
+ private $taxonomy_assignment_cache = null;
72
+
73
+
74
+ /**
75
+ * Produce a list of all taxonomies with groups that belong to them.
76
+ *
77
+ * @return WPCF_Field_Group_Term[][] Associative array where keys are taxonomy slugs and values are arrays of field
78
+ * groups that are associated with those taxonomies.
79
+ */
80
+ public function get_groups_by_taxonomies() {
81
+ if( null == $this->taxonomy_assignment_cache ) {
82
+ $groups = $this->query_groups();
83
+ $taxonomies = get_taxonomies();
84
+
85
+ $this->taxonomy_assignment_cache = array();
86
+ foreach( $taxonomies as $taxonomy ) {
87
+ $taxonomy_slug = $taxonomy;
88
+ $groups_for_taxonomy = array();
89
+
90
+ foreach( $groups as $group ) {
91
+ if( $group instanceof WPCF_Field_Group_Term
92
+ && $group->is_active()
93
+ && $group->has_associated_taxonomy( $taxonomy_slug )
94
+ ) {
95
+ $groups_for_taxonomy[] = $group;
96
+ }
97
+ }
98
+
99
+ $this->taxonomy_assignment_cache[ $taxonomy_slug ] = $groups_for_taxonomy;
100
+ }
101
+ }
102
+
103
+ return $this->taxonomy_assignment_cache;
104
+ }
105
+
106
+
107
+ /**
108
+ * Get array of groups that are associated with given taxonomy.
109
+ *
110
+ * @param string $taxonomy_slug Slug of the taxonomy
111
+ * @return WPCF_Field_Group_Term[] Associated term field groups.
112
+ */
113
+ public function get_groups_by_taxonomy( $taxonomy_slug ) {
114
+ $groups_by_taxonomies = $this->get_groups_by_taxonomies();
115
+ return wpcf_ensarr( wpcf_getarr( $groups_by_taxonomies, $taxonomy_slug ) );
116
+ }
117
+
118
+
119
+ /**
120
+ * This needs to be executed whenever a term group is updated.
121
+ *
122
+ * Hooked into the wpcf_group_updated action.
123
+ * Erases cache for the get_groups_by_taxonomies() method.
124
+ *
125
+ * @param int $group_id Ignored
126
+ * @param WPCF_Field_Group $group Field group that has been just updated.
127
+ */
128
+ public function on_group_updated( /** @noinspection PhpUnusedParameterInspection */ $group_id, $group ) {
129
+ if( $group instanceof WPCF_Field_Group_Term ) {
130
+ $this->taxonomy_assignment_cache = null;
131
+ }
132
+ }
133
+
134
+
135
+
136
+ }
embedded/classes/field/hooks_api.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This should contain all API filter hooks related to field types, field groups, field definitions and field instances.
5
+ *
6
+ * @todo Ensure initialization at proper time.
7
+ */
8
+ final class WPCF_Field_Hooks_API {
9
+
10
+
11
+ private static $instance = null;
12
+
13
+
14
+ /**
15
+ * Initialize the hooks API related to fields.
16
+ */
17
+ public static function initialize() {
18
+ if( null == self::$instance ) {
19
+ self::$instance = new self();
20
+ }
21
+ }
22
+
23
+
24
+ private function __clone() { }
25
+
26
+
27
+ private function __construct() {
28
+ // Put your add_filter here.
29
+ }
30
+
31
+ }
embedded/classes/field/instance.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Instance of a field belonging to some object.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ abstract class WPCF_Field_Instance extends WPCF_Field_Instance_Unsaved {
9
+
10
+ private $object_id;
11
+
12
+ /**
13
+ * WPCF_Field_Instance constructor.
14
+ *
15
+ * @param WPCF_Field_Definition $definition Field definition.
16
+ * @param int $object_id Id of the object containing the field.
17
+ */
18
+ public function __construct( $definition, $object_id ) {
19
+
20
+ parent::__construct( $definition );
21
+
22
+ if ( $object_id != (int) $object_id || 0 >= (int) $object_id ) {
23
+ throw new InvalidArgumentException( 'Invalid object id.' );
24
+ }
25
+ $this->object_id = (int) $object_id;
26
+ }
27
+
28
+
29
+ /**
30
+ * Accessor object to manipulate the database value directly.
31
+ *
32
+ * @return WPCF_Field_Accessor_Abstract
33
+ */
34
+ protected function get_accessor() {
35
+ if( null == $this->accessor ) {
36
+ $this->accessor = $this->get_definition()->get_accessor( $this );
37
+ }
38
+ return $this->accessor;
39
+ }
40
+
41
+
42
+ public function get_object_id() {
43
+ return $this->object_id;
44
+ }
45
+
46
+
47
+ /**
48
+ * Delete all field values (both for single and repetitive fields).
49
+ */
50
+ public function delete_all_values() {
51
+ $this->get_accessor()->delete_raw_value();
52
+ }
53
+
54
+
55
+ /**
56
+ * Overwrite current field values with new ones.
57
+ *
58
+ * @param array $values Array of values. For non-repetitive field there must be exactly one value. Order of values
59
+ * in this array will be stored as sort order.
60
+ * @return bool True on success, false if some error has occured.
61
+ */
62
+ public abstract function update_all_values( $values );
63
+
64
+
65
+ /**
66
+ * Add a single field value to the database.
67
+ *
68
+ * The value will be passed through filters as needed and stored, based on field configuration.
69
+ *
70
+ * @param mixed $value Raw value, which MUST be validated already.
71
+ *
72
+ * @return mixed
73
+ */
74
+ public abstract function add_value( $value );
75
+
76
+
77
+ /**
78
+ * @return string Meta key that is used to store value order for repetitive fields.
79
+ */
80
+ protected function get_order_meta_name() {
81
+ return sprintf( '_%s-sort-order', $this->get_definition()->get_slug() );
82
+ }
83
+
84
+
85
+ /**
86
+ * @return WPCF_Field_Accessor_Abstract An accessor to get the sort order for repetitive fields.
87
+ */
88
+ protected abstract function get_order_accessor();
89
+
90
+
91
+ /**
92
+ * For repetitive field, get the order of individual values.
93
+ *
94
+ * @return array Meta IDs in the order defining the field value order.
95
+ */
96
+ protected function get_sort_order() {
97
+ $accessor = $this->get_order_accessor();
98
+ return wpcf_ensarr( $accessor->get_raw_value() );
99
+ }
100
+
101
+
102
+ /**
103
+ * Update order of inidvidual values for a repetitive field.
104
+ *
105
+ * @param int[] $order Array of meta IDs. It must be a complete match to actual values stored in the database.
106
+ * @return bool|mixed Update result. Depends on the underlying accessor.
107
+ */
108
+ protected function set_sort_order( $order ) {
109
+ if( !is_array( $order ) ) {
110
+ return false;
111
+ }
112
+ $accessor = $this->get_order_accessor();
113
+ return $accessor->update_raw_value( $order );
114
+ }
115
+
116
+
117
+ /**
118
+ * @return mixed Value of the field in the "intermediate" format.
119
+ */
120
+ public function get_value() {
121
+ return $this->get_definition()->get_data_mapper()->database_to_intermediate( $this->get_raw_value() );
122
+ }
123
+
124
+ }
embedded/classes/field/instance_abstract.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class WPCF_Field_Instance_Abstract {
4
+
5
+ /** @var WPCF_Field_Definition */
6
+ protected $definition;
7
+
8
+
9
+ /** @var null|WPCF_Field_Accessor_Abstract */
10
+ protected $accessor = null;
11
+
12
+
13
+ /**
14
+ * WPCF_Field_Instance constructor.
15
+ *
16
+ * @param WPCF_Field_Definition $definition Field definition.
17
+ */
18
+ public function __construct( $definition ) {
19
+ if( ! $definition instanceof WPCF_Field_Definition ) {
20
+ throw new InvalidArgumentException( 'Invalid type of field definition.' );
21
+ }
22
+ $this->definition = $definition;
23
+ }
24
+
25
+
26
+ public function get_definition() { return $this->definition; }
27
+
28
+
29
+ public function get_field_type() { return $this->get_definition()->get_type(); }
30
+
31
+
32
+ /**
33
+ * Get the accessor to the field value.
34
+ *
35
+ * We can't access it directly because we don't know how - it can be stored in post meta, user meta or term meta.
36
+ *
37
+ * @return WPCF_Field_Accessor_Abstract
38
+ */
39
+ protected abstract function get_accessor();
40
+
41
+
42
+ /**
43
+ * Get raw value of the field directly from the database.
44
+ *
45
+ * @deprecated Use with caution! Usually the value is expected in the intermediate format, which is what get_value() is for.
46
+ * @return mixed Raw value of the field.
47
+ */
48
+ public function get_raw_value() {
49
+ return $this->get_accessor()->get_raw_value();
50
+ }
51
+
52
+
53
+ /**
54
+ * @return mixed Value of the field in the "intermediate" format.
55
+ */
56
+ public function get_value() {
57
+ return $this->get_raw_value();
58
+ }
59
+
60
+
61
+ /**
62
+ * @return int ID of the object that owns the field.
63
+ */
64
+ public abstract function get_object_id();
65
+
66
+ }
embedded/classes/field/instance_term.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Term field instance.
5
+ *
6
+ * This class exists to ensure that term field-specific operations will be performed consistently.
7
+ *
8
+ * @since 1.9
9
+ */
10
+ final class WPCF_Field_Instance_Term extends WPCF_Field_Instance {
11
+
12
+ /**
13
+ * Add a single field value to the database.
14
+ *
15
+ * The value will be passed through filters as needed and stored, based on field configuration.
16
+ *
17
+ * @param mixed $value Value in the "intermediate" format (which is not well defined yet), which MUST be validated already.
18
+ * @return bool True on success, false otherwise.
19
+ */
20
+ public function add_value( $value ) {
21
+
22
+ $result = $this->add_single_value( $value );
23
+
24
+ return ( true == $result || 0 < $result );
25
+
26
+ }
27
+
28
+
29
+ /**
30
+ * Add a single field value to the database.
31
+ *
32
+ * The value will be passed through filters as needed and stored, based on field configuration.
33
+ *
34
+ * @param mixed $value Value in the "intermediate" format (which is not well defined yet), which MUST be validated already.
35
+ * @return bool|int New meta ID or true if the value was added only virtually (no adding is needed).
36
+ */
37
+ private function add_single_value( $value ) {
38
+
39
+ // Shortcuts
40
+ $accessor = $this->get_accessor();
41
+ $definition = $this->get_definition();
42
+
43
+ // Trim strings
44
+ if ( is_string( $value ) ) {
45
+ $value = trim( $value );
46
+ }
47
+
48
+ // If the field has defined value to store to database, use that one (e.g. checkbox).
49
+ if( $value && $definition->has_forced_value() ) {
50
+ $value = $definition->get_forced_value();
51
+ }
52
+
53
+ // Apply all filters on saving
54
+ $value_unfiltered = $value;
55
+ $value = $this->filter_single_value_before_saving( $value_unfiltered );
56
+
57
+ $is_value_empty = ( is_null( $value ) || $value === false || $value === '' );
58
+ $should_save_empty_value = $definition->get_should_save_empty_value();
59
+ $is_forced_value_empty = ( $definition->has_forced_value() && preg_match( '/^0$/', $value ) && preg_match( '/^0$/', $definition->get_forced_value() ) );
60
+
61
+ if( ( !$is_value_empty || $should_save_empty_value) || $is_forced_value_empty ) {
62
+
63
+ $value = $definition->get_data_mapper()->intermediate_to_database( $value );
64
+
65
+ $meta_id = $accessor->add_raw_value( $value );
66
+
67
+ if( $meta_id > 0 ) {
68
+ $this->actions_after_single_value_saved( $value, $value_unfiltered, $meta_id );
69
+ }
70
+
71
+ return $meta_id;
72
+
73
+ } else {
74
+ // We're not storing anything to database.
75
+ return true;
76
+ }
77
+ }
78
+
79
+
80
+ /**
81
+ * Push single field value through set of filters before it is saved to database.
82
+ *
83
+ * @param mixed $original_value
84
+ * @return mixed
85
+ */
86
+ private function filter_single_value_before_saving( $original_value ) {
87
+
88
+ $definition = $this->get_definition();
89
+ $field_definition_array = $definition->get_definition_array();
90
+
91
+ // See wiki for filter description.
92
+ $value = apply_filters( 'wpcf_fields_termmeta_value_save', $original_value, $field_definition_array['type'], $definition, $field_definition_array, null );
93
+ $value = apply_filters( 'wpcf_fields_value_save', $value, $field_definition_array['type'], $definition->get_slug(), null );
94
+ $value = apply_filters( 'wpcf_fields_slug_' . $definition->get_slug() . '_value_save', $value, $field_definition_array, null );
95
+ $value = apply_filters( 'wpcf_fields_type_' . $field_definition_array['type'] . '_value_save', $value, $field_definition_array, null );
96
+
97
+ return $value;
98
+ }
99
+
100
+
101
+ /**
102
+ * Execute actions after saving a single field value to database.
103
+ *
104
+ * @param mixed $value Value that was saved.
105
+ * @param mixed $value_unfiltered Value before passing it through pre-save filters.
106
+ * @param int $meta_id Meta ID of the value.
107
+ */
108
+ private function actions_after_single_value_saved( $value, $value_unfiltered, $meta_id ) {
109
+
110
+ $definition = $this->get_definition();
111
+ $field_definition_array = $definition->get_definition_array();
112
+
113
+ /**
114
+ * Executed after each field value is saved (that means multiple times for repetitive fields).
115
+ *
116
+ * @param mixed $value The value that was stored in the database
117
+ * @param array $field_definition_array Field definition array.
118
+ * @param mixed $ignored Sometimes it may be WPCF_Field and sometimes null. Don't rely in this at all.
119
+ * @param int $meta_id ID of the meta record in the database.
120
+ * @param mixed $value_unfiltered The (more or less) original value before it was pushed through filters
121
+ * wpcf_fields_value_save & co.
122
+ * @since unknown
123
+ */
124
+ do_action( 'wpcf_fields_save', $value, $field_definition_array, null, $meta_id, $value_unfiltered );
125
+ do_action( 'wpcf_fields_slug_' . $definition->get_slug() . '_save', $value, $field_definition_array, null, $meta_id, $value_unfiltered );
126
+ do_action( 'wpcf_fields_type_' . $field_definition_array['type'] . '_save', $value, $field_definition_array, null, $meta_id, $value_unfiltered );
127
+
128
+ }
129
+
130
+
131
+ /**
132
+ * Overwrite current field values with new ones.
133
+ *
134
+ * @param array $values Array of values. For non-repetitive field there must be exactly one value. Order of values
135
+ * in this array will be stored as sort order.
136
+ * @return bool True on success, false if some error has occured.
137
+ */
138
+ public function update_all_values( $values ) {
139
+
140
+ // Quoting from original code:
141
+ // Since Types 1.2 we completely rewrite meta. It has no impact on frontend and covers a lot of cases
142
+ // (e.g. user change mode from single to repetitive).
143
+ $this->delete_all_values();
144
+
145
+ if( ! $this->get_definition()->get_is_repetitive() ) {
146
+
147
+ // Single field here. We expect exactly one value.
148
+ if( count( $values ) != 1 ) {
149
+ return false;
150
+ }
151
+
152
+ return $this->add_value( $values[0] );
153
+
154
+ } else {
155
+
156
+ // Saving repetitive field is a bit more complex, also because we need to execute these actions (mainly
157
+ // for WPML compatibility).
158
+ do_action(
159
+ 'wpcf_termmeta_before_adding_repetitive_field_values',
160
+ $this->get_object_id(),
161
+ $this->get_definition()->get_definition_array(),
162
+ $this
163
+ );
164
+
165
+ $is_success = true;
166
+
167
+ $meta_ids = array();
168
+
169
+ // Because we need to fire a special action before the last value is stored
170
+ $total_value_count = count( $values );
171
+ $current_value_number = 1;
172
+
173
+ foreach( $values as $value ) {
174
+
175
+ // They say it's needed only for Conditional case:
176
+ // https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/160422568/comments#comment_226301926
177
+ // $value = apply_filters( 'types_field_get_submitted_data', $value, $this );
178
+
179
+ if ( $total_value_count == $current_value_number ) {
180
+ // After this action we will store the last value.
181
+ do_action(
182
+ 'wpcf_termmeta_before_adding_last_repetitive_field_value',
183
+ $this->get_object_id(),
184
+ $this->get_definition()->get_definition_array(),
185
+ $this
186
+ );
187
+ }
188
+ $current_value_number++;
189
+
190
+ $meta_id = $this->add_single_value( $value );
191
+ $is_success = $is_success && ( 0 < $meta_id );
192
+ $meta_ids[] = $meta_id;
193
+ }
194
+
195
+ do_action(
196
+ 'wpcf_termmeta_after_adding_repetitive_field_values',
197
+ $this->get_object_id(),
198
+ $this->get_definition()->get_definition_array(),
199
+ $this
200
+ );
201
+
202
+ $this->set_sort_order( $meta_ids );
203
+
204
+ return $is_success;
205
+ }
206
+ }
207
+
208
+
209
+ /**
210
+ * @return WPCF_Field_Accessor_Abstract An accessor to get the sort order for repetitive fields.
211
+ */
212
+ protected function get_order_accessor() {
213
+ return new WPCF_Field_Accessor_Termmeta( $this->get_object_id(), $this->get_order_meta_name(), false );
214
+ }
215
+
216
+ }
embedded/classes/field/instance_unsaved.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPCF_Field_Instance_Unsaved extends WPCF_Field_Instance_Abstract {
4
+
5
+ /**
6
+ * Get the accessor to the field value.
7
+ *
8
+ * We can't access it directly because we don't know how - it can be stored in post meta, user meta or term meta.
9
+ *
10
+ * @return WPCF_Field_Accessor_Abstract
11
+ */
12
+ protected function get_accessor() {
13
+ return new WPCF_Field_Accessor_Dummy();
14
+ }
15
+
16
+ /**
17
+ * @return int ID of the object that owns the field. In this case it returns zero.
18
+ */
19
+ public function get_object_id() {
20
+ return 0;
21
+ }
22
+ }
embedded/classes/field/renderer/abstract.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ abstract class WPCF_Field_Renderer_Abstract {
5
+
6
+ /** @var null|WPCF_Field_Instance */
7
+ protected $field = null;
8
+
9
+ public function __construct( $field ) {
10
+ $this->field = $field;
11
+ }
12
+
13
+
14
+ /**
15
+ * @param bool $echo
16
+ *
17
+ * @return string
18
+ */
19
+ public abstract function render( $echo = false );
20
+
21
+ }
embedded/classes/field/renderer/toolset_forms.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Field renderer that uses toolset-forms to render a field.
5
+ *
6
+ * @since 1.9
7
+ */
8
+ class WPCF_Field_Renderer_Toolset_Forms extends WPCF_Field_Renderer_Abstract {
9
+
10
+
11
+ private $form_id;
12
+
13
+ private $hide_field_title = false;
14
+
15
+
16
+ public function __construct( $field, $form_id = '' ) {
17
+ parent::__construct( $field );
18
+
19
+ $this->form_id = $form_id;
20
+ }
21
+
22
+
23
+ /**
24
+ * Additional setup of the renderer.
25
+ *
26
+ * @param $args array Following arguments are supported:
27
+ * @type string $form_id
28
+ * @type bool $hide_field_title
29
+ */
30
+ public function setup( $args = array() ) {
31
+
32
+ $this->form_id = wpcf_getarr( $args, 'form_id', $this->form_id );
33
+
34
+ $this->hide_field_title = (bool) wpcf_getarr( $args, 'hide_field_title', $this->hide_field_title );
35
+ }
36
+
37
+ /**
38
+ * @param bool $echo
39
+ *
40
+ * @return string
41
+ */
42
+ public function render( $echo = false ) {
43
+
44
+ $field_config = $this->get_toolset_forms_config();
45
+
46
+ if( $this->hide_field_title ) {
47
+ $field_config['title'] = '';
48
+ }
49
+
50
+ $value_in_intermediate_format = $this->field->get_value();
51
+ $output = wptoolset_form_field( $this->get_form_id(), $field_config, $value_in_intermediate_format );
52
+
53
+ if( $echo ) {
54
+ echo $output;
55
+ }
56
+
57
+ return $output;
58
+ }
59
+
60
+
61
+ protected function get_form_id() { return $this->form_id; }
62
+
63
+
64
+ protected function get_toolset_forms_config() {
65
+ //$this->ensure_toolset_forms_includes();
66
+ return wptoolset_form_filter_types_field( $this->field->get_definition()->get_definition_array(), $this->field->get_object_id() );
67
+ }
68
+
69
+
70
+ // Not needed
71
+ //
72
+ // private static $toolset_forms_included = false;
73
+ //
74
+ // protected function ensure_toolset_forms_includes() {
75
+ // if( ! self::$toolset_forms_included ) {
76
+ // // ...
77
+ // }
78
+ //
79
+ // self::$toolset_forms_included = true;
80
+ //}
81
+ }
embedded/classes/field/term_definition_factory.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Factory for term field definitions.
5
+ */
6
+ final class WPCF_Field_Term_Definition_Factory extends WPCF_Field_Definition_Factory {
7
+
8
+ /**
9
+ * Name of the option used to store term field definitions.
10
+ */
11
+ const FIELD_DEFINITIONS_OPTION = 'wpcf-termmeta';
12
+
13
+
14
+ protected function get_option_name() {
15
+ return self::FIELD_DEFINITIONS_OPTION;
16
+ }
17
+
18
+
19
+ protected function get_class_name() {
20
+ return 'WPCF_Field_Definition_Term';
21
+ }
22
+
23
+
24
+ /**
25
+ * Shortcut to load_field_definition().
26
+ *
27
+ * @param string $field_key
28
+ * @return null|WPCF_Field_Definition
29
+ */
30
+ static function load( $field_key ) {
31
+ // we cannot use self::get_instance here, because of low PHP requirements and missing get_called_class function
32
+ // we have a fallback class for get_called_class but that scans files by debug_backtrace and return 'self'
33
+ // instead of WPCF_Field_Term_Definition_Factory like the original get_called_class() function does
34
+ // ends in an error because of parents (abstract) $var = new self();
35
+ return WPCF_Field_Term_Definition_Factory::get_instance()->load_field_definition( $field_key );
36
+ }
37
+
38
+ /**
39
+ * @return string[] All existing meta keys within the domain (= term meta).
40
+ */
41
+ protected function get_existing_meta_keys() {
42
+ global $wpdb;
43
+
44
+ $meta_keys = $wpdb->get_col(
45
+ "SELECT meta_key FROM {$wpdb->termmeta} GROUP BY meta_key HAVING meta_key NOT LIKE '\_%' ORDER BY meta_key"
46
+ );
47
+
48
+ return $meta_keys;
49
+ }
50
+
51
+ }
embedded/classes/field/type_definition.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Field type definition.
5
+ *
6
+ * This represents a single field type like "email", "audio", "checkbox" and so on. This class must be instantiated
7
+ * exclusively through WPCF_Field_Type_Definition_Factory.
8
+ */
9
+ final class WPCF_Field_Type_Definition {
10
+
11
+
12
+ /**
13
+ * @var string Slug of the registered field type.
14
+ */
15
+ private $field_type_slug;
16
+
17
+
18
+ /**
19
+ * @var string Name of the field type that can be displayed to the user.
20
+ */
21
+ private $display_name;
22
+
23
+
24
+ /**
25
+ * @var string Field description entered by the user.
26
+ */
27
+ private $description;
28
+
29
+
30
+ /**
31
+ * @var array Arguments defining the field type. Can contain some legacy values.
32
+ */
33
+ private $args;
34
+
35
+
36
+ /**
37
+ * WPCF_Field_Type_Definition constructor.
38
+ *
39
+ * @param string $field_type_slug Field type slug.
40
+ * @param array $args Additional array of arguments which should contain at least 'display_name' (or 'title')
41
+ * and 'description' elements, but omitting them is not critical.
42
+ */
43
+ public function __construct( $field_type_slug, $args ) {
44
+
45
+ if( sanitize_title( $field_type_slug ) != $field_type_slug ) {
46
+ throw new InvalidArgumentException( 'Invalid field type slug.' );
47
+ }
48
+
49
+ if( ! is_array( $args ) ) {
50
+ throw new InvalidArgumentException( 'Wrong arguments provided.' );
51
+ }
52
+
53
+ $this->field_type_slug = $field_type_slug;
54
+
55
+ // Try to fall back to legacy "title", and if even that fails, use id instead.
56
+ $this->display_name = sanitize_text_field( wpcf_getarr( $args, 'display_name', wpcf_getarr( $args, 'title', $field_type_slug ) ) );
57
+
58
+ $this->description = wpcf_getarr( $args, 'description', '' );
59
+ $this->args = $args;
60
+ }
61
+
62
+
63
+ public function get_slug() { return $this->field_type_slug; }
64
+
65
+ public function get_display_name() { return $this->display_name; }
66
+
67
+ public function get_description() { return $this->description; }
68
+
69
+
70
+ /**
71
+ * Direct access to the field type configuration.
72
+ *
73
+ * It is strongly encouraged to write custom (and safe) getters for anything you need to get from it.
74
+ *
75
+ * @return array
76
+ */
77
+ public function get_args() { return $this->args; }
78
+
79
+ }
embedded/classes/field/type_definition_factory.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Factory class for loading field type definitions.
5
+ *
6
+ * Handles creation of the objects as well as their caching.
7
+ *
8
+ * Currently it is only possible to load existing field types, not create new ones. We're depending on the legacy code
9
+ * in WPCF_Fields and field types defined through specially named functions. But that is hidden from anyone who uses
10
+ * this class.
11
+ */
12
+ final class WPCF_Field_Type_Definition_Factory {
13
+
14
+ private static $instance = null;
15
+
16
+ private function __construct() { }
17
+
18
+ private function __clone() { }
19
+
20
+
21
+ public static function get_instance() {
22
+ if( null == self::$instance ) {
23
+ self::$instance = new self();
24
+ }
25
+ return self::$instance;
26
+ }
27
+
28
+
29
+ /**
30
+ * @var array Associative array of instantiated field type definitions, indexed by field type slugs ("checkbox",
31
+ * "email" and such).
32
+ */
33
+ private $field_type_definitions = array();
34
+
35
+
36
+ /**
37
+ * @var null|array Cached array containing path to files (!) that contain specially named functions (!) that
38
+ * can be used to return configuration array for a field type (!). We're caching it because
39
+ * WPCF_Fields::getFieldsTypes() applies a filter each time it is called.
40
+ */
41
+ private $legacy_field_types = null;
42
+
43
+
44
+ /**
45
+ * @return array See $legacy_field_types.
46
+ */
47
+ private function get_legacy_field_types() {
48
+ if( null == $this->legacy_field_types ) {
49
+ $this->legacy_field_types = WPCF_Fields::getFieldsTypes();
50
+ }
51
+ return $this->legacy_field_types;
52
+ }
53
+
54
+
55
+ /**
56
+ * Load a field type definition.
57
+ *
58
+ * @param string $field_type_slug Slug of the field type. If the function fails to find the field type and the slug
59
+ * starts with a "wpcf-" prefix, it attempts to remove it and search again. This way, passing a field type ID,
60
+ * which usually has this form, is also supported.
61
+ * @return null|WPCF_Field_Type_Definition Field type definition or null if it can't be loaded.
62
+ */
63
+ public function load_field_type_definition( $field_type_slug ) {
64
+
65
+ if( !is_string( $field_type_slug ) ) {
66
+ return null;
67
+ }
68
+
69
+ // Check if we can use cached version.
70
+ if( !in_array( $field_type_slug, $this->field_type_definitions ) ) {
71
+
72
+ // now it gets hacky
73
+ $field_types = $this->get_legacy_field_types();
74
+ if( !in_array( $field_type_slug, array_keys( $field_types ) ) ) {
75
+ // Field slug not recognized. Maybe we got a field identifier instead. Check if we can remove
76
+ // the wpcf- prefix and try again.
77
+ $prefix = 'wpcf-';
78
+ if( substr( $field_type_slug, 0, strlen( $prefix ) ) == $prefix ) {
79
+ $field_type_slug = substr( $field_type_slug, strlen( $prefix ) );
80
+ if( !in_array( $field_type_slug, $field_types ) ) {
81
+ // Removing prefix didn't help
82
+ return null;
83
+ }
84
+ } else {
85
+ // There was no prefix to remove.
86
+ return null;
87
+ }
88
+ }
89
+
90
+ // Not using getFieldTypeData() directly to avoid unnecessary getFieldsTypes() and filter applying.
91
+ $field_type_configuration_path = $field_types[ $field_type_slug ];
92
+ $field_type_configuration = WPCF_Fields::getFieldTypeConfig( $field_type_configuration_path );
93
+
94
+ $field_type_id = wpcf_getarr( $field_type_configuration, 'id', null );
95
+ if( null == $field_type_id ) {
96
+ return null;
97
+ }
98
+
99
+ try {
100
+ $field_type_definition = new WPCF_Field_Type_Definition( $field_type_slug, $field_type_configuration );
101
+ } catch( Exception $e ) {
102
+ return null;
103
+ }
104
+
105
+ // Save new instance to cache.
106
+ $this->field_type_definitions[ $field_type_slug ] = $field_type_definition;
107
+ }
108
+
109
+ // Use cache.
110
+ return $this->field_type_definitions[ $field_type_slug ];
111
+ }
112
+
113
+
114
+ /**
115
+ * Static shortcut to load_field_type_definition.
116
+ *
117
+ * @param string $field_type_slug
118
+ * @return null|WPCF_Field_Type_Definition
119
+ */
120
+ public static function load( $field_type_slug ) {
121
+ // we cannot use self::get_instance here, because of low PHP requirements and missing get_called_class function
122
+ // we have a fallback class for get_called_class but that scans files by debug_backtrace and return 'self'
123
+ // instead of WPCF_Field_Type_Definition_Factory like the original get_called_class() function does
124
+ // ends in an error because of parents (abstract) $var = new self();
125
+ return WPCF_Field_Type_Definition_Factory::get_instance()->load_field_type_definition( $field_type_slug );
126
+ }
127
+ }
embedded/classes/field/utils.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Static class for shortcut functions related to field types, groups, definitions and instances.
5
+ * @since 1.9
6
+ */
7
+ final class WPCF_Field_Utils {
8
+
9
+ private function __construct() { }
10
+
11
+
12
+ /**
13
+ * Create a term field instance.
14
+ *
15
+ * @param string $field_slug Slug of existing field definition.
16
+ * @param int $term_id ID of the term where the field belongs.
17
+ *
18
+ * @return null|WPCF_Field_Instance Field instance or null if an error occurs.
19
+ * @since 1.9
20
+ */
21
+ public static function create_term_field_instance( $field_slug, $term_id ) {
22
+ try {
23
+ return new WPCF_Field_Instance( WPCF_Field_Term_Definition_Factory::load( $field_slug ), $term_id );
24
+ } catch( Exception $e ) {
25
+ return null;
26
+ }
27
+ }
28
+
29
+
30
+ /**
31
+ * Obtain toolset-forms "field configuration", which is an array of settings for specific field instance.
32
+ *
33
+ * @param WPCF_Field_Instance $field
34
+ * @since 1.9
35
+ */
36
+ public static function get_toolset_forms_field_config( $field ) {
37
+ return wptoolset_form_filter_types_field(
38
+ $field->get_definition()->get_definition_array(),
39
+ $field->get_object_id()
40
+ );
41
+ }
42
+
43
+
44
+ /**
45
+ * Gather an unique array of field definitions from given groups.
46
+ *
47
+ * The groups are expected to belong to the same domain (term/post/user), otherwise problems may occur when
48
+ * field slugs conflict.
49
+ *
50
+ * @param WPCF_Field_Group[] $field_groups
51
+ * @return WPCF_Field_Definition[]
52
+ * @since 1.9
53
+ */
54
+ public static function get_field_definitions_from_groups( $field_groups ) {
55
+ $field_definitions = array();
56
+ foreach( $field_groups as $group ) {
57
+ $group_field_definitions = $group->get_field_definitions();
58
+
59
+ foreach( $group_field_definitions as $field_definition ) {
60
+ $field_definitions[ $field_definition->get_slug() ] = $field_definition;
61
+ }
62
+ }
63
+ return $field_definitions;
64
+ }
65
+
66
+ }
embedded/classes/fields.php CHANGED
@@ -30,17 +30,18 @@ class WPCF_Fields
30
  * Returns array of available (registered) field types
31
  * and paths to config files.
32
  *
33
- * @return type
34
  */
35
  public static function getFieldsTypes() {
36
  $fields = array(
37
  'audio' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/audio.php',
38
- 'checkbox' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/checkbox.php',
39
  'checkboxes' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/checkboxes.php',
 
40
  'colorpicker' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/colorpicker.php',
41
  'date' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/date.php',
42
  'email' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/email.php',
43
  'embed' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/embed.php',
 
44
  'file' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/file.php',
45
  'image' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/image.php',
46
  'map' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/map.php',
@@ -99,8 +100,8 @@ class WPCF_Fields
99
  /**
100
  * Returns data for certain field type.
101
  *
102
- * @param type $type
103
- * @return type
104
  */
105
  public static function getFieldTypeConfig( $path ) {
106
  if ( !is_string( $path ) ) {
@@ -157,9 +158,9 @@ class WPCF_Fields
157
  if ( !isset( $data_script['src'] ) ) {
158
  continue;
159
  }
160
- $deps = !empty( $data_script['deps'] ) ? $data_script['deps'] : array();
161
- wp_enqueue_script( $handle, $data_script['src'], $deps,
162
- WPCF_VERSION );
163
  }
164
  }
165
  }
30
  * Returns array of available (registered) field types
31
  * and paths to config files.
32
  *
33
+ * @return array
34
  */
35
  public static function getFieldsTypes() {
36
  $fields = array(
37
  'audio' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/audio.php',
 
38
  'checkboxes' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/checkboxes.php',
39
+ 'checkbox' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/checkbox.php',
40
  'colorpicker' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/colorpicker.php',
41
  'date' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/date.php',
42
  'email' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/email.php',
43
  'embed' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/embed.php',
44
+ //'entry' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/entry.php',
45
  'file' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/file.php',
46
  'image' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/image.php',
47
  'map' => WPCF_EMBEDDED_INC_ABSPATH . '/fields/map.php',
100
  /**
101
  * Returns data for certain field type.
102
  *
103
+ * @param string $path
104
+ * @return array
105
  */
106
  public static function getFieldTypeConfig( $path ) {
107
  if ( !is_string( $path ) ) {
158
  if ( !isset( $data_script['src'] ) ) {
159
  continue;
160
  }
161
+ $deps = isset($data_script['deps']) && !empty( $data_script['deps'] ) ? $data_script['deps'] : array();
162
+ $ver = !empty( $data_script['ver'] ) ? $data_script['ver'] : WPCF_VERSION;
163
+ wp_enqueue_script( $handle, $data_script['src'], $deps, $ver);
164
  }
165
  }
166
  }
embedded/classes/forms.php CHANGED
@@ -143,7 +143,7 @@ class Enlimbo_Forms_Wpcf
143
  if ( $element['#type'] != 'fieldset' ) {
144
  if ( isset( $element['#name'] )
145
  && !in_array( $element['#type'],
146
- array('submit', 'reset') ) ) {
147
  // Set submitted data
148
  if ( !in_array( $element['#type'], array('checkboxes') )
149
  && empty( $element['#forced_value'] ) ) {
@@ -264,6 +264,7 @@ class Enlimbo_Forms_Wpcf
264
  'textarea',
265
  'textfield',
266
  'thumbnail',
 
267
  )
268
  );
269
  }
@@ -306,7 +307,7 @@ class Enlimbo_Forms_Wpcf
306
  public function renderElement( $element )
307
  {
308
  $method = $element['#type'];
309
- if ( !isset( $element['#name'] ) && $element['#type'] != 'markup' ) {
310
  if ( !isset( $element['#attributes']['name'] ) ) {
311
  return '#name or #attributes[\'name\'] required!';
312
  } else {
@@ -317,6 +318,8 @@ class Enlimbo_Forms_Wpcf
317
  if ( !isset( $element['#id'] ) ) {
318
  if ( isset( $element['#attributes']['id'] ) ) {
319
  $element['#id'] = $element['#attributes']['id'];
 
 
320
  } else {
321
  $element['#id'] = $element['#type'] . '-' . $this->_count( $element['#type'] );
322
  }
@@ -340,35 +343,53 @@ class Enlimbo_Forms_Wpcf
340
  */
341
  private function _setElementAttributes( $element )
342
  {
 
 
 
 
 
 
 
 
 
343
  $attributes = '';
344
  $error_class = isset( $element['#error'] ) ? ' ' . $this->css_class . '-error ' . $this->css_class . '-' . $element['#type'] . '-error ' . ' form-' . $element['#type'] . '-error ' . $element['#type'] . '-error form-error ' : '';
345
- $class = $this->css_class . '-' . $element['#type']
346
- . ' form-' . $element['#type'] . ' ' . $element['#type'];
347
- // Add JS validation
348
- // if ( !empty( $element['#validate'] ) ) {
349
- // $class .= ' js-types-validate';
350
- // }
351
- if ( isset( $element['#attributes'] ) ) {
352
- foreach ( $element['#attributes'] as $attribute => $value ) {
353
- // Prevent undesired elements
354
- if ( in_array( $attribute, array('id', 'name') ) ) {
355
- continue;
356
- }
357
- // Don't set disabled for checkbox
358
- // if ( $attribute == 'disabled' && $element['#type'] == 'checkbox' ) {
359
- // continue;
360
- // }
361
- // Append class values
362
- if ( $attribute == 'class' ) {
363
- $value = $value . ' ' . $class . $error_class;
364
- }
365
- // Set return string
366
- $attributes .= ' ' . $attribute . '="' . $value . '"';
367
  }
 
 
 
 
 
 
368
  }
369
  if ( !isset( $element['#attributes']['class'] ) ) {
370
  $attributes .= ' class="' . $class . $error_class . '"';
371
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  return $attributes;
373
  }
374
 
@@ -403,6 +424,15 @@ class Enlimbo_Forms_Wpcf
403
  $label = $element['#title'];
404
  }
405
  if ( !empty($label) ) {
 
 
 
 
 
 
 
 
 
406
  $element['_render']['label'] = sprintf(
407
  '<label class="%s-label %s-%s-label" for="%s">%s</label>',
408
  esc_attr($this->css_class),
@@ -436,7 +466,22 @@ class Enlimbo_Forms_Wpcf
436
  foreach ( $element['_render'] as $key => $value ) {
437
  $pattern = str_replace( '<' . strtoupper( $key ) . '>', $value, $pattern );
438
  }
439
- return $pattern;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  }
441
 
442
  /**
@@ -665,6 +710,9 @@ class Enlimbo_Forms_Wpcf
665
  */
666
  public function radio( $element )
667
  {
 
 
 
668
  $element['#type'] = 'radio';
669
  $element = $this->_setRender( $element );
670
  $element['_render']['element'] = '<input type="radio" id="'
@@ -697,7 +745,7 @@ class Enlimbo_Forms_Wpcf
697
  $pattern = isset( $element['#pattern'] ) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT>&nbsp;<LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
698
  $output = $this->_pattern( $pattern, $element );
699
  $output = $this->_wrapElement( $element, $output );
700
- return $output . "\r\n";
701
  }
702
 
703
  /**
@@ -714,21 +762,47 @@ class Enlimbo_Forms_Wpcf
714
  if ( !isset( $element['#name'] ) || empty( $element['#name'] ) ) {
715
  return FALSE;
716
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717
  $element['#type'] = 'radios';
718
  $element = $this->_setRender( $element );
719
  $element['_render']['element'] = '';
 
 
 
720
  foreach ( $element['#options'] as $ID => $value ) {
721
  $this->_count( 'radio' );
722
  if ( !is_array( $value ) ) {
723
  $value = array('#title' => $ID, '#value' => $value);
724
  $value['#inline'] = true;
725
- $value['#after'] = '<br />';
 
726
  }
727
  $value['#name'] = $element['#name'];
728
  $value['#default_value'] = isset( $element['#default_value'] ) ? $element['#default_value'] : $value['#value'];
729
  $value['#disable'] = isset( $element['#disable'] ) ? $element['#disable'] : false;
730
  $element['_render']['element'] .= $this->radio( $value );
731
  }
 
 
 
732
  $pattern = isset( $element['#pattern'] ) ? $element['#pattern'] : '<BEFORE><PREFIX><TITLE><DESCRIPTION><ELEMENT><SUFFIX><AFTER>';
733
  $output = $this->_pattern( $pattern, $element );
734
  $output = $this->_wrapElement( $element, $output );
@@ -880,6 +954,7 @@ class Enlimbo_Forms_Wpcf
880
  public function markup( $element )
881
  {
882
  if ( isset( $element['#pattern'] ) ) {
 
883
  $element['_render']['label'] = isset($element['#title'])? $element['#title']:__('[no title]', 'wpcf');
884
  $element['_render']['element'] = isset($element['#markup'])? $element['#markup']:'';
885
  return $this->_pattern( $element['#pattern'], $element );
@@ -890,6 +965,25 @@ class Enlimbo_Forms_Wpcf
890
  return '';
891
  }
892
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
893
  /**
894
  * Returns HTML formatted output for hidden element.
895
  *
@@ -932,7 +1026,20 @@ class Enlimbo_Forms_Wpcf
932
  */
933
  public function button( $element )
934
  {
935
- return $this->submit( $element, 'button', 'Button' );
 
 
 
 
 
 
 
 
 
 
 
 
 
936
  }
937
 
938
  /**
@@ -994,7 +1101,6 @@ class Enlimbo_Forms_Wpcf
994
  return $output;
995
  }
996
 
997
-
998
  /**
999
  * Searches and returns submitted data for element.
1000
  *
143
  if ( $element['#type'] != 'fieldset' ) {
144
  if ( isset( $element['#name'] )
145
  && !in_array( $element['#type'],
146
+ array('submit', 'reset', 'button') ) ) {
147
  // Set submitted data
148
  if ( !in_array( $element['#type'], array('checkboxes') )
149
  && empty( $element['#forced_value'] ) ) {
264
  'textarea',
265
  'textfield',
266
  'thumbnail',
267
+ 'notice',
268
  )
269
  );
270
  }
307
  public function renderElement( $element )
308
  {
309
  $method = $element['#type'];
310
+ if ( !isset( $element['#name'] ) && !in_array($element['#type'], array('notice', 'markup') )) {
311
  if ( !isset( $element['#attributes']['name'] ) ) {
312
  return '#name or #attributes[\'name\'] required!';
313
  } else {
318
  if ( !isset( $element['#id'] ) ) {
319
  if ( isset( $element['#attributes']['id'] ) ) {
320
  $element['#id'] = $element['#attributes']['id'];
321
+ } elseif ( isset($element['#name']) ) {
322
+ $element['#id'] = sprintf('wpcf-%s-%s', $element['#type'], md5($element['#name']));
323
  } else {
324
  $element['#id'] = $element['#type'] . '-' . $this->_count( $element['#type'] );
325
  }
343
  */
344
  private function _setElementAttributes( $element )
345
  {
346
+ /**
347
+ * sanitize #attributes type
348
+ */
349
+ if (
350
+ !isset( $element['#attributes'] )
351
+ || !is_array($element['#attributes'])
352
+ ) {
353
+ $element['#attributes'] = array();
354
+ }
355
  $attributes = '';
356
  $error_class = isset( $element['#error'] ) ? ' ' . $this->css_class . '-error ' . $this->css_class . '-' . $element['#type'] . '-error ' . ' form-' . $element['#type'] . '-error ' . $element['#type'] . '-error form-error ' : '';
357
+ $class = $this->css_class . '-' . $element['#type'] . ' form-' . $element['#type'] . ' ' . $element['#type'];
358
+ foreach ( $element['#attributes'] as $attribute => $value ) {
359
+ // Prevent undesired elements
360
+ if ( in_array( $attribute, array('id', 'name') ) ) {
361
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362
  }
363
+ // Append class values
364
+ if ( $attribute == 'class' ) {
365
+ $value = $value . ' ' . $class . $error_class;
366
+ }
367
+ // Set return string
368
+ $attributes .= ' ' . $attribute . '="' . $value . '"';
369
  }
370
  if ( !isset( $element['#attributes']['class'] ) ) {
371
  $attributes .= ' class="' . $class . $error_class . '"';
372
  }
373
+ /**
374
+ * disable if is setup #disable
375
+ */
376
+ if (
377
+ !in_array('disabled', $element['#attributes'])
378
+ && isset( $element['#disable'] )
379
+ && $element['#disable']
380
+ ) {
381
+ $attributes .= ' disabled="disabled"';
382
+ }
383
+ /**
384
+ * disable if is setup #disable
385
+ */
386
+ if (
387
+ !in_array('readonly', $element['#attributes'])
388
+ && isset( $element['#disable'] )
389
+ && $element['#disable']
390
+ ) {
391
+ $attributes .= ' readonly="readonly"';
392
+ }
393
  return $attributes;
394
  }
395
 
424
  $label = $element['#title'];
425
  }
426
  if ( !empty($label) ) {
427
+ /**
428
+ * add tooltip
429
+ */
430
+ if ( isset( $element['#attributes']['tooltip'] ) ) {
431
+ $label .= sprintf(
432
+ ' <i class="js-wpcf-tooltip wpcf-tooltip dashicons dashicons-editor-help" data-tooltip="%s"></i>',
433
+ esc_attr($element['#attributes']['tooltip'])
434
+ );
435
+ }
436
  $element['_render']['label'] = sprintf(
437
  '<label class="%s-label %s-%s-label" for="%s">%s</label>',
438
  esc_attr($this->css_class),
466
  foreach ( $element['_render'] as $key => $value ) {
467
  $pattern = str_replace( '<' . strtoupper( $key ) . '>', $value, $pattern );
468
  }
469
+ /**
470
+ * clear unreplaced placeholders
471
+ */
472
+ $placeholders = array(
473
+ 'AFTER',
474
+ 'BEFORE',
475
+ 'DESCRIPTION',
476
+ 'ELEMENT',
477
+ 'ERROR',
478
+ 'LABEL',
479
+ 'PREFIX',
480
+ 'SUFFIX',
481
+ 'TITLE',
482
+ );
483
+ $re = sprintf('/<(%s)>/', implode('|', $placeholders));
484
+ return preg_replace( $re, '', $pattern);
485
  }
486
 
487
  /**
710
  */
711
  public function radio( $element )
712
  {
713
+ if( !isset( $this->_count['radio'] ) )
714
+ $this->_count['radio'] = 0;
715
+
716
  $element['#type'] = 'radio';
717
  $element = $this->_setRender( $element );
718
  $element['_render']['element'] = '<input type="radio" id="'
745
  $pattern = isset( $element['#pattern'] ) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT>&nbsp;<LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
746
  $output = $this->_pattern( $pattern, $element );
747
  $output = $this->_wrapElement( $element, $output );
748
+ return $output;
749
  }
750
 
751
  /**
762
  if ( !isset( $element['#name'] ) || empty( $element['#name'] ) ) {
763
  return FALSE;
764
  }
765
+
766
+ $before = '';
767
+ $after = '<br >';
768
+ $list = false;
769
+
770
+ if (
771
+ true
772
+ && isset($element['#attributes'])
773
+ && isset($element['#attributes']['display'])
774
+ ) {
775
+ switch( $element['#attributes']['display'] ) {
776
+ case 'ol':
777
+ case 'ul':
778
+ $before = '<li>';
779
+ $after = '</li>';
780
+ $list = true;
781
+ }
782
+ }
783
+
784
  $element['#type'] = 'radios';
785
  $element = $this->_setRender( $element );
786
  $element['_render']['element'] = '';
787
+ if ( $list ) {
788
+ $element['_render']['element'] .= sprintf('<%s>', $element['#attributes']['display']);
789
+ }
790
  foreach ( $element['#options'] as $ID => $value ) {
791
  $this->_count( 'radio' );
792
  if ( !is_array( $value ) ) {
793
  $value = array('#title' => $ID, '#value' => $value);
794
  $value['#inline'] = true;
795
+ $value['#after'] = $after;
796
+ $value['#before'] = $before;
797
  }
798
  $value['#name'] = $element['#name'];
799
  $value['#default_value'] = isset( $element['#default_value'] ) ? $element['#default_value'] : $value['#value'];
800
  $value['#disable'] = isset( $element['#disable'] ) ? $element['#disable'] : false;
801
  $element['_render']['element'] .= $this->radio( $value );
802
  }
803
+ if ( $list ) {
804
+ $element['_render']['element'] .= sprintf('</%s>', $element['#attributes']['display']);
805
+ }
806
  $pattern = isset( $element['#pattern'] ) ? $element['#pattern'] : '<BEFORE><PREFIX><TITLE><DESCRIPTION><ELEMENT><SUFFIX><AFTER>';
807
  $output = $this->_pattern( $pattern, $element );
808
  $output = $this->_wrapElement( $element, $output );
954
  public function markup( $element )
955
  {
956
  if ( isset( $element['#pattern'] ) ) {
957
+ $element = $this->_setRender( $element );
958
  $element['_render']['label'] = isset($element['#title'])? $element['#title']:__('[no title]', 'wpcf');
959
  $element['_render']['element'] = isset($element['#markup'])? $element['#markup']:'';
960
  return $this->_pattern( $element['#pattern'], $element );
965
  return '';
966
  }
967
 
968
+ /**
969
+ * Returns HTML formatted output for notice element.
970
+ *
971
+ * @param array $element
972
+ * @return string
973
+ */
974
+ public function notice( $element )
975
+ {
976
+ if ( isset($element['#markup'] ) ) {
977
+ $element['#markup'] = sprintf(
978
+ '<div class="notice notice-%s below-h2"><p>%s</p></div>',
979
+ esc_attr(isset($element['#attributes']) && isset($element['#attributes']['type'])? $element['#attributes']['type']:'success'),
980
+ $element['#markup']
981
+ );
982
+ return $this->markup($element);
983
+ }
984
+ return '';
985
+ }
986
+
987
  /**
988
  * Returns HTML formatted output for hidden element.
989
  *
1026
  */
1027
  public function button( $element )
1028
  {
1029
+ $element['#type'] = __FUNCTION__;
1030
+ $element = $this->_setRender( $element );
1031
+ $element['_render']['element'] = sprintf(
1032
+ '<button type="%s" id="%s" name="%s" %s>',
1033
+ esc_attr(__FUNCTION__),
1034
+ esc_attr($element['#id']),
1035
+ esc_attr($element['#name']),
1036
+ $element['_attributes_string']
1037
+ );
1038
+ $element['_render']['element'] .= isset( $element['#value'] ) ? $element['#value'] : $title;
1039
+ $element['_render']['element'] .= '</button>';
1040
+ $pattern = isset( $element['#pattern'] ) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT><SUFFIX><AFTER>';
1041
+ $output = $this->_pattern( $pattern, $element );
1042
+ return $output;
1043
  }
1044
 
1045
  /**
1101
  return $output;
1102
  }
1103
 
 
1104
  /**
1105
  * Searches and returns submitted data for element.
1106
  *
embedded/classes/gui/term_field_editing.php ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Adds support for displaying and updating term fields on Edit Term page.
5
+ *
6
+ * Hooks into taxonomy-specific actions if there are some term field groups associated. Handles rendering fields
7
+ * through toolset-forms (hidden inside the renderer).
8
+ *
9
+ * @since 1.9
10
+ */
11
+ final class WPCF_GUI_Term_Field_Editing {
12
+
13
+
14
+ // This class is a singleton.
15
+ private static $instance = null;
16
+
17
+
18
+ /**
19
+ * ID of the form for toolset-forms.
20
+ *
21
+ * The value is not arbitrary, it must match the actual ID of the form tag, otherwise JS validation will break
22
+ * (and who knows what else). In this case the ID is dictated by the add and edit term pages.
23
+ */
24
+ const EDIT_FORM_ID = 'edittag';
25
+ const ADD_FORM_ID = 'addtag';
26
+
27
+
28
+ public static function initialize() {
29
+ if( null == self::$instance ) {
30
+ self::$instance = new self();
31
+ }
32
+ }
33
+
34
+
35
+ private function __construct() {
36
+ $this->add_hooks();
37
+ }
38
+
39
+
40
+ /**
41
+ * Hooks into taxonomy-specific actions if there are some term field groups associated.
42
+ */
43
+ private function add_hooks() {
44
+
45
+ $factory = WPCF_Field_Group_Term_Factory::get_instance();
46
+ $groups_by_taxonomies = $factory->get_groups_by_taxonomies();
47
+
48
+ $is_toolset_forms_support_needed = false;
49
+
50
+ foreach( $groups_by_taxonomies as $taxonomy => $groups ) {
51
+ if( !empty( $groups ) ) {
52
+
53
+ add_action( "{$taxonomy}_add_form_fields", array( $this, 'on_term_add' ) );
54
+ add_action( "{$taxonomy}_edit_form_fields", array( $this, 'on_term_edit' ), 10, 2 );
55
+ // add_action( "create_{$taxonomy}", array( $this, 'on_term_update' ), 10, 2 );
56
+ add_action( "edit_{$taxonomy}", array( $this, 'on_term_update' ), 10, 2 );
57
+
58
+ $is_toolset_forms_support_needed = true;
59
+ }
60
+ }
61
+
62
+ if( $is_toolset_forms_support_needed ) {
63
+ $this->add_toolset_forms_support();
64
+ }
65
+ }
66
+
67
+
68
+ public function on_term_add( $taxonomy_slug ) {
69
+ $groups = WPCF_Field_Group_Term_Factory::get_instance()->get_groups_by_taxonomy( $taxonomy_slug );
70
+
71
+ if( !empty( $groups ) ) {
72
+ printf(
73
+ '<div class="wpcf-add-term-page-box"><strong>%s</strong></div>',
74
+ __( 'This taxonomy has custom fields. You will be able to edit them after the term is saved.', 'wpcf' )
75
+ );
76
+ }
77
+
78
+ /*if( empty( $groups ) ) {
79
+ return;
80
+ }
81
+
82
+ foreach( $groups as $group ) {
83
+ $this->render_field_group_add_page( $group, null );
84
+ }*/
85
+ }
86
+
87
+
88
+ /**
89
+ * This will be called when editing an existing term.
90
+ *
91
+ * Renders term field groups associated with the taxonomy with all their fields, via toolset-forms.
92
+ *
93
+ * @link https://developer.wordpress.org/reference/hooks/taxonomy_edit_form_fields/
94
+ *
95
+ * @param WP_Term $term Term that is being edited.
96
+ * @param string $taxonomy_slug Taxonomy where the term belongs.
97
+ */
98
+ public function on_term_edit( $term, $taxonomy_slug ) {
99
+ $groups = WPCF_Field_Group_Term_Factory::get_instance()->get_groups_by_taxonomy( $taxonomy_slug );
100
+
101
+ if( empty( $groups ) ) {
102
+ return;
103
+ }
104
+
105
+ foreach( $groups as $group ) {
106
+ $this->render_field_group_edit_page( $group, $term->term_id );
107
+ }
108
+ }
109
+
110
+
111
+ public function on_term_update( $term_id, $tt_id ) {
112
+
113
+ // Get an array of fields that we need to update. We don't care about their groups here.
114
+ $term = get_term_by( 'term_taxonomy_id', $tt_id );
115
+ if( ! $term instanceof WP_Term ) {
116
+ return;
117
+ }
118
+ $groups = WPCF_Field_Group_Term_Factory::get_instance()->get_groups_by_taxonomy( $term->taxonomy );
119
+ if( empty( $groups ) ) {
120
+ return;
121
+ }
122
+ $field_definitions = WPCF_Field_Utils::get_field_definitions_from_groups( $groups );
123
+
124
+ $update_errors = $this->update_term_fields( $term_id, $field_definitions );
125
+
126
+ // Display errors if we have any.
127
+ if( !empty( $update_errors ) ) {
128
+ foreach( $update_errors as $update_error ) {
129
+ wpcf_admin_message_store( $update_error->get_error_message(), 'error' );
130
+ }
131
+ wpcf_admin_message_store(
132
+ sprintf(
133
+ '<strong>%s</strong>',
134
+ __( 'There has been a problem while saving custom fields. Please fix it and try again.', 'wpcf' )
135
+ ),
136
+ 'error'
137
+ );
138
+ }
139
+
140
+ }
141
+
142
+
143
+ /**
144
+ * Update fields for given term.
145
+ *
146
+ * @param int $term_id
147
+ * @param WPCF_Field_Definition[] $field_definitions
148
+ * @return WP_Error[]
149
+ */
150
+ private function update_term_fields( $term_id, $field_definitions ) {
151
+ $update_results = array();
152
+ foreach( $field_definitions as $field_definition ) {
153
+ $update_results[] = $this->update_single_field( $field_definition, $term_id );
154
+ }
155
+ return $this->filter_wp_errors_flat( $update_results );
156
+ }
157
+
158
+
159
+ /**
160
+ * From an array that can contain booleans, WP_Error and arrays of WP_Error, create an array containing all
161
+ * WP_Error instances only.
162
+ *
163
+ * @param array $update_results
164
+ * @return WP_Error[]
165
+ */
166
+ private function filter_wp_errors_flat( $update_results ) {
167
+ $errors = array();
168
+ foreach( $update_results as $update_result ) {
169
+ if( $update_result instanceof WP_Error ) {
170
+ $errors[] = $update_result;
171
+ } else if( is_array( $update_result ) ) {
172
+ foreach( $update_result as $error ) {
173
+ if( $error instanceof WP_Error ) {
174
+ $errors[] = $error;
175
+ }
176
+ }
177
+ }
178
+ }
179
+ return $errors;
180
+ }
181
+
182
+
183
+ /**
184
+ * @param WPCF_Field_Definition $field_definition
185
+ * @param int $term_id
186
+ *
187
+ * @return WP_Error|WP_Error[]|true
188
+ */
189
+ private function update_single_field( $field_definition, $term_id ) {
190
+ $field = new WPCF_Field_Instance_Term( $field_definition, $term_id );
191
+ $saver = new WPCF_Field_Data_Saver( $field, self::EDIT_FORM_ID );
192
+
193
+ $validation_results = $saver->validate_field_data();
194
+
195
+ $errors = array();
196
+ foreach( $validation_results as $index => $validation_result ) {
197
+
198
+ if( $validation_result instanceof WP_Error ) {
199
+ $error_message = sprintf( '%s %s',
200
+ sprintf( __( 'Field "%s" not updated:', 'wpcf' ), $field_definition->get_name() ),
201
+ implode( ', ', $validation_result->get_error_data() )
202
+ );
203
+ $errors[] = new WP_Error( 'wpcf_field_not_updated', $error_message );
204
+ }
205
+ }
206
+
207
+ if( !empty( $errors ) ) {
208
+ return $errors;
209
+ }
210
+
211
+ $saving_result = $saver->save_field_data();
212
+
213
+ return $saving_result;
214
+ }
215
+
216
+
217
+ /**
218
+ * Load various assets needed by the toolset-forms blob.
219
+ *
220
+ * @since 1.9
221
+ */
222
+ private function add_toolset_forms_support() {
223
+ // JS and CSS assets related to fields - mostly generic ones.
224
+ wpcf_edit_post_screen_scripts();
225
+
226
+ // Needed for fields that have something to do with files
227
+ WPToolset_Field_File::file_enqueue_scripts();
228
+
229
+ // Extra enqueuing of media assets needed since WPToolset_Field_File doesn't know about termmeta.
230
+ wp_enqueue_media();
231
+
232
+ // We need to append form-specific data for the JS validation script.
233
+ add_action( 'admin_footer', array( $this, 'render_js_validation_data' ) );
234
+ }
235
+
236
+
237
+ /**
238
+ * Appends form-specific data for the JS validation script.
239
+ *
240
+ * @since 1.9
241
+ */
242
+ public function render_js_validation_data() {
243
+ wpcf_form_render_js_validation( '.validate' );
244
+ }
245
+
246
+
247
+ /**
248
+ * Render table rows with individual field group.
249
+ *
250
+ * @param WPCF_Field_Group_Term $field_group
251
+ * @param int|null $term_id ID of the term whose fields are being rendered.
252
+ */
253
+ private function render_field_group_edit_page( $field_group, $term_id ) {
254
+ $field_definitions = $field_group->get_field_definitions();
255
+
256
+ printf(
257
+ '<tr><th scope="row" colspan="2"><hr /><strong>%s</strong></th></tr>',
258
+ $field_group->get_display_name()
259
+ );
260
+
261
+ /** @var WPCF_Field_Definition_Term $field_definition */
262
+ foreach( $field_definitions as $field_definition ) {
263
+ printf(
264
+ '<tr class="form-field"><th scope="row">%s</th><td>%s</td></tr>',
265
+ $field_definition->get_display_name(),
266
+ $this->get_toolset_forms_field( $field_definition, self::EDIT_FORM_ID, $term_id, true )
267
+ );
268
+ }
269
+ }
270
+
271
+
272
+ /**
273
+ * Render table rows with individual field group.
274
+ *
275
+ * @param WPCF_Field_Group_Term $field_group
276
+ * @param int|null $term_id ID of the term whose fields are being rendered.
277
+ */
278
+ /*private function render_field_group_add_page( $field_group, $term_id ) {
279
+ $field_definitions = $field_group->get_field_definitions();
280
+
281
+ printf(
282
+ '<hr /><h4>%s</h4>',
283
+ $field_group->get_title()
284
+ );
285
+
286
+ /// @var WPCF_Field_Definition_Term $field_definition
287
+ foreach( $field_definitions as $field_definition ) {
288
+ printf(
289
+ '<div class="form-field wpcf-add-term-form-field">%s</div>',
290
+ $this->get_toolset_forms_field( $field_definition, self::ADD_FORM_ID, $term_id, false )
291
+ );
292
+ }
293
+ }*/
294
+
295
+
296
+ /**
297
+ * Get the toolset-forms markup for an individual field.
298
+ *
299
+ * @param WPCF_Field_Definition_Term $field_definition
300
+ * @param string $form_id ID of the form for toolset-forms.
301
+ * @param int|null $term_id ID of the term whose fields are being rendered.
302
+ * @param bool $hide_field_title Determine if toolset-forms title above the field should be displayed.
303
+ *
304
+ * @return string Markup with the field.
305
+ */
306
+ private function get_toolset_forms_field( $field_definition, $form_id, $term_id, $hide_field_title ) {
307
+
308
+ if( null == $term_id ) {
309
+ $field = new WPCF_Field_Instance_Unsaved( $field_definition );
310
+ } else {
311
+ $field = new WPCF_Field_Instance_Term( $field_definition, $term_id );
312
+ }
313
+
314
+ $tf_renderer = new WPCF_Field_Renderer_Toolset_Forms( $field, $form_id );
315
+ $tf_renderer->setup( array( 'hide_field_title' => (bool) $hide_field_title ) );
316
+
317
+ return $tf_renderer->render( false );
318
+
319
+ }
320
+ }
embedded/classes/helper.ajax.php CHANGED
@@ -126,7 +126,7 @@ class WPCF_Helper_Ajax
126
  }
127
  }
128
  }
129
- return 'console.log("asdasdsdasdasdasdasd");'.$js_execute;
130
  }
131
 
132
  }
126
  }
127
  }
128
  }
129
+ return $js_execute;
130
  }
131
 
132
  }
embedded/classes/loader.php CHANGED
@@ -169,11 +169,13 @@ class WPCF_Loader
169
  WPCF_EMBEDDED_RES_RELPATH . '/css/colorbox.css', array(),
170
  WPCF_VERSION );
171
  }
172
- if ( !wp_style_is( 'toolset-font-awesome', 'registered' ) ) {
173
- wp_register_style( 'toolset-font-awesome',
174
- WPCF_EMBEDDED_RES_RELPATH . '/css/font-awesome/css/font-awesome.min.css',
175
- array('admin-bar', 'wp-admin', 'buttons', 'media-views'),
176
- WPCF_VERSION );
 
 
177
  }
178
  if ( !wp_style_is( 'toolset-dashicons', 'registered' ) ) {
179
  wp_register_style(
169
  WPCF_EMBEDDED_RES_RELPATH . '/css/colorbox.css', array(),
170
  WPCF_VERSION );
171
  }
172
+ if ( !wp_style_is( 'font-awesome', 'registered' ) ) {
173
+ wp_register_style(
174
+ 'font-awesome',
175
+ WPCF_EMBEDDED_RELPATH.'/toolset/toolset-common/utility/css/font-awesome/css/font-awesome.min.css',
176
+ array(),
177
+ '4.4.0'
178
+ );
179
  }
180
  if ( !wp_style_is( 'toolset-dashicons', 'registered' ) ) {
181
  wp_register_style(
embedded/classes/post-types/messages.php CHANGED
@@ -6,6 +6,6 @@
6
  */
7
 
8
  $messages = array(
9
- 'warning_singular_plural_match' => __( "It is not recommended to have same plural and singular name for a post type. Please use a different name for the singular and plural names.", 'wpcf' ),
10
  'warning_singular_plural_match_ignore' => __( 'Ignore this warning.', 'wpcf' ),
11
  );
6
  */
7
 
8
  $messages = array(
9
+ 'warning_singular_plural_match' => __( "It is not recommended to have same plural and singular name for a Post Type. Please use a different name for the singular and plural names.", 'wpcf' ),
10
  'warning_singular_plural_match_ignore' => __( 'Ignore this warning.', 'wpcf' ),
11
  );
embedded/classes/relationship/form-child.php CHANGED
@@ -97,6 +97,12 @@ class WPCF_Relationship_Child_Form
97
  $this->_dummy_post = true;
98
  }
99
  $this->child_post_type_object = get_post_type_object( $this->child_post_type );
 
 
 
 
 
 
100
 
101
  // Collect params from request
102
  foreach ( $this->__params as $__param ) {
@@ -114,7 +120,7 @@ class WPCF_Relationship_Child_Form
114
  return;
115
  }
116
  /**
117
- * custom post types
118
  */
119
  $post_types = get_option( WPCF_OPTION_NAME_CUSTOM_TYPES, array() );
120
  if (
@@ -192,20 +198,16 @@ class WPCF_Relationship_Child_Form
192
 
193
  // Pagination
194
  $total_items = count( $this->children );
195
- $per_page = $wpcf->relationship->get_items_per_page( $this->parent_post_type,
196
- $this->child_post_type );
197
  $page = isset( $_GET['page'] ) ? intval( $_GET['page'] ) : 1;
198
- $numberposts = $page == 1 ? 1 : ($page - 1) * $per_page;
199
- $slice = $page == 1 ? 0 : ($page - 1) * $per_page;
200
- $next = count( $this->children ) > $numberposts + $per_page;
201
- $prev = $page == 1 ? false : true;
202
  if ( $total_items > $per_page ) {
203
- $this->children = array_splice( $this->children, $slice, $per_page );
204
  }
205
 
206
- $this->pagination_top = wpcf_pr_admin_has_pagination( $this->parent,
207
- $this->child_post_type, $page, $prev, $next, $per_page,
208
- $total_items );
209
  /*
210
  *
211
  *
@@ -549,7 +551,7 @@ class WPCF_Relationship_Child_Form
549
  );
550
  }
551
  /**
552
- * Returns HTML formatted taxonomy form.
553
  *
554
  * @param type $taxonomy
555
  * @return type
@@ -818,28 +820,19 @@ class WPCF_Relationship_Child_Form
818
  || $header == '_wp_featured_image'
819
  ) {
820
  $headers[$header] = $this->get_header($header);
821
- } else if ( strpos( $header, WPCF_META_PREFIX ) === 0
822
- && isset( $wpcf_fields[str_replace( WPCF_META_PREFIX, '',
823
- $header )] ) ) {
824
- wpcf_field_enqueue_scripts( $wpcf_fields[str_replace( WPCF_META_PREFIX,
825
- '', $header )]['type'] );
826
- $field_dir = $sort_field == $header ? $dir : $dir_default;
827
- $headers[$header] = '';
828
- $headers[$header] .= $sort_field == $header ? '<div class="wpcf-pr-sort-' . $dir . '"></div>' : '';
829
- $headers[$header] .= '<a href="' . admin_url( 'admin-ajax.php?action=wpcf_ajax&amp;wpcf_action=pr_sort&amp;field='
830
- . $header . '&amp;sort=' . $field_dir . '&amp;post_id=' . $post->ID . '&amp;post_type='
831
- . $post_type . '&amp;_wpnonce='
832
- . wp_create_nonce( 'pr_sort' ) ) . '">' . stripslashes( $wpcf_fields[str_replace( WPCF_META_PREFIX,
833
- '', $header )]['name'] ) . '</a>';
834
  } else {
 
 
 
 
 
 
 
 
835
  $field_dir = $sort_field == $header ? $dir : $dir_default;
836
  $headers[$header] = '';
837
  $headers[$header] .= $sort_field == $header ? '<div class="wpcf-pr-sort-' . $dir . '"></div>' : '';
838
- $headers[$header] .= '<a href="' . admin_url( 'admin-ajax.php?action=wpcf_ajax&amp;wpcf_action=pr_sort&amp;field='
839
- . $header . '&amp;sort=' . $field_dir . '&amp;post_id=' . $post->ID . '&amp;post_type='
840
- . $post_type . '&amp;_wpnonce='
841
- . wp_create_nonce( 'pr_sort' ) ) . '">'
842
- . $this->get_header($header) . '</a>';
843
  }
844
  }
845
  if ( !empty( $this->headers['__parents'] ) ) {
97
  $this->_dummy_post = true;
98
  }
99
  $this->child_post_type_object = get_post_type_object( $this->child_post_type );
100
+ if (
101
+ !isset($this->child_post_type_object->slug)
102
+ && isset($this->child_post_type_object->name)
103
+ ) {
104
+ $this->child_post_type_object->slug = $this->child_post_type_object->name;
105
+ }
106
 
107
  // Collect params from request
108
  foreach ( $this->__params as $__param ) {
120
  return;
121
  }
122
  /**
123
+ * post types
124
  */
125
  $post_types = get_option( WPCF_OPTION_NAME_CUSTOM_TYPES, array() );
126
  if (
198
 
199
  // Pagination
200
  $total_items = count( $this->children );
201
+ $per_page = $wpcf->relationship->get_items_per_page( $this->parent_post_type, $this->child_post_type );
 
202
  $page = isset( $_GET['page'] ) ? intval( $_GET['page'] ) : 1;
203
+ $offset = ( $page == 1 ) ? 0 : ( ( $page - 1 ) * $per_page );
204
+ $next = ( $total_items > ( $offset + $per_page ) );
205
+ $prev = ( $page == 1 ) ? false : true;
 
206
  if ( $total_items > $per_page ) {
207
+ $this->children = array_splice( $this->children, $offset, $per_page );
208
  }
209
 
210
+ $this->pagination_top = wpcf_pr_admin_has_pagination( $this->parent, $this->child_post_type, $page, $prev, $next, $per_page, $total_items );
 
 
211
  /*
212
  *
213
  *
551
  );
552
  }
553
  /**
554
+ * Returns HTML formatted Taxonomy form.
555
  *
556
  * @param type $taxonomy
557
  * @return type
820
  || $header == '_wp_featured_image'
821
  ) {
822
  $headers[$header] = $this->get_header($header);
 
 
 
 
 
 
 
 
 
 
 
 
 
823
  } else {
824
+ $link_text = $this->get_header($header);
825
+ if (
826
+ strpos( $header, WPCF_META_PREFIX ) === 0
827
+ && isset( $wpcf_fields[str_replace( WPCF_META_PREFIX, '', $header )] )
828
+ ) {
829
+ wpcf_field_enqueue_scripts( $wpcf_fields[str_replace( WPCF_META_PREFIX, '', $header )]['type'] );
830
+ $link_text = stripslashes( $wpcf_fields[str_replace( WPCF_META_PREFIX, '', $header )]['name'] );
831
+ }
832
  $field_dir = $sort_field == $header ? $dir : $dir_default;
833
  $headers[$header] = '';
834
  $headers[$header] .= $sort_field == $header ? '<div class="wpcf-pr-sort-' . $dir . '"></div>' : '';
835
+ $headers[$header] .= '<a href="' . admin_url( 'admin-ajax.php?action=wpcf_ajax&amp;wpcf_action=pr_sort&amp;field=' . $header . '&amp;sort=' . $field_dir . '&amp;post_id=' . $post->ID . '&amp;post_type=' . $post_type . '&amp;_wpnonce=' . wp_create_nonce( 'pr_sort' ) ) . '">' . $link_text . '</a>';
 
 
 
 
836
  }
837
  }
838
  if ( !empty( $this->headers['__parents'] ) ) {
embedded/classes/repeater.php CHANGED
@@ -618,3 +618,579 @@ class WPCF_Repeater extends WPCF_Field
618
  }
619
 
620
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
618
  }
619
 
620
  }
621
+
622
+ /*
623
+
624
+ */
625
+
626
+ class WPCF_Termmeta_Repeater extends WPCF_Termmeta_Field
627
+ {
628
+
629
+ /**
630
+ * Field order
631
+ *
632
+ * @var type
633
+ */
634
+ var $order;
635
+
636
+ /**
637
+ * Indexing
638
+ *
639
+ * Set counts when processing fields.
640
+ *
641
+ * @var type
642
+ */
643
+ var $index = 0;
644
+
645
+ /**
646
+ * Field title
647
+ * @var type
648
+ */
649
+ var $title = '';
650
+
651
+ /**
652
+ * Field description.
653
+ *
654
+ * @var type
655
+ */
656
+ var $description = '';
657
+
658
+ function __construct() {
659
+ parent::__construct();
660
+ if ( is_admin() ) {
661
+ wpcf_admin_add_js_settings( 'wpcf_repetitive_last_warning',
662
+ __( 'Sorry, can not delete all fields.', 'wpcf' ) );
663
+ }
664
+ }
665
+
666
+ /**
667
+ * Calls parent set func.
668
+ *
669
+ * @param type $post
670
+ * @param type $field
671
+ */
672
+ function set( $term_id, $field ) {
673
+ parent::set( $term_id, $field );
674
+ $this->index = 0;
675
+ }
676
+
677
+ /**
678
+ * Save fields
679
+ *
680
+ * If $data empty, $_POST will be checked
681
+ *
682
+ * @global type $wpcf
683
+ * @param type $data
684
+ * @return boolean
685
+ */
686
+ function save( $data = null ) {
687
+
688
+ global $wpcf;
689
+
690
+ // Delete all fields
691
+ delete_term_meta( $this->term_id, $this->slug );
692
+
693
+ // Allow $data to replace $_POST
694
+ if ( is_null( $data ) && isset( $_POST['wpcf'][$this->cf['slug']] ) ) {
695
+ $data = $_POST['wpcf'][$this->cf['slug']];
696
+ }
697
+
698
+ // Set data
699
+ if ( !empty( $data ) ) {
700
+
701
+ // Insert new meta and collect all new mids
702
+ $mids = array();
703
+ foreach ( $data as $meta_value ) {
704
+
705
+ /*
706
+ *
707
+ * Deprecated!
708
+ */
709
+ if ( is_array( $meta_value ) && isset( $meta_value['new_value'] ) ) {
710
+ $meta_value = $meta_value['new_value'];
711
+ $wpcf->debug->deprecated['repetitive_new_value_used'] = 'repetitive_new_value_used';
712
+ }
713
+
714
+ // Apply filters
715
+ $_meta_value = $this->_filter_save_termmeta_value( $meta_value );
716
+ $_meta_value = $this->_filter_save_value( $_meta_value );
717
+
718
+ // Adding each field will return $mid
719
+ // $unique = false
720
+ if ( !empty( $_meta_value ) ) {
721
+ $mid = add_term_meta( $this->term_id, $this->slug,
722
+ $_meta_value );
723
+ $mids[] = $mid;
724
+
725
+ // Call insert post actions on each field
726
+ $this->_action_save( $this->cf, $_meta_value, $mid,
727
+ $meta_value );
728
+ }
729
+ }
730
+
731
+ // Save order
732
+ if ( !empty( $mids ) ) {
733
+ update_term_meta( $this->term_id, $this->order_meta_name,
734
+ $mids );
735
+ }
736
+
737
+ // Return true - field found
738
+ return true;
739
+ }
740
+
741
+ // Return false if field missed
742
+ return false;
743
+ }
744
+
745
+ /**
746
+ * Fetch and sort fields.
747
+ *
748
+ * @global object $wpdb
749
+ */
750
+ function _get_meta() {
751
+ global $wpdb;
752
+
753
+ $cache_key = md5( 'termmetarepeater::_get_meta' . $this->term_id . $this->slug );
754
+ $cache_group = 'types_cache';
755
+ $cached_object = wp_cache_get( $cache_key, $cache_group );
756
+
757
+ if ( $this->use_cache ) {
758
+ if ( false != $cached_object && is_array( $cached_object ) ) {
759
+ return $cached_object;
760
+ }
761
+ }
762
+
763
+ $this->order_meta_name = '_' . $this->slug . '-sort-order';
764
+
765
+ $_meta = parent::_get_meta();
766
+
767
+ $ordered = array();
768
+ $this->order = get_term_meta( $this->term_id, $this->order_meta_name,
769
+ true );
770
+
771
+ $cache_key_termfield = md5( 'termmeta::_get_meta' . $this->term_id . $this->slug );
772
+ $cached_object_termfield = wp_cache_get( $cache_key_termfield, $cache_group );
773
+
774
+ if ( $this->use_cache ) {
775
+ if ( false != $cached_object_termfield && is_array( $cached_object_termfield ) ) {// WordPress cache
776
+ $r = $cached_object_termfield;
777
+ } else {
778
+ $r = $wpdb->get_results(
779
+ $wpdb->prepare(
780
+ "SELECT * FROM {$wpdb->termmeta}
781
+ WHERE term_id=%d
782
+ AND meta_key=%s",
783
+ $this->term_id, $this->slug )
784
+ );
785
+ }
786
+ }
787
+
788
+ if ( !empty( $r ) ) {
789
+ $_meta = array();
790
+ $_meta['by_meta_id'] = array();
791
+ $_meta['by_meta_key'] = array();
792
+
793
+ // Default order
794
+ foreach ( $r as $meta ) {
795
+ //print_r($meta);exit;
796
+ // This will use last item in array if multiple values exist
797
+ $_meta['single'] = maybe_unserialize( $meta->meta_value );
798
+ // Sort by meta_id column
799
+ $_meta['by_meta_id'][$meta->meta_id]
800
+ = maybe_unserialize( $meta->meta_value );
801
+ // Sort by meta_key
802
+ $_meta['by_meta_key'][] = maybe_unserialize( $meta->meta_value );
803
+ }
804
+ ksort( $_meta['by_meta_id'] );
805
+
806
+ // Custom order
807
+ if ( !empty( $this->order ) ) {
808
+ foreach ( $this->order as $meta_id ) {
809
+ if ( isset( $_meta['by_meta_id'][$meta_id] ) ) {
810
+ $_meta['custom_order'][$meta_id] = $_meta['by_meta_id'][$meta_id];
811
+ }
812
+ }
813
+ // This ones are orphaned
814
+ foreach ( $_meta['by_meta_id'] as $meta_id => $meta ) {
815
+ if ( !isset( $ordered[$meta_id] ) ) {
816
+ $_meta['custom_order'][$meta_id] = $meta;
817
+ }
818
+ }
819
+ } else {
820
+ $_meta['custom_order'] = $_meta['by_meta_id'];
821
+ }
822
+ } else if ( !is_null( $this->meta_object ) ) {
823
+ $_meta = array();
824
+ $_meta['single'] = maybe_unserialize( $this->meta_object->meta_value );
825
+ // Sort by meta_id column
826
+ $_meta['by_meta_id'][$this->meta_object->meta_id] = maybe_unserialize( $this->meta_object->meta_value );
827
+ // Sort by meta_key
828
+ $_meta['by_meta_key'][] = maybe_unserialize( $this->meta_object->meta_value );
829
+ } else {
830
+ $_meta = array();
831
+ $_meta['single'] = '';
832
+ $_meta['by_meta_id'] = array();
833
+ $_meta['by_meta_key'] = array();
834
+ }
835
+
836
+ if ( empty( $_meta['custom_order'] ) ) {
837
+ $_meta['custom_order'] = $_meta['by_meta_id'];
838
+ }
839
+
840
+ wp_cache_add( $cache_key, $_meta, $cache_group );// WordPress cache
841
+ return $_meta;
842
+ }
843
+
844
+ /**
845
+ * Sets repetitive field form.
846
+ *
847
+ * @todo Make more distinction between $field_form and $form_field
848
+ */
849
+ function get_fields_form( $is_profile = '' ) {
850
+ $form = array();
851
+ $form_id = $this->cf['id'];
852
+ $unique_id = wpcf_unique_id( serialize( $this->cf ) );
853
+
854
+ // Process fields
855
+ // Check if has any value
856
+ if ( empty( $this->meta['single'] ) ) {
857
+ // To prevent passing array to field
858
+ $this->meta = null;
859
+ $this->__meta = null;
860
+ $this->cf['value'] = null;
861
+
862
+ $field_form = $this->get_field_form( '' );
863
+
864
+ foreach ( $field_form as $field_key => $field ) {
865
+ $form_field[$form_id . '_repetitive_0_' . $field_key] = $field;
866
+ }
867
+ } else {
868
+
869
+ $ordered = !empty( $this->meta['custom_order'] ) ? $this->meta['custom_order'] : $this->meta['by_meta_id'];
870
+ foreach ( $ordered as $meta_id => $meta_value ) {
871
+
872
+ $this->cf['value'] = $meta_value;
873
+ $this->meta_object->meta_id = $meta_id;
874
+
875
+ // Set single field form
876
+
877
+ $field_form = $this->get_field_form( $meta_value, $meta_id );
878
+
879
+ foreach ( $field_form as $field_key => $field ) {
880
+ $form_field[$form_id . '_repetitive_' . strval( $meta_id ) . '_' . $field_key] = $field;
881
+ }
882
+
883
+ $form_field[$form_id . '_repetitive_meta_id_' . strval( $meta_id )] = array(
884
+ '#type' => 'hidden',
885
+ '#name' => '',
886
+ '#value' => $meta_id,
887
+ );
888
+ }
889
+ }
890
+
891
+ // Set main wrapper
892
+ // Check if conditional
893
+ global $wpcf;
894
+
895
+ // Set style
896
+ /*
897
+ *
898
+ *
899
+ * Hide if field not passed check
900
+ * TODO Move this to WPCF_Conditional
901
+ */
902
+ $show = true;
903
+ if ( $wpcf->conditional->is_conditional( $this->cf ) ) {
904
+ $wpcf->conditional->set( $this->post, $this->cf );
905
+ $show = $wpcf->conditional->evaluate();
906
+ }
907
+ $css_cd = !$show ? 'display:none;' : '';
908
+
909
+ /**
910
+ *
911
+ *
912
+ *
913
+ *
914
+ * Set title and description
915
+ * TODO See if can be improved getting main element
916
+ *
917
+ * Get first element and extract details
918
+ * Pass emty string as value to avoid using meta as array
919
+ */
920
+ //
921
+ $_c = array_values( parent::_get_meta_form( '' ) );
922
+ array_shift( $_c );
923
+ $_main_element = array_shift( $_c );
924
+ // Set title and desc
925
+ if ( !empty( $_main_element['#title'] ) ) {
926
+ $this->title = $_main_element['#title'];
927
+ }
928
+ if ( !empty( $_main_element['#description'] ) ) {
929
+ $this->description = $_main_element['#description'];
930
+ }
931
+ $addTagHeaderStart = $addTagHeaderEnd = '';
932
+ if ( $is_profile == 1 ) {
933
+ $addTagHeaderStart = '<div class="wpcf-repeater-profile-line-left">';
934
+ $addTagHeaderEnd = '</div><div class="wpcf-repeater-profile-line-right">';
935
+ }
936
+ // Set title
937
+ $form[$unique_id . '_main_title'] = array(
938
+ '#type' => 'markup',
939
+ '#markup' => $addTagHeaderStart . '<strong>' . $this->title . '</strong><br/>' . $addTagHeaderEnd,
940
+ );
941
+
942
+ /*
943
+ *
944
+ *
945
+ * Start wrapper
946
+ */
947
+ $form[$unique_id . '_repetitive_wrapper_open'] = array(
948
+ '#type' => 'markup',
949
+ '#markup' => ''
950
+ . '<div id="wpcf_'
951
+ . $form_id
952
+ . '_repetitive_wrapper_' . $unique_id
953
+ . '" class="wpcf-wrap wpcf-repetitive-wrapper" style="' . $css_cd . '">',
954
+ );
955
+
956
+ // Set hidden mark field
957
+ /*
958
+ *
959
+ *
960
+ *
961
+ * This actually marks field as repetitive
962
+ * IMPORTANT!!! IF NOT marked field won't be saved at all!
963
+ *
964
+ * @see wpcf_admin_post_save_post_hook()
965
+ */
966
+ $form[$form_id . '_hidden_mark'] = array(
967
+ '#type' => 'hidden',
968
+ '#name' => '__wpcf_repetitive[' . $this->slug . ']',
969
+ '#value' => 1,
970
+ '#id' => $form_id . '_hidden_mark',
971
+ );
972
+
973
+ // Sortable
974
+ $form[$form_id . '_repetitive_sortable_open'] = array(
975
+ '#type' => 'markup',
976
+ '#markup' => '<div id="wpcf_'
977
+ . $form_id
978
+ . '_repetitive_sortable_' . wpcf_unique_id( serialize( $this->cf ) )
979
+ . '" class="wpcf-repetitive-sortable-wrapper">',
980
+ '#id' => $form_id . '_repetitive_sortable_wrapper_open',
981
+ );
982
+
983
+ // Append field form
984
+ $form = $form + $form_field;
985
+
986
+ // Close sortable wrapper
987
+ $form[$form_id . '_repetitive_sortable_close'] = array(
988
+ '#type' => 'markup',
989
+ '#markup' => '</div>',
990
+ '#id' => $form_id . '_repetitive_sortable_close',
991
+ );
992
+
993
+ // Add AJAX response at the end of repetitive field
994
+ // Show only on page load not when calling AJAX
995
+ if ( !defined( 'DOING_AJAX' ) ) {
996
+ $form[$form_id . '_repetitive_ajax_response'] = array(
997
+ '#type' => 'markup',
998
+ '#markup' => '<div class="wpcf-repetitive-response"></div>',
999
+ '#id' => $form_id . '_repetitive_ajax_response',
1000
+ );
1001
+
1002
+ // Add description
1003
+ $form[$unique_id . '_main_description'] = array(
1004
+ '#type' => 'markup',
1005
+ '#markup' => '<div class="wpcf-repetitive-description">'
1006
+ . wpautop( stripslashes( strip_tags( $this->description ) ) )
1007
+ . '</div>',
1008
+ );
1009
+
1010
+ // 'Add' button
1011
+ $form[$form_id . '_repetitive_form'] = array(
1012
+ '#type' => 'markup',
1013
+ '#markup' => wpcf_repetitive_umform( $this->cf,
1014
+ $this->currentUID ),
1015
+ '#id' => $form_id . '_repetitive_form',
1016
+ );
1017
+ }
1018
+
1019
+ // Close wrapper
1020
+ $form[$unique_id . '_repetitive_wrapper_close'] = array(
1021
+ '#type' => 'markup',
1022
+ '#markup' => '</div></div>',
1023
+ );
1024
+
1025
+ return $form;
1026
+ }
1027
+
1028
+ /**
1029
+ * Sete repetitive form for single field.
1030
+ *
1031
+ * @param type $meta
1032
+ * @return string
1033
+ */
1034
+ function get_field_form( $meta_value = null, $meta_id = null ) {
1035
+
1036
+ $form = array();
1037
+ if ( is_null( $meta_value ) ) {
1038
+ $key = 'wpcf_field_' . wpcf_unique_id( md5( $this->index ) . $meta_id );
1039
+ } else {
1040
+ $key = 'wpcf_field_' . md5( maybe_serialize( $meta_value ) . $meta_id );
1041
+ }
1042
+
1043
+ if ( is_null( $meta_value ) ||
1044
+ (is_array( $meta_value ) && isset( $meta_value['custom_order'] ) )
1045
+ ) {
1046
+ $meta_value = $this->meta['single'];
1047
+ }
1048
+
1049
+ // Open drag div
1050
+ $form[$key . '_drag_open'] = array(
1051
+ '#type' => 'markup',
1052
+ '#markup' => '<div class="wpcf-repetitive-drag-and-drop">'
1053
+ );
1054
+
1055
+ // Use WPCF_Field::get_field_form()
1056
+ $field_form = parent::_get_meta_form( $meta_value, $meta_id, false );
1057
+
1058
+ /*
1059
+ *
1060
+ * Apply filters to each form element.
1061
+ * Here we add specific properties
1062
+ * e.g. Skype alters fields.
1063
+ */
1064
+ $_loop = false;
1065
+ foreach ( $field_form as $k => $field ) {
1066
+
1067
+ /*
1068
+ *
1069
+ * IMPORTANT
1070
+ * We change name to hold array
1071
+ */
1072
+ if ( isset( $field['#name'] ) ) {
1073
+ $temp = explode( '[' . $this->cf['slug'] . ']', $field['#name'] );
1074
+
1075
+ // Assign new name
1076
+ $field['#name'] = $temp[0] . '[' . $this->cf['slug'] . ']' . '['
1077
+ . $key . ']';
1078
+
1079
+ // Append rest if any
1080
+ if ( isset( $temp[1] ) ) {
1081
+ $field['#name'] .= $temp[1];
1082
+ }
1083
+ }
1084
+
1085
+ // Apply filters
1086
+ $field_form[$k] = apply_filters( 'wpcf_repetitive_field', $field,
1087
+ $this->post, $this->cf, $k );
1088
+
1089
+ // BREAKPOINT
1090
+ /*
1091
+ * This is place where we clean display.
1092
+ * First item is displayed as it is, each after is reduced.
1093
+ * If called via AJAX - that means it added and should be reduced.
1094
+ */
1095
+ // if ( $_loop == true || defined( 'DOING_AJAX' ) ) {
1096
+ /*
1097
+ * See if field has Repeater pattern defined
1098
+ */
1099
+ if ( isset( $field['__repeater_restricted'] )
1100
+ && is_array( $field['__repeater_restricted'] ) ) {
1101
+ foreach ( $field['__repeater_restricted'] as $_e => $_v ) {
1102
+ if ( isset( $field[$_e] ) ) {
1103
+ unset( $field[$_e] );
1104
+ }
1105
+ }
1106
+ } else {
1107
+ unset( $field['#title'], $field['#description'] );
1108
+ }
1109
+ // Set main
1110
+ $field_form[$k] = $field;
1111
+ // }
1112
+ // $_loop = true;
1113
+ }
1114
+
1115
+ // Just append form
1116
+ $form = $form + $field_form;
1117
+
1118
+ // Open control div
1119
+ $form[$key . '_control_open'] = array(
1120
+ '#type' => 'markup',
1121
+ '#markup' => '<div class="wpcf-repetitive-control">'
1122
+ );
1123
+
1124
+ // Drag button
1125
+ $form[$key . '_drag_button'] = array(
1126
+ '#type' => 'markup',
1127
+ '#markup' => wpcf_repetitive_drag_button( $this->cf, $this->post ),
1128
+ );
1129
+
1130
+ // 'Delete' button
1131
+ $form[$key . '_delete_button'] = array(
1132
+ '#type' => 'markup',
1133
+ '#markup' => wpcf_repetitive_delete_button( $this->cf, $this->post,
1134
+ $meta_id ),
1135
+ );
1136
+
1137
+ // Close control div
1138
+ $form[$key . '_control_close'] = array(
1139
+ '#type' => 'markup',
1140
+ '#markup' => '</div>',
1141
+ );
1142
+
1143
+ // Close drag div
1144
+ $form[$key . '_drag_close'] = array(
1145
+ '#type' => 'markup',
1146
+ '#markup' => '</div>',
1147
+ );
1148
+
1149
+ // Count it and set JS var
1150
+ $this->_set_form_count();
1151
+ wpcf_admin_add_js_settings( 'wpcf_repetitive_count_' . md5( $this->cf['id'] ),
1152
+ $this->index );
1153
+
1154
+ return $form;
1155
+ }
1156
+
1157
+ /**
1158
+ * Set counting elements.
1159
+ */
1160
+ function _set_form_count() {
1161
+ if ( $this->index === 0 ) {
1162
+ if ( defined( 'DOING_AJAX' ) && isset( $_POST['count'] ) ) {
1163
+ $this->index = intval( $_POST['count'] );
1164
+ }
1165
+ }
1166
+ $this->index += 1;
1167
+ }
1168
+
1169
+ /**
1170
+ * Deletes meta.
1171
+ *
1172
+ * @global object $wpdb
1173
+ *
1174
+ * @param type $meta_key
1175
+ *
1176
+ */
1177
+ function delete( $meta_id ) {
1178
+ global $wpdb;
1179
+ $r = $wpdb->query(
1180
+ $wpdb->prepare(
1181
+ "DELETE FROM {$wpdb->termmeta}
1182
+ WHERE term_id = %d
1183
+ AND meta_id = %d",
1184
+ $this->term_id, intval( $meta_id )
1185
+ )
1186
+ );
1187
+ if ( $r === false ) {
1188
+ return WP_Error( 'wpcf_repeater_delete_field',
1189
+ 'Repeater failed deleting term ID: '
1190
+ . $this->term_id . '; meta_ID: ' . intval( $meta_id ) );
1191
+ }
1192
+ return $r;
1193
+ }
1194
+
1195
+ }
1196
+
embedded/classes/usermeta_field.php CHANGED
@@ -9,12 +9,14 @@
9
  class WPCF_Usermeta_Field extends WPCF_Field
10
  {
11
 
12
- /**
13
- * Set current post and field.
14
- *
15
- * @param type $post
16
- * @param type $cf
17
- */
 
 
18
  function set( $user_id, $cf ) {
19
 
20
  global $wpcf;
9
  class WPCF_Usermeta_Field extends WPCF_Field
10
  {
11
 
12
+ /**
13
+ * Set current post and field.
14
+ *
15
+ * @param int $user_id
16
+ * @param type $cf
17
+ *
18
+ * @return bool
19
+ */
20
  function set( $user_id, $cf ) {
21
 
22
  global $wpcf;
embedded/classes/utils.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class of helper functions that don't fit anywhere else.
5
+ */
6
+ final class WPCF_Utils {
7
+
8
+
9
+ /**
10
+ * Shortcut method for retrieving public built-in taxonomies.
11
+ *
12
+ * @param string $output_mode 'objects'|'names'
13
+ *
14
+ * @return object[] Array of taxonomy objects or names.
15
+ */
16
+ static function get_builtin_taxonomies( $output_mode = 'objects' ) {
17
+ // todo add simple caching
18
+ return get_taxonomies( array( 'public' => true, '_builtin' => true ), $output_mode );
19
+ }
20
+
21
+
22
+ /**
23
+ * Get a definitive set of all taxonomies recognized by Types.
24
+ *
25
+ * Respects if some builtin taxonomy is overridden by Types.
26
+ *
27
+ * @return array
28
+ */
29
+ static function get_all_taxonomies() {
30
+ // todo add simple caching
31
+ $taxonomies = array();
32
+
33
+ // Read custom taxonomies first.
34
+ $custom_taxonomies = get_option( WPCF_OPTION_NAME_CUSTOM_TAXONOMIES, array() );
35
+ if ( is_array( $custom_taxonomies ) ) {
36
+ foreach ( $custom_taxonomies as $slug => $data ) {
37
+ $taxonomies[ $slug ] = $data;
38
+ }
39
+ }
40
+
41
+ // Get built-in taxonomies and add them to the set, but avoid overwriting custom taxonomies
42
+ $builtin_taxonomies = self::object_to_array_deep( self::get_builtin_taxonomies() );
43
+ foreach ( $builtin_taxonomies as $slug => $data ) {
44
+ // check if built-in taxonomies are already saved as custom taxonomies
45
+ if ( isset( $taxonomies[ $slug ] ) ) {
46
+ continue;
47
+ }
48
+
49
+ if ( ! isset( $data['slug'] ) ) {
50
+ $data['slug'] = $slug;
51
+ }
52
+
53
+ $taxonomies[ $slug ] = $data;
54
+ }
55
+
56
+ return $taxonomies;
57
+ }
58
+
59
+
60
+ /**
61
+ * Transform an object and all it's fields recursively into an associative array. If any object's field is
62
+ * an array, individual elements of the array will be transformed as well.
63
+ *
64
+ * @param object|array $object The object or array of objects to transform.
65
+ * @return array
66
+ */
67
+ static function object_to_array_deep( $object ) {
68
+ if ( is_array( $object ) || is_object( $object ) ) {
69
+ $result = array();
70
+ foreach ( $object as $key => $value ) {
71
+ $result[ $key ] = self::object_to_array_deep( $value );
72
+ }
73
+
74
+ return $result;
75
+ }
76
+
77
+ return $object;
78
+ }
79
+
80
+
81
+ /**
82
+ * Try to convert a taxonomy slug to a label.
83
+ *
84
+ * @param string $slug Taxonomy slug.
85
+ * @param string $label_name One of the available labels of the taxonomy.
86
+ *
87
+ * @link https://codex.wordpress.org/Function_Reference/get_taxonomies Taxonomy object description.
88
+ *
89
+ * @return string Selected taxonomy label or slug if the label was not found.
90
+ */
91
+ static function taxonomy_slug_to_label( $slug, $label_name = 'name' ) {
92
+ $all_taxonomies = self::get_all_taxonomies();
93
+
94
+ $taxonomy_display_name = wpcf_getnest( $all_taxonomies, array( $slug, 'labels', $label_name ), $slug );
95
+
96
+ return $taxonomy_display_name;
97
+ }
98
+
99
+
100
+ /**
101
+ * Check if searched string is a substring of the value.
102
+ *
103
+ * @param string $search_string
104
+ * @param string $value
105
+ * @return bool
106
+ */
107
+ static function is_string_match( $search_string, $value ) {
108
+ return ( false !== strpos( mb_strtolower( $value ), mb_strtolower( trim( $search_string ) ) ) );
109
+ }
110
+
111
+ }
embedded/classes/validate.php CHANGED
@@ -1,463 +1,6 @@
1
  <?php
2
- require_once dirname( __FILE__ ) . '/validation-cakephp.php';
3
-
4
  /**
5
- * Validation class
6
- *
7
- * @version 1.0
8
  */
9
- class Wpcf_Validate
10
- {
11
-
12
- /**
13
- * Holds generic messages.
14
- * @var type
15
- */
16
- public static $messages = null;
17
-
18
- /**
19
- * Holds function names.
20
- * @var type
21
- */
22
- private static $_cake_aliases = array(
23
- 'digits' => 'numeric',
24
- 'number' => 'numeric',
25
- 'alphanumeric' => 'alphaNumericWhitespaces',
26
- 'nospecialchars' => 'noSpecialChars',
27
- 'maxlength' => 'maxLength',
28
- );
29
-
30
- /**
31
- * Current validation has 'required' method.
32
- * @var type
33
- */
34
- private static $_is_required = false;
35
- private static $_validation_object = null;
36
-
37
- /**
38
- * Sets calls.
39
- *
40
- * @param type $args
41
- * @param type $value
42
- * @return type
43
- */
44
- public static function check( $args, $value )
45
- {
46
- // Init validation object
47
- if ( is_null( self::$_validation_object ) ) {
48
- self::$_validation_object = new Wpcf_Cake_Validation();
49
- }
50
- // Check if there is 'required' method
51
- if ( array_key_exists( 'required', $args ) ) {
52
- self::$_is_required = true;
53
- }
54
-
55
- // Loop over validation array
56
- foreach ( $args as $method => $v ) {
57
- // Use this class method
58
- if ( is_callable( array('Wpcf_Validate', $method) ) ) {
59
- $check = call_user_func_array( array('Wpcf_Validate', $method),
60
- array($v, $value) );
61
- // Use CakePHP method
62
- } else if ( (isset( self::$_cake_aliases[$method] )
63
- && is_callable( array('Wpcf_Cake_Validation', self::$_cake_aliases[$method]) ))
64
- || is_callable( array('Wpcf_Cake_Validation', $method) ) ) {
65
-
66
- // Check if validation pattern is set
67
- if ( isset( $v['pattern'] ) ) {
68
- $pattern = array_flip( explode( '.', $v['pattern'] ) );
69
- foreach ( $pattern as $arg_key => $arg_value ) {
70
- if ( isset( $v[$arg_key] ) ) {
71
- $pattern[$arg_key] = $v[$arg_key];
72
- }
73
- }
74
- $pattern['check'] = $value;
75
- $v = $pattern;
76
- // Apply simple pattern (check, value)
77
- } else {
78
- unset( $v['active'], $v['message'] );
79
- $v = array($value) + $v;
80
- }
81
-
82
- // Validate
83
- if ( isset( self::$_cake_aliases[$method] ) && is_callable( array('Wpcf_Cake_Validation', self::$_cake_aliases[$method]) ) ) {
84
- // $check = @call_user_func_array(array('Wpcf_Cake_Validation', self::$_cake_aliases[$method]),
85
- // array_values($v));
86
- $check = @call_user_func_array( array(self::$_validation_object, self::$_cake_aliases[$method]),
87
- array_values( $v ) );
88
- } else {
89
- // $check = @call_user_func_array(array('Wpcf_Cake_Validation', $method),
90
- // array_values($v));
91
- $check = @call_user_func_array( array(self::$_validation_object, $method),
92
- array_values( $v ) );
93
- }
94
- if ( !$check ) {
95
- $check = array();
96
- $check['error'] = 1;
97
- }
98
- // No method available
99
- } else {
100
- return array('error' => 1, 'message' => 'No validation method');
101
- }
102
-
103
- // Set error
104
- if ( isset( $check['error'] ) ) {
105
- // Don't return error if it's empty but not required
106
- if ( (!empty( $value ) && $method != 'required' && self::$_is_required)
107
- || (empty( $value ) && $method == 'required') ) {
108
- $sprintf = isset($v['value']) ? $v['value'] : '';
109
- $check['message'] = !empty( $v['message'] ) ? $v['message'] : self::get_message($method, $sprintf);
110
- return $check;
111
- }
112
- }
113
- }
114
-
115
- return true;
116
- }
117
-
118
- /**
119
- * Checks if method is available.
120
- *
121
- * @param type $method
122
- * @return type
123
- */
124
- public static function canValidate( $method )
125
- {
126
- return (is_callable( array('Wpcf_Validate', $method) )
127
- || (isset( self::$_cake_aliases[$method] )
128
- && is_callable( array('Wpcf_Cake_Validation', self::$_cake_aliases[$method]) ))
129
- || is_callable( array('Wpcf_Cake_Validation', $method) ));
130
- }
131
-
132
- /**
133
- * Checks if method has form data.
134
- *
135
- * @param type $method
136
- * @return type
137
- */
138
- public static function hasForm( $method )
139
- {
140
- return is_callable( array('Wpcf_Validate', $method . '_form') );
141
- }
142
-
143
- /**
144
- * Inits messages.
145
- */
146
- private static function _set_messages()
147
- {
148
- // Set outside in /admin.php
149
- self::$messages = wpcf_admin_validation_messages();
150
- }
151
-
152
- /**
153
- * Return method invalid message.
154
- *
155
- * @param type $method
156
- * @return type
157
- */
158
- public static function get_message( $method, $sprintf = '' )
159
- {
160
- return wpcf_admin_validation_messages($method, $sprintf);
161
- if ( is_null( self::$messages ) ) {
162
- self::_set_messages();
163
- }
164
- if ( isset( self::$messages[$method] ) ) {
165
- return self::$messages[$method];
166
- }
167
- return null;
168
- }
169
-
170
- /**
171
- * Checks 'required'.
172
- *
173
- * @param type $args
174
- * @param type $value
175
- * @return type
176
- */
177
- public static function required( $args, $value )
178
- {
179
- if ( empty( $value ) && $value !== 0 && $value !== '0' ) {
180
- return array(
181
- 'error' => 1,
182
- );
183
- }
184
- return true;
185
- }
186
-
187
- /**
188
- * Returns form data.
189
- *
190
- * @param type $field
191
- * @param type $data
192
- * @return array
193
- */
194
- public static function required_form( $field, $data = array() )
195
- {
196
- $form = array();
197
- $form['required-checkbox'] = array(
198
- '#type' => 'checkbox',
199
- '#title' => __( 'Required', 'wpcf' ),
200
- '#name' => $field['#name'] . '[active]',
201
- '#default_value' => isset( $data['active'] ) ? 1 : 0,
202
- '#inline' => true,
203
- '#suffix' => '<br />',
204
- );
205
- $form['required-value'] = array(
206
- '#type' => 'hidden',
207
- '#value' => 'true',
208
- '#name' => $field['#name'] . '[value]',
209
- );
210
- $form['required-message'] = self::get_custom_message( $field,
211
- self::get_message( 'required' ), $data );
212
- return $form;
213
- }
214
-
215
- /**
216
- * Checks 'email'.
217
- *
218
- * @param type $args
219
- * @param type $value
220
- * @return type
221
- */
222
- public static function email( $args, $value )
223
- {
224
- if ( !is_email( $value ) ) {
225
- return array(
226
- 'error' => 1,
227
- );
228
- }
229
- return true;
230
- }
231
-
232
- /**
233
- * Checks 'rewriteslug'.
234
- *
235
- * @param type $args
236
- * @param type $value
237
- * @return type
238
- */
239
- public static function rewriteslug( $args, $value )
240
- {
241
- if ( preg_match( '#[^a-zA-Z0-9\/\_\-\%]#', $value ) === false ) {
242
- return array(
243
- 'error' => 1,
244
- );
245
- }
246
- return true;
247
- }
248
-
249
- public static function skype( $args, $value )
250
- {
251
- return true;
252
- }
253
-
254
- /**
255
- * Returns form data.
256
- *
257
- * @param type $field
258
- * @param type $data
259
- * @return array
260
- */
261
- public static function email_form( $field, $data = array() )
262
- {
263
- $form = array();
264
- $form['email-checkbox'] = array(
265
- '#type' => 'checkbox',
266
- '#title' => __( 'Email', 'wpcf' ),
267
- '#name' => $field['#name'] . '[active]',
268
- '#default_value' => isset( $data['active'] ) ? 1 : 0,
269
- '#inline' => true,
270
- '#suffix' => '<br />',
271
- );
272
-
273
- $form['email-message'] = self::get_custom_message( $field,
274
- self::get_message( 'email' ), $data );
275
- return $form;
276
- }
277
-
278
- /**
279
- * Returns form data.
280
- *
281
- * @param type $field
282
- * @param type $data
283
- * @return array
284
- */
285
- public static function url_form( $field, $data = array() )
286
- {
287
- $form = array();
288
- $form['url-checkbox'] = array(
289
- '#type' => 'checkbox',
290
- '#title' => 'URL',
291
- '#name' => $field['#name'] . '[active]',
292
- '#default_value' => isset( $data['active'] ) ? 1 : 0,
293
- '#inline' => true,
294
- '#suffix' => '<br />',
295
- );
296
-
297
- $form['url-checkbox'] = self::setForced( $form['url-checkbox'],
298
- $field, $data );
299
-
300
- $form['url-message'] = self::get_custom_message( $field,
301
- self::get_message( 'url' ), $data );
302
- return $form;
303
- }
304
-
305
- /**
306
- * Returns form data.
307
- *
308
- * @param type $field
309
- * @param type $data
310
- * @return array
311
- */
312
- public static function date_form( $field, $data = array() )
313
- {
314
- $form = array();
315
- $form['date-checkbox'] = array(
316
- '#type' => 'checkbox',
317
- '#title' => __( 'Date', 'wpcf' ),
318
- '#name' => $field['#name'] . '[active]',
319
- '#default_value' => isset( $data['active'] ) ? 1 : 0,
320
- '#inline' => true,
321
- '#suffix' => '<br />',
322
- );
323
- $form['date-format'] = array(
324
- '#type' => 'hidden',
325
- '#value' => 'mdy',
326
- '#name' => $field['#name'] . '[format]',
327
- );
328
- $form['date-pattern'] = array(
329
- '#type' => 'hidden',
330
- '#value' => 'check.format',
331
- '#name' => $field['#name'] . '[pattern]',
332
- );
333
- $form['url-message'] = self::get_custom_message( $field,
334
- self::get_message( 'date' ), $data );
335
- return $form;
336
- }
337
-
338
- /**
339
- * Returns form data.
340
- *
341
- * @param type $field
342
- * @param type $data
343
- * @return array
344
- */
345
- public static function digits_form( $field, $data = array() )
346
- {
347
- $form = array();
348
- $attributes = array();
349
- $default_value = isset( $data['active'] ) ? 1 : 0;
350
- $form['digits-checkbox'] = array(
351
- '#type' => 'checkbox',
352
- '#title' => __( 'Digits', 'wpcf' ),
353
- '#name' => $field['#name'] . '[active]',
354
- '#default_value' => $default_value,
355
- '#inline' => true,
356
- '#suffix' => '<br />',
357
- '#attributes' => $attributes,
358
- );
359
- $form['digits-checkbox'] = self::setForced( $form['digits-checkbox'],
360
- $field, $data );
361
-
362
- $form['digits-message'] = self::get_custom_message( $field,
363
- self::get_message( 'digits' ), $data );
364
- return $form;
365
- }
366
-
367
- /**
368
- * Returns form data.
369
- *
370
- * @param type $field
371
- * @param type $data
372
- * @return array
373
- */
374
- public static function number_form( $field, $data = array() )
375
- {
376
- $form = array();
377
- $attributes = array();
378
- $default_value = isset( $data['active'] ) ? 1 : 0;
379
- $form['number-checkbox'] = array(
380
- '#type' => 'checkbox',
381
- '#title' => __( 'Numeric', 'wpcf' ),
382
- '#name' => $field['#name'] . '[active]',
383
- '#default_value' => $default_value,
384
- '#inline' => true,
385
- '#suffix' => '<br />',
386
- '#attributes' => $attributes,
387
- );
388
- $form['number-checkbox'] = self::setForced( $form['number-checkbox'],
389
- $field, $data );
390
-
391
- $form['number-message'] = self::get_custom_message( $field,
392
- self::get_message( 'number' ), $data );
393
- return $form;
394
- }
395
-
396
- /**
397
- * Returns form data.
398
- *
399
- * @param type $field
400
- * @param type $data
401
- * @return array
402
- */
403
- public static function skype_form( $field, $data = array() )
404
- {
405
- $form = array();
406
- $form['skype-checkbox'] = array(
407
- '#type' => 'checkbox',
408
- '#title' => 'Skype',
409
- '#name' => $field['#name'] . '[active]',
410
- '#default_value' => isset( $data['active'] ) ? 1 : 0,
411
- '#inline' => true,
412
- '#suffix' => '<br />',
413
- );
414
- $form['skype-checkbox'] = self::setForced( $form['skype-checkbox'], $field, $data );
415
- $form['skype-message'] = self::get_custom_message( $field, self::get_message( 'skype' ), $data );
416
- return $form;
417
- }
418
-
419
- public static function setForced( $element, $field, $data = array() )
420
- {
421
- $attributes = array();
422
- $default_value = isset( $data['active'] ) ? 1 : 0;
423
- if ( !empty( $data['method_data']['forced'] ) ) {
424
- if ( !isset( $element['#attributes'] ) ) {
425
- $element['#attributes'] = array();
426
- }
427
- $element['#attributes']['readonly'] = 'readonly';
428
- $element['#attributes']['onclick'] = 'jQuery(this).attr(\'checked\', \'checked\');';
429
- $element['#default_value'] = 1;
430
- }
431
- return $element;
432
- }
433
-
434
- /**
435
- * Returns 'custom message' field.
436
- *
437
- * @param type $field
438
- * @param type $default
439
- * @param type $data
440
- * @return type
441
- */
442
- public static function get_custom_message( $field, $default, $data )
443
- {
444
- return array(
445
- '#type' => 'textfield',
446
- // '#title' => __('Custom message', 'wpcf'),
447
- '#name' => $field['#name'] . '[message]',
448
- '#value' => !empty( $data['message'] ) ? $data['message'] : $default,
449
- '#inline' => true,
450
- // '#suffix' => '<br /><br />',
451
- );
452
- }
453
-
454
- public static function negativeTimestamp( $args, $value ) {
455
- if ( !fields_date_timestamp_neg_supported() && intval( $value ) < 0 ) {
456
- return array(
457
- 'error' => 1,
458
- );
459
- }
460
- return true;
461
- }
462
-
463
- }
1
  <?php
 
 
2
  /**
3
+ * moved to toolset-common
4
+ * ../toolset/toolset-common/classes/validate.php
 
5
  */
6
+ require_once dirname( __FILE__ ) . '/../toolset/toolset-common/classes/validate.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/WPML/wpml-string-shortcode.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- /** provide default implementation of [wpml-string] shortcode for when
3
- * wpml plugin is not active.
4
- */
5
-
6
- if (!isset($wpml_string_sub_active)) {
7
-
8
- add_action('init', 'stub_wpml_add_shortcode', 100);
9
-
10
- $wpml_string_sub_active = true;
11
-
12
- if( !function_exists('stub_wpml_add_shortcode') )
13
- {
14
- function stub_wpml_add_shortcode() {
15
- global $WPML_String_Translation;
16
-
17
- if (!isset($WPML_String_Translation)) {
18
- // WPML string translation is not active
19
- // Add our own do nothing shortcode
20
-
21
- add_shortcode('wpml-string', 'stub_wpml_string_shortcode');
22
-
23
- }
24
- }
25
- }
26
-
27
- if( !function_exists('stub_wpml_string_shortcode') )
28
- {
29
- function stub_wpml_string_shortcode($atts, $value) {
30
- // return un-processed.
31
- return do_shortcode($value);
32
- }
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/Zip.php DELETED
@@ -1,861 +0,0 @@
1
- <?php
2
- /**
3
- * Class to create and manage a Zip file.
4
- *
5
- * Initially inspired by CreateZipFile by Rochak Chauhan www.rochakchauhan.com (http://www.phpclasses.org/browse/package/2322.html)
6
- * and
7
- * http://www.pkware.com/documents/casestudies/APPNOTE.TXT Zip file specification.
8
- *
9
- * License: GNU LGPL 2.1.
10
- *
11
- * @author A. Grandt <php@grandt.com>
12
- * @copyright 2009-2014 A. Grandt
13
- * @license GNU LGPL 2.1
14
- * @link http://www.phpclasses.org/package/6110
15
- * @link https://github.com/Grandt/PHPZip
16
- * @version 1.62
17
- */
18
- class Zip {
19
- const VERSION = 1.62;
20
-
21
- const ZIP_LOCAL_FILE_HEADER = "\x50\x4b\x03\x04"; // Local file header signature
22
- const ZIP_CENTRAL_FILE_HEADER = "\x50\x4b\x01\x02"; // Central file header signature
23
- const ZIP_END_OF_CENTRAL_DIRECTORY = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
24
-
25
- const EXT_FILE_ATTR_DIR = 010173200020; // Permission 755 drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D);
26
- const EXT_FILE_ATTR_FILE = 020151000040; // Permission 644 -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A);
27
-
28
- const ATTR_VERSION_TO_EXTRACT = "\x14\x00"; // Version needed to extract
29
- const ATTR_MADE_BY_VERSION = "\x1E\x03"; // Made By Version
30
-
31
- // UID 1000, GID 0
32
- const EXTRA_FIELD_NEW_UNIX_GUID = "\x75\x78\x0B\x00\x01\x04\xE8\x03\x00\x00\x04\x00\x00\x00\x00";
33
-
34
- // Unix file types
35
- const S_IFIFO = 0010000; // named pipe (fifo)
36
- const S_IFCHR = 0020000; // character special
37
- const S_IFDIR = 0040000; // directory
38
- const S_IFBLK = 0060000; // block special
39
- const S_IFREG = 0100000; // regular
40
- const S_IFLNK = 0120000; // symbolic link
41
- const S_IFSOCK = 0140000; // socket
42
-
43
- // setuid/setgid/sticky bits, the same as for chmod:
44
-
45
- const S_ISUID = 0004000; // set user id on execution
46
- const S_ISGID = 0002000; // set group id on execution
47
- const S_ISTXT = 0001000; // sticky bit
48
-
49
- // And of course, the other 12 bits are for the permissions, the same as for chmod:
50
- // When addding these up, you can also just write the permissions as a simgle octal number
51
- // ie. 0755. The leading 0 specifies octal notation.
52
- const S_IRWXU = 0000700; // RWX mask for owner
53
- const S_IRUSR = 0000400; // R for owner
54
- const S_IWUSR = 0000200; // W for owner
55
- const S_IXUSR = 0000100; // X for owner
56
- const S_IRWXG = 0000070; // RWX mask for group
57
- const S_IRGRP = 0000040; // R for group
58
- const S_IWGRP = 0000020; // W for group
59
- const S_IXGRP = 0000010; // X for group
60
- const S_IRWXO = 0000007; // RWX mask for other
61
- const S_IROTH = 0000004; // R for other
62
- const S_IWOTH = 0000002; // W for other
63
- const S_IXOTH = 0000001; // X for other
64
- const S_ISVTX = 0001000; // save swapped text even after use
65
-
66
- // Filetype, sticky and permissions are added up, and shifted 16 bits left BEFORE adding the DOS flags.
67
-
68
- // DOS file type flags, we really only use the S_DOS_D flag.
69
-
70
- const S_DOS_A = 0000040; // DOS flag for Archive
71
- const S_DOS_D = 0000020; // DOS flag for Directory
72
- const S_DOS_V = 0000010; // DOS flag for Volume
73
- const S_DOS_S = 0000004; // DOS flag for System
74
- const S_DOS_H = 0000002; // DOS flag for Hidden
75
- const S_DOS_R = 0000001; // DOS flag for Read Only
76
-
77
- private $zipMemoryThreshold = 1048576; // Autocreate tempfile if the zip data exceeds 1048576 bytes (1 MB)
78
-
79
- private $zipData = NULL;
80
- private $zipFile = NULL;
81
- private $zipComment = NULL;
82
- private $cdRec = array(); // central directory
83
- private $offset = 0;
84
- private $isFinalized = FALSE;
85
- private $addExtraField = TRUE;
86
-
87
- private $streamChunkSize = 65536;
88
- private $streamFilePath = NULL;
89
- private $streamTimestamp = NULL;
90
- private $streamFileComment = NULL;
91
- private $streamFile = NULL;
92
- private $streamData = NULL;
93
- private $streamFileLength = 0;
94
- private $streamExtFileAttr = null;
95
- /**
96
- * A custom temporary folder, or a callable that returns a custom temporary file.
97
- * @var string|callable
98
- */
99
- public static $temp = null;
100
-
101
- /**
102
- * Constructor.
103
- *
104
- * @param boolean $useZipFile Write temp zip data to tempFile? Default FALSE
105
- */
106
- function __construct($useZipFile = FALSE) {
107
- if ($useZipFile) {
108
- $this->zipFile = tmpfile();
109
- } else {
110
- $this->zipData = "";
111
- }
112
- }
113
-
114
- function __destruct() {
115
- if (is_resource($this->zipFile)) {
116
- fclose($this->zipFile);
117
- }
118
- $this->zipData = NULL;
119
- }
120
-
121
- /**
122
- * Extra fields on the Zip directory records are Unix time codes needed for compatibility on the default Mac zip archive tool.
123
- * These are enabled as default, as they do no harm elsewhere and only add 26 bytes per file added.
124
- *
125
- * @param bool $setExtraField TRUE (default) will enable adding of extra fields, anything else will disable it.
126
- */
127
- function setExtraField($setExtraField = TRUE) {
128
- $this->addExtraField = ($setExtraField === TRUE);
129
- }
130
-
131
- /**
132
- * Set Zip archive comment.
133
- *
134
- * @param string $newComment New comment. NULL to clear.
135
- * @return bool $success
136
- */
137
- public function setComment($newComment = NULL) {
138
- if ($this->isFinalized) {
139
- return FALSE;
140
- }
141
- $this->zipComment = $newComment;
142
-
143
- return TRUE;
144
- }
145
-
146
- /**
147
- * Set zip file to write zip data to.
148
- * This will cause all present and future data written to this class to be written to this file.
149
- * This can be used at any time, even after the Zip Archive have been finalized. Any previous file will be closed.
150
- * Warning: If the given file already exists, it will be overwritten.
151
- *
152
- * @param string $fileName
153
- * @return bool $success
154
- */
155
- public function setZipFile($fileName) {
156
- if (is_file($fileName)) {
157
- unlink($fileName);
158
- }
159
- $fd=fopen($fileName, "x+b");
160
- if (is_resource($this->zipFile)) {
161
- rewind($this->zipFile);
162
- while (!feof($this->zipFile)) {
163
- fwrite($fd, fread($this->zipFile, $this->streamChunkSize));
164
- }
165
-
166
- fclose($this->zipFile);
167
- } else {
168
- fwrite($fd, $this->zipData);
169
- $this->zipData = NULL;
170
- }
171
- $this->zipFile = $fd;
172
-
173
- return TRUE;
174
- }
175
-
176
- /**
177
- * Add an empty directory entry to the zip archive.
178
- * Basically this is only used if an empty directory is added.
179
- *
180
- * @param string $directoryPath Directory Path and name to be added to the archive.
181
- * @param int $timestamp (Optional) Timestamp for the added directory, if omitted or set to 0, the current time will be used.
182
- * @param string $fileComment (Optional) Comment to be added to the archive for this directory. To use fileComment, timestamp must be given.
183
- * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
184
- * @return bool $success
185
- */
186
- public function addDirectory($directoryPath, $timestamp = 0, $fileComment = NULL, $extFileAttr = self::EXT_FILE_ATTR_DIR) {
187
- if ($this->isFinalized) {
188
- return FALSE;
189
- }
190
- $directoryPath = str_replace("\\", "/", $directoryPath);
191
- $directoryPath = rtrim($directoryPath, "/");
192
-
193
- if (strlen($directoryPath) > 0) {
194
- $this->buildZipEntry($directoryPath.'/', $fileComment, "\x00\x00", "\x00\x00", $timestamp, "\x00\x00\x00\x00", 0, 0, $extFileAttr);
195
- return TRUE;
196
- }
197
- return FALSE;
198
- }
199
-
200
- /**
201
- * Add a file to the archive at the specified location and file name.
202
- *
203
- * @param string $data File data.
204
- * @param string $filePath Filepath and name to be used in the archive.
205
- * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
206
- * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given.
207
- * @param bool $compress (Optional) Compress file, if set to FALSE the file will only be stored. Default TRUE.
208
- * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
209
- * @return bool $success
210
- */
211
- public function addFile($data, $filePath, $timestamp = 0, $fileComment = NULL, $compress = TRUE, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
212
- if ($this->isFinalized) {
213
- return FALSE;
214
- }
215
-
216
- if (is_resource($data) && get_resource_type($data) == "stream") {
217
- $this->addLargeFile($data, $filePath, $timestamp, $fileComment, $extFileAttr);
218
- return FALSE;
219
- }
220
-
221
- $gzData = "";
222
- $gzType = "\x08\x00"; // Compression type 8 = deflate
223
- $gpFlags = "\x00\x00"; // General Purpose bit flags for compression type 8 it is: 0=Normal, 1=Maximum, 2=Fast, 3=super fast compression.
224
- $dataLength = strlen($data);
225
- $fileCRC32 = pack("V", crc32($data));
226
-
227
- if ($compress) {
228
- $gzTmp = gzcompress($data);
229
- $gzData = substr(substr($gzTmp, 0, strlen($gzTmp) - 4), 2); // gzcompress adds a 2 byte header and 4 byte CRC we can't use.
230
- // The 2 byte header does contain useful data, though in this case the 2 parameters we'd be interrested in will always be 8 for compression type, and 2 for General purpose flag.
231
- $gzLength = strlen($gzData);
232
- } else {
233
- $gzLength = $dataLength;
234
- }
235
-
236
- if ($gzLength >= $dataLength) {
237
- $gzLength = $dataLength;
238
- $gzData = $data;
239
- $gzType = "\x00\x00"; // Compression type 0 = stored
240
- $gpFlags = "\x00\x00"; // Compression type 0 = stored
241
- }
242
-
243
- if (!is_resource($this->zipFile) && ($this->offset + $gzLength) > $this->zipMemoryThreshold) {
244
- $this->zipflush();
245
- }
246
-
247
- $this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr);
248
-
249
- $this->zipwrite($gzData);
250
-
251
- return TRUE;
252
- }
253
-
254
- /**
255
- * Add the content to a directory.
256
- *
257
- * @author Adam Schmalhofer <Adam.Schmalhofer@gmx.de>
258
- * @author A. Grandt
259
- *
260
- * @param string $realPath Path on the file system.
261
- * @param string $zipPath Filepath and name to be used in the archive.
262
- * @param bool $recursive Add content recursively, default is TRUE.
263
- * @param bool $followSymlinks Follow and add symbolic links, if they are accessible, default is TRUE.
264
- * @param array &$addedFiles Reference to the added files, this is used to prevent duplicates, efault is an empty array.
265
- * If you start the function by parsing an array, the array will be populated with the realPath
266
- * and zipPath kay/value pairs added to the archive by the function.
267
- * @param bool $overrideFilePermissions Force the use of the file/dir permissions set in the $extDirAttr
268
- * and $extFileAttr parameters.
269
- * @param int $extDirAttr Permissions for directories.
270
- * @param int $extFileAttr Permissions for files.
271
- */
272
- public function addDirectoryContent($realPath, $zipPath, $recursive = TRUE, $followSymlinks = TRUE, &$addedFiles = array(),
273
- $overrideFilePermissions = FALSE, $extDirAttr = self::EXT_FILE_ATTR_DIR, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
274
- if (file_exists($realPath) && !isset($addedFiles[realpath($realPath)])) {
275
- if (is_dir($realPath)) {
276
- if ($overrideFilePermissions) {
277
- $this->addDirectory($zipPath, 0, null, $extDirAttr);
278
- } else {
279
- $this->addDirectory($zipPath, 0, null, self::getFileExtAttr($realPath));
280
- }
281
- }
282
-
283
- $addedFiles[realpath($realPath)] = $zipPath;
284
-
285
- $iter = new DirectoryIterator($realPath);
286
- foreach ($iter as $file) {
287
- if ($file->isDot()) {
288
- continue;
289
- }
290
- $newRealPath = $file->getPathname();
291
- $newZipPath = self::pathJoin($zipPath, $file->getFilename());
292
-
293
- if (file_exists($newRealPath) && ($followSymlinks === TRUE || !is_link($newRealPath))) {
294
- if ($file->isFile()) {
295
- $addedFiles[realpath($newRealPath)] = $newZipPath;
296
- if ($overrideFilePermissions) {
297
- $this->addLargeFile($newRealPath, $newZipPath, 0, null, $extFileAttr);
298
- } else {
299
- $this->addLargeFile($newRealPath, $newZipPath, 0, null, self::getFileExtAttr($newRealPath));
300
- }
301
- } else if ($recursive === TRUE) {
302
- $this->addDirectoryContent($newRealPath, $newZipPath, $recursive, $followSymlinks, $addedFiles, $overrideFilePermissions, $extDirAttr, $extFileAttr);
303
- } else {
304
- if ($overrideFilePermissions) {
305
- $this->addDirectory($zipPath, 0, null, $extDirAttr);
306
- } else {
307
- $this->addDirectory($zipPath, 0, null, self::getFileExtAttr($newRealPath));
308
- }
309
- }
310
- }
311
- }
312
- }
313
- }
314
-
315
- /**
316
- * Add a file to the archive at the specified location and file name.
317
- *
318
- * @param string $dataFile File name/path.
319
- * @param string $filePath Filepath and name to be used in the archive.
320
- * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
321
- * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given.
322
- * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
323
- * @return bool $success
324
- */
325
- public function addLargeFile($dataFile, $filePath, $timestamp = 0, $fileComment = NULL, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
326
- if ($this->isFinalized) {
327
- return FALSE;
328
- }
329
-
330
- if (is_string($dataFile) && is_file($dataFile)) {
331
- $this->processFile($dataFile, $filePath, $timestamp, $fileComment, $extFileAttr);
332
- } else if (is_resource($dataFile) && get_resource_type($dataFile) == "stream") {
333
- $fh = $dataFile;
334
- $this->openStream($filePath, $timestamp, $fileComment, $extFileAttr);
335
-
336
- while (!feof($fh)) {
337
- $this->addStreamData(fread($fh, $this->streamChunkSize));
338
- }
339
- $this->closeStream($this->addExtraField);
340
- }
341
- return TRUE;
342
- }
343
-
344
- /**
345
- * Create a stream to be used for large entries.
346
- *
347
- * @param string $filePath Filepath and name to be used in the archive.
348
- * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
349
- * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given.
350
- * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this.
351
- * @throws Exception Throws an exception in case of errors
352
- * @return bool $success
353
- */
354
- public function openStream($filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
355
- if (!function_exists('sys_get_temp_dir')) {
356
- throw new Exception("Zip " . self::VERSION . " requires PHP version 5.2.1 or above if large files are used.");
357
- }
358
-
359
- if ($this->isFinalized) {
360
- return FALSE;
361
- }
362
-
363
- $this->zipflush();
364
-
365
- if (strlen($this->streamFilePath) > 0) {
366
- $this->closeStream();
367
- }
368
-
369
- $this->streamFile = self::getTemporaryFile();
370
- $this->streamData = fopen($this->streamFile, "wb");
371
- $this->streamFilePath = $filePath;
372
- $this->streamTimestamp = $timestamp;
373
- $this->streamFileComment = $fileComment;
374
- $this->streamFileLength = 0;
375
- $this->streamExtFileAttr = $extFileAttr;
376
-
377
- return TRUE;
378
- }
379
-
380
- /**
381
- * Add data to the open stream.
382
- *
383
- * @param string $data
384
- * @throws Exception Throws an exception in case of errors
385
- * @return mixed length in bytes added or FALSE if the archive is finalized or there are no open stream.
386
- */
387
- public function addStreamData($data) {
388
- if ($this->isFinalized || strlen($this->streamFilePath) == 0) {
389
- return FALSE;
390
- }
391
-
392
- $length = fwrite($this->streamData, $data, strlen($data));
393
- if ($length != strlen($data)) {
394
- throw new Exception("File IO: Error writing; Length mismatch: Expected " . strlen($data) . " bytes, wrote " . ($length === FALSE ? "NONE!" : $length));
395
- }
396
- $this->streamFileLength += $length;
397
-
398
- return $length;
399
- }
400
-
401
- /**
402
- * Close the current stream.
403
- *
404
- * @return bool $success
405
- */
406
- public function closeStream() {
407
- if ($this->isFinalized || strlen($this->streamFilePath) == 0) {
408
- return FALSE;
409
- }
410
-
411
- fflush($this->streamData);
412
- fclose($this->streamData);
413
-
414
- $this->processFile($this->streamFile, $this->streamFilePath, $this->streamTimestamp, $this->streamFileComment, $this->streamExtFileAttr);
415
-
416
- $this->streamData = null;
417
- $this->streamFilePath = null;
418
- $this->streamTimestamp = null;
419
- $this->streamFileComment = null;
420
- $this->streamFileLength = 0;
421
- $this->streamExtFileAttr = null;
422
-
423
- // Windows is a little slow at times, so a millisecond later, we can unlink this.
424
- unlink($this->streamFile);
425
-
426
- $this->streamFile = null;
427
-
428
- return TRUE;
429
- }
430
-
431
- private function processFile($dataFile, $filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) {
432
- if ($this->isFinalized) {
433
- return FALSE;
434
- }
435
-
436
- $tempzip = self::getTemporaryFile();
437
-
438
- $zip = new ZipArchive;
439
- if ($zip->open($tempzip) === TRUE) {
440
- $zip->addFile($dataFile, 'file');
441
- $zip->close();
442
- }
443
-
444
- $file_handle = fopen($tempzip, "rb");
445
- $stats = fstat($file_handle);
446
- $eof = $stats['size']-72;
447
-
448
- fseek($file_handle, 6);
449
-
450
- $gpFlags = fread($file_handle, 2);
451
- $gzType = fread($file_handle, 2);
452
- fread($file_handle, 4);
453
- $fileCRC32 = fread($file_handle, 4);
454
- $v = unpack("Vval", fread($file_handle, 4));
455
- $gzLength = $v['val'];
456
- $v = unpack("Vval", fread($file_handle, 4));
457
- $dataLength = $v['val'];
458
-
459
- $this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr);
460
-
461
- fseek($file_handle, 34);
462
- $pos = 34;
463
-
464
- while (!feof($file_handle) && $pos < $eof) {
465
- $datalen = $this->streamChunkSize;
466
- if ($pos + $this->streamChunkSize > $eof) {
467
- $datalen = $eof-$pos;
468
- }
469
- $data = fread($file_handle, $datalen);
470
- $pos += $datalen;
471
-
472
- $this->zipwrite($data);
473
- }
474
-
475
- fclose($file_handle);
476
-
477
- unlink($tempzip);
478
- }
479
-
480
- /**
481
- * Close the archive.
482
- * A closed archive can no longer have new files added to it.
483
- *
484
- * @return bool $success
485
- */
486
- public function finalize() {
487
- if (!$this->isFinalized) {
488
- if (strlen($this->streamFilePath) > 0) {
489
- $this->closeStream();
490
- }
491
- $cd = implode("", $this->cdRec);
492
-
493
- $cdRecSize = pack("v", sizeof($this->cdRec));
494
- $cdRec = $cd . self::ZIP_END_OF_CENTRAL_DIRECTORY
495
- . $cdRecSize . $cdRecSize
496
- . pack("VV", strlen($cd), $this->offset);
497
- if (!empty($this->zipComment)) {
498
- $cdRec .= pack("v", strlen($this->zipComment)) . $this->zipComment;
499
- } else {
500
- $cdRec .= "\x00\x00";
501
- }
502
-
503
- $this->zipwrite($cdRec);
504
-
505
- $this->isFinalized = TRUE;
506
- $this->cdRec = NULL;
507
-
508
- return TRUE;
509
- }
510
- return FALSE;
511
- }
512
-
513
- /**
514
- * Get the handle ressource for the archive zip file.
515
- * If the zip haven't been finalized yet, this will cause it to become finalized
516
- *
517
- * @return zip file handle
518
- */
519
- public function getZipFile() {
520
- if (!$this->isFinalized) {
521
- $this->finalize();
522
- }
523
-
524
- $this->zipflush();
525
-
526
- rewind($this->zipFile);
527
-
528
- return $this->zipFile;
529
- }
530
-
531
- /**
532
- * Get the zip file contents
533
- * If the zip haven't been finalized yet, this will cause it to become finalized
534
- *
535
- * @return zip data
536
- */
537
- public function getZipData() {
538
- if (!$this->isFinalized) {
539
- $this->finalize();
540
- }
541
- if (!is_resource($this->zipFile)) {
542
- return $this->zipData;
543
- } else {
544
- rewind($this->zipFile);
545
- $filestat = fstat($this->zipFile);
546
- return fread($this->zipFile, $filestat['size']);
547
- }
548
- }
549
-
550
- /**
551
- * Send the archive as a zip download
552
- *
553
- * @param String $fileName The name of the Zip archive, in ISO-8859-1 (or ASCII) encoding, ie. "archive.zip". Optional, defaults to NULL, which means that no ISO-8859-1 encoded file name will be specified.
554
- * @param String $contentType Content mime type. Optional, defaults to "application/zip".
555
- * @param String $utf8FileName The name of the Zip archive, in UTF-8 encoding. Optional, defaults to NULL, which means that no UTF-8 encoded file name will be specified.
556
- * @param bool $inline Use Content-Disposition with "inline" instead of "attached". Optional, defaults to FALSE.
557
- * @throws Exception Throws an exception in case of errors
558
- * @return bool Always returns true (for backward compatibility).
559
- */
560
- function sendZip($fileName = null, $contentType = "application/zip", $utf8FileName = null, $inline = false) {
561
- if (!$this->isFinalized) {
562
- $this->finalize();
563
- }
564
- $headerFile = null;
565
- $headerLine = null;
566
- if(headers_sent($headerFile, $headerLine)) {
567
- throw new Exception("Unable to send file '$fileName'. Headers have already been sent from '$headerFile' in line $headerLine");
568
- }
569
- if(ob_get_contents() !== false && strlen(ob_get_contents())) {
570
- throw new Exception("Unable to send file '$fileName'. Output buffer contains the following text (typically warnings or errors):\n" . ob_get_contents());
571
- }
572
- if(@ini_get('zlib.output_compression')) {
573
- @ini_set('zlib.output_compression', 'Off');
574
- }
575
- header("Pragma: public");
576
- header("Last-Modified: " . @gmdate("D, d M Y H:i:s T"));
577
- header("Expires: 0");
578
- header("Accept-Ranges: bytes");
579
- header("Connection: close");
580
- header("Content-Type: " . $contentType);
581
- $cd = "Content-Disposition: ";
582
- if ($inline) {
583
- $cd .= "inline";
584
- } else {
585
- $cd .= "attached";
586
- }
587
- if ($fileName) {
588
- $cd .= '; filename="' . $fileName . '"';
589
- }
590
- if ($utf8FileName) {
591
- $cd .= "; filename*=UTF-8''" . rawurlencode($utf8FileName);
592
- }
593
- header($cd);
594
- header("Content-Length: ". $this->getArchiveSize());
595
- if (!is_resource($this->zipFile)) {
596
- echo $this->zipData;
597
- } else {
598
- rewind($this->zipFile);
599
- while (!feof($this->zipFile)) {
600
- echo fread($this->zipFile, $this->streamChunkSize);
601
- }
602
- }
603
- return true;
604
- }
605
-
606
- /**
607
- * Return the current size of the archive
608
- *
609
- * @return $size Size of the archive
610
- */
611
- public function getArchiveSize() {
612
- if (!is_resource($this->zipFile)) {
613
- return strlen($this->zipData);
614
- }
615
- $filestat = fstat($this->zipFile);
616
-
617
- return $filestat['size'];
618
- }
619
-
620
- /**
621
- * Calculate the 2 byte dostime used in the zip entries.
622
- *
623
- * @param int $timestamp
624
- * @return 2-byte encoded DOS Date
625
- */
626
- private function getDosTime($timestamp = 0) {
627
- $timestamp = (int)$timestamp;
628
- $oldTZ = @date_default_timezone_get();
629
- date_default_timezone_set('UTC');
630
- $date = ($timestamp == 0 ? getdate() : getdate($timestamp));
631
- date_default_timezone_set($oldTZ);
632
- if ($date["year"] >= 1980) {
633
- return pack("V", (($date["mday"] + ($date["mon"] << 5) + (($date["year"]-1980) << 9)) << 16) |
634
- (($date["seconds"] >> 1) + ($date["minutes"] << 5) + ($date["hours"] << 11)));
635
- }
636
- return "\x00\x00\x00\x00";
637
- }
638
-
639
- /**
640
- * Build the Zip file structures
641
- *
642
- * @param string $filePath
643
- * @param string $fileComment
644
- * @param string $gpFlags
645
- * @param string $gzType
646
- * @param int $timestamp
647
- * @param string $fileCRC32
648
- * @param int $gzLength
649
- * @param int $dataLength
650
- * @param int $extFileAttr Use self::EXT_FILE_ATTR_FILE for files, self::EXT_FILE_ATTR_DIR for Directories.
651
- */
652
- private function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) {
653
- $filePath = str_replace("\\", "/", $filePath);
654
- $fileCommentLength = (empty($fileComment) ? 0 : strlen($fileComment));
655
- $timestamp = (int)$timestamp;
656
- $timestamp = ($timestamp == 0 ? time() : $timestamp);
657
-
658
- $dosTime = $this->getDosTime($timestamp);
659
- $tsPack = pack("V", $timestamp);
660
-
661
- if (!isset($gpFlags) || strlen($gpFlags) != 2) {
662
- $gpFlags = "\x00\x00";
663
- }
664
-
665
- $isFileUTF8 = mb_check_encoding($filePath, "UTF-8") && !mb_check_encoding($filePath, "ASCII");
666
- $isCommentUTF8 = !empty($fileComment) && mb_check_encoding($fileComment, "UTF-8") && !mb_check_encoding($fileComment, "ASCII");
667
-
668
- $localExtraField = "";
669
- $centralExtraField = "";
670
-
671
- if ($this->addExtraField) {
672
- $localExtraField .= "\x55\x54\x09\x00\x03" . $tsPack . $tsPack . Zip::EXTRA_FIELD_NEW_UNIX_GUID;
673
- $centralExtraField .= "\x55\x54\x05\x00\x03" . $tsPack . Zip::EXTRA_FIELD_NEW_UNIX_GUID;
674
- }
675
-
676
- if ($isFileUTF8 || $isCommentUTF8) {
677
- $flag = 0;
678
- $gpFlagsV = unpack("vflags", $gpFlags);
679
- if (isset($gpFlagsV['flags'])) {
680
- $flag = $gpFlagsV['flags'];
681
- }
682
- $gpFlags = pack("v", $flag | (1 << 11));
683
-
684
- if ($isFileUTF8) {
685
- $utfPathExtraField = "\x75\x70"
686
- . pack ("v", (5 + strlen($filePath)))
687
- . "\x01"
688
- . pack("V", crc32($filePath))
689
- . $filePath;
690
-
691
- $localExtraField .= $utfPathExtraField;
692
- $centralExtraField .= $utfPathExtraField;
693
- }
694
- if ($isCommentUTF8) {
695
- $centralExtraField .= "\x75\x63" // utf8 encoded file comment extra field
696
- . pack ("v", (5 + strlen($fileComment)))
697
- . "\x01"
698
- . pack("V", crc32($fileComment))
699
- . $fileComment;
700
- }
701
- }
702
-
703
- $header = $gpFlags . $gzType . $dosTime. $fileCRC32
704
- . pack("VVv", $gzLength, $dataLength, strlen($filePath)); // File name length
705
-
706
- $zipEntry = self::ZIP_LOCAL_FILE_HEADER
707
- . self::ATTR_VERSION_TO_EXTRACT
708
- . $header
709
- . pack("v", strlen($localExtraField)) // Extra field length
710
- . $filePath // FileName
711
- . $localExtraField; // Extra fields
712
-
713
- $this->zipwrite($zipEntry);
714
-
715
- $cdEntry = self::ZIP_CENTRAL_FILE_HEADER
716
- . self::ATTR_MADE_BY_VERSION
717
- . ($dataLength === 0 ? "\x0A\x00" : self::ATTR_VERSION_TO_EXTRACT)
718
- . $header
719
- . pack("v", strlen($centralExtraField)) // Extra field length
720
- . pack("v", $fileCommentLength) // File comment length
721
- . "\x00\x00" // Disk number start
722
- . "\x00\x00" // internal file attributes
723
- . pack("V", $extFileAttr) // External file attributes
724
- . pack("V", $this->offset) // Relative offset of local header
725
- . $filePath // FileName
726
- . $centralExtraField; // Extra fields
727
-
728
- if (!empty($fileComment)) {
729
- $cdEntry .= $fileComment; // Comment
730
- }
731
-
732
- $this->cdRec[] = $cdEntry;
733
- $this->offset += strlen($zipEntry) + $gzLength;
734
- }
735
-
736
- private function zipwrite($data) {
737
- if (!is_resource($this->zipFile)) {
738
- $this->zipData .= $data;
739
- } else {
740
- fwrite($this->zipFile, $data);
741
- fflush($this->zipFile);
742
- }
743
- }
744
-
745
- private function zipflush() {
746
- if (!is_resource($this->zipFile)) {
747
- $this->zipFile = tmpfile();
748
- fwrite($this->zipFile, $this->zipData);
749
- $this->zipData = NULL;
750
- }
751
- }
752
-
753
- /**
754
- * Join $file to $dir path, and clean up any excess slashes.
755
- *
756
- * @param string $dir
757
- * @param string $file
758
- */
759
- public static function pathJoin($dir, $file) {
760
- if (empty($dir) || empty($file)) {
761
- return self::getRelativePath($dir . $file);
762
- }
763
- return self::getRelativePath($dir . '/' . $file);
764
- }
765
-
766
- /**
767
- * Clean up a path, removing any unnecessary elements such as /./, // or redundant ../ segments.
768
- * If the path starts with a "/", it is deemed an absolute path and any /../ in the beginning is stripped off.
769
- * The returned path will not end in a "/".
770
- *
771
- * Sometimes, when a path is generated from multiple fragments,
772
- * you can get something like "../data/html/../images/image.jpeg"
773
- * This will normalize that example path to "../data/images/image.jpeg"
774
- *
775
- * @param string $path The path to clean up
776
- * @return string the clean path
777
- */
778
- public static function getRelativePath($path) {
779
- $path = preg_replace("#/+\.?/+#", "/", str_replace("\\", "/", $path));
780
- $dirs = explode("/", rtrim(preg_replace('#^(?:\./)+#', '', $path), '/'));
781
-
782
- $offset = 0;
783
- $sub = 0;
784
- $subOffset = 0;
785
- $root = "";
786
-
787
- if (empty($dirs[0])) {
788
- $root = "/";
789
- $dirs = array_splice($dirs, 1);
790
- } else if (preg_match("#[A-Za-z]:#", $dirs[0])) {
791
- $root = strtoupper($dirs[0]) . "/";
792
- $dirs = array_splice($dirs, 1);
793
- }
794
-
795
- $newDirs = array();
796
- foreach ($dirs as $dir) {
797
- if ($dir !== "..") {
798
- $subOffset--;
799
- $newDirs[++$offset] = $dir;
800
- } else {
801
- $subOffset++;
802
- if (--$offset < 0) {
803
- $offset = 0;
804
- if ($subOffset > $sub) {
805
- $sub++;
806
- }
807
- }
808
- }
809
- }
810
-
811
- if (empty($root)) {
812
- $root = str_repeat("../", $sub);
813
- }
814
- return $root . implode("/", array_slice($newDirs, 0, $offset));
815
- }
816
-
817
- /**
818
- * Create the file permissions for a file or directory, for use in the extFileAttr parameters.
819
- *
820
- * @param int $owner Unix permisions for owner (octal from 00 to 07)
821
- * @param int $group Unix permisions for group (octal from 00 to 07)
822
- * @param int $other Unix permisions for others (octal from 00 to 07)
823
- * @param bool $isFile
824
- * @return EXTRERNAL_REF field.
825
- */
826
- public static function generateExtAttr($owner = 07, $group = 05, $other = 05, $isFile = true) {
827
- $fp = $isFile ? self::S_IFREG : self::S_IFDIR;
828
- $fp |= (($owner & 07) << 6) | (($group & 07) << 3) | ($other & 07);
829
-
830
- return ($fp << 16) | ($isFile ? self::S_DOS_A : self::S_DOS_D);
831
- }
832
-
833
- /**
834
- * Get the file permissions for a file or directory, for use in the extFileAttr parameters.
835
- *
836
- * @param string $filename
837
- * @return external ref field, or FALSE if the file is not found.
838
- */
839
- public static function getFileExtAttr($filename) {
840
- if (file_exists($filename)) {
841
- $fp = fileperms($filename) << 16;
842
- return $fp | (is_dir($filename) ? self::S_DOS_D : self::S_DOS_A);
843
- }
844
- return FALSE;
845
- }
846
- /**
847
- * Returns the path to a temporary file.
848
- * @return string
849
- */
850
- private static function getTemporaryFile() {
851
- if(is_callable(self::$temp)) {
852
- $temporaryFile = @call_user_func(self::$temp);
853
- if(is_string($temporaryFile) && strlen($temporaryFile) && is_writable($temporaryFile)) {
854
- return $temporaryFile;
855
- }
856
- }
857
- $temporaryDirectory = (is_string(self::$temp) && strlen(self::$temp)) ? self::$temp : sys_get_temp_dir();
858
- return tempnam($temporaryDirectory, 'Zip');
859
- }
860
- }
861
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/array2xml.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
-
3
- if (!class_exists('ICL_Array2XML')) {
4
-
5
- /**
6
- * Converts array to XML
7
- */
8
- class ICL_Array2XML
9
- {
10
-
11
- var $text;
12
- var $arrays, $keys, $node_flag, $depth, $xml_parser;
13
-
14
- function array2xml($array, $root) {
15
- $this->depth = 1;
16
- $this->text = "<?xml version=\"1.0\" encoding=\""
17
- . get_option('blog_charset'). "\"?>\r\n<$root>\r\n";
18
- $this->text .= $this->array_transform($array);
19
- $this->text .="</$root>";
20
- return $this->text;
21
- }
22
-
23
- function array_transform($array) {
24
- $output = '';
25
- $indent = str_repeat(' ', $this->depth * 4);
26
- $child_key = false;
27
- if (isset($array['__key'])) {
28
- $child_key = $array['__key'];
29
- unset($array['__key']);
30
- }
31
- foreach ($array as $key => $value) {
32
- $key = str_replace(' ', '___032___', $key); // encode spaces
33
- if (!is_array($value)) {
34
- if (empty($key)) {
35
- continue;
36
- }
37
- $key = $child_key ? $child_key : $key;
38
- $output .= $indent . "<$key>" . htmlspecialchars($value, ENT_QUOTES) . "</$key>\r\n";
39
- } else {
40
- $this->depth++;
41
- $key = $child_key ? $child_key : $key;
42
- $output_temp = $this->array_transform($value);
43
- if (!empty($output_temp)) {
44
- $output .= $indent . "<$key>\r\n";
45
- $output .= $output_temp;
46
- $output .= $indent . "</$key>\r\n";
47
- }
48
- $this->depth--;
49
- }
50
- }
51
- return $output;
52
- }
53
-
54
- }
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/changelog.txt DELETED
@@ -1,31 +0,0 @@
1
- Common 1.X (month day, 2015)
2
- - Added "ico" file type as proper image file.
3
-
4
- Common 1.6 (June 11, 2015)
5
- - Tagged for Types 1.7, Views 1.9 and Layouts 1.2
6
-
7
- -------------------------------------------------------------------------------------------------------------------
8
- Common 1.5 (Apr 1, 2015)
9
- - Tagged for Types 1.6.6, Views 1.8, CRED 1.3.6 and Layouts 1.1.
10
- - Fixed issue when there is more than one CRED form on a page with the same taxonomy.
11
- - Fixed a little problem with edit skype button modal window - was too narrow.
12
- - Fixed empty title problem for filter "wpt_field_options" on user edit/add screen.
13
- https://wp-types.com/forums/topic/populate-select-field-in-wpcf-um-group/
14
- - Added filter "toolset_editor_add_form_buttons" to disable Toolset buttons on the post editor.
15
- - Added placeholder attributes to fields.
16
- - Updated CakePHP validation URL method to allow new TLD's.
17
-
18
- -------------------------------------------------------------------------------------------------------------------
19
- Common 1.4 (Feb 2 2015)
20
- - Tagged for Views 1.7, Types 1.6.5, CRED 1.3.5 and Layouts 1.0 beta1
21
- - Updated Installer to 1.5
22
-
23
- -------------------------------------------------------------------------------------------------------------------
24
- Common 1.3.1 (Dec 16 2014)
25
- - Tagged for Views 1.7 beta1 and Layouts 1.0 beta1
26
- - Fixed issue about Editor addon and ACF compatibility
27
- - Fixed issue about branding loader
28
-
29
- -------------------------------------------------------------------------------------------------------------------
30
- Common 1.3 (Dec 15 2014)
31
- - Tagged for Views 1.7 beta1 and Layouts 1.0 beta1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/classes/class-toolset-admin-bar-menu.php DELETED
@@ -1,779 +0,0 @@
1
- <?php
2
-
3
- if ( ! class_exists( 'Toolset_Admin_Bar_Menu' ) ) {
4
-
5
- class Toolset_Admin_Bar_Menu {
6
-
7
- // singleton
8
- private static $instance;
9
-
10
- /**
11
- * Avoid executing more than once the code
12
- * @var type bool
13
- */
14
- private $done;
15
-
16
- /** @const */
17
- public static $default_wordpress_archives = array( 'home-blog', 'search', 'author', 'year', 'month', 'day' );
18
-
19
- private function __construct() {
20
- $this->done = false;
21
-
22
- add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 99 );
23
- add_filter( 'toolset_filter_toolset_admin_bar_menu_disable', array( $this, 'admin_bar_menu_disable' ), 1 );
24
-
25
- if ( is_admin() ) {
26
-
27
- /*
28
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
29
- */
30
-
31
- } else {
32
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ) );
33
- }
34
- }
35
-
36
- public static function get_instance() {
37
- if ( ! self::$instance ) {
38
- self::$instance = new Toolset_Admin_Bar_Menu();
39
- }
40
-
41
- return self::$instance;
42
- }
43
-
44
- public function enqueue_styles() {
45
-
46
- if( ! is_admin_bar_showing() ) {
47
- return;
48
- }
49
-
50
- if ( $this->is_layouts_available() ) {
51
-
52
- // Check also @WPDD_Layouts::enqueue_toolset_common_styles()
53
- global $wpddlayout;
54
- $wpddlayout->enqueue_styles( array( 'toolset-common' ) );
55
-
56
- } else if ( $this->is_views_available() ) {
57
-
58
- wp_enqueue_style( 'onthegosystems-icons', WPV_URL_EMBEDDED . '/common/res/css/toolset-common.css', array(), WPV_VERSION );
59
- wp_enqueue_style( 'toolset-common', WPV_URL_EMBEDDED . '/onthego-resources/onthegosystems-icons/css/onthegosystems-icons.css', array( 'onthegosystems-icons' ), WPV_VERSION );
60
-
61
- }
62
- }
63
-
64
- /**
65
- * @see action admin_bar_menu
66
- */
67
- public function admin_bar_menu( $wp_admin_bar ) {
68
- // Check this haven't called more than once
69
- if ( $this->done ) {
70
- return;
71
- }
72
-
73
- /**
74
- * Filter to disable the Toolset Admin Bar menu
75
- *
76
- * Used to disable the Admin Bar Menu when the 'show_admin_bar_shortcut' entry on the 'toolset_options' option has an 'off' value
77
- * It is up to the plugins to produce a GUI for setting that value
78
- *
79
- * @since 1.7
80
- */
81
-
82
- if ( apply_filters( 'toolset_filter_toolset_admin_bar_menu_disable', false ) ) {
83
- return;
84
- }
85
-
86
- if ( $this->get_default_plugin() && $this->has_capatibilities() && $this->is_assignable() ) {
87
-
88
- //
89
- // We create a Toolset menu and a child submenu.
90
- // Clicking the parent achieves the same result than clicking the child
91
- // Maybe we add extra menu options in the future
92
- //
93
- // (Icon) Design with Toolset < $href >
94
- // |
95
- // +- $title < $href >
96
- //
97
-
98
- $menu_data = $this->get_menu_data();
99
- if ( empty( $menu_data ) ) {
100
- // If no menu is available, then don't render menu
101
- return;
102
- }
103
- list( $title, $href ) = $menu_data;
104
-
105
- $args = array(
106
- 'id' => 'toolset_admin_bar_menu',
107
- 'title' => __( 'Design with Toolset', 'wpv-views' ),
108
- 'href' => $href,
109
- 'meta' => array( 'class' => 'toolset-edit-link' )
110
- );
111
- $wp_admin_bar->add_node( $args );
112
-
113
- $args = array(
114
- 'parent' => 'toolset_admin_bar_menu',
115
- 'id' => 'toolset_design_this_item',
116
- 'title' => $title,
117
- 'href' => $href,
118
- );
119
- $wp_admin_bar->add_node( $args );
120
-
121
- $settings_href = $this->get_settings_href();
122
- $args = array(
123
- 'parent' => 'toolset_admin_bar_menu',
124
- 'id' => 'toolset_remove_this_menu',
125
- 'title' => __( 'Remove this menu', 'wpv-views' ),
126
- 'href' => $settings_href,
127
- );
128
- $wp_admin_bar->add_node( $args );
129
-
130
- $this->done = true;
131
- }
132
- }
133
-
134
- /**
135
- * Disable the Admin Bar Menu entry when the 'show_admin_bar_shortcut' entry on the 'toolset_options' option has an 'off' value
136
- *
137
- * @since 1.7
138
- */
139
- public function admin_bar_menu_disable( $state ) {
140
- $toolset_options = get_option( 'toolset_options', array() );
141
- $toolset_admin_bar_menu_remove = ( isset( $toolset_options['show_admin_bar_shortcut'] ) && $toolset_options['show_admin_bar_shortcut'] == 'off' ) ? true : false;
142
- if ( $toolset_admin_bar_menu_remove ) {
143
- $state = true;
144
- }
145
- return $state;
146
- }
147
-
148
- /**
149
- * User is admin or similar?
150
- * @return boolean
151
- */
152
- private function has_capatibilities() {
153
- $manage_options = current_user_can( 'manage_options' );
154
-
155
- $has_layouts = $this->is_layouts_available();
156
-
157
- $has_views = $this->is_views_available();
158
-
159
- return $manage_options && ( $has_layouts || $has_views );
160
- }
161
-
162
- /**
163
- * Can you assign what you are seeing right now to a Layout, Content Template or WordPress Archive?
164
- * @return boolean
165
- */
166
- private function is_assignable() {
167
-
168
- $context = $this->get_context();
169
- if ( ! $context ) { return false; }
170
- list( $type, $class ) = explode( '|', $context );
171
-
172
- if ( is_admin() ) {
173
-
174
- /*
175
- global $post_type;
176
- $screen = get_current_screen();
177
- if( preg_match( '/^(edit|edit-tags|post)$/', $screen->base ) && empty($screen->action) ) {
178
-
179
- if( 'edit' === $screen->base ) {
180
-
181
- // $post_type | archive
182
-
183
- if ( 'page' === $post_type ) {
184
- return false;
185
- }
186
-
187
- $post_type_object = get_post_type_object( $screen->post_type );
188
- if ( ! ( $post_type_object->publicly_queryable && $post_type_object->has_archive ) ) {
189
- return false;
190
- }
191
-
192
- } else if( 'edit-tags' === $screen->base ) {
193
-
194
- // $taxonomy | archive
195
-
196
- $taxonomy = get_taxonomy( $screen->taxonomy );
197
- if ( !( $taxonomy->public ) ) {
198
- return false;
199
- }
200
-
201
- } else if( 'post' === $screen->base ) {
202
-
203
- // $post_type | page
204
-
205
- $post_type_object = get_post_type_object( $screen->post_type );
206
- if ( ! $post_type_object->publicly_queryable ) {
207
- return false;
208
- }
209
-
210
- }
211
-
212
- }
213
- */
214
-
215
- } else {
216
-
217
- // Backend
218
- if( 'page' === $class && '404' === $type ) {
219
-
220
- return $this->is_layouts_available() && ( WPDD_Layouts_Users_Profiles::user_can_create() && WPDD_Layouts_Users_Profiles::user_can_assign() || WPDD_Layouts_Users_Profiles::user_can_edit() );
221
-
222
- } else if ( 'page' === $class ) {
223
-
224
- $post_type_object = get_post_type_object( $type );
225
- $is_cpt = $post_type_object != null;
226
- if( ! $is_cpt /* || ! $post_type_object->publicly_queryable */ ) {
227
- return false;
228
- }
229
-
230
- } else if ( 'archive' === $class && in_array( $type, self::$default_wordpress_archives ) ) {
231
- // DO NOTHING
232
- } else if ( 'archive' === $class && 'page' === $type ) {
233
- return false;
234
- } else if ( 'archive' === $class ) {
235
-
236
- $taxonomy = get_taxonomy( $type );
237
- $is_tax = $taxonomy !== false;
238
- if ( $is_tax && ! $taxonomy->public ) {
239
- return false;
240
- }
241
-
242
- $post_type_object = get_post_type_object( $type );
243
- $is_cpt = $post_type_object != null;
244
- if( $is_cpt && ( ! $post_type_object->publicly_queryable || ! $post_type_object->has_archive ) ) {
245
- return false;
246
- }
247
-
248
- }
249
-
250
- }
251
-
252
- return true;
253
- }
254
-
255
- private function is_layouts_available() {
256
- global $wpddlayout;
257
-
258
- // class WPDDL_Admin_Pages exists only in full version
259
- return class_exists( 'WPDDL_Admin_Pages' ) && isset( $wpddlayout ) && is_object( $wpddlayout );
260
- }
261
-
262
- private function is_views_available() {
263
- global $WP_Views;
264
-
265
- // class WP_Views_plugin exists only in full version
266
- return class_exists( 'WP_Views_plugin' ) && isset( $WP_Views ) && is_object( $WP_Views );
267
- }
268
-
269
- /**
270
- * Get the best plugin available
271
- * @return string (layouts|views|)
272
- */
273
- private function get_default_plugin() {
274
- // Layouts always has precedence
275
- if ( $this->is_layouts_available() ) {
276
- return 'layouts';
277
- } else if ( $this->is_views_available() ) {
278
- return 'views';
279
- } else {
280
- // Other toolset plugins may be present
281
- return null;
282
- }
283
- }
284
-
285
- private function get_settings_href() {
286
- $plugin_name = $this->get_default_plugin();
287
-
288
- if( 'layouts' === $plugin_name ) {
289
- return admin_url( 'admin.php?page=dd_layout_settings' ).'#toolset-admin-bar-settings';
290
- } else /* 'views' */ {
291
- return admin_url( 'admin.php?page=views-settings' ).'#toolset-admin-bar-settings';
292
- }
293
- }
294
-
295
- /**
296
- * Finds the right action depending on what you're seeing and have done
297
- * @returns array ($title, $href) or null (do not show menu)
298
- */
299
- private function get_menu_data() {
300
-
301
- $context = $this->get_context();
302
- if ( ! $context ) {
303
- // No context => No menu
304
- return null;
305
- }
306
-
307
- // Get type {post types, taxonomies, wordpress archives slugs, 404} and class {page, archive}
308
- list( $type, $class ) = explode( '|', $context );
309
-
310
- // We are using the best plugin available by default, unless state otherwise below
311
- $plugin_used = $this->get_default_plugin();
312
-
313
- $layout_id = 0;
314
- $ct_id = 0;
315
- $wpa_id = 0;
316
- $post_id = 0;
317
- $edit_link = null;
318
-
319
- $is_new = true;
320
- // warning! syntax sugar ahead
321
-
322
- // Layouts - Edit Link
323
- if ( $is_new && $this->is_layouts_available() && WPDD_Layouts_Users_Profiles::user_can_edit() ) {
324
-
325
- global $wpddlayout;
326
-
327
- if( is_admin() ) {
328
-
329
- /*
330
- // Only individual pages, post type pages, post type archives
331
- // and taxonomy archives are editable from backend
332
- //
333
-
334
- $screen = get_current_screen();
335
- if( preg_match( '/^(edit|edit-tags|post)$/', $screen->base ) ) {
336
- // Exists layout? $layout_id?
337
-
338
- if( 'edit' === $screen->base ) {
339
- // $post_type | archive
340
-
341
- $post_type_object = get_post_type_object( $screen->post_type );
342
- $option_type_name = WPDD_layout_post_loop_cell_manager::OPTION_TYPES_PREFIX . $post_type_object->name;
343
- if ( $post_type_object && property_exists( $post_type_object, 'public' ) && $post_type_object->public && $wpddlayout->layout_post_loop_cell_manager->get_option( $option_type_name ) ) {
344
- $layout_id = (int) $wpddlayout->layout_post_loop_cell_manager->get_option( $option_type_name );
345
- }
346
-
347
- } else if( 'edit-tags' === $screen->base ) {
348
- // $taxonomy | archive
349
-
350
- $option_type_name = WPDD_layout_post_loop_cell_manager::OPTION_TAXONOMY_PREFIX . $screen->taxonomy;
351
- if ( $wpddlayout->layout_post_loop_cell_manager->get_option( $option_type_name ) ) {
352
- $layout_id = (int) $wpddlayout->layout_post_loop_cell_manager->get_option( $option_type_name );
353
- }
354
-
355
- } else if( 'post' === $screen->base ) {
356
- // $post_type | page
357
-
358
- // Individual
359
- $layout_slug = get_post_meta( (int) $_GET['post'], WPDDL_LAYOUTS_META_KEY, true );
360
- if( ! empty( $layout_slug ) ) {
361
- $layout_id = WPDD_Layouts::get_layout_id_by_slug( $layout_slug );
362
-
363
- }
364
-
365
- // Multiple
366
- if( (int) $layout_id == 0 ) {
367
- $layout_object = $wpddlayout->post_types_manager->get_layout_to_type_object( $type );
368
- $layout_id = $layout_object && property_exists( $layout_object, 'layout_id' ) && $layout_object->layout_id > 0
369
- ? $layout_object->layout_id
370
- : 0;
371
- }
372
-
373
- }
374
-
375
- }
376
- */
377
-
378
- } else if ( (int) $wpddlayout->get_rendered_layout_id() > 0 ) {
379
-
380
- $layout_id = $wpddlayout->get_rendered_layout_id();
381
-
382
- }
383
-
384
- $is_new = $layout_id > 0 ? false : true;
385
- $plugin_used = ! $is_new ? 'layouts' : $plugin_used;
386
-
387
- }
388
-
389
- // Views - Edit Link
390
- if ( $is_new && $this->is_views_available() ) {
391
-
392
- global $WPV_settings;
393
-
394
- if( is_admin() ) {
395
-
396
- /*
397
- // Same as Layouts
398
- $screen = get_current_screen();
399
- if( preg_match( '/^(edit|edit-tags|post)$/', $screen->base ) ) {
400
- // Exists layout? $layout_id?
401
-
402
- if( 'edit' === $screen->base ) {
403
- // $post_type | archive
404
-
405
- if ( isset( $WPV_settings['view_cpt_' . $type] ) && $WPV_settings['views_template_for_' . $type] > 0 ) {
406
- $wpa_id = $WPV_settings['view_cpt_' . $type];
407
- }
408
-
409
- } else if( 'edit-tags' === $screen->base ) {
410
- // $taxonomy | archive
411
-
412
- if ( isset( $WPV_settings['view_taxonomy_loop_' . $type] ) && $WPV_settings['view_taxonomy_loop_' . $type] > 0 ) {
413
- $wpa_id = $WPV_settings['view_taxonomy_loop_' . $type];
414
- }
415
-
416
- } else if( 'post' === $screen->base ) {
417
- // $post_type | page
418
-
419
- // Individual
420
- if ( isset( $_GET['post'] ) && (int) $_GET['post'] > 0 ) {
421
- $ct_id = (int) get_post_meta( (int) $_GET['post'], '_views_template', true );
422
- }
423
-
424
- // Multiple
425
- if ( (int) $ct_id == 0
426
- && isset( $WPV_settings['views_template_for_' . $type] )
427
- && $WPV_settings['views_template_for_' . $type] > 0
428
- ) {
429
- $ct_id = $WPV_settings['views_template_for_' . $type];
430
- }
431
-
432
- }
433
-
434
- }
435
-
436
- if ( ( int ) $wpa_id > 0 || ( int ) $ct_id > 0 ) {
437
- $is_new = false;
438
- }
439
- */
440
- } else {
441
-
442
- if ( 'archive' === $class && 'page' != $type ) {
443
- /* WordPress Archive */
444
-
445
- // WordPress Loop Archives
446
- if( in_array( $type, self::$default_wordpress_archives )
447
- && isset( $WPV_settings['view_'.$type.'-page'] )
448
- && (int) $WPV_settings['view_'.$type.'-page'] > 0
449
- ) {
450
- $wpa_id = (int) $WPV_settings['view_'.$type.'-page'];
451
- }
452
-
453
- // Taxonomy Archive
454
- if( ! $wpa_id ) {
455
- $taxonomy = get_taxonomy( $type );
456
- $is_tax = $taxonomy !== false;
457
- if( $is_tax
458
- && isset( $WPV_settings['view_taxonomy_loop_' . $type] )
459
- && (int) $WPV_settings['view_taxonomy_loop_' . $type] > 0
460
- ) {
461
- $wpa_id = $WPV_settings['view_taxonomy_loop_' . $type];
462
- }
463
- }
464
-
465
- // Post Type Archive
466
- if( ! $wpa_id ) {
467
- $post_type_object = get_post_type_object( $type );
468
- $is_cpt = $post_type_object != null;
469
- if( $is_cpt && isset( $WPV_settings['view_cpt_' . $type] )
470
- && $WPV_settings['view_cpt_' . $type] > 0
471
- ) {
472
- $wpa_id = $WPV_settings['view_cpt_' . $type];
473
- }
474
- }
475
-
476
- if ( (int) $wpa_id > 0 ) {
477
- $is_new = false;
478
- }
479
-
480
- } else if( 'page' === $class && ! is_404() ) {
481
- /* Content Template */
482
-
483
- // Individual
484
- $ct_id = (int) get_post_meta( get_the_ID(), '_views_template', true );
485
-
486
- // Multiple
487
- if( (int) $ct_id == 0 ) {
488
-
489
- // This doesn't satisfies expectations.
490
- // You cannot edit content templates you're not seeing, even if they're assigned to the current post type.
491
- // FIXME: Define the right behavior.
492
- // My proposal: if there is a CT assigned to post type, suggest "bind this and edit template" or similar approach
493
-
494
- /*
495
- if( isset( $WPV_settings['views_template_for_'.$type] ) && $WPV_settings['views_template_for_'.$type] > 0 ) {
496
- $ct_id = $WPV_settings['views_template_for_'.$type];
497
- }
498
- */
499
- }
500
-
501
- if ( (int) $ct_id > 0 ) {
502
- $is_new = false;
503
- }
504
-
505
- }
506
-
507
- }
508
-
509
- $plugin_used = ! $is_new ? 'views' : $plugin_used;
510
-
511
- }
512
-
513
- // $plugin_used - Create Link
514
- if ( $is_new ) {
515
- if( is_admin() ) {
516
-
517
- /*
518
- $screen = get_current_screen();
519
- if( $screen->id == 'post' ) {
520
- $post_id = (int) $_GET['post'];
521
- }
522
- */
523
-
524
- } else {
525
- $post_id = get_the_ID();
526
- }
527
- }
528
-
529
- $title = $this->get_title ( $plugin_used, $is_new, $type, $class, max( array( $layout_id, $ct_id, $wpa_id, $post_id ) ) );
530
- $edit_link = $this->get_edit_link( $plugin_used, $is_new, $type, $class, max( array( $layout_id, $ct_id, $wpa_id, $post_id ) ) );
531
-
532
- if ( $edit_link !== null ) {
533
- return array( $title, $edit_link );
534
- } else {
535
- // No valid data => No menu
536
- return null;
537
- }
538
- }
539
-
540
- /**
541
- * Returns an string with the context where the link is going to be display
542
- * It is going to be like "post_type|archive" or null if link should not be displayed
543
- * @return string {post_type or archive_type or taxonomy or 404}|{page or archive}
544
- */
545
- private function get_context() {
546
-
547
- // Rule of thumb: if there is a list of posts, it is an archive
548
-
549
- // null means we will not show the link
550
- $context = null;
551
-
552
- if ( is_admin() ) {
553
-
554
- /*
555
- // There are less places inside the admin to define Layouts/Templates
556
-
557
- global $post_type;
558
-
559
- $screen = get_current_screen();
560
-
561
- if ( $screen->base == 'edit' && $post_type !== 'page' ) {
562
- // list of posts page => create an archive ( WordPress Archive )
563
- return "$post_type|archive";
564
- } else if ( $screen->base == 'post' && empty( $screen->action ) ) {
565
- // post editor page => create a page ( Content Template )
566
- return "$post_type|page";
567
- } else if ( $screen->base == 'edit-tags' ) {
568
- // taxonomy page => always an archive ( WordPress Archive )
569
- return "{$screen->taxonomy}|archive";
570
- }
571
- */
572
-
573
- } else {
574
-
575
- global $post, $wp_query;
576
-
577
- if ( is_home() ) {
578
- // Blog posts index
579
- $context = 'home-blog|archive';
580
- } else if ( is_search() ) {
581
- $context = 'search|archive';
582
- } else if ( is_author() ) {
583
- $context = 'author|archive';
584
- } else if ( is_year() ) {
585
- $context = 'year|archive';
586
- } else if ( is_month() ) {
587
- $context = 'month|archive';
588
- } else if ( is_day() ) {
589
- $context = 'day|archive';
590
- } else if ( is_category() ) {
591
- $context = 'category|archive';
592
- } else if ( is_tag() ) {
593
- $context = 'post_tag|archive';
594
- } else if ( is_tax() ) {
595
- $term = $wp_query->get_queried_object();
596
- if (
597
- $term
598
- && isset( $term->taxonomy )
599
- ) {
600
- $context = $term->taxonomy . '|archive';
601
- }
602
- } else if ( is_post_type_archive() ) {
603
- $post_type = $wp_query->get('post_type');
604
- if ( is_array( $post_type ) ) {
605
- $post_type = reset( $post_type );
606
- }
607
- $context = $post_type . '|archive';
608
- } else if ( is_404() ) {
609
- // Special WordPress Error 404 Page
610
- $context = '404|page';
611
- } else if ( is_object( $post ) && get_class( $post ) === 'WP_Post' ) {
612
- $context = get_post_type() . '|page';
613
- }
614
-
615
- }
616
-
617
- return $context;
618
- }
619
-
620
- /**
621
- * Get title for menu subitem
622
- * @param string $plugin are we using 'layouts' or 'views'?
623
- * @param boolean $is_new are we creating a new object?
624
- * @param string $type post_type, taxonomy or wp slug
625
- * @param string $class (single) page or archive
626
- * @param int $post_id must be layout or template id if !$is_new, else post
627
- * @return string title for menu subitem
628
- */
629
- private function get_title( $plugin, $is_new, $type, $class, $post_id = null) {
630
-
631
- if ( $is_new ) {
632
- /* Create */
633
- // "Create a new 'Layout for Restaurant archives'"
634
- // "Create a new 'Content Template for Restaurants'"
635
- // "Create a new 'WordPress Archive for Restaurant archives'"
636
-
637
- $create_a_new = __( 'Create a new', 'wpv-views' );
638
- $object = $this->get_name_auto( $plugin, $type, $class, $post_id );
639
-
640
- return trim( sprintf( '%s %s', $create_a_new, $object ) );
641
-
642
- } else {
643
- /* Edit */
644
- // "Edit 'Restaurants' Layout"
645
- // "Edit 'Layout for Restaurants' Layout" => "Edit 'Layout for Restaurants'"
646
- // "Edit 'Layout for Restaurant archives' Layout" => "Edit 'Layout for Restaurant' archives"
647
-
648
- $edit = __( 'Edit', 'wpv-views' );
649
-
650
- // Layout or Content Template or WordPress Archive
651
- $layouts = __( 'Layout', 'wpv-views' );
652
- $views = 'archive' === $class ? __( 'Archive', 'wpv-views' ) : __( 'Template', 'wpv-views' );
653
- $artifact = 'layouts' === $plugin ? $layouts : $views;
654
-
655
- // avoid "'Layout for Restaurant archives' Layout"
656
- // get "'Layout for Restaurants'" instead
657
- $post_title = get_the_title( $post_id );
658
- $object = strpos( $post_title, $artifact ) === false ? sprintf( '%s %s', $post_title, $artifact ) : $post_title;
659
-
660
- return trim( sprintf( '%s %s', $edit, $object ) );
661
-
662
- }
663
-
664
- }
665
-
666
- /**
667
- * Get a valid and self-defining title for a Layout, Content Template or WordPress Archive
668
- *
669
- * @param string $plugin layouts or views
670
- * @param string $type post_type, taxonomy or wp slug
671
- * @param string $class page or archive
672
- * @param int|null $post_id
673
- *
674
- * @return string
675
- *
676
- * @since unknown
677
- */
678
- public function get_name_auto( $plugin, $type, $class, $post_id = null ) {
679
- // Examples:
680
- // Layout for Restaurants
681
- // Layout for Restaurant archives
682
- // Content Template for Restaurants
683
- // WordPress Archive for Restaurants
684
-
685
- /* Layout or Content Template or WordPress Archive */
686
- $layouts = __( 'Layout', 'wpv-views' );
687
- $views = 'archive' === $class ? __( 'Archive', 'wpv-views' ) : __( 'Template', 'wpv-views' );
688
- $artifact = 'layouts' === $plugin ? $layouts : $views;
689
-
690
- /* for */
691
- $for = __( 'for', 'wpv-views' );
692
-
693
- /* selection */
694
- $selection = '';
695
-
696
- if ( 'page' === $class && '404' === $type && 'layouts' === $plugin ) {
697
- $selection = __( 'Error 404 page', 'wpv-views' );
698
- } else if ( 'page' === $type ) {
699
- $selection = get_the_title( $post_id );
700
- } else if ( 'page' === $class ) {
701
- $post_type = get_post_type_object( $type );
702
- $selection = ucfirst( $post_type->label );
703
- } else if ( 'archive' === $class && in_array( $type, self::$default_wordpress_archives ) ) {
704
- $selection = sprintf( '%s %s', ucfirst( $type ), __( 'Archives', 'wpv-views' ) );
705
- /*
706
- } else if ( 'archive' === $class && preg_match( '/^(category|post_tag)$/', $type ) ) {
707
- $taxonomy = get_taxonomy( $type );
708
- $selection = 'layouts' === $plugin ? sprintf( '%s %s', ucfirst( $taxonomy->labels->singular_name ), __( 'Archives', 'wpv-views' ) ) : ucfirst( $taxonomy->labels->name );
709
- */
710
- } else if ( 'archive' === $class ) {
711
- $post_type = get_post_type_object( $type );
712
- $is_cpt = $post_type != null;
713
-
714
- $taxonomy = get_taxonomy( $type );
715
- $is_tax = $taxonomy !== false;
716
-
717
- if ( $is_cpt ) {
718
- $selection = 'layouts' === $plugin ? sprintf( '%s %s', ucfirst( $post_type->labels->singular_name ), __( 'Archives', 'wpv-views' ) ) : ucfirst( $post_type->labels->name );
719
- } else if ( $is_tax ) {
720
- $selection = 'layouts' === $plugin ? sprintf( '%s %s', ucfirst( $taxonomy->labels->singular_name ), __( 'Archives', 'wpv-views' ) ) : ucfirst( $taxonomy->labels->name );
721
- } else {
722
- $selection = __( 'Unsupported post type archives', 'wpv-views' );
723
- }
724
-
725
- } else {
726
- $selection = __( 'Unsupported page', 'wpv-views' );
727
- }
728
-
729
- return trim( sprintf( '%s %s %s', $artifact, $for, $selection ) );
730
- }
731
-
732
- public function get_edit_link( $plugin, $is_new, $type, $class, $post_id = null ) {
733
- $edit_link = null;
734
-
735
- if( 'layouts' === $plugin ) {
736
-
737
- if( $is_new && WPDD_Layouts_Users_Profiles::user_can_create() && WPDD_Layouts_Users_Profiles::user_can_assign() ) {
738
- $edit_link = wp_nonce_url( admin_url( sprintf( 'admin.php?page=dd_layouts_create_auto&type=%s&class=%s&post=%s', $type, $class, $post_id ) ), 'create_auto' );
739
- } else if( $post_id > 0 && WPDD_Layouts_Users_Profiles::user_can_edit() ) {
740
- // Layouts editor
741
- $edit_link = admin_url( sprintf( 'admin.php?page=dd_layouts_edit&layout_id=%s&action=edit', $post_id ) );
742
- }
743
-
744
- } else if ( 'views' === $plugin && '404' != $type /* No support for Error 404 page */ ) {
745
-
746
- if ( $is_new ) {
747
- $edit_link = wp_nonce_url( admin_url( sprintf( 'admin.php?page=views_create_auto&type=%s&class=%s&post=%s', $type, $class, $post_id ) ), 'create_auto' );
748
- } else if( $post_id > 0 ) {
749
-
750
- if( 'archive' === $class ) {
751
- // Views' WordPress Archive editor
752
- $edit_link = admin_url( sprintf( 'admin.php?page=view-archives-editor&view_id=%s', $post_id ) );
753
- } else if( 'page' === $class ) {
754
- // Views' Content Temaplate editor
755
- //$edit_link = admin_url( sprintf( 'post.php?action=edit&post=%s', $post_id ) );
756
- $edit_link = esc_url_raw(
757
- add_query_arg(
758
- array( 'page' => WPV_CT_EDITOR_PAGE_NAME, 'ct_id' => esc_attr( $post_id ), 'action' => 'edit' ),
759
- admin_url( 'admin.php' )
760
- )
761
- );
762
- }
763
-
764
- }
765
- }
766
-
767
- return $edit_link;
768
- }
769
-
770
- }
771
-
772
- // We have checked if @class Toolset_Admin_Bar_Menu already existed.
773
- // After that, we've defined the class. Now, we instantiate it once.
774
- // This works lìke a singleton.
775
- // But the class itself is also a singleton. Using design patterns
776
- // clarifies and prevents against changes in future.
777
- global $toolset_admin_bar_menu;
778
- $toolset_admin_bar_menu = Toolset_Admin_Bar_Menu::get_instance();
779
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/classes/class.toolset.promo.php DELETED
@@ -1,193 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
-
8
- if (!class_exists('Toolset_Promotion')) {
9
-
10
- /**
11
- * Class to show promotion message.
12
- *
13
- * @since 1.5
14
- * @access public
15
- */
16
- class Toolset_Promotion
17
- {
18
- private $version = '1.0';
19
-
20
- public function __construct()
21
- {
22
- add_action('admin_init', array($this, 'admin_init'));
23
- add_action('admin_footer', array($this, 'admin_footer'));
24
- add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
25
- add_action('plugins_loaded', 'on_the_go_systems_branding_plugins_loaded');
26
- }
27
-
28
- /**
29
- * Register script and styles
30
- *
31
- * Register script and styles for future usage.
32
- *
33
- * @since 1.5
34
- *
35
- */
36
- public function admin_init()
37
- {
38
- wp_register_script(
39
- 'toolset-colorbox',
40
- plugins_url('/res/js/jquery.colorbox-min.js', dirname(__FILE__)),
41
- array('jquery'),
42
- '1.4.31'
43
- );
44
- wp_register_script(
45
- __CLASS__,
46
- plugins_url('/res/js/toolset-promotion.js', dirname(__FILE__)),
47
- array('underscore', 'toolset-colorbox'),
48
- $this->version,
49
- true
50
- );
51
- wp_register_style(
52
- 'toolset-colorbox',
53
- plugins_url('/res/css/colorbox.css', dirname(__FILE__)),
54
- false,
55
- '1.4.31'
56
- );
57
- wp_register_style(
58
- __CLASS__,
59
- plugins_url('/res/css/toolset-promotion.css', dirname(__FILE__)),
60
- array('toolset-colorbox', 'onthego-admin-styles'),
61
- $this->version
62
- );
63
- }
64
-
65
- /**
66
- * Enqueue scripts & styles
67
- *
68
- * After check is a correct place, this function enqueue scripts & styles
69
- * for toolset promotion box.
70
- *
71
- * @since 1.5
72
- *
73
- */
74
- public function admin_enqueue_scripts()
75
- {
76
- if (!is_admin() || !function_exists('get_current_screen')) {
77
- return;
78
- }
79
- /**
80
- * List of admin page id
81
- *
82
- * Filter allow to add or change list of admin screen id for checking
83
- * where we need enqueue toolset promotion assets.
84
- *
85
- * @since 1.5
86
- *
87
- * @param array $screen_ids List of admin page screen ids.
88
- *
89
- */
90
- $screen_ids = apply_filters('toolset_promotion_screen_ids', array());
91
- if (empty($screen_ids)) {
92
- return;
93
- }
94
- $screen = get_current_screen();
95
- if (!in_array($screen->id, $screen_ids)) {
96
- return;
97
- }
98
- wp_enqueue_style(__CLASS__);
99
- wp_enqueue_script(__CLASS__);
100
- }
101
-
102
- /**
103
- * Print in footer
104
- *
105
- * Print nessary elemnt in admin footer
106
- *
107
- * @since 1.5
108
- *
109
- */
110
- public function admin_footer()
111
- {
112
- $link_learn = $this->get_affiliate_link_string('http://wp-types.com/');
113
- $link_button = $this->get_affiliate_link_string('http://wp-types.com/#buy-toolset');
114
-
115
- ob_start();
116
- ?>
117
-
118
- <div class="ddl-dialogs-container">
119
- <div id="js-buy-toolset-embedded-message-wrap"></div>
120
- </div>
121
- <script type="text/html" id="js-buy-toolset-embedded-message">
122
- <div class="toolset-modal">
123
- <h2><?php _e('Want to edit Views, CRED forms and Layouts? Get the full <em>Toolset</em> package!', 'wpcf'); ?></h2>
124
-
125
- <div class="content">
126
- <p class="full"><?php _e('The full <em>Toolset</em> package allows you to develop and customize themes without touching PHP. You will be able to:', 'wpcf'); ?></p>
127
-
128
- <div class="icons">
129
- <ul>
130
- <li class="template"><?php _e('Create templates', 'wpcf'); ?></li>
131
- <li class="layout"><?php _e('Design page layouts using drag-and-drop', 'wpcf'); ?></li>
132
- <li class="toolset-search"><?php _e('Build parametric searches', 'wpcf'); ?></li>
133
- </ul>
134
- <ul>
135
- <li class="list"><?php _e('Display lists of content', 'wpcf'); ?></li>
136
- <li class="form"><?php _e('Create front-end content editing forms', 'wpcf'); ?></li>
137
- <li class="more"><?php _e('and more…', 'wpcf'); ?></li>
138
- </ul>
139
- </div>
140
-
141
- <p class="description"><?php _e('Once you buy the full Toolset, you will be able to edit Views, CRED forms and Layouts in your site, as well as build new ones.', 'wpcf'); ?></p>
142
-
143
- <a href="<?php echo $link_button; ?>"
144
- class="button"><?php _e('<em>Toolset</em> Package Options', 'wpcf'); ?></a>
145
- <a href="<?php echo $link_learn; ?>"
146
- class="learn"><?php _e('Learn more about <em>Toolset</em>', 'wpcf'); ?></a>
147
-
148
- </div>
149
- <span class="icon-toolset-logo"></span>
150
- <span class="js-close-promotional-message"></span>
151
- </div>
152
- </script>
153
- <?php
154
- echo ob_get_clean();
155
- }
156
-
157
- private function get_affiliate_link_string($link)
158
- {
159
- if (function_exists('installer_ep_get_configuration') === false) {
160
- return $link;
161
- }
162
-
163
- $info = installer_ep_get_configuration(wp_get_theme()->Name);
164
-
165
- if (!isset($info['repositories']) &&
166
- !isset($info['repositories']['toolset'])
167
- ) {
168
- return $link;
169
-
170
- } else if (
171
- isset($info['repositories']['toolset']['affiliate_id']) &&
172
- isset($info['repositories']['toolset']['affiliate_key'])
173
- ) {
174
- $id = $info['repositories']['toolset']['affiliate_id'];
175
- $key = $info['repositories']['toolset']['affiliate_key'];
176
-
177
- $hash = explode( '#', $link );
178
- if( count($hash) > 1 ){
179
- $link = $hash[0];
180
- $hash = "#" . $hash[1];
181
- } else {
182
- $hash = '';
183
- }
184
-
185
- return sprintf("%s?aid=%s&affiliate_key=%s%s", $link, $id, $key, $hash);
186
- }
187
-
188
- return $link;
189
- }
190
-
191
- }
192
-
193
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/classes/control_forms.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- include_once 'forms.php';
4
-
5
- class Enlimbo_Control_Forms extends Enlimbo_Forms_Wpcf {
6
-
7
- private $_urlParam = '';
8
-
9
- public function isSubmitted($id = '') {
10
- if(!empty($id)) {
11
- $this->_urlParam = $id;
12
- }
13
-
14
- if(empty($this->_urlParam)) {
15
- return false;
16
- }
17
-
18
- return isset($_GET[$this->_urlParam]);
19
- }
20
-
21
- public function renderElements($elements) {
22
- if(isset($elements['field'])) {
23
- $this->_urlParam = $elements['field']['#name'];
24
- }
25
-
26
- return parent::renderElements($elements);
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/classes/forms.php DELETED
@@ -1,972 +0,0 @@
1
- <?php
2
- /**
3
- * Returns HTML formatted output for elements and handles form submission.
4
- *
5
- *
6
- * @version 1.0
7
- */
8
- if (!class_exists('Enlimbo_Forms_Wpcf')) {
9
-
10
- class Enlimbo_Forms_Wpcf
11
- {
12
-
13
- /**
14
- * @var string
15
- */
16
- private $_id;
17
-
18
- /**
19
- * @var array
20
- */
21
- private $_errors = array();
22
-
23
- /**
24
- * @var array
25
- */
26
- private $_elements = array();
27
-
28
- /**
29
- * @var array
30
- */
31
- private $_count = array();
32
-
33
- /**
34
- * @var string
35
- */
36
- public $css_class = 'wpcf-form';
37
-
38
- /**
39
- * Auto handler
40
- *
41
- * Renders.
42
- *
43
- * @param array $element
44
- * @return HTML formatted output
45
- */
46
- public function getId() {
47
- return $this->_id;
48
- }
49
-
50
- public function autoHandle($id, $form)
51
- {
52
- // Auto-add wpnonce field
53
- $form['_wpnonce'] = array(
54
- '#type' => 'markup',
55
- '#markup' => wp_nonce_field($id, '_wpnonce_wpcf', true, false)
56
- );
57
-
58
- $this->_id = $id;
59
- $this->_elements = $form;
60
-
61
- do_action('wpcf_form_autohandle', $id, $form, $this);
62
- do_action('wpcf_form_autohandle_' . $id, $form, $this);
63
-
64
- // get submitted data
65
- if ($this->isSubmitted()) {
66
-
67
- do_action('wpcf_form_autohandle_submit', $id, $form, $this);
68
- do_action('wpcf_form_autohandle_submit_' . $id, $form, $this);
69
-
70
- // check if errors (validation)
71
- $this->validate($this->_elements);
72
-
73
- do_action('wpcf_form_autohandle_validate', $id, $form, $this);
74
- do_action('wpcf_form_autohandle_validate_' . $id, $form, $this);
75
-
76
- // callback
77
- if (empty($this->_errors)) {
78
-
79
- if (isset($form['#form']['callback'])) {
80
- if (is_array($form['#form']['callback'])) {
81
- foreach ($form['#form']['callback'] as $callback) {
82
- if (is_callable($callback)) {
83
- call_user_func($callback, $this);
84
- }
85
- }
86
- } else {
87
- if (is_callable($form['#form']['callback'])) {
88
- call_user_func($form['#form']['callback'], $this);
89
- }
90
- }
91
- }
92
- // Maybe triggered by callback function
93
- if (empty($this->_errors)) {
94
- // redirect
95
- do_action('wpcf_form_autohandle_redirection', $id,
96
- $form, $this);
97
- do_action('wpcf_form_autohandle_redirection_' . $id,
98
- $form, $this);
99
- if (!isset($form['#form']['redirection'])) {
100
- header('Location: ' . $_SERVER['REQUEST_URI']);
101
- } else if ($form['#form']['redirection'] != false) {
102
- header('Location: ' . $form['#form']['redirection']);
103
- }
104
- }
105
- }
106
- }
107
- }
108
-
109
- /**
110
- * Checks if form is submitted.
111
- *
112
- * @param type $id
113
- * @return type
114
- */
115
- public function isSubmitted($id = '')
116
- {
117
- if (empty($id)) {
118
- $id = $this->_id;
119
- }
120
- return (isset($_REQUEST['_wpnonce_wpcf'])
121
- && wp_verify_nonce($_REQUEST['_wpnonce_wpcf'], $id));
122
- }
123
-
124
- /**
125
- * Loops over elements and validates them.
126
- *
127
- * @param type $elements
128
- */
129
- public function validate(&$elements)
130
- {
131
- require_once WPCF_EMBEDDED_ABSPATH . '/classes/validate.php';
132
- foreach ($elements as $key => &$element) {
133
- if (!isset($element['#type'])
134
- || !$this->_isValidType($element['#type'])) {
135
- continue;
136
- }
137
- if ($element['#type'] != 'fieldset') {
138
- if (isset($element['#name'])
139
- && !in_array($element['#type'],
140
- array('submit', 'reset'))) {
141
- // Set submitted data
142
- if (!in_array($element['#type'], array('checkboxes'))
143
- && empty($element['#forced_value'])) {
144
- $element['#value'] = $this->getSubmittedData($element);
145
- } else if (!empty($element['#options'])
146
- && empty($element['#forced_value'])) {
147
- foreach ($element['#options'] as $option_key => $option) {
148
- $option['#type'] = 'checkbox';
149
- $element['#options'][$option_key]['#value'] = $this->getSubmittedData($option);
150
- }
151
- }
152
- }
153
- // Validate
154
- if (isset($element['#validate'])) {
155
- $this->validateElement($element);
156
- }
157
- } else if (isset($element['#type'])
158
- && $element['#type'] == 'fieldset') {
159
- $this->validate($element);
160
- } else if (is_array($element)) {
161
- $this->validate($element);
162
- }
163
- }
164
- }
165
-
166
- /**
167
- * Validates element.
168
- *
169
- * @param type $element
170
- */
171
- public function validateElement(&$element)
172
- {
173
- $check = Wpcf_Validate::check($element['#validate'],
174
- $element['#value']);
175
- if (isset($check['error'])) {
176
- $this->_errors = true;
177
- $element['#error'] = $check['message'];
178
- }
179
- }
180
-
181
- /**
182
- * Checks if there are errors.
183
- *
184
- * @return type
185
- */
186
- public function isError()
187
- {
188
- return $this->_errors;
189
- }
190
-
191
- /**
192
- * Sets errors to true.
193
- */
194
- public function triggerError()
195
- {
196
- $this->_errors = true;
197
- }
198
-
199
- /**
200
- * Renders form.
201
- *
202
- * @return type
203
- */
204
- public function renderForm()
205
- {
206
- // loop over elements and render them
207
- return $this->renderElements($this->_elements);
208
- }
209
-
210
- /**
211
- * Counts element types.
212
- *
213
- * @param type $type
214
- * @return type
215
- */
216
- private function _count($type) {
217
- if (!isset($this->_count[$type])) {
218
- $this->_count[$type] = 0;
219
- }
220
- $this->_count[$type] += 1;
221
- return $this->_count[$type];
222
- }
223
-
224
- /**
225
- * Check if element is of valid type
226
- *
227
- * @param string $type
228
- * @return boolean
229
- */
230
- private function _isValidType($type)
231
- {
232
- return in_array($type,
233
- array('select', 'checkboxes', 'checkbox', 'radios',
234
- 'radio', 'textfield', 'textarea', 'file', 'submit', 'reset',
235
- 'hidden', 'fieldset', 'markup', 'button'));
236
- }
237
-
238
- /**
239
- * Renders elements.
240
- *
241
- * @param type $elements
242
- * @return type
243
- */
244
- public function renderElements($elements)
245
- {
246
- $output = '';
247
- foreach ($elements as $key => $element) {
248
- if (!isset($element['#type'])
249
- || !$this->_isValidType($element['#type'])) {
250
- continue;
251
- }
252
- if ($element['#type'] != 'fieldset') {
253
- $output .= $this->renderElement($element);
254
- } else if (isset($element['#type'])
255
- && $element['#type'] == 'fieldset') {
256
- $buffer = $this->renderElements($element);
257
- $output .= $this->fieldset($element, 'wrap', $buffer);
258
- } else if (is_array($element)) {
259
- $output .= $this->renderElements($element);
260
- }
261
- }
262
- return $output;
263
- }
264
-
265
- /**
266
- * Renders element.
267
- *
268
- * Depending on element type, it calls class methods.
269
- *
270
- * @param array $element
271
- * @return HTML formatted output
272
- */
273
- public function renderElement($element)
274
- {
275
- $method = $element['#type'];
276
- if (!isset($element['#name']) && $element['#type'] != 'markup') {
277
- if (!isset($element['#attributes']['name'])) {
278
- return '#name or #attributes[\'name\'] required!';
279
- } else {
280
- $element['#name'] = $element['#attributes']['name'];
281
- }
282
- }
283
- if (is_callable(array($this, $method))) {
284
- if (!isset($element['#id'])) {
285
- if (isset($element['#attributes']['id'])) {
286
- $element['#id'] = $element['#attributes']['id'];
287
- } else {
288
- $element['#id'] = $element['#type'] . '-'
289
- . $this->_count($element['#type']);
290
- }
291
- }
292
- if (isset($this->_errors[$element['#id']])) {
293
- $element['#error'] = $this->_errors[$element['#id']];
294
- }
295
- // Add JS validation
296
- if (!empty($element['#validate'])) {
297
- wpcf_form_add_js_validation($element);
298
- }
299
- return $this->{$method}($element);
300
- }
301
- }
302
-
303
- /**
304
- * Sets other element attributes.
305
- *
306
- * @param array $element
307
- * @return string
308
- */
309
- private function _setElementAttributes($element)
310
- {
311
- $attributes = '';
312
- $error_class = isset($element['#error']) ? ' ' . $this->css_class . '-error ' . $this->css_class . '-' . $element['#type'] . '-error ' . ' form-' . $element['#type'] . '-error ' . $element['#type'] . '-error form-error ' : '';
313
- $class = $this->css_class . '-' . $element['#type']
314
- . ' form-' . $element['#type'] . ' ' . $element['#type'];
315
- if (isset($element['#attributes'])) {
316
- foreach ($element['#attributes'] as $attribute => $value) {
317
- // Prevent undesired elements
318
- if (in_array($attribute, array('id', 'name'))) {
319
- continue;
320
- }
321
- // Don't set disabled for checkbox
322
- if ( ( 'disabled' == $attribute || '#disabled' == $attribute ) && $element['#type'] == 'checkbox') {
323
- continue;
324
- }
325
- // Append class values
326
- if ($attribute == 'class') {
327
- $value = $value . ' ' . $class . $error_class;
328
-
329
- }
330
- // Set return string
331
- $attributes .= ' ' . $attribute . '="' . $value . '"';
332
- }
333
- }
334
- if (!isset($element['#attributes']['class'])) {
335
- $is_default_element = isset( $element['#default_value'] ) && $element['#default_value'] ? ' wpcf-default-value-input' : '';
336
-
337
- $attributes .= ' class="' . $class . $error_class . $is_default_element . '"';
338
- }
339
- return $attributes;
340
- }
341
-
342
- /**
343
- * Sets render elements.
344
- *
345
- * @param array $element
346
- */
347
- private function _setRender($element)
348
- {
349
- if (!isset($element['#id'])) {
350
- if (isset($element['#attributes']['id'])) {
351
- $element['#id'] = $element['#attributes']['id'];
352
- } else {
353
- $element['#id'] = 'form-' . md5(serialize($element)) . '-'
354
- . $this->_count($element['#type']);
355
- }
356
- }
357
- $element['_attributes_string'] = $this->_setElementAttributes($element);
358
- $element['_render'] = array();
359
- $element['_render']['prefix'] = isset($element['#prefix']) ? $element['#prefix'] . "\r\n" : '';
360
- $element['_render']['suffix'] = isset($element['#suffix']) ? $element['#suffix'] . "\r\n" : '';
361
- $element['_render']['before'] = isset($element['#before']) ? $element['#before'] . "\r\n" : '';
362
- $element['_render']['after'] = isset($element['#after']) ? $element['#after'] . "\r\n" : '';
363
- $labelclass = '';
364
- if ( isset( $element['#labelclass'] ) ) {
365
- $labelclass = $element['#labelclass'] . ' ';
366
- }
367
- $labelstyle = '';
368
- if ( isset( $element['#labelstyle'] ) ) {
369
- $labelstyle = ' style="' . $element['#labelstyle'] . '" ';
370
- }
371
- $element['_render']['label'] = isset($element['#title']) ? '<label class="'
372
- . $labelclass
373
- . $this->css_class . '-label ' . $this->css_class . '-'
374
- . $element['#type'] . '-label" for="' . $element['#id'] . '"'.
375
- $labelstyle . '>'
376
- . stripslashes($element['#title'])
377
- . '</label>' . "\r\n" : '';
378
- $element['_render']['title'] = $this->_setElementTitle($element);
379
- $element['_render']['description'] = isset($element['#description']) ? $this->_setElementDescription($element) : '';
380
- $element['_render']['error'] = $this->renderError($element) . "\r\n";
381
-
382
- return $element;
383
- }
384
-
385
- /**
386
- * Applies pattern to output.
387
- *
388
- * Pass element property #pattern to get custom renedered element.
389
- *
390
- * @param array $pattern
391
- * Accepts: <prefix><suffix><label><title><desription><error>
392
- * @param array $element
393
- */
394
- private function _pattern($pattern, $element)
395
- {
396
- $pattern = strtolower($pattern);
397
- foreach ($element['_render'] as $key => $value) {
398
- $pattern = str_replace('<' . strtolower($key) . '>', $value,
399
- $pattern);
400
- }
401
- return $pattern;
402
- }
403
-
404
- /**
405
- * Wrapps element in <div></div>.
406
- *
407
- * @param arrat $element
408
- * @param string $output
409
- * @return string
410
- */
411
- private function _wrapElement($element, $output)
412
- {
413
- if (empty($element['#inline'])) {
414
- $wrapped = '<div id="' . $element['#id'] . '-wrapper"'
415
- . ' class="form-item form-item-' . $element['#type'] . ' '
416
- . $this->css_class . '-item '
417
- . $this->css_class . '-item-' . $element['#type']
418
- . '">' . $output . '</div>';
419
- return $wrapped;
420
- }
421
- return $output;
422
- }
423
-
424
- /**
425
- * Returns HTML formatted output for element's title.
426
- *
427
- * @param string $element
428
- * @return string
429
- */
430
- private function _setElementTitle($element)
431
- {
432
- $output = '';
433
- if (isset($element['#title'])) {
434
- $output .= '<div class="title '
435
- . $this->css_class . '-title '
436
- . $this->css_class . '-title-' . $element['#type'] . ' '
437
- . 'title-' . $element['#type'] . '">'
438
- . stripslashes($element['#title'])
439
- . "</div>\r\n";
440
- }
441
- return $output;
442
- }
443
-
444
- /**
445
- * Returns HTML formatted output for element's description.
446
- *
447
- * @param array $element
448
- * @return string
449
- */
450
- private function _setElementDescription($element)
451
- {
452
- $element['#description'] = stripslashes($element['#description']);
453
- $output = "\r\n"
454
- . '<div class="description '
455
- . $this->css_class . '-description '
456
- . $this->css_class . '-description-' . $element['#type'] . ' '
457
- . 'description-' . $element['#type'] . '">'
458
- . $element['#description'] . "</div>\r\n";
459
- return $output;
460
- }
461
-
462
- /**
463
- * Returns HTML formatted element's error message.
464
- *
465
- * Pass #supress_errors in #form element to avoid error rendering.
466
- *
467
- * @param array $element
468
- * @return string
469
- */
470
- public function renderError($element)
471
- {
472
- if (!isset($element['#error'])) {
473
- return '';
474
- }
475
- $output = '<div class="form-error '
476
- . $this->css_class . '-error '
477
- . $this->css_class . '-form-error '
478
- . $this->css_class . '-' . $element['#type'] . '-error '
479
- . $element['#type'] . '-error form-error-label'
480
- . '">' . $element['#error'] . '</div>'
481
- . "\r\n";
482
- return $output;
483
- }
484
-
485
- /**
486
- * Returns HTML formatted output for fieldset.
487
- *
488
- * @param array $element
489
- * @param string $action open|close|wrap
490
- * @param string $wrap_content HTML formatted output of child elements
491
- * @return string
492
- */
493
- public function fieldset($element, $action = 'open', $wrap_content = '')
494
- {
495
- $collapsible_open = '<div class="fieldset-wrapper">';
496
- $collapsible_close = '</div>';
497
- $legend_class = '';
498
- if (!isset($element['#id'])) {
499
- $element['#id'] = 'fieldset-' . $this->_count('fieldset');
500
- }
501
- if (!isset($element['_attributes_string'])) {
502
- $element['_attributes_string'] = $this->_setElementAttributes($element);
503
- }
504
- if ((isset($element['#collapsible']) && $element['#collapsible'])
505
- || (isset($element['#collapsed']) && $element['#collapsed'])) {
506
- $collapsible_open = '<div class="collapsible fieldset-wrapper">';
507
- $collapsible_close = '</div>';
508
- $legend_class = ' class="legend-expanded"';
509
- }
510
- if (isset($element['#collapsed']) && $element['#collapsed']) {
511
- $collapsible_open = str_replace('class="', 'class="collapsed ',
512
- $collapsible_open);
513
- $legend_class = ' class="legend-collapsed"';
514
- }
515
- $output = '';
516
- switch ($action) {
517
- case 'close':
518
- $output .= $collapsible_close . "</fieldset>\r\n";
519
- $output .= isset($element['#suffix']) ? $element['#suffix']
520
- . "\r\n" : '';
521
- $output .= "\n\r";
522
- break;
523
-
524
- case 'open':
525
- $output .= $collapsible_open;
526
- $output .= isset($element['#prefix']) ? $element['#prefix']
527
- . "\r\n" : '';
528
- $output .= '<fieldset' . $element['_attributes_string']
529
- . ' id="' . $element['#id'] . '">' . "\r\n";
530
- $output .= isset($element['#title']) ? '<legend'
531
- . $legend_class . '>'
532
- . stripslashes($element['#title'])
533
- . "</legend>\r\n" : '';
534
- $output .=
535
- isset($element['#description']) ? $this->_setElementDescription($element) : '';
536
- $output .= "\n\r";
537
- break;
538
-
539
- case 'wrap':
540
- if (!empty($wrap_content)) {
541
- $output .= isset($element['#prefix']) ? $element['#prefix'] : '';
542
- $output .= '<fieldset' . $element['_attributes_string']
543
- . ' id="' . $element['#id'] . '">' . "\r\n";
544
- $output .= '<legend' . $legend_class . '>'
545
- . stripslashes($element['#title'])
546
- . "</legend>\r\n"
547
- . $collapsible_open;
548
- $output .= isset($element['#description']) ? $this->_setElementDescription($element) : '';
549
- $output .= $wrap_content . $collapsible_close
550
- . "</fieldset>\r\n";
551
- $output .=
552
- isset($element['#suffix']) ? $element['#suffix'] : '';
553
- $output .= "\n\r";
554
- }
555
- break;
556
- }
557
- return $output;
558
- }
559
-
560
- /**
561
- * Returns HTML formatted output for checkbox element.
562
- *
563
- * @param array $element
564
- * @return string
565
- */
566
- public function checkbox($element)
567
- {
568
-
569
- $element['#type'] = 'checkbox';
570
- $element = $this->_setRender($element);
571
- $element['_render']['element'] = '<input type="checkbox" id="'
572
- . $element['#id'] . '" name="'
573
- . $element['#name'] . '" value="';
574
- // Specific: if value is empty force 1 to be rendered
575
- // Juan: removed this 1 forced value since it broke the default value in checkboxes filter controls
576
- $element['_render']['element'] .=
577
- !empty($element['#value']) ? htmlspecialchars($element['#value']) : '';
578
- $element['_render']['element'] .= '"' . $element['_attributes_string'];
579
- $element['_render']['element'] .= ((!$this->isSubmitted()
580
- && !empty($element['#default_value']))
581
- || ($this->isSubmitted()
582
- && !empty($element['#value']))) ? ' checked="checked"' : '';
583
- if (!empty($element['#attributes']['disabled']) || !empty($element['#disable'])) {
584
- $element['_render']['element'] .= ' onclick="javascript:return false; if(this.checked == 1){this.checked=1; return true;}else{this.checked=0; return false;}"';
585
- }
586
- if (!empty($element['#attributes']['#disabled'])) {
587
- $element['_render']['element'] .= ' disabled="disabled"';
588
- }
589
-
590
- $element['_render']['element'] .= ' />';
591
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT>&nbsp;<LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
592
- $output = $this->_pattern($pattern, $element);
593
- $output = $this->_wrapElement($element, $output);
594
- return $output . "\r\n";
595
- }
596
-
597
- /**
598
- * Returns HTML formatted output for checkboxes element.
599
- *
600
- * Renders more than one checkboxes provided as elements in '#options'
601
- * array element.
602
- *
603
- * @param array $element
604
- * @return string
605
- */
606
- public function checkboxes($element)
607
- {
608
- $element['#type'] = 'checkboxes';
609
- $element = $this->_setRender($element);
610
- $clone = $element;
611
- $clone['#type'] = 'checkbox';
612
- $element['_render']['element'] = '';
613
- foreach ($element['#options'] as $ID => $value) {
614
- if (!is_array($value)) {
615
- $value = array('#title' => $ID, '#value' => $value, '#name' => $element['#name'] . '[]');
616
- }
617
- $element['_render']['element'] .= $this->checkbox($value);
618
- }
619
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><PREFIX><TITLE><DESCRIPTION><ELEMENT><SUFFIX><AFTER>';
620
- $output = $this->_pattern($pattern, $element);
621
- $output = $this->_wrapElement($element, $output);
622
- return $output;
623
- }
624
-
625
- /**
626
- * Returns HTML formatted output for radio element.
627
- *
628
- * @param array $element
629
- * @return string
630
- */
631
- public function radio($element)
632
- {
633
- $element['#type'] = 'radio';
634
- $element = $this->_setRender($element);
635
- $element['_render']['element'] = '<input type="radio" id="'
636
- . $element['#id'] . '" name="'
637
- . $element['#name'] . '" value="';
638
- $element['_render']['element'] .= isset($element['#value']) ? htmlspecialchars($element['#value']) : $this->_count['radio'];
639
- $element['_render']['element'] .= '"';
640
- $element['_render']['element'] .= $element['_attributes_string'];
641
- $element['_render']['element'] .= ( isset($element['#value'])
642
- && $element['#value'] === $element['#default_value']) ? ' checked="checked"' : '';
643
- if (isset($element['#disable']) && $element['#disable']) {
644
- $element['_render']['element'] .= ' disabled="disabled"';
645
- }
646
- $element['_render']['element'] .= ' />';
647
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT>&nbsp;<LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
648
- $output = $this->_pattern($pattern, $element);
649
- $output = $this->_wrapElement($element, $output);
650
- return $output . "\r\n";
651
- }
652
-
653
- /**
654
- * Returns HTML formatted output for radios elements.
655
- *
656
- * Radios are provided via #options array.
657
- * Requires #name value.
658
- *
659
- * @param array $element
660
- * @return string
661
- */
662
- public function radios($element)
663
- {
664
- if (!isset($element['#name']) || empty($element['#name'])) {
665
- return FALSE;
666
- }
667
- $element['#type'] = 'radios';
668
- $element = $this->_setRender($element);
669
- $element['_render']['element'] = '';
670
- foreach ($element['#options'] as $ID => $value) {
671
- $this->_count('radio');
672
- if (!is_array($value)) {
673
- $value = array('#title' => $ID, '#value' => $value);
674
- $value['#inline'] = true;
675
- $value['#after'] = '<br />';
676
- }
677
- $value['#name'] = $element['#name'];
678
- $value['#default_value'] = isset($element['#default_value']) ? $element['#default_value'] : $value['#value'];
679
- if ( !isset( $value['#disable'] ) ) {
680
- $value['#disable'] = isset($element['#disable']) ? $element['#disable'] : false;
681
- }
682
- if ( isset( $element['#attributes'] ) && !isset( $value['#attributes'] ) ) {
683
- $value['#attributes'] = $element['#attributes'];
684
- }
685
- $element['_render']['element'] .= $this->radio($value);
686
- }
687
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><PREFIX><TITLE><DESCRIPTION><ELEMENT><SUFFIX><AFTER>';
688
- $output = $this->_pattern($pattern, $element);
689
- $output = $this->_wrapElement($element, $output);
690
- return $output;
691
- }
692
-
693
- /**
694
- * Returns HTML formatted output for select element.
695
- *
696
- * @param array $element
697
- * @return string
698
- */
699
- public function select($element)
700
- {
701
- $element['#type'] = 'select';
702
- $element = $this->_setRender($element);
703
- $multiple = isset( $element['#multiple'] ) ? $element['#multiple'] : '';
704
-
705
- $element['_render']['element'] = '<select '.$multiple.' id="' . $element['#id']
706
- . '" name="' . $element['#name'] . '"'
707
- . $element['_attributes_string'] . ">\r\n";
708
- $count = 1;
709
- foreach ($element['#options'] as $id => $value) {
710
- if (!is_array($value)) {
711
- $value = array('#title' => $id, '#value' => $value);
712
- }
713
- if (!isset($value['#value'])) {
714
- $value['#value'] = $this->_count['select'] . '-' . $count;
715
- $count += 1;
716
- }
717
-
718
- $value['#type'] = 'option';
719
- $element['_render']['element'] .= '<option value="'
720
- . htmlspecialchars($value['#value']) . '"';
721
-
722
- if( is_array( $element['#default_value'] ) )
723
- {
724
- $element['_render']['element'] .= in_array( $value['#value'], $element['#default_value'] ) ? ' selected="selected"' : '';
725
- }
726
- else
727
- {
728
- $element['_render']['element'] .= ( $element['#default_value']
729
- == $value['#value']) ? ' selected="selected"' : '';
730
- }
731
- if ( isset( $value['#disable'] ) ) {
732
- $element['_render']['element'] .= ' disabled="disabled"';
733
- }
734
-
735
- $element['_render']['element'] .= $this->_setElementAttributes($value);
736
- $element['_render']['element'] .= '>';
737
- $element['_render']['element'] .= isset($value['#title']) ? $value['#title'] : $value['#value'];
738
- $element['_render']['element'] .= "</option>\r\n";
739
- }
740
- $element['_render']['element'] .= "</select>\r\n";
741
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><LABEL><DESCRIPTION><ERROR><PREFIX><ELEMENT><SUFFIX><AFTER>';
742
- $output = $this->_pattern($pattern, $element);
743
- $output = $this->_wrapElement($element, $output);
744
- return $output;
745
- }
746
-
747
- /**
748
- * Returns HTML formatted output for textfield element.
749
- *
750
- * @param array $element
751
- * @return string
752
- */
753
- public function textfield($element)
754
- {
755
- $element['#type'] = 'textfield';
756
- $element = $this->_setRender($element);
757
- $element['_render']['element'] = '<input type="text" id="'
758
- . $element['#id'] . '" name="' . $element['#name'] . '" value="';
759
- $element['_render']['element'] .= isset($element['#value']) ? htmlspecialchars(stripslashes($element['#value'])) : '';
760
- $element['_render']['element'] .= '"' . $element['_attributes_string'];
761
- if (isset($element['#disable']) && $element['#disable']) {
762
- $element['_render']['element'] .= ' disabled="disabled"';
763
- }
764
- $element['_render']['element'] .= ' />';
765
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><LABEL><ERROR><PREFIX><ELEMENT><SUFFIX><DESCRIPTION><AFTER>';
766
- $output = $this->_pattern($pattern, $element);
767
- $output = $this->_wrapElement($element, $output);
768
- return $output . "\r\n";
769
- }
770
-
771
- /**
772
- * Returns HTML formatted output for textfield element.
773
- *
774
- * @param array $element
775
- * @return string
776
- */
777
- public function password($element)
778
- {
779
- $element['#type'] = 'password';
780
- $element = $this->_setRender($element);
781
- $element['_render']['element'] = '<input type="password" id="'
782
- . $element['#id'] . '" name="' . $element['#name'] . '" value="';
783
- $element['_render']['element'] .= isset($element['#value']) ? $element['#value'] : '';
784
- $element['_render']['element'] .= '"' . $element['_attributes_string'];
785
- if (isset($element['#disable']) && $element['#disable']) {
786
- $element['_render']['element'] .= ' disabled="disabled"';
787
- }
788
- $element['_render']['element'] .= ' />';
789
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><LABEL><ERROR><PREFIX><ELEMENT><SUFFIX><DESCRIPTION><AFTER>';
790
- $output = $this->_pattern($pattern, $element);
791
- $output = $this->_wrapElement($element, $output);
792
- return $output . "\r\n";
793
- }
794
-
795
- /**
796
- * Returns HTML formatted output for textarea element.
797
- *
798
- * @param array $element
799
- * @return string
800
- */
801
- public function textarea($element)
802
- {
803
- $element['#type'] = 'textarea';
804
- if (!isset($element['#attributes']['rows'])) {
805
- $element['#attributes']['rows'] = 5;
806
- }
807
- if (!isset($element['#attributes']['cols'])) {
808
- $element['#attributes']['cols'] = 1;
809
- }
810
- $element = $this->_setRender($element);
811
- $element['_render']['element'] = '<textarea id="' . $element['#id']
812
- . '" name="' . $element['#name'] . '"'
813
- . $element['_attributes_string'] . '>';
814
- $element['_render']['element'] .= isset($element['#value']) ? htmlspecialchars(stripslashes($element['#value'])) : '';
815
- $element['_render']['element'] .= '</textarea>' . "\r\n";
816
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><LABEL><DESCRIPTION><ERROR><PREFIX><ELEMENT><SUFFIX><AFTER>';
817
- $output = $this->_pattern($pattern, $element);
818
- $output = $this->_wrapElement($element, $output);
819
- return $output . "\r\n";
820
- }
821
-
822
- /**
823
- * Returns HTML formatted output for file upload element.
824
- *
825
- * @param array $element
826
- * @return string
827
- */
828
- public function file($element)
829
- {
830
- $element['#type'] = 'file';
831
- $element = $this->_setRender($element);
832
- $element['_render']['element'] = '<input type="file" id="'
833
- . $element['#id'] . '" name="' . $element['#name'] . '"'
834
- . $element['_attributes_string'];
835
- if (isset($element['#disable']) && $element['#disable']) {
836
- $element['_render']['element'] .= ' disabled="disabled"';
837
- }
838
- $element['_render']['element'] .= ' />';
839
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><LABEL><ERROR><PREFIX><ELEMENT><DESCRIPTION><SUFFIX><AFTER>';
840
- $output = $this->_pattern($pattern, $element);
841
- $output = $this->_wrapElement($element, $output);
842
- return $output;
843
- }
844
-
845
- /**
846
- * Returns HTML formatted output for markup element.
847
- *
848
- * @param array $element
849
- * @return string
850
- */
851
- public function markup($element)
852
- {
853
- return $element['#markup'];
854
- }
855
-
856
- /**
857
- * Returns HTML formatted output for hidden element.
858
- *
859
- * @param array $element
860
- * @return string
861
- */
862
- public function hidden($element)
863
- {
864
- $element['#type'] = 'hidden';
865
- $output = '<input type="hidden" id="' . $element['#id'] . '" name="'
866
- . $element['#name'] . '" value="';
867
- $output .= isset($element['#value']) ? $element['#value'] : 1;
868
- $output .= '" />';
869
- return $output;
870
- }
871
-
872
- /**
873
- * Returns HTML formatted output for reset button element.
874
- *
875
- * @param array $element
876
- * @return string
877
- */
878
- public function reset($element)
879
- {
880
- return $this->submit($element, 'reset', 'Reset');
881
- }
882
-
883
- /**
884
- * Returns HTML formatted output for button element.
885
- *
886
- * @param array $element
887
- * @return string
888
- */
889
- public function button($element)
890
- {
891
- return $this->submit($element, 'button', 'Button');
892
- }
893
-
894
- /**
895
- * Returns HTML formatted output for radio element.
896
- *
897
- * Used by reset and button.
898
- *
899
- * @param array $element
900
- * @param string $type
901
- * @param string $title
902
- * @return string
903
- */
904
- public function submit($element, $type = 'submit', $title = 'Submit')
905
- {
906
- $element['#type'] = $type;
907
- $element = $this->_setRender($element);
908
- $element['_render']['element'] = '<input type="' . $type . '" id="'
909
- . $element['#id'] . '" name="' . $element['#name'] . '" value="';
910
- $element['_render']['element'] .= isset($element['#value']) ? $element['#value'] : $title;
911
- $element['_render']['element'] .= '"' . $element['_attributes_string']
912
- . ' />';
913
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT><SUFFIX><AFTER>';
914
- $output = $this->_pattern($pattern, $element);
915
- return $output;
916
- }
917
-
918
- /**
919
- * Searches and returns submitted data for element.
920
- *
921
- * @param type $element
922
- * @return type mixed
923
- */
924
- public function getSubmittedData($element)
925
- {
926
- $name = $element['#name'];
927
- if (strpos($name, '[') === false) {
928
- if ($element['#type'] == 'file') {
929
- return $_FILES[$name]['tmp_name'];
930
- }
931
- return isset($_REQUEST[$name]) ? $_REQUEST[$name] : in_array($element['#type'],
932
- array('textfield', 'textarea')) ? '' : 0;
933
- }
934
-
935
- $parts = explode('[', $name);
936
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/196173458/comments
937
- //Security Fixing
938
- //$parts = array_map(create function('&$a', 'return trim($a, \']\');'), $parts);
939
- $parts = array_map("cred_mytrimfunction", $parts);
940
- if (!isset($_REQUEST[$parts[0]])) {
941
- return in_array($element['#type'],
942
- array('textfield', 'textarea')) ? '' : 0;
943
- }
944
- $search = $_REQUEST[$parts[0]];
945
- for ($index = 0; $index < count($parts); $index++) {
946
- $key = $parts[$index];
947
- // We're at the end but no data retrieved
948
- if (!isset($parts[$index + 1])) {
949
- return in_array($element['#type'],
950
- array('textfield', 'textarea')) ? '' : 0;
951
- }
952
- $key_next = $parts[$index + 1];
953
- if ($index > 0) {
954
- if (!isset($search[$key])) {
955
- return in_array($element['#type'],
956
- array('textfield', 'textarea')) ? '' : 0;
957
- } else {
958
- $search = $search[$key];
959
- }
960
- }
961
- if (is_array($search) && array_key_exists($key_next, $search)) {
962
- if (!is_array($search[$key_next])) {
963
- return $search[$key_next];
964
- }
965
- }
966
- }
967
- return 0;
968
- }
969
-
970
- }
971
-
972
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/classes/validate.php DELETED
@@ -1,425 +0,0 @@
1
- <?php
2
- require_once dirname(__FILE__) . '/validation-cakephp.php';
3
-
4
- /**
5
- * Validation class
6
- *
7
- * @version 1.0
8
- */
9
-
10
- if(!class_exists('Wpcf_Validate')) {
11
- class Wpcf_Validate
12
- {
13
-
14
- /**
15
- * Holds generic messages.
16
- * @var type
17
- */
18
- public static $messages = null;
19
- /**
20
- * Holds function names.
21
- * @var type
22
- */
23
- private static $_cake_aliases = array(
24
- 'digits' => 'numeric',
25
- 'number' => 'numeric',
26
- 'alphanumeric' => 'alphaNumericWhitespaces',
27
- 'nospecialchars' => 'noSpecialChars',
28
- );
29
- /**
30
- * Current validation has 'required' method.
31
- * @var type
32
- */
33
- private static $_is_required = false;
34
-
35
- private static $_validation_object = null;
36
-
37
- /**
38
- * Sets calls.
39
- *
40
- * @param type $args
41
- * @param type $value
42
- * @return type
43
- */
44
- public static function check($args, $value)
45
- {
46
- // Init validation object
47
- if (is_null(self::$_validation_object)) {
48
- self::$_validation_object = new Wpcf_Cake_Validation();
49
- }
50
-
51
- // Init messages
52
- if (is_null(self::$messages)) {
53
- self::_set_messages();
54
- }
55
- // Check if there is 'required' method
56
- if (array_key_exists('required', $args)) {
57
- self::$_is_required = true;
58
- }
59
-
60
- // Loop over validation array
61
- foreach ($args as $method => $v) {
62
- // Use this class method
63
- if (is_callable(array('Wpcf_Validate', $method))) {
64
- $check = call_user_func_array(array('Wpcf_Validate', $method),
65
- array($v, $value));
66
- // Use CakePHP method
67
- } else if ((isset(self::$_cake_aliases[$method])
68
- && is_callable(array('Wpcf_Cake_Validation', self::$_cake_aliases[$method])))
69
- || is_callable(array('Wpcf_Cake_Validation', $method))) {
70
-
71
- // Check if validation pattern is set
72
- if (isset($v['pattern'])) {
73
- $pattern = array_flip(explode('.', $v['pattern']));
74
- foreach ($pattern as $arg_key => $arg_value) {
75
- if (isset($v[$arg_key])) {
76
- $pattern[$arg_key] = $v[$arg_key];
77
- }
78
- }
79
- $pattern['check'] = $value;
80
- $v = $pattern;
81
- // Apply simple pattern (check, value)
82
- } else {
83
- unset($v['active'], $v['message']);
84
- $v = array($value) + $v;
85
- }
86
-
87
- // Validate
88
- if (isset(self::$_cake_aliases[$method]) && is_callable(array('Wpcf_Cake_Validation', self::$_cake_aliases[$method]))) {
89
- // $check = @call_user_func_array(array('Wpcf_Cake_Validation', self::$_cake_aliases[$method]),
90
- // array_values($v));
91
- $check = @call_user_func_array(array(self::$_validation_object, self::$_cake_aliases[$method]),
92
- array_values($v));
93
- } else {
94
- // $check = @call_user_func_array(array('Wpcf_Cake_Validation', $method),
95
- // array_values($v));
96
- $check = @call_user_func_array(array(self::$_validation_object, $method),
97
- array_values($v));
98
- }
99
- if (!$check) {
100
- $check = array();
101
- $check['error'] = 1;
102
- }
103
- // No method available
104
- } else {
105
- return array('error' => 1, 'message' => 'No validation method');
106
- }
107
-
108
- // Set error
109
- if (isset($check['error'])) {
110
- // Don't return error if it's empty but not required
111
- if ((!empty($value) && $method != 'required' && self::$_is_required)
112
- || (empty($value) && $method == 'required')) {
113
- $check['message'] = !empty($v['message']) ? $v['message'] : self::$messages[$method];
114
- return $check;
115
- }
116
- }
117
- }
118
-
119
- return true;
120
- }
121
-
122
- /**
123
- * Checks if method is available.
124
- *
125
- * @param type $method
126
- * @return type
127
- */
128
- public static function canValidate($method)
129
- {
130
- return (is_callable(array('Wpcf_Validate', $method))
131
- || (isset(self::$_cake_aliases[$method])
132
- && is_callable(array('Wpcf_Cake_Validation', self::$_cake_aliases[$method])))
133
- || is_callable(array('Wpcf_Cake_Validation', $method)));
134
- }
135
-
136
- /**
137
- * Checks if method has form data.
138
- *
139
- * @param type $method
140
- * @return type
141
- */
142
- public static function hasForm($method)
143
- {
144
- return is_callable(array('Wpcf_Validate', $method . '_form'));
145
- }
146
-
147
- /**
148
- * Inits messages.
149
- */
150
- private static function _set_messages()
151
- {
152
- // Set outside in /admin.php
153
- self::$messages = wpcf_admin_validation_messages();
154
- }
155
-
156
- /**
157
- * Return method invalid message.
158
- *
159
- * @param type $method
160
- * @return type
161
- */
162
- public static function get_message($method)
163
- {
164
- if (is_null(self::$messages)) {
165
- self::_set_messages();
166
- }
167
- if (isset(self::$messages[$method])) {
168
- return self::$messages[$method];
169
- }
170
- return null;
171
- }
172
-
173
- /**
174
- * Checks 'required'.
175
- *
176
- * @param type $args
177
- * @param type $value
178
- * @return type
179
- */
180
- public static function required($args, $value)
181
- {
182
- if (empty($value) && $value !== 0 && $value !== '0') {
183
- return array(
184
- 'error' => 1,
185
- );
186
- }
187
- return true;
188
- }
189
-
190
- /**
191
- * Returns form data.
192
- *
193
- * @param type $field
194
- * @param type $data
195
- * @return array
196
- */
197
- public static function required_form($field, $data = array())
198
- {
199
- $form = array();
200
- $form['required-checkbox'] = array(
201
- '#type' => 'checkbox',
202
- '#title' => __('Required', 'wpcf'),
203
- '#name' => $field['#name'] . '[active]',
204
- '#default_value' => isset($data['active']) ? 1 : 0,
205
- '#inline' => true,
206
- '#suffix' => '<br />',
207
- );
208
- $form['required-value'] = array(
209
- '#type' => 'hidden',
210
- '#value' => 'true',
211
- '#name' => $field['#name'] . '[value]',
212
- );
213
- $form['required-message'] = self::get_custom_message($field,
214
- self::get_message('required'), $data);
215
- return $form;
216
- }
217
-
218
- /**
219
- * Checks 'email'.
220
- *
221
- * @param type $args
222
- * @param type $value
223
- * @return type
224
- */
225
- public static function email($args, $value)
226
- {
227
- if (!is_email($value)) {
228
- return array(
229
- 'error' => 1,
230
- );
231
- }
232
- return true;
233
- }
234
-
235
- /**
236
- * Checks 'rewriteslug'.
237
- *
238
- * @param type $args
239
- * @param type $value
240
- * @return type
241
- */
242
- public static function rewriteslug($args, $value)
243
- {
244
- if (preg_match('#[^a-zA-Z0-9\/\_\-\%]#', $value) === false) {
245
- return array(
246
- 'error' => 1,
247
- );
248
- }
249
- return true;
250
- }
251
-
252
- /**
253
- * Returns form data.
254
- *
255
- * @param type $field
256
- * @param type $data
257
- * @return array
258
- */
259
- public static function email_form($field, $data = array())
260
- {
261
- $form = array();
262
- $form['email-checkbox'] = array(
263
- '#type' => 'checkbox',
264
- '#title' => __('Email', 'wpcf'),
265
- '#name' => $field['#name'] . '[active]',
266
- '#default_value' => isset($data['active']) ? 1 : 0,
267
- '#inline' => true,
268
- '#suffix' => '<br />',
269
- );
270
-
271
- $form['email-message'] = self::get_custom_message($field,
272
- self::get_message('email'), $data);
273
- return $form;
274
- }
275
-
276
- /**
277
- * Returns form data.
278
- *
279
- * @param type $field
280
- * @param type $data
281
- * @return array
282
- */
283
- public static function url_form($field, $data = array())
284
- {
285
- $form = array();
286
- $form['url-checkbox'] = array(
287
- '#type' => 'checkbox',
288
- '#title' => 'URL',
289
- '#name' => $field['#name'] . '[active]',
290
- '#default_value' => isset($data['active']) ? 1 : 0,
291
- '#inline' => true,
292
- '#suffix' => '<br />',
293
- );
294
-
295
- $form['url-message'] = self::get_custom_message($field,
296
- self::get_message('url'), $data);
297
- return $form;
298
- }
299
-
300
- /**
301
- * Returns form data.
302
- *
303
- * @param type $field
304
- * @param type $data
305
- * @return array
306
- */
307
- public static function date_form($field, $data = array())
308
- {
309
- $form = array();
310
- $form['date-checkbox'] = array(
311
- '#type' => 'checkbox',
312
- '#title' => __('Date', 'wpcf'),
313
- '#name' => $field['#name'] . '[active]',
314
- '#default_value' => isset($data['active']) ? 1 : 0,
315
- '#inline' => true,
316
- '#suffix' => '<br />',
317
- );
318
- $form['date-format'] = array(
319
- '#type' => 'hidden',
320
- '#value' => 'mdy',
321
- '#name' => $field['#name'] . '[format]',
322
- );
323
- $form['date-pattern'] = array(
324
- '#type' => 'hidden',
325
- '#value' => 'check.format',
326
- '#name' => $field['#name'] . '[pattern]',
327
- );
328
- $form['url-message'] = self::get_custom_message($field,
329
- self::get_message('date'), $data);
330
- return $form;
331
- }
332
-
333
- /**
334
- * Returns form data.
335
- *
336
- * @param type $field
337
- * @param type $data
338
- * @return array
339
- */
340
- public static function digits_form($field, $data = array())
341
- {
342
- $form = array();
343
- $attributes = array();
344
- $default_value = isset($data['active']) ? 1 : 0;
345
- $form['digits-checkbox'] = array(
346
- '#type' => 'checkbox',
347
- '#title' => __('Digits', 'wpcf'),
348
- '#name' => $field['#name'] . '[active]',
349
- '#default_value' => $default_value,
350
- '#inline' => true,
351
- '#suffix' => '<br />',
352
- '#attributes' => $attributes,
353
- );
354
- $form['digits-checkbox'] = self::setForced($form['digits-checkbox'], $field, $data);
355
-
356
- $form['digits-message'] = self::get_custom_message($field,
357
- self::get_message('digits'), $data);
358
- return $form;
359
- }
360
-
361
- /**
362
- * Returns form data.
363
- *
364
- * @param type $field
365
- * @param type $data
366
- * @return array
367
- */
368
- public static function number_form($field, $data = array())
369
- {
370
- $form = array();
371
- $attributes = array();
372
- $default_value = isset($data['active']) ? 1 : 0;
373
- $form['number-checkbox'] = array(
374
- '#type' => 'checkbox',
375
- '#title' => __('Numeric', 'wpcf'),
376
- '#name' => $field['#name'] . '[active]',
377
- '#default_value' => $default_value,
378
- '#inline' => true,
379
- '#suffix' => '<br />',
380
- '#attributes' => $attributes,
381
- );
382
- $form['number-checkbox'] = self::setForced($form['number-checkbox'], $field, $data);
383
-
384
- $form['number-message'] = self::get_custom_message($field,
385
- self::get_message('number'), $data);
386
- return $form;
387
- }
388
-
389
- public static function setForced($element, $field, $data = array())
390
- {
391
- $attributes = array();
392
- $default_value = isset($data['active']) ? 1 : 0;
393
- if (!empty($data['method_data']['forced'])) {
394
- if (!isset($element['#attributes'])) {
395
- $element['#attributes'] = array();
396
- }
397
- $element['#attributes']['readonly'] = 'readonly';
398
- $element['#attributes']['onclick'] = 'jQuery(this).attr(\'checked\', \'checked\');';
399
- $element['#default_value'] = 1;
400
- }
401
- return $element;
402
- }
403
-
404
- /**
405
- * Returns 'custom message' field.
406
- *
407
- * @param type $field
408
- * @param type $default
409
- * @param type $data
410
- * @return type
411
- */
412
- public static function get_custom_message($field, $default, $data)
413
- {
414
- return array(
415
- '#type' => 'textfield',
416
- // '#title' => __('Custom message', 'wpcf'),
417
- '#name' => $field['#name'] . '[message]',
418
- '#value' => !empty($data['message']) ? $data['message'] : $default,
419
- '#inline' => true,
420
- // '#suffix' => '<br /><br />',
421
- );
422
- }
423
-
424
- }
425
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/classes/validation-cakephp.php DELETED
@@ -1,1139 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Validation Class. Used for validation of model data
5
- *
6
- * PHP versions 4 and 5
7
- *
8
- * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
9
- * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
10
- *
11
- * Licensed under The MIT License
12
- * Redistributions of files must retain the above copyright notice.
13
- *
14
- * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
15
- * @link http://cakephp.org CakePHP(tm) Project
16
- * @package cake
17
- * @subpackage cake.cake.libs
18
- * @since CakePHP(tm) v 1.2.0.3830
19
- * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
20
- */
21
- //if (!class_exists('Multibyte')) {
22
- // App::import('Core', 'Multibyte', false);
23
- //}
24
- /**
25
- * Offers different validation methods.
26
- *
27
- * @package cake
28
- * @subpackage cake.cake.libs
29
- * @since CakePHP v 1.2.0.3830
30
- */
31
- //class Validation extends Object {
32
- if (!class_exists('Wpcf_Cake_Validation')) {
33
-
34
- class Wpcf_Cake_Validation {
35
-
36
- /**
37
- * Set the value of methods $check param.
38
- *
39
- * @var string
40
- * @access public
41
- */
42
- var $check = null;
43
-
44
- /**
45
- * Set to a valid regular expression in the class methods.
46
- * Can be set from $regex param also
47
- *
48
- * @var string
49
- * @access public
50
- */
51
- var $regex = null;
52
-
53
- /**
54
- * Some complex patterns needed in multiple places
55
- *
56
- * @var array
57
- * @access private
58
- */
59
- var $__pattern = array(
60
- 'hostname' => '(?:[a-z0-9][-a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)'
61
- );
62
-
63
- /**
64
- * Some class methods use a country to determine proper validation.
65
- * This can be passed to methods in the $country param
66
- *
67
- * @var string
68
- * @access public
69
- */
70
- var $country = null;
71
-
72
- /**
73
- * Some class methods use a deeper validation when set to true
74
- *
75
- * @var string
76
- * @access public
77
- */
78
- var $deep = null;
79
-
80
- /**
81
- * Some class methods use the $type param to determine which validation to perfom in the method
82
- *
83
- * @var string
84
- * @access public
85
- */
86
- var $type = null;
87
-
88
- /**
89
- * Holds an array of errors messages set in this class.
90
- * These are used for debugging purposes
91
- *
92
- * @var array
93
- * @access public
94
- */
95
- var $errors = array();
96
-
97
- /**
98
- * Gets a reference to the Validation object instance
99
- *
100
- * @return object Validation instance
101
- * @access public
102
- * @static
103
- */
104
- function &getInstance() {
105
- static $instance = array();
106
-
107
- if (!$instance) {
108
- $instance[0] = new Wpcf_Cake_Validation();
109
- }
110
- return $instance[0];
111
- }
112
-
113
- /**
114
- * Checks that a string contains something other than whitespace
115
- *
116
- * Returns true if string contains something other than whitespace
117
- *
118
- * $check can be passed as an array:
119
- * array('check' => 'valueToCheck');
120
- *
121
- * @param mixed $check Value to check
122
- * @return boolean Success
123
- * @access public
124
- */
125
- function notEmpty($check) {
126
- $_this = & Wpcf_Cake_Validation::getInstance();
127
- $_this->__reset();
128
- $_this->check = $check;
129
-
130
- if (is_array($check)) {
131
- $_this->_extract($check);
132
- }
133
-
134
- if (empty($_this->check) && $_this->check != '0') {
135
- return false;
136
- }
137
- $_this->regex = '/[^\s]+/m';
138
- return $_this->_check();
139
- }
140
-
141
- /**
142
- * Checks that a string contains only integer or letters
143
- *
144
- * Returns true if string contains only integer or letters
145
- *
146
- * $check can be passed as an array:
147
- * array('check' => 'valueToCheck');
148
- *
149
- * @param mixed $check Value to check
150
- * @return boolean Success
151
- * @access public
152
- */
153
- function alphaNumeric($check) {
154
- $_this = & Wpcf_Cake_Validation::getInstance();
155
- $_this->__reset();
156
- $_this->check = $check;
157
-
158
- if (is_array($check)) {
159
- $_this->_extract($check);
160
- }
161
-
162
- if (empty($_this->check) && $_this->check != '0') {
163
- return false;
164
- }
165
- $_this->regex = '/^[a-zA-Z0-9]*$/mu';
166
- $return = $_this->_check();
167
-
168
- if (!$return) {
169
- $_this->regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/mu';
170
- $return = $_this->_check();
171
- }
172
-
173
- return $_this->_check();
174
- }
175
-
176
- function alphaNumericWhitespaces($check) {
177
- $_this = & Wpcf_Cake_Validation::getInstance();
178
- $_this->__reset();
179
- $_this->check = $check;
180
-
181
- if (is_array($check)) {
182
- $_this->_extract($check);
183
- }
184
-
185
- if (empty($_this->check) && $_this->check != '0') {
186
- return false;
187
- }
188
- $_this->regex = '/^[a-zA-Z0-9\s\-\_]*$/mu';
189
- $return = $_this->_check();
190
-
191
- if (!$return) {
192
- $_this->regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}\s\-\_]+$/mu';
193
- $return = $_this->_check();
194
- }
195
-
196
- return $return;
197
- }
198
-
199
- /**
200
- * Checks that a string length is within s specified range.
201
- * Spaces are included in the character count.
202
- * Returns true is string matches value min, max, or between min and max,
203
- *
204
- * @param string $check Value to check for length
205
- * @param integer $min Minimum value in range (inclusive)
206
- * @param integer $max Maximum value in range (inclusive)
207
- * @return boolean Success
208
- * @access public
209
- */
210
- function between($check, $min, $max) {
211
- $length = strlen($check);
212
- return ($length >= $min && $length <= $max);
213
- }
214
-
215
- /**
216
- * Returns true if field is left blank -OR- only whitespace characters are present in it's value
217
- * Whitespace characters include Space, Tab, Carriage Return, Newline
218
- *
219
- * $check can be passed as an array:
220
- * array('check' => 'valueToCheck');
221
- *
222
- * @param mixed $check Value to check
223
- * @return boolean Success
224
- * @access public
225
- */
226
- function blank($check) {
227
- $_this = & Wpcf_Cake_Validation::getInstance();
228
- $_this->__reset();
229
- $_this->check = $check;
230
-
231
- if (is_array($check)) {
232
- $_this->_extract($check);
233
- }
234
-
235
- $_this->regex = '/[^\\s]/';
236
- return !$_this->_check();
237
- }
238
-
239
- /**
240
- * Validation of credit card numbers.
241
- * Returns true if $check is in the proper credit card format.
242
- *
243
- * @param mixed $check credit card number to validate
244
- * @param mixed $type 'all' may be passed as a sting, defaults to fast which checks format of most major credit cards
245
- * if an array is used only the values of the array are checked.
246
- * Example: array('amex', 'bankcard', 'maestro')
247
- * @param boolean $deep set to true this will check the Luhn algorithm of the credit card.
248
- * @param string $regex A custom regex can also be passed, this will be used instead of the defined regex values
249
- * @return boolean Success
250
- * @access public
251
- * @see Wpcf_Cake_Validation::_luhn()
252
- */
253
- function cc($check, $type = 'fast', $deep = false, $regex = null) {
254
- $_this = & Wpcf_Cake_Validation::getInstance();
255
- $_this->__reset();
256
- $_this->check = $check;
257
- $_this->type = $type;
258
- $_this->deep = $deep;
259
- $_this->regex = $regex;
260
-
261
- if (is_array($check)) {
262
- $_this->_extract($check);
263
- }
264
- $_this->check = str_replace(array('-', ' '), '', $_this->check);
265
-
266
- if (strlen($_this->check) < 13) {
267
- return false;
268
- }
269
-
270
- if (!is_null($_this->regex)) {
271
- if ($_this->_check()) {
272
- return $_this->_luhn();
273
- }
274
- }
275
- $cards = array(
276
- 'all' => array(
277
- 'amex' => '/^3[4|7]\\d{13}$/',
278
- 'bankcard' => '/^56(10\\d\\d|022[1-5])\\d{10}$/',
279
- 'diners' => '/^(?:3(0[0-5]|[68]\\d)\\d{11})|(?:5[1-5]\\d{14})$/',
280
- 'disc' => '/^(?:6011|650\\d)\\d{12}$/',
281
- 'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/',
282
- 'enroute' => '/^2(?:014|149)\\d{11}$/',
283
- 'jcb' => '/^(3\\d{4}|2100|1800)\\d{11}$/',
284
- 'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
285
- 'mc' => '/^5[1-5]\\d{14}$/',
286
- 'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
287
- 'switch' => '/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/',
288
- 'visa' => '/^4\\d{12}(\\d{3})?$/',
289
- 'voyager' => '/^8699[0-9]{11}$/'
290
- ),
291
- 'fast' => '/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/'
292
- );
293
-
294
- if (is_array($_this->type)) {
295
- foreach ($_this->type as $value) {
296
- $_this->regex = $cards['all'][strtolower($value)];
297
-
298
- if ($_this->_check()) {
299
- return $_this->_luhn();
300
- }
301
- }
302
- } elseif ($_this->type == 'all') {
303
- foreach ($cards['all'] as $value) {
304
- $_this->regex = $value;
305
-
306
- if ($_this->_check()) {
307
- return $_this->_luhn();
308
- }
309
- }
310
- } else {
311
- $_this->regex = $cards['fast'];
312
-
313
- if ($_this->_check()) {
314
- return $_this->_luhn();
315
- }
316
- }
317
- }
318
-
319
- /**
320
- * Used to compare 2 numeric values.
321
- *
322
- * @param mixed $check1 if string is passed for a string must also be passed for $check2
323
- * used as an array it must be passed as array('check1' => value, 'operator' => 'value', 'check2' -> value)
324
- * @param string $operator Can be either a word or operand
325
- * is greater >, is less <, greater or equal >=
326
- * less or equal <=, is less <, equal to ==, not equal !=
327
- * @param integer $check2 only needed if $check1 is a string
328
- * @return boolean Success
329
- * @access public
330
- */
331
- function comparison($check1, $operator = null, $check2 = null) {
332
- if (is_array($check1)) {
333
- extract($check1, EXTR_OVERWRITE);
334
- }
335
- $operator = str_replace(array(' ', "\t", "\n", "\r", "\0", "\x0B"), '', strtolower($operator));
336
-
337
- switch ($operator) {
338
- case 'isgreater':
339
- case '>':
340
- if ($check1 > $check2) {
341
- return true;
342
- }
343
- break;
344
- case 'isless':
345
- case '<':
346
- if ($check1 < $check2) {
347
- return true;
348
- }
349
- break;
350
- case 'greaterorequal':
351
- case '>=':
352
- if ($check1 >= $check2) {
353
- return true;
354
- }
355
- break;
356
- case 'lessorequal':
357
- case '<=':
358
- if ($check1 <= $check2) {
359
- return true;
360
- }
361
- break;
362
- case 'equalto':
363
- case '==':
364
- if ($check1 == $check2) {
365
- return true;
366
- }
367
- break;
368
- case 'notequal':
369
- case '!=':
370
- if ($check1 != $check2) {
371
- return true;
372
- }
373
- break;
374
- default:
375
- $_this = & Wpcf_Cake_Validation::getInstance();
376
- $_this->errors[] = __('You must define the $operator parameter for Wpcf_Cake_Validation::comparison()', 'wpcf');
377
- break;
378
- }
379
- return false;
380
- }
381
-
382
- /**
383
- * Used when a custom regular expression is needed.
384
- *
385
- * @param mixed $check When used as a string, $regex must also be a valid regular expression.
386
- * As and array: array('check' => value, 'regex' => 'valid regular expression')
387
- * @param string $regex If $check is passed as a string, $regex must also be set to valid regular expression
388
- * @return boolean Success
389
- * @access public
390
- */
391
- function custom($check, $regex = null) {
392
- $_this = & Wpcf_Cake_Validation::getInstance();
393
- $_this->__reset();
394
- $_this->check = $check;
395
- $_this->regex = $regex;
396
- if (is_array($check)) {
397
- $_this->_extract($check);
398
- }
399
- if ($_this->regex === null) {
400
- $_this->errors[] = __('You must define a regular expression for Wpcf_Cake_Validation::custom()', 'wpcf');
401
- return false;
402
- }
403
- return $_this->_check();
404
- }
405
-
406
- /**
407
- * Date validation, determines if the string passed is a valid date.
408
- * keys that expect full month, day and year will validate leap years
409
- *
410
- * @param string $check a valid date string
411
- * @param mixed $format Use a string or an array of the keys below. Arrays should be passed as array('dmy', 'mdy', etc)
412
- * Keys: dmy 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash
413
- * mdy 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash
414
- * ymd 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash
415
- * dMy 27 December 2006 or 27 Dec 2006
416
- * Mdy December 27, 2006 or Dec 27, 2006 comma is optional
417
- * My December 2006 or Dec 2006
418
- * my 12/2006 separators can be a space, period, dash, forward slash
419
- * @param string $regex If a custom regular expression is used this is the only validation that will occur.
420
- * @return boolean Success
421
- * @access public
422
- */
423
- function date($check, $format = 'ymd', $regex = null) {
424
-
425
- $date_format = wpcf_get_date_format();
426
- $cake_date_formats = array(
427
- 'F j, Y' => 'Mdy',
428
- 'Y/m/d' => 'ymd',
429
- 'm/d/Y' => 'mdy',
430
- 'd/m/Y' => 'dmy',
431
- 'd/m/y' => 'dmy',
432
- );
433
-
434
- $format = $cake_date_formats[$date_format];
435
-
436
- $_this = & Wpcf_Cake_Validation::getInstance();
437
- $_this->__reset();
438
- $_this->check = $check;
439
- $_this->regex = $regex;
440
-
441
- if (!is_null($_this->regex)) {
442
- return $_this->_check();
443
- }
444
-
445
- $regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.|\\x20)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.|\\x20)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.|\\x20)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
446
- $regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])(\\/|-|\\.|\\x20)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.|\\x20)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.|\\x20)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
447
- $regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\\/|-|\\.|\\x20)(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})(\\/|-|\\.|\\x20)(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%';
448
- $regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/';
449
- $regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/';
450
- $regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\\d)\\d{2})$%';
451
- $regex['my'] = '%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$%';
452
-
453
- $format = (is_array($format)) ? array_values($format) : array($format);
454
- foreach ($format as $key) {
455
- $_this->regex = $regex[$key];
456
-
457
- if ($_this->_check() === true) {
458
- return true;
459
- }
460
- }
461
- return false;
462
- }
463
-
464
- /**
465
- * Time validation, determines if the string passed is a valid time.
466
- * Validates time as 24hr (HH:MM) or am/pm ([H]H:MM[a|p]m)
467
- * Does not allow/validate seconds.
468
- *
469
- * @param string $check a valid time string
470
- * @return boolean Success
471
- * @access public
472
- */
473
- function time($check) {
474
- $_this = & Wpcf_Cake_Validation::getInstance();
475
- $_this->__reset();
476
- $_this->check = $check;
477
- $_this->regex = '%^((0?[1-9]|1[012])(:[0-5]\d){0,2}([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%';
478
- return $_this->_check();
479
- }
480
-
481
- /**
482
- * Boolean validation, determines if value passed is a boolean integer or true/false.
483
- *
484
- * @param string $check a valid boolean
485
- * @return boolean Success
486
- * @access public
487
- */
488
- function boolean($check) {
489
- $booleanList = array(0, 1, '0', '1', true, false);
490
- return in_array($check, $booleanList, true);
491
- }
492
-
493
- /**
494
- * Checks that a value is a valid decimal. If $places is null, the $check is allowed to be a scientific float
495
- * If no decimal point is found a false will be returned. Both the sign and exponent are optional.
496
- *
497
- * @param integer $check The value the test for decimal
498
- * @param integer $places if set $check value must have exactly $places after the decimal point
499
- * @param string $regex If a custom regular expression is used this is the only validation that will occur.
500
- * @return boolean Success
501
- * @access public
502
- */
503
- function decimal($check, $places = null, $regex = null) {
504
- $_this = & Wpcf_Cake_Validation::getInstance();
505
- $_this->__reset();
506
- $_this->regex = $regex;
507
- $_this->check = $check;
508
-
509
- if (is_null($_this->regex)) {
510
- if (is_null($places)) {
511
- $_this->regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/';
512
- } else {
513
- $_this->regex = '/^[-+]?[0-9]*\\.{1}[0-9]{' . $places . '}$/';
514
- }
515
- }
516
- return $_this->_check();
517
- }
518
-
519
- /**
520
- * Validates for an email address.
521
- *
522
- * @param string $check Value to check
523
- * @param boolean $deep Perform a deeper validation (if true), by also checking availability of host
524
- * @param string $regex Regex to use (if none it will use built in regex)
525
- * @return boolean Success
526
- * @access public
527
- */
528
- function email($check, $deep = false, $regex = null) {
529
- $_this = & Wpcf_Cake_Validation::getInstance();
530
- $_this->__reset();
531
- $_this->check = $check;
532
- $_this->regex = $regex;
533
- $_this->deep = $deep;
534
-
535
- if (is_array($check)) {
536
- $_this->_extract($check);
537
- }
538
-
539
- if (is_null($_this->regex)) {
540
- $_this->regex = '/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@' . $_this->__pattern['hostname'] . '$/i';
541
- }
542
- $return = $_this->_check();
543
-
544
- if ($_this->deep === false || $_this->deep === null) {
545
- return $return;
546
- }
547
-
548
- if ($return === true && preg_match('/@(' . $_this->__pattern['hostname'] . ')$/i', $_this->check, $regs)) {
549
- if (function_exists('getmxrr') && getmxrr($regs[1], $mxhosts)) {
550
- return true;
551
- }
552
- if (function_exists('checkdnsrr') && checkdnsrr($regs[1], 'MX')) {
553
- return true;
554
- }
555
- return is_array(gethostbynamel($regs[1]));
556
- }
557
- return false;
558
- }
559
-
560
- /**
561
- * Check that value is exactly $comparedTo.
562
- *
563
- * @param mixed $check Value to check
564
- * @param mixed $comparedTo Value to compare
565
- * @return boolean Success
566
- * @access public
567
- */
568
- function equalTo($check, $comparedTo) {
569
- return ($check === $comparedTo);
570
- }
571
-
572
- /**
573
- * Check that value has a valid file extension.
574
- *
575
- * @param mixed $check Value to check
576
- * @param array $extensions file extenstions to allow
577
- * @return boolean Success
578
- * @access public
579
- */
580
- function extension($check, $extensions = array('gif', 'jpeg', 'png', 'jpg')) {
581
- if (is_array($check)) {
582
- return Wpcf_Cake_Validation::extension(array_shift($check), $extensions);
583
- }
584
- $extension = strtolower(array_pop(explode('.', $check)));
585
- foreach ($extensions as $value) {
586
- if ($extension == strtolower($value)) {
587
- return true;
588
- }
589
- }
590
- return false;
591
- }
592
-
593
- /**
594
- * Validation of an IP address.
595
- *
596
- * Valid IP version strings for type restriction are:
597
- * - both: Check both IPv4 and IPv6, return true if the supplied address matches either version
598
- * - IPv4: Version 4 (Eg: 127.0.0.1, 192.168.10.123, 203.211.24.8)
599
- * - IPv6: Version 6 (Eg: ::1, 2001:0db8::1428:57ab)
600
- *
601
- * @param string $check The string to test.
602
- * @param string $type The IP Version to test against
603
- * @return boolean Success
604
- * @access public
605
- */
606
- function ip($check, $type = 'both') {
607
- $_this = & Wpcf_Cake_Validation::getInstance();
608
- $success = false;
609
- $type = strtolower($type);
610
- if ($type === 'ipv4' || $type === 'both') {
611
- $success |= $_this->_ipv4($check);
612
- }
613
- if ($type === 'ipv6' || $type === 'both') {
614
- $success |= $_this->_ipv6($check);
615
- }
616
- return $success;
617
- }
618
-
619
- /**
620
- * Validation of IPv4 addresses.
621
- *
622
- * @param string $check IP Address to test
623
- * @return boolean Success
624
- * @access protected
625
- */
626
- function _ipv4($check) {
627
- if (function_exists('filter_var')) {
628
- return filter_var($check, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV4)) !== false;
629
- }
630
- $this->__populateIp();
631
- $this->check = $check;
632
- $this->regex = '/^' . $this->__pattern['IPv4'] . '$/';
633
- return $this->_check();
634
- }
635
-
636
- /**
637
- * Validation of IPv6 addresses.
638
- *
639
- * @param string $check IP Address to test
640
- * @return boolean Success
641
- * @access protected
642
- */
643
- function _ipv6($check) {
644
- if (function_exists('filter_var')) {
645
- return filter_var($check, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV6)) !== false;
646
- }
647
- $this->__populateIp();
648
- $this->check = $check;
649
- $this->regex = '/^' . $this->__pattern['IPv6'] . '$/';
650
- return $this->_check();
651
- }
652
-
653
- /**
654
- * Checks whether the length of a string is greater or equal to a minimal length.
655
- *
656
- * @param string $check The string to test
657
- * @param integer $min The minimal string length
658
- * @return boolean Success
659
- * @access public
660
- */
661
- function minLength($check, $min) {
662
- $length = strlen($check);
663
- return ($length >= $min);
664
- }
665
-
666
- /**
667
- * Checks whether the length of a string is smaller or equal to a maximal length..
668
- *
669
- * @param string $check The string to test
670
- * @param integer $max The maximal string length
671
- * @return boolean Success
672
- * @access public
673
- */
674
- function maxLength($check, $max) {
675
- $length = strlen($check);
676
- return ($length <= $max);
677
- }
678
-
679
- /**
680
- * Checks that a value is a monetary amount.
681
- *
682
- * @param string $check Value to check
683
- * @param string $symbolPosition Where symbol is located (left/right)
684
- * @return boolean Success
685
- * @access public
686
- */
687
- function money($check, $symbolPosition = 'left') {
688
- $_this = & Wpcf_Cake_Validation::getInstance();
689
- $_this->check = $check;
690
-
691
- if ($symbolPosition == 'right') {
692
- $_this->regex = '/^(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?(?<!\x{00a2})\p{Sc}?$/u';
693
- } else {
694
- $_this->regex = '/^(?!\x{00a2})\p{Sc}?(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?$/u';
695
- }
696
- return $_this->_check();
697
- }
698
-
699
- /**
700
- * Validate a multiple select.
701
- *
702
- * Valid Options
703
- *
704
- * - in => provide a list of choices that selections must be made from
705
- * - max => maximun number of non-zero choices that can be made
706
- * - min => minimum number of non-zero choices that can be made
707
- *
708
- * @param mixed $check Value to check
709
- * @param mixed $options Options for the check.
710
- * @return boolean Success
711
- * @access public
712
- */
713
- function multiple($check, $options = array()) {
714
- $defaults = array('in' => null, 'max' => null, 'min' => null);
715
- $options = array_merge($defaults, $options);
716
- $check = array_filter((array) $check);
717
- if (empty($check)) {
718
- return false;
719
- }
720
- if ($options['max'] && count($check) > $options['max']) {
721
- return false;
722
- }
723
- if ($options['min'] && count($check) < $options['min']) {
724
- return false;
725
- }
726
- if ($options['in'] && is_array($options['in'])) {
727
- foreach ($check as $val) {
728
- if (!in_array($val, $options['in'])) {
729
- return false;
730
- }
731
- }
732
- }
733
- return true;
734
- }
735
-
736
- /**
737
- * Checks if a value is numeric.
738
- *
739
- * @param string $check Value to check
740
- * @return boolean Succcess
741
- * @access public
742
- */
743
- function numeric($check) {
744
- return is_numeric($check);
745
- }
746
-
747
- /**
748
- * Checks if a value is integer.
749
- *
750
- * @param string $check Value to check
751
- * @return boolean Succcess
752
- * @access public
753
- */
754
- function integer($check) {
755
- return is_int(intval($check));
756
- }
757
-
758
- /**
759
- * Checks if a value is valid hexadecimal.
760
- *
761
- * @param string $check Value to check
762
- * @return boolean Succcess
763
- * @access public
764
- */
765
- function hexadecimal($check) {
766
- return preg_match('/^#[a-f0-9]{6}$/i', $check);
767
- }
768
-
769
- /**
770
- * Check that a value is a valid phone number.
771
- *
772
- * @param mixed $check Value to check (string or array)
773
- * @param string $regex Regular expression to use
774
- * @param string $country Country code (defaults to 'all')
775
- * @return boolean Success
776
- * @access public
777
- */
778
- function phone($check, $regex = null, $country = 'all') {
779
- $_this = & Wpcf_Cake_Validation::getInstance();
780
- $_this->check = $check;
781
- $_this->regex = $regex;
782
- $_this->country = $country;
783
- if (is_array($check)) {
784
- $_this->_extract($check);
785
- }
786
-
787
- if (is_null($_this->regex)) {
788
- switch ($_this->country) {
789
- case 'us':
790
- case 'all':
791
- case 'can':
792
- // includes all NANPA members. see http://en.wikipedia.org/wiki/North_American_Numbering_Plan#List_of_NANPA_countries_and_territories
793
- $_this->regex = '/^(?:\+?1)?[-. ]?\\(?[2-9][0-8][0-9]\\)?[-. ]?[2-9][0-9]{2}[-. ]?[0-9]{4}$/';
794
- break;
795
- }
796
- }
797
- if (empty($_this->regex)) {
798
- return $_this->_pass('phone', $check, $country);
799
- }
800
- return $_this->_check();
801
- }
802
-
803
- /**
804
- * Checks that a given value is a valid postal code.
805
- *
806
- * @param mixed $check Value to check
807
- * @param string $regex Regular expression to use
808
- * @param string $country Country to use for formatting
809
- * @return boolean Success
810
- * @access public
811
- */
812
- function postal($check, $regex = null, $country = null) {
813
- $_this = & Wpcf_Cake_Validation::getInstance();
814
- $_this->check = $check;
815
- $_this->regex = $regex;
816
- $_this->country = $country;
817
- if (is_array($check)) {
818
- $_this->_extract($check);
819
- }
820
- if (empty($country)) {
821
- $_this->country = 'us';
822
- }
823
-
824
- if (is_null($_this->regex)) {
825
- switch ($_this->country) {
826
- case 'uk':
827
- $_this->regex = '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i';
828
- break;
829
- case 'ca':
830
- $_this->regex = '/\\A\\b[ABCEGHJKLMNPRSTVXY][0-9][A-Z] ?[0-9][A-Z][0-9]\\b\\z/i';
831
- break;
832
- case 'it':
833
- case 'de':
834
- $_this->regex = '/^[0-9]{5}$/i';
835
- break;
836
- case 'be':
837
- $_this->regex = '/^[1-9]{1}[0-9]{3}$/i';
838
- break;
839
- case 'us':
840
- $_this->regex = '/\\A\\b[0-9]{5}(?:-[0-9]{4})?\\b\\z/i';
841
- break;
842
- }
843
- }
844
- if (empty($_this->regex)) {
845
- return $_this->_pass('postal', $check, $country);
846
- }
847
- return $_this->_check();
848
- }
849
-
850
- /**
851
- * Validate that a number is in specified range.
852
- * if $lower and $upper are not set, will return true if
853
- * $check is a legal finite on this platform
854
- *
855
- * @param string $check Value to check
856
- * @param integer $lower Lower limit
857
- * @param integer $upper Upper limit
858
- * @return boolean Success
859
- * @access public
860
- */
861
- function range($check, $lower = null, $upper = null) {
862
- if (!is_numeric($check)) {
863
- return false;
864
- }
865
- if (isset($lower) && isset($upper)) {
866
- return ($check > $lower && $check < $upper);
867
- }
868
- return is_finite($check);
869
- }
870
-
871
- /**
872
- * Checks that a value is a valid Social Security Number.
873
- *
874
- * @param mixed $check Value to check
875
- * @param string $regex Regular expression to use
876
- * @param string $country Country
877
- * @return boolean Success
878
- * @access public
879
- */
880
- function ssn($check, $regex = null, $country = null) {
881
- $_this = & Wpcf_Cake_Validation::getInstance();
882
- $_this->check = $check;
883
- $_this->regex = $regex;
884
- $_this->country = $country;
885
- if (is_array($check)) {
886
- $_this->_extract($check);
887
- }
888
-
889
- if (is_null($_this->regex)) {
890
- switch ($_this->country) {
891
- case 'dk':
892
- $_this->regex = '/\\A\\b[0-9]{6}-[0-9]{4}\\b\\z/i';
893
- break;
894
- case 'nl':
895
- $_this->regex = '/\\A\\b[0-9]{9}\\b\\z/i';
896
- break;
897
- case 'us':
898
- $_this->regex = '/\\A\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b\\z/i';
899
- break;
900
- }
901
- }
902
- if (empty($_this->regex)) {
903
- return $_this->_pass('ssn', $check, $country);
904
- }
905
- return $_this->_check();
906
- }
907
-
908
- /**
909
- * Checks that a value is a valid uuid - http://tools.ietf.org/html/rfc4122
910
- *
911
- * @param string $check Value to check
912
- * @return boolean Success
913
- * @access public
914
- */
915
- function uuid($check) {
916
- $_this = & Wpcf_Cake_Validation::getInstance();
917
- $_this->check = $check;
918
- $_this->regex = '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i';
919
- return $_this->_check();
920
- }
921
-
922
- /**
923
- * Checks that a value is a valid URL according to http://www.w3.org/Addressing/URL/url-spec.txt
924
- *
925
- * The regex checks for the following component parts:
926
- *
927
- * - a valid, optional, scheme
928
- * - a valid ip address OR
929
- * a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt
930
- * with an optional port number
931
- * - an optional valid path
932
- * - an optional query string (get parameters)
933
- * - an optional fragment (anchor tag)
934
- *
935
- * @param string $check Value to check
936
- * @param boolean $strict Require URL to be prefixed by a valid scheme (one of http(s)/ftp(s)/file/news/gopher)
937
- * @return boolean Success
938
- * @access public
939
- */
940
- function url($check, $strict = false) {
941
- $_this = & Wpcf_Cake_Validation::getInstance();
942
- $_this->__populateIp();
943
- $_this->check = $check;
944
- $validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~[]') . '\/0-9a-z\p{L}\p{N}]|(%[0-9a-f]{2}))';
945
- $_this->regex = '/^(?:(?:https?|ftps?|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
946
- '(?:' . $_this->__pattern['IPv4'] . '|\[' . $_this->__pattern['IPv6'] . '\]|' . $_this->__pattern['hostname'] . ')' .
947
- '(?::[1-9][0-9]{0,4})?' .
948
- '(?:\/?|\/' . $validChars . '*)?' .
949
- '(?:\?' . $validChars . '*)?' .
950
- '(?:#' . $validChars . '*)?$/iu';
951
- return $_this->_check();
952
- }
953
-
954
- /**
955
- * Checks if a value is in a given list.
956
- *
957
- * @param string $check Value to check
958
- * @param array $list List to check against
959
- * @return boolean Succcess
960
- * @access public
961
- */
962
- function inList($check, $list) {
963
- return in_array($check, $list);
964
- }
965
-
966
- /**
967
- * Runs an user-defined validation.
968
- *
969
- * @param mixed $check value that will be validated in user-defined methods.
970
- * @param object $object class that holds validation method
971
- * @param string $method class method name for validation to run
972
- * @param array $args arguments to send to method
973
- * @return mixed user-defined class class method returns
974
- * @access public
975
- */
976
- function userDefined($check, $object, $method, $args = null) {
977
- return call_user_func_array(array(&$object, $method), array($check, $args));
978
- }
979
-
980
- function noSpecialChars($check) {
981
- return preg_match('#[^a-zA-Z0-9\s\_\-]#', $check) ? false : true;
982
- }
983
-
984
- function rewriteSlug($check) {
985
- return preg_match('#[^a-zA-Z0-9\s\_\-\%]#', $check) ? false : true;
986
- }
987
-
988
- /**
989
- * Attempts to pass unhandled Validation locales to a class starting with $classPrefix
990
- * and ending with Validation. For example $classPrefix = 'nl', the class would be
991
- * `NlValidation`.
992
- *
993
- * @param string $method The method to call on the other class.
994
- * @param mixed $check The value to check or an array of parameters for the method to be called.
995
- * @param string $classPrefix The prefix for the class to do the validation.
996
- * @return mixed Return of Passed method, false on failure
997
- * @access protected
998
- * */
999
- function _pass($method, $check, $classPrefix) {
1000
- $className = ucwords($classPrefix) . 'Validation';
1001
- if (!class_exists($className)) {
1002
- trigger_error(sprintf(__('Could not find %s class, unable to complete validation.', true), $className), E_USER_WARNING);
1003
- return false;
1004
- }
1005
- if (!is_callable(array($className, $method))) {
1006
- trigger_error(sprintf(__('Method %s does not exist on %s unable to complete validation.', true), $method, $className), E_USER_WARNING);
1007
- return false;
1008
- }
1009
- $check = (array) $check;
1010
- return call_user_func_array(array($className, $method), $check);
1011
- }
1012
-
1013
- /**
1014
- * Runs a regular expression match.
1015
- *
1016
- * @return boolean Success of match
1017
- * @access protected
1018
- */
1019
- function _check() {
1020
- $_this = & Wpcf_Cake_Validation::getInstance();
1021
- if (preg_match($_this->regex, $_this->check)) {
1022
- $_this->error[] = false;
1023
- return true;
1024
- } else {
1025
- $_this->error[] = true;
1026
- return false;
1027
- }
1028
- }
1029
-
1030
- /**
1031
- * Get the values to use when value sent to validation method is
1032
- * an array.
1033
- *
1034
- * @param array $params Parameters sent to validation method
1035
- * @return void
1036
- * @access protected
1037
- */
1038
- function _extract($params) {
1039
- $_this = & Wpcf_Cake_Validation::getInstance();
1040
- extract($params, EXTR_OVERWRITE);
1041
-
1042
- if (isset($check)) {
1043
- $_this->check = $check;
1044
- }
1045
- if (isset($regex)) {
1046
- $_this->regex = $regex;
1047
- }
1048
- if (isset($country)) {
1049
- $_this->country = strtolower($country);
1050
- }
1051
- if (isset($deep)) {
1052
- $_this->deep = $deep;
1053
- }
1054
- if (isset($type)) {
1055
- $_this->type = $type;
1056
- }
1057
- }
1058
-
1059
- /**
1060
- * Luhn algorithm
1061
- *
1062
- * @see http://en.wikipedia.org/wiki/Luhn_algorithm
1063
- * @return boolean Success
1064
- * @access protected
1065
- */
1066
- function _luhn() {
1067
- $_this = & Wpcf_Cake_Validation::getInstance();
1068
- if ($_this->deep !== true) {
1069
- return true;
1070
- }
1071
- if ($_this->check == 0) {
1072
- return false;
1073
- }
1074
- $sum = 0;
1075
- $length = strlen($_this->check);
1076
-
1077
- for ($position = 1 - ($length % 2); $position < $length; $position += 2) {
1078
- $sum += $_this->check[$position];
1079
- }
1080
-
1081
- for ($position = ($length % 2); $position < $length; $position += 2) {
1082
- $number = $_this->check[$position] * 2;
1083
- $sum += ($number < 10) ? $number : $number - 9;
1084
- }
1085
-
1086
- return ($sum % 10 == 0);
1087
- }
1088
-
1089
- /*
1090
- * Lazily popualate the IP address patterns used for validations
1091
- *
1092
- * @return void
1093
- * @access private
1094
- */
1095
-
1096
- function __populateIp() {
1097
- if (!isset($this->__pattern['IPv6'])) {
1098
- $pattern = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}';
1099
- $pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})';
1100
- $pattern .= '|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})';
1101
- $pattern .= '(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)';
1102
- $pattern .= '{4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
1103
- $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}';
1104
- $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|';
1105
- $pattern .= '((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}';
1106
- $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
1107
- $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4})';
1108
- $pattern .= '{0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)';
1109
- $pattern .= '|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]';
1110
- $pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})';
1111
- $pattern .= '{1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?';
1112
-
1113
- $this->__pattern['IPv6'] = $pattern;
1114
- }
1115
- if (!isset($this->__pattern['IPv4'])) {
1116
- $pattern = '(?:(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])';
1117
- $this->__pattern['IPv4'] = $pattern;
1118
- }
1119
- }
1120
-
1121
- /**
1122
- * Reset internal variables for another validation run.
1123
- *
1124
- * @return void
1125
- * @access private
1126
- */
1127
- function __reset() {
1128
- $this->check = null;
1129
- $this->regex = null;
1130
- $this->country = null;
1131
- $this->deep = null;
1132
- $this->type = null;
1133
- $this->error = array();
1134
- $this->errors = array();
1135
- }
1136
-
1137
- }
1138
-
1139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/debug/debug-information.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * produce debug information
5
- *
6
- *
7
- */
8
-
9
- include_once dirname(__FILE__) . '/functions_debug_information.php';
10
- $debug_information = new ICL_Debug_Information();
11
- $debug_data = $debug_information->get_debug_info();
12
- ?>
13
- <div class="wrap">
14
- <h2><?php _e('Debug information', 'wpv-views');?></h2>
15
- <div id="poststuff">
16
- <div id="toolset-debug-info" class="postbox">
17
- <h3 class="handle"><span><?php _e( 'Debug information', 'wpv-views' ) ?></span></h3>
18
- <div class="inside">
19
- <p><?php _e( 'This information allows our support team to see the versions of WordPress, plugins and theme on your site. Provide this information if requested in our support forum. No passwords or other confidential information is included.', 'sitepress', 'wpv-views' ) ?></p><br/>
20
- <textarea style="font-size:10px;width:100%;height:250px;" rows="26" readonly="readonly"><?php echo esc_html( $debug_information->do_json_encode( $debug_data ) );?></textarea>
21
- </div>
22
- </div>
23
- </div>
24
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/debug/functions_debug_information.php DELETED
@@ -1,160 +0,0 @@
1
- <?php
2
- /**
3
- * produce debug information
4
- *
5
- *
6
- */
7
-
8
- class ICL_Debug_Information
9
- {
10
- function __construct() {
11
- }
12
- function __destruct() {
13
- }
14
-
15
- function get_debug_info($info=array()) {
16
- if (!is_array($info)) {
17
- $info = explode(',', $info);
18
- }
19
- if (empty($info)) {
20
- $info = array('core', 'plugins', 'theme', 'extra-debug');
21
- }
22
-
23
- $output = array();
24
- foreach ($info as $type) {
25
- switch ($type) {
26
- case 'core':
27
- $output['core'] = $this->get_core_info();
28
- break;
29
- case 'plugins':
30
- $output['plugins'] = $this->get_plugins_info();
31
- break;
32
- case 'theme':
33
- $output['theme'] = $this->get_theme_info();
34
- break;
35
- case 'extra-debug':
36
- $output['extra-debug'] = apply_filters('icl_get_extra_debug_info', array());
37
- break;
38
- }
39
- }
40
- return $output;
41
- }
42
-
43
- /**
44
- *
45
- * @global object $wpdb
46
- *
47
- */
48
- function get_core_info() {
49
-
50
- global $wpdb;
51
-
52
- $core = array(
53
- 'Wordpress' => array(
54
- 'Multisite' => is_multisite() ? 'Yes' : 'No',
55
- 'SiteURL' => site_url(),
56
- 'HomeURL' => home_url(),
57
- 'Version' => get_bloginfo( 'version' ),
58
- 'PermalinkStructure' => get_option( 'permalink_structure' ),
59
- 'PostTypes' => implode( ', ', get_post_types( '', 'names' ) ),
60
- 'PostSatus' => implode( ', ', get_post_stati() )
61
- ),
62
- 'Server' => array(
63
- 'jQueryVersion' => wp_script_is( 'jquery', 'registered' ) ? $GLOBALS['wp_scripts']->registered['jquery']->ver : __( 'n/a', 'wpv-views' ),
64
- 'PHPVersion' => phpversion(),
65
- 'MySQLVersion' => $wpdb->db_version(),
66
- 'ServerSoftware' => $_SERVER['SERVER_SOFTWARE']
67
- ),
68
- 'PHP' => array(
69
- 'MemoryLimit' => ini_get( 'memory_limit' ),
70
- 'UploadMax' => ini_get( 'upload_max_filesize' ),
71
- 'PostMax' => ini_get( 'post_max_size' ),
72
- 'TimeLimit' => ini_get( 'max_execution_time' ),
73
- 'MaxInputVars' => ini_get( 'max_input_vars' ),
74
- ),
75
- );
76
-
77
- return $core;
78
- }
79
-
80
- function get_plugins_info() {
81
-
82
- if ( ! function_exists( 'get_plugins' ) ) {
83
- $admin_includes_path = str_replace( site_url('/', 'admin'), ABSPATH, admin_url('includes/', 'admin') );
84
- require_once $admin_includes_path . 'plugin.php';
85
- }
86
-
87
- $plugins = get_plugins();
88
- $active_plugins = get_option('active_plugins');
89
- $active_plugins_info = array();
90
- foreach ($active_plugins as $plugin) {
91
- if (isset($plugins[$plugin])) {
92
- unset($plugins[$plugin]['Description']);
93
- $active_plugins_info[$plugin] = $plugins[$plugin];
94
- }
95
- }
96
-
97
- $mu_plugins = get_mu_plugins();
98
-
99
- $dropins = get_dropins();
100
-
101
- $output =array(
102
- 'active_plugins' => $active_plugins_info,
103
- 'mu_plugins' => $mu_plugins,
104
- 'dropins' => $dropins,
105
- );
106
-
107
- return $output;
108
- }
109
-
110
- function get_theme_info() {
111
-
112
- if ( get_bloginfo( 'version' ) < '3.4' ) {
113
- $current_theme = get_theme_data( get_stylesheet_directory() . '/style.css' );
114
- $theme = $current_theme;
115
- unset($theme['Description']);
116
- unset($theme['Satus']);
117
- unset($theme['Tags']);
118
- } else {
119
- $current_theme = wp_get_theme();
120
- $theme = array(
121
- 'Name' => $current_theme->Name,
122
- 'ThemeURI' => $current_theme->ThemeURI,
123
- 'Author' => $current_theme->Author,
124
- 'AuthorURI' => $current_theme->AuthorURI,
125
- 'Template' => $current_theme->Template,
126
- 'Version' => $current_theme->Version,
127
- 'TextDomain' => $current_theme->TextDomain,
128
- 'DomainPath' => $current_theme->DomainPath,
129
- );
130
- }
131
-
132
- return $theme;
133
- }
134
-
135
-
136
- function do_json_encode($data)
137
- {
138
- if (version_compare(phpversion(), '5.3.0', '<')) {
139
- return json_encode($data);
140
- }
141
- $json_options = 0;
142
- if (defined('JSON_HEX_TAG')) {
143
- $json_options += JSON_HEX_TAG;
144
- }
145
- if (defined('JSON_HEX_APOS')) {
146
- $json_options += JSON_HEX_APOS;
147
- }
148
- if (defined('JSON_HEX_QUOT')) {
149
- $json_options += JSON_HEX_QUOT;
150
- }
151
- if (defined('JSON_HEX_AMP')) {
152
- $json_options += JSON_HEX_AMP;
153
- }
154
- if (defined('JSON_UNESCAPED_UNICODE')) {
155
- $json_options += JSON_UNESCAPED_UNICODE;
156
- }
157
- return json_encode($data, $json_options);
158
- }
159
-
160
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/expression-parser/js/parser.js DELETED
@@ -1,2923 +0,0 @@
1
- /**
2
- *
3
- * Toolset Parser, advanced parser for arithmetic,logical and comparision expressions
4
- * by Nikos M. <nikos.m@icanlocalize.com>
5
- *
6
- * Main Features:
7
- * + user variables
8
- * + support mathematical, and date functions
9
- * + limited date parsing
10
- *
11
- * Additional Features:
12
- * + typed tokens
13
- * + typed user variables
14
- * + added string literals
15
- * + support advanced mathematical, string and date functions
16
- * + support advanced date operations (like (date + 3 days) or (3 days=date1-date2)) (not yet)
17
- * + support typecasting
18
- * + can parse and format every localized PHP date format
19
- * + precompilation of expressions into functions
20
- * + faster, optimized code
21
- * + use of closures for encapsulation and better access
22
- * + heavy refactoring, and various bug fixes
23
- *
24
- * inspired by
25
- * JS Expression Evaluator by Prasad P. Khandekar
26
- *
27
- **/
28
-
29
- // js closure paradise (or maybe hell?)
30
- (function(window){
31
- window.ToolsetParser=window.ToolsetParser ||
32
-
33
- (function(window){
34
-
35
- var keywords;
36
-
37
- var Functions=(function(){
38
- var _cookies=false;
39
- var _regexs={};
40
- var _params={
41
- user:{
42
- ID:0,
43
- role:'',
44
- roles:[],
45
- login:'',
46
- display_name:''
47
- }
48
- };
49
-
50
- function _setParams(params)
51
- {
52
- for (var n in params)
53
- {
54
- if (params.hasOwnProperty(n))
55
- _params[n]=params[n];
56
- }
57
- }
58
-
59
- function _Cookie(name)
60
- {
61
- var i,c,C;
62
-
63
- if (!_cookies)
64
- {
65
- c = document.cookie.split(/;\s*/);
66
- _cookies = {};
67
-
68
- i=c.length;
69
- while(--i>=0)
70
- {
71
- C = c[i].split('=');
72
- _cookies[C[0]] = C[1];
73
- }
74
- }
75
- return (_cookies[name])?_cookies[name]:'';
76
- }
77
-
78
- function _User(att)
79
- {
80
- att=att.toUpperCase();
81
-
82
- switch (att)
83
- {
84
- case 'ID':
85
- return _params['user']['ID']+'';
86
- case 'NAME':
87
- return _params['user']['display_name'];
88
- case 'ROLE':
89
- return _params['user']['role'];
90
- case 'LOGIN':
91
- return _params['user']['login'];
92
- default:
93
- return '';
94
- }
95
- return '';
96
- }
97
-
98
- function _Regex(rx, opts)
99
- {
100
- // cache regexes
101
- var _prefix='__REGEX_' /*,flags, pattern, inputRX*/;
102
-
103
- // replace flags not supported in JS
104
- opts=opts.replace(/[^gimy]/,'');
105
-
106
- // !opts && (opts='');
107
- if (!_regexs[_prefix+rx+opts])
108
- {
109
- /*inputRX=rx;
110
- flags = inputRX.replace(/.*\/([gimy]*)$/, '$1');
111
- pattern = inputRX.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');*/
112
- _regexs[_prefix+rx+opts]=new RegExp(rx /*pattern*/, /*flags+*/opts);
113
- //console.log(_regexs[_prefix+rx+opts]);
114
- }
115
- return _regexs[_prefix+rx+opts];
116
- }
117
-
118
- function _Contains(a,v)
119
- {
120
- var found=false;
121
- var ii=a.length;
122
- while(--ii>=0)
123
- {
124
- if (a[ii]==v)
125
- {
126
- found=true;
127
- break;
128
- }
129
- }
130
- return found;
131
- }
132
-
133
- return {
134
- setParams : _setParams,
135
- User : _User,
136
- Cookie : _Cookie,
137
- Regex : _Regex,
138
- Contains : _Contains
139
- };
140
- })();
141
-
142
- // private class
143
- var DateParser = (function(){
144
-
145
- // private members
146
- var
147
- _ZONE_NAMES = {'AM' : 'AM','PM' : 'PM'},
148
-
149
- //_MONTH_NAMES = {'January':'January','February':'February','March':'March','April':'April','May':'May','June':'June','July':'July','August':'August','September':'September','October':'October','November':'November','December':'December'},
150
-
151
- //_DAY_NAMES = {'Sunday':'Sunday','Monday':'Monday','Tuesday':'Tuesday','Wednesday':'Wednesday','Thursday':'Thursday','Friday':'Friday','Saturday':'Saturday'},
152
-
153
- _MONTH_NAMES = ['January','February','March','April','May','June','July','August','September','October','November','December'],
154
-
155
- _DAY_NAMES = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
156
-
157
- _ENGLISH_MONTH_NAMES = new Array('January','February','March','April','May','June','July','August','September','October','November','December'),
158
-
159
- _ENGLISH_DAY_NAMES = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'),
160
-
161
- _to_int = function(str)
162
- {
163
- // return the integer representation of the string given as argument
164
- return parseInt(str , 10);
165
- },
166
-
167
- _escape_regexp = function(str)
168
- {
169
- // return string with special characters escaped
170
- return str.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
171
- },
172
-
173
- _str_pad = function(n, c)
174
- {
175
- if ((n = n + '').length < c)
176
- {
177
- return new Array((++c) - n.length).join('0') + n;
178
- }
179
- return n;
180
- },
181
-
182
- _is_string = function(s)
183
- {
184
- if (typeof(s)=='string' ||
185
- (typeof(s)=='object' && ((s instanceof String) || Object.prototype.toString.call(s) === '[object String]')))
186
- return true;
187
- return false;
188
- };
189
-
190
-
191
- var _parseDate = function(date, supposed_format)
192
- {
193
- // if already a date object
194
- if (typeof(date)!='undefined' && ((date instanceof Date) || Object.prototype.toString.call(date) === '[object Date]'))
195
- {
196
- date.setHours(0,0,0,0); // normalize time part
197
- return date;
198
- }
199
-
200
- if (
201
- typeof(date)=='undefined' ||
202
- date==null ||
203
- !_is_string(date) ||
204
- typeof(supposed_format)=='undefined' ||
205
- supposed_format==null ||
206
- !_is_string(supposed_format)
207
- )
208
- return false;
209
-
210
- // treat argument as a string
211
- str_date = date + '';
212
- supposed_format = supposed_format+'';
213
-
214
- // if value is given
215
- if (str_date != '' && supposed_format != '')
216
- {
217
-
218
- var
219
- // prepare the format by removing white space from it
220
- // and also escape characters that could have special meaning in a regular expression
221
- format = _escape_regexp(supposed_format.replace(/\s/g, '')),
222
-
223
- // allowed characters in date's format
224
- format_chars = ['d','D','j','l','N','S','w','F','m','M','n','Y','y'],
225
-
226
- // "matches" will contain the characters defining the date's format
227
- matches = new Array,
228
-
229
- // "regexp" will contain the regular expression built for each of the characters used in the date's format
230
- regexp = new Array;
231
-
232
- // iterate through the allowed characters in date's format
233
- for (var i = 0; i < format_chars.length; i++)
234
- {
235
- // if character is found in the date's format
236
- if ((position = format.indexOf(format_chars[i])) > -1)
237
-
238
- // save it, alongside the character's position
239
- matches.push({character: format_chars[i], position: position});
240
- }
241
-
242
- // sort characters defining the date's format based on their position, ascending
243
- matches.sort(function(a, b){ return a.position - b.position });
244
-
245
- // iterate through the characters defining the date's format
246
- for (var index=0; index<matches.length; index++)
247
- {
248
- var match=matches[index];
249
-
250
- // add to the array of regular expressions, based on the character
251
- switch (match.character)
252
- {
253
-
254
- case 'd': regexp.push('0[1-9]|[12][0-9]|3[01]'); break;
255
- case 'D': regexp.push('[a-z]{3}'); break;
256
- case 'j': regexp.push('[1-9]|[12][0-9]|3[01]'); break;
257
- case 'l': regexp.push('[a-z]+'); break;
258
- case 'N': regexp.push('[1-7]'); break;
259
- case 'S': regexp.push('st|nd|rd|th'); break;
260
- case 'w': regexp.push('[0-6]'); break;
261
- case 'F': regexp.push('[a-z]+'); break;
262
- case 'm': regexp.push('0[1-9]|1[012]+'); break;
263
- case 'M': regexp.push('[a-z]{3}'); break;
264
- case 'n': regexp.push('[1-9]|1[012]'); break;
265
- case 'Y': regexp.push('[0-9]{4}'); break;
266
- case 'y': regexp.push('[0-9]{2}'); break;
267
-
268
- }
269
- }
270
-
271
- // if we have an array of regular expressions
272
- if (regexp.length)
273
- {
274
-
275
- // we will replace characters in the date's format in reversed order
276
- matches.reverse();
277
-
278
- // iterate through the characters in date's format
279
- for (var index=0; index<matches.length; index++)
280
- {
281
- var match=matches[index];
282
-
283
- // replace each character with the appropriate regular expression
284
- format = format.replace(match.character, '(' + regexp[regexp.length - index - 1] + ')');
285
- }
286
-
287
- // the final regular expression
288
- regexp = new RegExp('^' + format + '$', 'ig');
289
-
290
- // if regular expression was matched
291
- if ((segments = regexp.exec(str_date.replace(/\s/g, ''))))
292
- {
293
-
294
- // check if date is a valid date (i.e. there's no February 31)
295
- var original_day,
296
- original_month,
297
- original_year,
298
- english_days = _ENGLISH_DAY_NAMES, //['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
299
- english_months = _ENGLISH_MONTH_NAMES,//['January','February','March','April','May','June','July','August','September','October','November','December'],
300
- iterable,
301
-
302
- // by default, we assume the date is valid
303
- valid = true;
304
-
305
- // reverse back the characters in the date's format
306
- matches.reverse();
307
-
308
- // iterate through the characters in the date's format
309
- for (var index=0; index<matches.length; index++)
310
- {
311
- var match=matches[index];
312
-
313
- // if the date is not valid, don't look further
314
- if (!valid) break; //return true;
315
-
316
- // based on the character
317
- switch (match.character)
318
- {
319
-
320
- case 'm':
321
- case 'n':
322
-
323
- // extract the month from the value entered by the user
324
- original_month = _to_int(segments[index + 1]);
325
-
326
- break;
327
-
328
- case 'd':
329
- case 'j':
330
-
331
- // extract the day from the value entered by the user
332
- original_day = _to_int(segments[index + 1]);
333
-
334
- break;
335
-
336
- case 'D':
337
- case 'l':
338
- case 'F':
339
- case 'M':
340
-
341
- // if day is given as day name, we'll check against the names in the used language
342
- if (match.character == 'D' || match.character == 'l') iterable = _DAY_NAMES;
343
-
344
- // if month is given as month name, we'll check against the names in the used language
345
- else iterable = _MONTH_NAMES;
346
-
347
- // by default, we assume the day or month was not entered correctly
348
- valid = false;
349
-
350
- // iterate through the month/days in the used language
351
- for (var key=0; key<iterable.length; key++)
352
- {
353
- // if month/day was entered correctly, don't look further
354
- if (valid) break; //return true;
355
-
356
- var value=iterable[key];
357
-
358
- // if month/day was entered correctly
359
- if (segments[index + 1].toLowerCase() == value.substring(0, (match.character == 'D' || match.character == 'M' ? 3 : value.length)).toLowerCase())
360
- {
361
-
362
- // extract the day/month from the value entered by the user
363
- switch (match.character)
364
- {
365
-
366
- case 'D': segments[index + 1] = english_days[key].substring(0, 3); break;
367
- case 'l': segments[index + 1] = english_days[key]; break;
368
- case 'F': segments[index + 1] = english_months[key]; original_month = key + 1; break;
369
- case 'M': segments[index + 1] = english_months[key].substring(0, 3); original_month = key + 1; break;
370
-
371
- }
372
-
373
- // day/month value is valid
374
- valid = true;
375
-
376
- }
377
-
378
- }
379
-
380
- break;
381
-
382
- case 'Y':
383
-
384
- // extract the year from the value entered by the user
385
- original_year = _to_int(segments[index + 1]);
386
-
387
- break;
388
-
389
- case 'y':
390
-
391
- // extract the year from the value entered by the user
392
- original_year = '19' + _to_int(segments[index + 1]);
393
-
394
- break;
395
-
396
- }
397
- }
398
-
399
- // if everything is ok so far
400
- if (valid)
401
- {
402
- // generate a Date object using the values entered by the user
403
- // (handle also the case when original_month and/or original_day are undefined - i.e date format is "Y-m" or "Y")
404
- var date = new Date(original_year, (original_month || 1) - 1, original_day || 1);
405
-
406
- // if, after that, the date is the same as the date entered by the user
407
- if (date.getFullYear() == original_year && date.getDate() == (original_day || 1) && date.getMonth() == ((original_month || 1) - 1))
408
- {
409
- // normalize time part, only date part checked
410
- date.setHours(0,0,0,0);
411
- // return the date as JavaScript date object
412
- return date;
413
- }
414
- }
415
- }
416
- }
417
- }
418
- // if script gets this far, return false as something must've went wrong
419
- return false;
420
- };
421
-
422
- var _formatDate = function(date, format)
423
- {
424
-
425
- // if not a date object
426
- if (typeof(date)=='undefined' || date==null || !(date instanceof Date) || Object.prototype.toString.call(date) !== '[object Date]')
427
- {
428
- return '';
429
- }
430
-
431
- date.setHours(0,0,0,0); // normalize time
432
-
433
- if (format=='')
434
- return date.toString();
435
-
436
- var result = '',
437
-
438
- // extract parts of the date:
439
- // day number, 1 - 31
440
- j = date.getDate(),
441
-
442
- // day of the week, 0 - 6, Sunday - Saturday
443
- w = date.getDay(),
444
-
445
- // the name of the day of the week Sunday - Saturday
446
- l = _DAY_NAMES[w],
447
-
448
- // the month number, 1 - 12
449
- n = date.getMonth() + 1,
450
-
451
- // the month name, January - December
452
- f = _MONTH_NAMES[n - 1],
453
-
454
- // the year (as a string)
455
- y = date.getFullYear() + '';
456
-
457
- // iterate through the characters in the format
458
- for (var i = 0; i < format.length; i++)
459
- {
460
-
461
- // extract the current character
462
- var chr = format.charAt(i);
463
-
464
- // see what character it is
465
- switch(chr)
466
- {
467
- // year as two digits
468
- case 'y': y = y.substr(2);
469
-
470
- // year as four digits
471
- case 'Y': result += y; break;
472
-
473
- // month number, prefixed with 0
474
- case 'm': n = _str_pad(n, 2);
475
-
476
- // month number, not prefixed with 0
477
- case 'n': result += n; break;
478
-
479
- // month name, three letters
480
- case 'M': f = f.substr(0, 3);
481
-
482
- // full month name
483
- case 'F': result += f; break;
484
-
485
- // day number, prefixed with 0
486
- case 'd': j = _str_pad(j, 2);
487
-
488
- // day number not prefixed with 0
489
- case 'j': result += j; break;
490
-
491
- // day name, three letters
492
- case 'D': l = l.substr(0, 3);
493
-
494
- // full day name
495
- case 'l': result += l; break;
496
-
497
- // ISO-8601 numeric representation of the day of the week, 1 - 7
498
- case 'N': w++;
499
-
500
- // day of the week, 0 - 6
501
- case 'w': result += w; break;
502
-
503
- // English ordinal suffix for the day of the month, 2 characters
504
- // (st, nd, rd or th (works well with j))
505
- case 'S':
506
-
507
- if (j % 10 == 1 && j != '11') result += 'st';
508
-
509
- else if (j % 10 == 2 && j != '12') result += 'nd';
510
-
511
- else if (j % 10 == 3 && j != '13') result += 'rd';
512
-
513
- else result += 'th';
514
-
515
- break;
516
-
517
- // this is probably the separator
518
- default: result += chr;
519
-
520
- }
521
-
522
- }
523
- // return formated date
524
- return result;
525
- };
526
-
527
- // public (static) methods
528
- return {
529
-
530
- setDateLocaleStrings : function(dn, mn, zn)
531
- {
532
- if (typeof mn != 'undefined')
533
- {
534
- _MONTH_NAMES = mn;
535
- }
536
- if (typeof dn != 'undefined')
537
- {
538
- _DAY_NAMES = dn;
539
- }
540
- if (typeof zn != 'undefined')
541
- _ZONE_NAMES = zn;
542
- },
543
-
544
- parseDate : _parseDate,
545
- formatDate : _formatDate,
546
-
547
- isDate : function (val, format, getDate)
548
- {
549
- var date=_parseDate(val,format);
550
- if (date!==false)
551
- {
552
- if (typeof(getDate)!='undefined' && typeof(getDate)=='object')
553
- {
554
- getDate.date=date;
555
- }
556
- return true;
557
- }
558
- return false;
559
- },
560
-
561
- currentDate : function()
562
- {
563
- var _now=new Date();
564
- _now.setHours(0,0,0,0); // normalize time part
565
- return _now;
566
- }
567
- };
568
- })();
569
-
570
- var Stack = (function(){
571
- // Converts stack contents into a comma separated string
572
- function _dumpStack()
573
- {
574
- var intCntr = 0;
575
- var strRet = "";
576
- if (this.intIndex == 0) return null;
577
- for (intCntr = 0; intCntr < this.intIndex; intCntr++)
578
- {
579
- if (strRet.length == 0)
580
- strRet += this.arrStack[intCntr].val;
581
- else
582
- strRet += "," + this.arrStack[intCntr].val;
583
- }
584
- return strRet;
585
- }
586
-
587
- // Returns size of stack
588
- function _getSize()
589
- {
590
- return this.intIndex;
591
- }
592
-
593
- // This method tells us if this Stack object is empty
594
- function _isStackEmpty()
595
- {
596
- if (this.intIndex == 0)
597
- return true;
598
- else
599
- return false;
600
- }
601
-
602
- // This method pushes a new element onto the top of the stack
603
- function _pushElement(newData)
604
- {
605
- // Assign our new element to the top
606
- //debugAssert ("Pushing " + newData);
607
- this.arrStack[this.intIndex++] = newData;
608
- //this.intIndex++;
609
- }
610
-
611
- // This method pops the top element off of the stack
612
- function _popElement()
613
- {
614
- var retVal;
615
-
616
- retVal = null;
617
- if (this.intIndex > 0)
618
- {
619
- // Assign our new element to the top
620
- //this.intIndex--;
621
- retVal = this.arrStack[--this.intIndex];
622
- }
623
- return retVal;
624
- }
625
-
626
- // Gets an element at a particular offset from top of the stack
627
- function _getElement(intPos)
628
- {
629
- var retVal;
630
-
631
- //alert ("Size : " + this.intIndex + ", Index " + intPos);
632
- if (intPos >= 0 && intPos < this.intIndex)
633
- retVal = this.arrStack[this.intIndex - intPos - 1];
634
- return retVal;
635
- }
636
- // Stack object constructor
637
- return function()
638
- {
639
- this.arrStack = new Array();
640
- this.intIndex = 0;
641
-
642
- this.Size = _getSize;
643
- this.IsEmpty = _isStackEmpty;
644
- this.Push = _pushElement;
645
- this.Pop = _popElement;
646
- this.Get = _getElement;
647
- this.toString = _dumpStack;
648
- };
649
- })();
650
-
651
- var Tokenizer = (function(DateParser){
652
-
653
- // private members
654
- var _tok_map_prefix = '__TOKEN_MAP_PREFIX__',
655
- _Alpha = "abcdefghijklmnopqrstuvwxyz",
656
- _lstAlpha = _Alpha + _Alpha.toUpperCase(),
657
- _lstVariablePrefix = '_$' + _lstAlpha,
658
- _lstDigits = "0123456789",
659
- _lstArithOps = ["^","*","/","%","+","-"],
660
- _lstLogicOps = ["NOT","!","OR","|","AND","&"],
661
- _lstCompaOps = ["<","<=",">",">=","<>","=","lt","lte","gt","gte","ne","eq"],
662
- _lstFuncOps = ["AVG","ABS","ACOS","ARRAY","ASC","ASIN","ATAN","CHR","CONTAINS","COOKIE","COS","DATE","FIX","HEX","IIF","LCASE","LEN","LEFT","LOG","MAX","MID","MIN","NUM","RAND","REGEX","RIGHT","ROUND","SIN","SQRT","STR","TAN","TODAY","UCASE","USER", "EMPTY", "empty"],
663
-
664
- _UNARY_NEGATIVE = "-",
665
- _UNARY_NEGATION = "!",
666
- _ARG_TERMINAL = "?",
667
-
668
- _aritOpMap = {},
669
- _logiOpMap = {},
670
- _compOpMap = {},
671
- _funcMap = {},
672
-
673
- _TOKEN_TYPES = { __DEFAULT__:0, STRING_LITERAL:8, REGEX: 83, ARRAY:81, ARRAY_LITERAL:82, DATE:1, ARITHMETIC_OP:2, LOGICAL_OP:3, COMPARISON_OP:4, NUMBER:5, BOOLEAN:6, VARIABLE:7, FUNCTION:9, COMMA:10, LEFT_PAREN:11, LEFT_BRACKET:111, RIGHT_PAREN:12, RIGHT_BRACKET:122, ARG_TERMINAL:13, UNARY_NEGATIVE:14, UNARY_NEGATION:15, EMPTY_TOKEN:30, UNKNOWN:40 },
674
-
675
- _isDefined = function(s)
676
- {
677
- return ((typeof(s)=='undefined' || s==null)?false:true);
678
- },
679
- _isDigit = function(c)
680
- {
681
- if (!_isDefined(c))
682
- return false;
683
- return ((c!='' && _lstDigits.indexOf(c) >= 0)?true:false);
684
- },
685
- _isAlpha = function(c)
686
- {
687
- if (!_isDefined(c))
688
- return false;
689
- return ((c!='' && _lstAlpha.indexOf(c) >= 0)?true:false);
690
- },
691
- _isOperator = function(s)
692
- {
693
- if (!_isDefined(s))
694
- return false;
695
- return ((_aritOpMap[_tok_map_prefix + s])?true:false);
696
- },
697
- _isLogicOperator = function(s)
698
- {
699
- if (!_isDefined(s))
700
- return false;
701
- return ((_logiOpMap[_tok_map_prefix + s])?true:false);
702
- },
703
- _isCompOperator = function(s)
704
- {
705
- if (!_isDefined(s))
706
- return false;
707
- return ((_compOpMap[_tok_map_prefix + s])?true:false);
708
- },
709
- _isFunction = function(s)
710
- {
711
- if (!_isDefined(s))
712
- return false;
713
- return ((_funcMap[_tok_map_prefix + s])?true:false);
714
- },
715
- _isVariableName = function(s)
716
- {
717
- if (!_isDefined(s))
718
- return false;
719
- c=(s=='')?'':s.charAt(0);
720
- return ((c!='' && _lstVariablePrefix.indexOf(c) >= 0)?true:false);
721
- },
722
- _isDateInstance = function(s)
723
- {
724
- if (!_isDefined(s))
725
- return false;
726
- if (typeof(s)=='object' && ((s instanceof Date) || Object.prototype.toString.call(s) == '[object Date]'))
727
- return true;
728
- return false;
729
- },
730
- _isArrayInstance = function(s)
731
- {
732
- if (!_isDefined(s))
733
- return false;
734
- if (typeof(s)=='object' && ((s instanceof Array) || Object.prototype.toString.call(s) == '[object Array]'))
735
- return true;
736
- return false;
737
- },
738
- _isRegExpInstance = function(s)
739
- {
740
- if (!_isDefined(s))
741
- return false;
742
- if (typeof(s)=='object' && ((s instanceof RegExp) || Object.prototype.toString.call(s) == '[object RegExp]'))
743
- return true;
744
- return false;
745
- },
746
- _isNumber = function(s)
747
- {
748
- var type_s=typeof(s);
749
- if (!_isDefined(s)) return false;
750
- if (_isDateInstance(s) || _isRegExpInstance(s) || _isArrayInstance(s)) return false;
751
- if ((type_s=='number' || (type_s=='object' && Object.prototype.toString.call(s) !== '[object Number]')) /*&& !isNaN(s)*/)
752
- return true;
753
- var dblNo = Number.NaN;
754
- dblNo = new Number(s);
755
- return ((isNaN(dblNo))?false:true);
756
- },
757
- _isBoolean = function(s)
758
- {
759
- if (!_isDefined(s))
760
- return false;
761
-
762
- var varType = typeof(s);
763
- var strTmp = s;
764
-
765
- if (varType == "boolean") return true;
766
- if (varType == "number" || varType == "function" || varType == 'undefined') return false;
767
- if (_isNumber(s) || _isDateInstance(s) || _isRegExpInstance(s) || _isArrayInstance(s)) return false;
768
- if (varType == "object") strTmp = strTmp.toString();
769
- if (strTmp.toUpperCase && (strTmp.toUpperCase() == "TRUE" || strTmp.toUpperCase() == "FALSE")) return true;
770
- return false;
771
- },
772
- _rtrim = function(s, ch)
773
- {
774
- var w_space;
775
- if (typeof ch == 'undefined')
776
- w_space = String.fromCharCode(32);
777
- else
778
- w_space = ch;
779
- var v_length = s.length;
780
- var strTemp = "";
781
- if(v_length < 0)
782
- {
783
- return"";
784
- }
785
- var iTemp = v_length - 1;
786
-
787
- while(iTemp > -1)
788
- {
789
- if(s.charAt(iTemp) == w_space)
790
- {
791
- }
792
- else
793
- {
794
- strTemp = s.substring(0, iTemp + 1);
795
- break;
796
- }
797
- iTemp = iTemp - 1;
798
- }
799
- return strTemp;
800
- },
801
- _ltrim = function (s, ch)
802
- {
803
- var w_space;
804
- if (typeof ch == 'undefined')
805
- w_space = String.fromCharCode(32);
806
- else
807
- w_space = ch;
808
- if(v_length < 1)
809
- {
810
- return "";
811
- }
812
- var v_length = s.length;
813
- var strTemp = "";
814
- var iTemp = 0;
815
-
816
- while(iTemp < v_length)
817
- {
818
- if(s.charAt(iTemp) == w_space)
819
- {
820
- }
821
- else
822
- {
823
- strTemp = s.substring(iTemp, v_length);
824
- break;
825
- }
826
- iTemp = iTemp + 1;
827
- }
828
- return strTemp;
829
- },
830
- _trim = function(s, ch)
831
- {
832
- if (s.length < 1) return "";
833
-
834
- s = _rtrim(_ltrim(s, ch), ch);
835
- if (s == "")
836
- return "";
837
- else
838
- return s;
839
- };
840
-
841
- // build maps for fast lookup
842
- var _buildMaps=function()
843
- {
844
- var i;
845
-
846
- for (i=0; i<_lstArithOps.length; i++)
847
- {
848
- _aritOpMap[_tok_map_prefix + _lstArithOps[i]]=true;
849
- }
850
- for (i=0; i<_lstLogicOps.length; i++)
851
- {
852
- _logiOpMap[_tok_map_prefix + _lstLogicOps[i]]=true;
853
- }
854
- for (i=0; i<_lstCompaOps.length; i++)
855
- {
856
- _compOpMap[_tok_map_prefix + _lstCompaOps[i]]=true;
857
- }
858
- for (i=0; i<_lstFuncOps.length; i++)
859
- {
860
- _funcMap[_tok_map_prefix + _lstFuncOps[i]]=true;
861
- }
862
- };
863
-
864
- var _makeToken = function(tok, force_type)
865
- {
866
- var token={val:tok, type:_TOKEN_TYPES.UNKNOWN};
867
- var typeoftok=typeof(tok);
868
-
869
- if (typeof(force_type) == 'undefined' || force_type==null || force_type=='')
870
- force_type=_TOKEN_TYPES.__DEFAULT__;
871
-
872
- switch (force_type)
873
- {
874
- case _TOKEN_TYPES.EMPTY_TOKEN:
875
- token.type=_TOKEN_TYPES.EMPTY_TOKEN;
876
- token.isEmpty=true;
877
- token.val='';
878
- break;
879
- case _TOKEN_TYPES.STRING_LITERAL:
880
- token.type=_TOKEN_TYPES.STRING_LITERAL;
881
- token.isStringLiteral=true;
882
- token.val=tok.toString();
883
- break;
884
- case _TOKEN_TYPES.DATE:
885
- if (_isDateInstance(tok))
886
- {
887
- token.type=_TOKEN_TYPES.DATE;
888
- token.isDate=true;
889
- }
890
- break;
891
- case _TOKEN_TYPES.ARRAY:
892
- if (!_isArrayInstance(tok))
893
- {
894
- token.val=[tok];
895
- }
896
- token.type=_TOKEN_TYPES.ARRAY;
897
- token.isArray=true;
898
- break;
899
- case _TOKEN_TYPES.REGEX:
900
- if (!_isRegExpInstance(tok))
901
- {
902
- token.val=Functions.Regex(tok);
903
- }
904
- token.type=_TOKEN_TYPES.REGEX;
905
- token.isRegex=true;
906
- break;
907
- case _TOKEN_TYPES.COMMA:
908
- token.type=_TOKEN_TYPES.COMMA;
909
- token.isComma=true;
910
- token.val=',';
911
- break;
912
- case _TOKEN_TYPES.LEFT_PAREN:
913
- token.type=_TOKEN_TYPES.LEFT_PAREN;
914
- token.isLeftParen=true;
915
- token.isParen=true;
916
- token.val='(';
917
- break;
918
- case _TOKEN_TYPES.RIGHT_PAREN:
919
- token.type=_TOKEN_TYPES.RIGHT_PAREN;
920
- token.isRightParen=true;
921
- token.isParen=true;
922
- token.val=')';
923
- break;
924
- case _TOKEN_TYPES.ARG_TERMINAL:
925
- token.type=_TOKEN_TYPES.ARG_TERMINAL;
926
- token.isArgTerminal=true;
927
- token.val=_ARG_TERMINAL;
928
- break;
929
- case _TOKEN_TYPES.UNARY_NEGATIVE:
930
- token.type=_TOKEN_TYPES.UNARY_NEGATIVE;
931
- token.isUnaryNegative=true;
932
- token.val=_UNARY_NEGATIVE;
933
- token.isArithmeticOp=true;
934
- token.isOp=true;
935
- break;
936
- case _TOKEN_TYPES.UNARY_NEGATION:
937
- token.type=_TOKEN_TYPES.UNARY_NEGATION;
938
- token.isUnaryNegation=true;
939
- token.val=_UNARY_NEGATION;
940
- token.isLogicOp=true;
941
- token.isOp=true;
942
- break;
943
- case _TOKEN_TYPES.NUMBER:
944
- token.type=_TOKEN_TYPES.NUMBER;
945
- token.isNumber=true;
946
- if (typeoftok=='string')
947
- token.val=new Number(tok);
948
- else if (typeoftok=='number')
949
- token.val=tok;
950
- else if (typeoftok=='boolean')
951
- token.val=(tok==true)?1:0;
952
- else if (typeoftok=='object')
953
- token.val=new Number(tok.toString());
954
- break;
955
- case _TOKEN_TYPES.BOOLEAN:
956
- token.type=_TOKEN_TYPES.BOOLEAN;
957
- token.isBoolean=true;
958
- if (typeoftok=='boolean')
959
- token.val=tok;
960
- else if (typeoftok=='string')
961
- token.val=(tok.toUpperCase()=='TRUE')?true:false;
962
- else if (typeoftok=='number')
963
- token.val=(tok != 0)?true:false;
964
- else if (Object.prototype.toString.call(tok) === '[object Number]')
965
- token.val=(tok.valueOf() != 0)?true:false;
966
- else if (typeoftok=='object')
967
- token.val=(tok.toString().toUpperCase()=='TRUE')?true:false;
968
- break;
969
- case _TOKEN_TYPES.VARIABLE:
970
- token.type=_TOKEN_TYPES.VARIABLE;
971
- token.isVariable=true;
972
- break;
973
- case _TOKEN_TYPES.__DEFAULT__:
974
- default:
975
- if (
976
- (typeoftok=='object' &&
977
- ((tok instanceof String) || Object.prototype.toString.call(tok) === '[object String]') &&
978
- tok._isStringLiteral)
979
- )
980
- {
981
- token.type=_TOKEN_TYPES.STRING_LITERAL;
982
- token.isStringLiteral=true;
983
- token.val=tok.toString();
984
- }
985
- // date token
986
- else if (_isDateInstance(tok))
987
- {
988
- token.type=_TOKEN_TYPES.DATE;
989
- token.isDate=true;
990
- }
991
- // array token
992
- else if (_isArrayInstance(tok))
993
- {
994
- token.type=_TOKEN_TYPES.ARRAY;
995
- token.isArray=true;
996
- }
997
- // regex token
998
- else if (_isRegExpInstance(tok))
999
- {
1000
- token.type=_TOKEN_TYPES.REGEX;
1001
- token.isRegex=true;
1002
- }
1003
- else if (tok==',')
1004
- {
1005
- token.type=_TOKEN_TYPES.COMMA;
1006
- token.isComma=true;
1007
- token.val=',';
1008
- }
1009
- else if (tok=='(')
1010
- {
1011
- token.type=_TOKEN_TYPES.LEFT_PAREN;
1012
- token.isLeftParen=true;
1013
- token.isParen=true;
1014
- token.val='(';
1015
- token.isOp=true;
1016
- }
1017
- else if (tok==')')
1018
- {
1019
- token.type=_TOKEN_TYPES.RIGHT_PAREN;
1020
- token.isRightParen=true;
1021
- token.isParen=true;
1022
- token.val=')';
1023
- //token.isOp=true;
1024
- }
1025
- /*else if (tok=='{')
1026
- {
1027
- token.type=_TOKEN_TYPES.LEFT_BRACKET;
1028
- token.isLeftBracket=true;
1029
- token.isBracket=true;
1030
- token.val='{';
1031
- token.isOp=true;
1032
- }
1033
- else if (tok=='}')
1034
- {
1035
- token.type=_TOKEN_TYPES.RIGHT_BRACKET;
1036
- token.isRightBracket=true;
1037
- token.isBracket=true;
1038
- token.val='}';
1039
- //token.isOp=true;
1040
- }*/
1041
- else if (_isNumber(tok))
1042
- {
1043
- token.type=_TOKEN_TYPES.NUMBER;
1044
- token.isNumber=true;
1045
- if (typeoftok=='string')
1046
- token.val=new Number(tok).valueOf();
1047
- else if (typeoftok=='number')
1048
- token.val=tok;
1049
- else if (typeoftok=='boolean')
1050
- token.val=(tok==true)?1:0;
1051
- else if (typeoftok=='object')
1052
- token.val=new Number(tok.toString()).valueOf();
1053
- }
1054
- else if (_isBoolean(tok))
1055
- {
1056
- token.type=_TOKEN_TYPES.BOOLEAN;
1057
- token.isBoolean=true;
1058
- if (typeoftok=='boolean')
1059
- token.val=tok;
1060
- else if (typeoftok=='string')
1061
- token.val=(tok.toUpperCase()=='TRUE')?true:false;
1062
- else if (typeoftok=='number')
1063
- token.val=(tok != 0)?true:false;
1064
- else if (Object.prototype.toString.call(tok) === '[object Number]')
1065
- token.val=(tok.valueOf() != 0)?true:false;
1066
- else if (typeoftok=='object')
1067
- token.val=(tok.toString().toUpperCase()=='TRUE')?true:false;
1068
- }
1069
- else if (_isOperator(tok))
1070
- {
1071
- token.type=_TOKEN_TYPES.ARITHMETIC_OP;
1072
- token.isArithmeticOp=true;
1073
- token.isOp=true;
1074
-
1075
- }
1076
- else if (_isLogicOperator(tok))
1077
- {
1078
- token.type=_TOKEN_TYPES.LOGICAL_OP;
1079
- token.isLogicOp=true;
1080
- token.isOp=true;
1081
- }
1082
- else if (_isCompOperator(tok))
1083
- {
1084
- token.type=_TOKEN_TYPES.COMPARISON_OP;
1085
- token.isCompOp=true;
1086
- token.isOp=true;
1087
- }
1088
- else if (_isFunction(tok))
1089
- {
1090
- token.type=_TOKEN_TYPES.FUNCTION;
1091
- token.isFunction=true;
1092
- token.val=tok;
1093
- }
1094
- else if (_isVariableName(tok))
1095
- {
1096
- token.type=_TOKEN_TYPES.VARIABLE;
1097
- token.isVariable=true;
1098
- }
1099
- break;
1100
- }
1101
- if (token.isOp || token.isFunction)
1102
- {
1103
- var intRet = 0;
1104
-
1105
- switch(token.val)
1106
- {
1107
- case "+" :
1108
- case "-" :
1109
- intRet = 50;
1110
- break;
1111
- case "*" :
1112
- case "/" :
1113
- case "%" :
1114
- intRet = 60;
1115
- break;
1116
- case "^" :
1117
- intRet = 70;
1118
- break;
1119
- case _UNARY_NEGATIVE:
1120
- case _UNARY_NEGATION:
1121
- case "!" :
1122
- case "NOT" :
1123
- intRet = 100;
1124
- break;
1125
- case "(" :
1126
- intRet = 1000;
1127
- break;
1128
- /*case "{" :
1129
- intRet = 500; // as function
1130
- break;*/
1131
- case "AND" :
1132
- case "&" :
1133
- intRet = 35;
1134
- break;
1135
- case "OR" :
1136
- case "|" :
1137
- intRet = 30;
1138
- break;
1139
- case ">" :
1140
- case ">=" :
1141
- case "<" :
1142
- case "<=" :
1143
- case "=" :
1144
- case "<>" :
1145
- case "gt" :
1146
- case "gte" :
1147
- case "lt" :
1148
- case "lte" :
1149
- case "eq" :
1150
- case "ne" :
1151
- intRet = 40;
1152
- break;
1153
- default :
1154
- if (token.isFunction)
1155
- intRet = 500;
1156
- else
1157
- intRet = 0;
1158
- break;
1159
- }
1160
- token.precedence=intRet;
1161
- }
1162
- else
1163
- token.precedence=0;
1164
-
1165
- //console.log(token);
1166
- return token;
1167
- };
1168
-
1169
- var _EMPTY_TOKEN = _makeToken('', _TOKEN_TYPES.EMPTY_TOKEN);
1170
- var _EMPTY_STRING = _makeToken('', _TOKEN_TYPES.STRING_LITERAL);
1171
-
1172
- // public (static) methods
1173
- return {
1174
-
1175
- makeToken : _makeToken,
1176
-
1177
- cloneToken : function(tok)
1178
- {
1179
- var newtok={};
1180
-
1181
- for (var at in tok)
1182
- {
1183
- if (tok.hasOwnProperty(at))
1184
- {
1185
- if (_isDateInstance(tok[at]))
1186
- newtok[at]=new Date(tok[at].getTime());
1187
- else
1188
- newtok[at]=tok[at];
1189
- }
1190
- }
1191
- return newtok;
1192
- },
1193
-
1194
- TOKEN_TYPE : _TOKEN_TYPES,
1195
-
1196
- EMPTY_TOKEN : _EMPTY_TOKEN,
1197
-
1198
- EMPTY_STRING : _EMPTY_STRING,
1199
-
1200
- UNARY_NEGATIVE : _makeToken(_UNARY_NEGATIVE, _TOKEN_TYPES.UNARY_NEGATIVE),
1201
-
1202
- UNARY_NEGATION : _makeToken(_UNARY_NEGATION, _TOKEN_TYPES.UNARY_NEGATION),
1203
-
1204
- ARG_TERMINAL : _makeToken(_ARG_TERMINAL, _TOKEN_TYPES.ARG_TERMINAL),
1205
-
1206
- isBoolean : _isBoolean,
1207
-
1208
- isNumber : _isNumber,
1209
-
1210
- isString : function(a)
1211
- {
1212
- if (!_isDefined(a)) return false;
1213
- var typeofa=typeof(a);
1214
- if (_isNumber(a) || _isBoolean(a) || _isArrayInstance(a) || _isDateInstance(a) || _isRegExpInstance(a)) return false;
1215
-
1216
- if (
1217
- typeofa=='string' ||
1218
- (
1219
- typeofa=='object' &&
1220
- ((a instanceof String) || Object.prototype.toString.call(a) === '[object String]')
1221
- )
1222
- )
1223
- return true;
1224
- return false;
1225
- },
1226
-
1227
- isDateInstance : _isDateInstance,
1228
-
1229
- isArrayInstance : _isArrayInstance,
1230
-
1231
- isRegExpInstance : _isRegExpInstance,
1232
-
1233
- isDate : function(pstrVal, format, getDate)
1234
- {
1235
- if (!_isDefined(pstrVal))
1236
- return false;
1237
- if (_isDateInstance(pstrVal))
1238
- {
1239
- if (typeof(getDate)!='undefined')
1240
- getDate.date=pstrVal;
1241
- return true;
1242
- }
1243
- return DateParser.isDate(pstrVal, format, getDate);
1244
- },
1245
-
1246
- toArray : function(v)
1247
- {
1248
- if (_isArrayInstance(v))
1249
- return v;
1250
- else return [v];
1251
- },
1252
-
1253
- toNumber : function(pobjVal)
1254
- {
1255
- var dblRet = Number.NaN;
1256
-
1257
- if (typeof(pobjVal) == "number")
1258
- return pobjVal;
1259
- else
1260
- {
1261
- dblRet = new Number(pobjVal);
1262
- return dblRet.valueOf();
1263
- }
1264
- },
1265
-
1266
- toBoolean : function(pobjVal)
1267
- {
1268
- var dblNo = Number.NaN;
1269
- var strTmp = null;
1270
-
1271
- if (pobjVal == null || pobjVal == undefined)
1272
- throw "Boolean value is not defined!";
1273
- else if (typeof(pobjVal) == "boolean")
1274
- return pobjVal;
1275
- else if (typeof(pobjVal) == "number")
1276
- return (pobjVal != 0);
1277
- else if (_isNumber(pobjVal))
1278
- {
1279
- dblNo = Tokenizer.toNumber(pobjVal);
1280
- if (isNaN(dblNo))
1281
- return null;
1282
- else
1283
- return (dblNo != 0);
1284
- }
1285
- else if (typeof(pobjVal) == "object")
1286
- {
1287
- strTmp = pobjVal.toString();
1288
- if (strTmp.toUpperCase() == "TRUE")
1289
- return true;
1290
- else if (strTmp.toUpperCase() == "FALSE")
1291
- return false;
1292
- else
1293
- return null;
1294
- }
1295
- else if (typeof(pobjVal) == "string")
1296
- {
1297
- if (pobjVal.toUpperCase() == "TRUE")
1298
- return true;
1299
- else if (pobjVal.toUpperCase() == "FALSE")
1300
- return false;
1301
- else
1302
- return null;
1303
- }
1304
- else
1305
- return null;
1306
- },
1307
-
1308
- Tokanize : function(pstrExpression)
1309
- {
1310
-
1311
- var intCntr, intBraces;
1312
- var arrTokens;
1313
- var intIndex, intPos;
1314
- var chrChar, chrNext;
1315
- var strToken, prevToken;
1316
-
1317
- // build fast lookup maps
1318
- _buildMaps();
1319
-
1320
- intCntr = 0;
1321
- intBraces = 0;
1322
- intBrackets = 0;
1323
- intIndex = 0;
1324
- strToken = "";
1325
- arrTokens = new Array();
1326
- pstrExpression = _trim(pstrExpression);
1327
- while (intCntr < pstrExpression.length)
1328
- {
1329
- prevToken = _EMPTY_TOKEN;
1330
- chrChar = pstrExpression.substr(intCntr, 1);
1331
- switch (chrChar)
1332
- {
1333
- case " " :
1334
- if (strToken.length > 0)
1335
- {
1336
- arrTokens[intIndex] = _makeToken(strToken);
1337
- intIndex++;
1338
- strToken = "";
1339
- }
1340
- break;
1341
- //case "{":
1342
- case "(":
1343
- //(chrChar=='(')?intBraces++:intBrackets++;
1344
- intBraces++;
1345
- if (strToken.length > 0)
1346
- {
1347
- arrTokens[intIndex] = _makeToken(strToken);
1348
- intIndex++;
1349
- strToken = "";
1350
- }
1351
- arrTokens[intIndex] = _makeToken(chrChar);
1352
- intIndex++;
1353
- break;
1354
- //case "}" :
1355
- case ")" :
1356
- //(chrChar==')')?intBraces--:intBrackets--;
1357
- intBraces--;
1358
- if (strToken.length > 0)
1359
- {
1360
- arrTokens[intIndex] = _makeToken(strToken);
1361
- intIndex++;
1362
- strToken = "";
1363
- }
1364
- arrTokens[intIndex] = _makeToken(chrChar);
1365
- intIndex++;
1366
- break;
1367
- case "^" :
1368
- case "*" :
1369
- case "/" :
1370
- case "%" :
1371
- case "&" :
1372
- case "|" :
1373
- case "," :
1374
- case "!" :
1375
- if (strToken.length > 0)
1376
- {
1377
- arrTokens[intIndex] = _makeToken(strToken);
1378
- intIndex++;
1379
- strToken = "";
1380
- }
1381
- arrTokens[intIndex] = _makeToken(chrChar);
1382
- intIndex++;
1383
- break;
1384
- case "-" :
1385
- if (strToken.length > 0)
1386
- {
1387
- arrTokens[intIndex] = _makeToken(strToken);
1388
- intIndex++;
1389
- strToken = "";
1390
- }
1391
- chrNext = pstrExpression.substr(intCntr + 1, 1);
1392
- if (arrTokens.length > 0)
1393
- prevToken = arrTokens[intIndex - 1];
1394
- if (/*intCntr == 0 ||*/((prevToken.isArithmeticOp ||
1395
- prevToken.isLeftParen || prevToken.isComma) &&
1396
- (_isDigit(chrNext) || chrNext == "(")))
1397
- {
1398
- // Negative Number
1399
- strToken += chrChar;
1400
- }
1401
- else
1402
- {
1403
- arrTokens[intIndex] = _makeToken(chrChar);
1404
- intIndex++;
1405
- strToken = "";
1406
- }
1407
- break;
1408
- case "+" :
1409
- if (strToken.length > 0)
1410
- {
1411
- arrTokens[intIndex] = _makeToken(strToken);
1412
- intIndex++;
1413
- strToken = "";
1414
- }
1415
- chrNext = pstrExpression.substr(intCntr + 1, 1);
1416
- if (arrTokens.length > 0)
1417
- prevToken = arrTokens[intIndex - 1];
1418
- if (/*intCntr == 0 ||*/ ((prevToken.isArithmeticOp ||
1419
- prevToken.isLeftParen || prevToken.isComma) &&
1420
- (_isDigit(chrNext) || chrNext == "(")))
1421
- {
1422
- // positive Number
1423
- strToken += chrChar;
1424
- }
1425
- else
1426
- {
1427
- arrTokens[intIndex] = _makeToken(chrChar);
1428
- intIndex++;
1429
- strToken = "";
1430
- }
1431
- break;
1432
- case "<" :
1433
- chrNext = pstrExpression.substr(intCntr + 1, 1);
1434
- if (strToken.length > 0)
1435
- {
1436
- arrTokens[intIndex] = _makeToken(strToken);
1437
- intIndex++;
1438
- strToken = "";
1439
- }
1440
- if (chrNext == "=")
1441
- {
1442
- arrTokens[intIndex] = _makeToken(chrChar + "=");
1443
- intIndex++;
1444
- intCntr++;
1445
- }
1446
- else if (chrNext == ">")
1447
- {
1448
- arrTokens[intIndex] = _makeToken(chrChar + ">");
1449
- intIndex++;
1450
- intCntr++;
1451
- }
1452
- else
1453
- {
1454
- arrTokens[intIndex] = _makeToken(chrChar);
1455
- intIndex++;
1456
- }
1457
- break;
1458
- case ">" :
1459
- chrNext = pstrExpression.substr(intCntr + 1, 1);
1460
- if (strToken.length > 0)
1461
- {
1462
- arrTokens[intIndex] = _makeToken(strToken);
1463
- intIndex++;
1464
- strToken = "";
1465
- }
1466
- if (chrNext == "=")
1467
- {
1468
- arrTokens[intIndex] = _makeToken(chrChar + "=");
1469
- intIndex++;
1470
- intCntr++;
1471
- }
1472
- else
1473
- {
1474
- arrTokens[intIndex] = _makeToken(chrChar);
1475
- intIndex++;
1476
- }
1477
- break;
1478
- case "=" :
1479
- if (strToken.length > 0)
1480
- {
1481
- arrTokens[intIndex] = _makeToken(strToken);
1482
- intIndex++;
1483
- strToken = "";
1484
- }
1485
- arrTokens[intIndex] = _makeToken(chrChar);
1486
- intIndex++;
1487
- break;
1488
- case "'" :
1489
- case "\"" :
1490
- if (strToken.length > 0)
1491
- {
1492
- arrTokens[intIndex] = _makeToken(strToken);
1493
- intIndex++;
1494
- strToken = "";
1495
- }
1496
-
1497
- intPos = pstrExpression.indexOf(chrChar, intCntr + 1);
1498
- if (intPos < 0)
1499
- throw "Unterminated string constant";
1500
- else
1501
- {
1502
- strToken += pstrExpression.substring(intCntr + 1, intPos);
1503
- strToken=new String(strToken);
1504
- strToken._isStringLiteral=true;
1505
- arrTokens[intIndex] = _makeToken(strToken);
1506
- intIndex++;
1507
- strToken = "";
1508
- intCntr = intPos;
1509
- }
1510
- break;
1511
- default :
1512
- strToken += chrChar;
1513
- break;
1514
- }
1515
- intCntr++;
1516
- }
1517
- if (intBraces > 0)
1518
- throw "Unbalanced parenthesis!";
1519
-
1520
- if (strToken.length > 0)
1521
- arrTokens[intIndex] = _makeToken(strToken);
1522
- return arrTokens;
1523
- }
1524
- }
1525
- })(DateParser);
1526
-
1527
- /*------------------------------------------------------------------------------
1528
- * NAME : HandleFunctions
1529
- * PURPOSE : Execute built-in functions
1530
- * PARAMETERS : pstrTok - The current function name
1531
- * pStack - Operand stack
1532
- * RETURNS : Nothing, the result is pushed back onto the stack.
1533
- *----------------------------------------------------------------------------*/
1534
- function _HandleFunctions(pstrTok, pStack, pdtFormat, parrVars)
1535
- {
1536
- var varTmp, varTerm, varTerm2, objTmp, varFormat;
1537
- var objOp1, objOp2, objFormat;
1538
- var arrArgs;
1539
- var intCntr;
1540
-
1541
-
1542
-
1543
- if (!pstrTok.isFunction)
1544
- throw "Unsupported function token [" + pstrTok.val + "]";
1545
-
1546
- varTmp = pstrTok.val;
1547
- arrArgs = new Array();
1548
- varTerm = Tokenizer.ARG_TERMINAL;
1549
- while ( !pStack.IsEmpty() )
1550
- {
1551
- varTerm = pStack.Pop();
1552
- if (!varTerm.isArgTerminal)
1553
- arrArgs[arrArgs.length] = varTerm;
1554
- else
1555
- break;
1556
- }
1557
-
1558
- // console.log( 'testing functions ', varTmp, arrArgs );
1559
-
1560
- switch (varTmp)
1561
- {
1562
- case "ARRAY" :
1563
- var arrArray=new Array();
1564
-
1565
- objTmp = 0;
1566
- intCntr = arrArgs.length;
1567
- while (--intCntr >= 0)
1568
- {
1569
- varTerm = arrArgs[intCntr];
1570
- if (varTerm.isVariable)
1571
- {
1572
- objTmp = parrVars[varTerm.val];
1573
- if (objTmp == undefined || objTmp == null)
1574
- throw "Variable [" + varTerm.val + "] not defined";
1575
- else
1576
- varTerm = objTmp;
1577
- }
1578
- arrArray=arrArray.concat(Tokenizer.toArray(varTerm.val));
1579
- }
1580
- pStack.Push(Tokenizer.makeToken(arrArray,Tokenizer.TOKEN_TYPE.ARRAY));
1581
- break;
1582
- case "TODAY" :
1583
- pStack.Push(Tokenizer.makeToken(DateParser.currentDate(), Tokenizer.TOKEN_TYPE.DATE));
1584
- break;
1585
- case "ACOS" :
1586
- case "ASIN" :
1587
- case "ATAN" :
1588
- throw "Function [" + varTmp + "] is not implemented!";
1589
- break;
1590
- case "ABS" :
1591
- case "CHR" :
1592
- case "COS" :
1593
- case "FIX" :
1594
- case "HEX" :
1595
- case "LOG" :
1596
- case "RAND" :
1597
- case "ROUND" :
1598
- case "SIN" :
1599
- case "SQRT" :
1600
- case "TAN" :
1601
-
1602
- if (varTmp != "RAND")
1603
- {
1604
- if (arrArgs.length < 1)
1605
- throw varTmp + " requires at least one argument!";
1606
- else if (arrArgs.length > 1)
1607
- throw varTmp + " requires only one argument!";
1608
- }
1609
- else
1610
- {
1611
- if (arrArgs.length < 1)
1612
- throw varTmp + " requires at least one argument!";
1613
- else if (arrArgs.length > 2)
1614
- throw varTmp + " requires at most two arguments!";
1615
- }
1616
- varTerm = arrArgs[0];
1617
- if (varTerm.isVariable)
1618
- {
1619
- objTmp = parrVars[varTerm.val];
1620
- if (objTmp == undefined || objTmp == null)
1621
- throw "Variable [" + varTerm.val + "] not defined";
1622
- else
1623
- varTerm = objTmp;
1624
- }
1625
-
1626
- objTmp = varTerm.val;
1627
-
1628
- if( varTerm.val !== 0 && !varTerm.val )
1629
- throw varTmp + " operates on numeric operands only!";
1630
-
1631
- else if ( isNaN( +varTerm.val ) )
1632
- throw varTmp + " operates on numeric operands only!";
1633
- else
1634
- {
1635
-
1636
- objTmp = Tokenizer.toNumber(varTerm.val);
1637
- if (varTmp == "RAND")
1638
- {
1639
- rand_max=Math.floor(objTmp);
1640
- if (arrArgs.length == 2)
1641
- {
1642
- varTerm = arrArgs[1];
1643
- if (varTerm.isVariable)
1644
- {
1645
- objTmp = parrVars[varTerm.val];
1646
- if (objTmp == undefined || objTmp == null)
1647
- throw "Variable [" + varTerm.val + "] not defined";
1648
- else
1649
- varTerm = objTmp;
1650
- }
1651
-
1652
- if (!varTerm.isNumber)
1653
- throw varTmp + " operates on numeric operands only!";
1654
-
1655
- objTmp = Tokenizer.toNumber(varTerm.val);
1656
-
1657
- rand_min=Math.floor(objTmp);
1658
- }
1659
- }
1660
- }
1661
-
1662
- if (varTmp == "ABS")
1663
- pStack.Push(Tokenizer.makeToken(Math.abs(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1664
- else if (varTmp == "CHR"){
1665
- // TODO check what happens when $objTmp is empty; what does fromCharCode() return?
1666
-
1667
- pStack.Push(Tokenizer.makeToken(String.fromCharCode(objTmp),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1668
- }
1669
- else if (varTmp == "COS")
1670
- pStack.Push(Tokenizer.makeToken(Math.cos(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1671
- else if (varTmp == "FIX")
1672
- pStack.Push(Tokenizer.makeToken(Math.floor(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1673
- else if (varTmp == "HEX")
1674
- pStack.Push(Tokenizer.makeToken(objTmp.toString(16),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1675
- else if (varTmp == "LOG")
1676
- pStack.Push(Tokenizer.makeToken(Math.log(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1677
- else if (varTmp == "RAND")
1678
- pStack.Push(Tokenizer.makeToken(Math.round(rand_min+(rand_max-rand_min)*Math.random()),Tokenizer.TOKEN_TYPE.NUMBER));
1679
- else if (varTmp == "ROUND")
1680
- pStack.Push(Tokenizer.makeToken(Math.round(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1681
- else if (varTmp == "SIN")
1682
- pStack.Push(Tokenizer.makeToken(Math.sin(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1683
- else if (varTmp == "SQRT")
1684
- pStack.Push(Tokenizer.makeToken(Math.sqrt(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1685
- else if (varTmp == "TAN")
1686
- pStack.Push(Tokenizer.makeToken(Math.tan(objTmp),Tokenizer.TOKEN_TYPE.NUMBER));
1687
- break;
1688
- case "STR" :
1689
- if (arrArgs.length < 1)
1690
- throw varTmp + " requires at least one argument!";
1691
- else if (arrArgs.length > 2)
1692
- throw varTmp + " requires at most two arguments!";
1693
- varTerm = arrArgs[arrArgs.length-1];
1694
- if (varTerm.isVariable)
1695
- {
1696
- objTmp = parrVars[varTerm.val];
1697
- if (objTmp == undefined || objTmp == null)
1698
- throw "Variable [" + varTerm.val + "] not defined";
1699
- else
1700
- varTerm = objTmp;
1701
- }
1702
- // if date, output formated date string
1703
- if (varTerm.isDate)
1704
- {
1705
- var format='';
1706
- if (arrArgs.length==2)
1707
- {
1708
- varFormat = arrArgs[0];
1709
- if (varFormat.isVariable)
1710
- {
1711
- objTmp = parrVars[varFormat.val];
1712
- if (objTmp == undefined || objTmp == null)
1713
- throw "Variable [" + varFormat.val + "] not defined";
1714
- else
1715
- varFormat = objTmp;
1716
- }
1717
-
1718
- if (!varFormat.isStringLiteral)
1719
- throw "format argument for " + varTmp + " must be a string!";
1720
- format=varFormat.val;
1721
- }
1722
- pStack.Push(Tokenizer.makeToken(DateParser.formatDate(varTerm.val, format),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1723
- }
1724
- else // just convert to string
1725
- pStack.Push(Tokenizer.makeToken(varTerm.val.toString(),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1726
- break;
1727
- case "ASC" :
1728
-
1729
- if (arrArgs.length > 1)
1730
- throw varTmp + " requires only one argument!";
1731
- else if (arrArgs.length < 1)
1732
- throw varTmp + " requires at least one argument!";
1733
- varTerm = arrArgs[0];
1734
- if (varTerm.isVariable)
1735
- {
1736
- objTmp = parrVars[varTerm.val];
1737
- if (objTmp == undefined || objTmp == null)
1738
- throw "Variable [" + varTerm.val + "] not defined";
1739
- else
1740
- varTerm = objTmp;
1741
- }
1742
- if( varTerm.isNumber )
1743
- {
1744
- varTerm.val = varTerm.val.toString();
1745
- varTerm.isStringLiteral = true;
1746
- }
1747
-
1748
- if (!varTerm.isStringLiteral)
1749
- throw varTmp + " requires a string type operand!";
1750
- else
1751
- {
1752
- if ( varTerm.val ) {
1753
- pStack.Push(Tokenizer.makeToken(varTerm.val.charCodeAt(0),Tokenizer.TOKEN_TYPE.NUMBER));
1754
- } else {
1755
- pStack.Push(Tokenizer.makeToken(0,Tokenizer.TOKEN_TYPE.NUMBER));
1756
- }
1757
- }
1758
- break;
1759
- case "REGEX" :
1760
- if (arrArgs.length < 1)
1761
- throw varTmp + " requires at least one argument!";
1762
- else if (arrArgs.length > 2)
1763
- throw varTmp + " requires at most two arguments!";
1764
-
1765
- varTerm = arrArgs[arrArgs.length-1];
1766
- if (varTerm.isVariable)
1767
- {
1768
- objTmp = parrVars[varTerm.val];
1769
- if (objTmp == undefined || objTmp == null)
1770
- throw "Variable [" + varTerm.val + "] not defined";
1771
- else
1772
- varTerm = objTmp;
1773
- }
1774
-
1775
- if (!varTerm.isStringLiteral)
1776
- throw varTmp + " operates on string type operands!";
1777
-
1778
- var opts=Tokenizer.EMPTY_STRING;
1779
- if (arrArgs.length==2)
1780
- {
1781
- opts = arrArgs[0];
1782
- if (opts.isVariable)
1783
- {
1784
- objTmp = parrVars[opts.val];
1785
- if (objTmp == undefined || objTmp == null)
1786
- throw "Variable [" + opts.val + "] not defined";
1787
- else
1788
- opts = objTmp;
1789
- }
1790
-
1791
- if (!opts.isStringLiteral)
1792
- throw varTmp + " operates on string type operands!";
1793
- }
1794
- pStack.Push(Tokenizer.makeToken(Functions.Regex(varTerm.val.toString(), opts.val.toString()),Tokenizer.TOKEN_TYPE.REGEX));
1795
- break;
1796
- case "LCASE" :
1797
- case "UCASE" :
1798
- case "NUM" :
1799
-
1800
- if (arrArgs.length < 1)
1801
- throw varTmp + " requires at least one argument!";
1802
- else if (arrArgs.length > 1)
1803
- throw varTmp + " requires only one argument!";
1804
-
1805
- varTerm = arrArgs[0];
1806
- if (varTerm.isVariable)
1807
- {
1808
- objTmp = parrVars[varTerm.val];
1809
- if (objTmp == undefined || objTmp == null)
1810
- throw "Variable [" + varTerm.val + "] not defined";
1811
- else
1812
- varTerm = objTmp;
1813
- }
1814
-
1815
- if( varTerm.isNumber )
1816
- {
1817
- varTerm.val = varTerm.val.toString();
1818
- varTerm.isStringLiteral = true;
1819
- }
1820
-
1821
- if (!varTerm.isStringLiteral && varTmp != "NUM")
1822
- throw varTmp + " requires a string type operand!";
1823
- else
1824
- {
1825
- if (varTmp == "LCASE")
1826
- {
1827
- pStack.Push(Tokenizer.makeToken(varTerm.val.toLowerCase(),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1828
- }
1829
- else if (varTmp == "UCASE")
1830
- {
1831
- pStack.Push(Tokenizer.makeToken(varTerm.val.toUpperCase(),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1832
- }
1833
- else if (varTmp == "NUM")
1834
- {
1835
- objTmp=Tokenizer.toNumber(varTerm.val)+0.0;
1836
- if (isNaN(objTmp))
1837
- throw varTmp + " cannot convert [" + varTerm.val + "] to number!";
1838
- pStack.Push(Tokenizer.makeToken(objTmp,Tokenizer.TOKEN_TYPE.NUMBER));
1839
- }
1840
- }
1841
- break;
1842
- case "LEN" :
1843
- if (arrArgs.length < 1)
1844
- throw varTmp + " requires at least one argument!";
1845
- else if (arrArgs.length > 1)
1846
- throw varTmp + " requires only one argument!";
1847
-
1848
- varTerm = arrArgs[0];
1849
- if (varTerm.isVariable)
1850
- {
1851
- objTmp = parrVars[varTerm.val];
1852
- if (objTmp == undefined || objTmp == null)
1853
- throw "Variable [" + varTerm.val + "] not defined";
1854
- else
1855
- varTerm = objTmp;
1856
- }
1857
-
1858
- if (!varTerm.isArray && !varTerm.isStringLiteral)
1859
- throw varTmp + " requires a string or array type operand!";
1860
- else
1861
- {
1862
- pStack.Push(Tokenizer.makeToken(varTerm.val.length,Tokenizer.TOKEN_TYPE.NUMBER));
1863
- }
1864
- break;
1865
- case "USER" :
1866
- if (arrArgs.length < 1)
1867
- throw varTmp + " requires at least one argument!";
1868
- else if (arrArgs.length > 1)
1869
- throw varTmp + " requires only one argument!";
1870
-
1871
- varTerm = arrArgs[0];
1872
- if (varTerm.isVariable)
1873
- {
1874
- objTmp = parrVars[varTerm.val];
1875
- if (objTmp == undefined || objTmp == null)
1876
- throw "Variable [" + varTerm.val + "] not defined";
1877
- else
1878
- varTerm = objTmp;
1879
- }
1880
-
1881
- if (!varTerm.isStringLiteral)
1882
- throw varTmp + " requires a string type operand!";
1883
- else
1884
- {
1885
- pStack.Push(Tokenizer.makeToken(Functions.User(varTerm.val),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1886
- }
1887
- break;
1888
- case "COOKIE" :
1889
- if (arrArgs.length < 1)
1890
- throw varTmp + " requires at least one argument!";
1891
- else if (arrArgs.length > 1)
1892
- throw varTmp + " requires only one argument!";
1893
-
1894
- varTerm = arrArgs[0];
1895
- if (varTerm.isVariable)
1896
- {
1897
- objTmp = parrVars[varTerm.val];
1898
- if (objTmp == undefined || objTmp == null)
1899
- throw "Variable [" + varTerm.val + "] not defined";
1900
- else
1901
- varTerm = objTmp;
1902
- }
1903
-
1904
- if (!varTerm.isStringLiteral)
1905
- throw varTmp + " requires a string type operand!";
1906
- else
1907
- {
1908
- //console.log(varTerm.val,varTerm.val.length);
1909
- pStack.Push(Tokenizer.makeToken(Functions.Cookie(varTerm.val),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
1910
- }
1911
- break;
1912
- case "CONTAINS" :
1913
- // console.log( 'testing functions ', varTmp, arrArgs );
1914
- if (arrArgs.length < 2)
1915
- throw varTmp + " requires at least two arguments!";
1916
- else if (arrArgs.length > 2)
1917
- throw varTmp + " requires only two arguments!";
1918
-
1919
- varTerm = arrArgs[1];
1920
- if (varTerm.isVariable)
1921
- {
1922
- objTmp = parrVars[varTerm.val];
1923
- if (objTmp == undefined || objTmp == null)
1924
- throw "Variable [" + varTerm.val + "] not defined";
1925
- else
1926
- varTerm = objTmp;
1927
- }
1928
- varTerm2 = arrArgs[0];
1929
- if (varTerm2.isVariable)
1930
- {
1931
- objTmp = parrVars[varTerm2.val];
1932
- if (objTmp == undefined || objTmp == null)
1933
- throw "Variable [" + varTerm2.val + "] not defined";
1934
- else
1935
- varTerm2 = objTmp;
1936
- }
1937
-
1938
- if ( !varTerm.isArray )
1939
- throw varTmp + " requires an array as first argument!";
1940
- else
1941
- {
1942
- var found=false;
1943
- /*var ii=varTerm.val.length;
1944
- while(--ii>=0)
1945
- {
1946
- if (varTerm.val[ii]==varTerm2.val)
1947
- {
1948
- found=true;
1949
- break;
1950
- }
1951
- }*/
1952
- found=Functions.Contains(varTerm.val, varTerm2.val);
1953
- pStack.Push(Tokenizer.makeToken(found,Tokenizer.TOKEN_TYPE.BOOLEAN));
1954
- }
1955
- break;
1956
- case "DATE" :
1957
- if (arrArgs.length < 2)
1958
- throw varTmp + " requires at least two arguments!";
1959
- else if (arrArgs.length > 2)
1960
- throw varTmp + " requires only two arguments!";
1961
-
1962
- varTerm = arrArgs[1];
1963
- if (varTerm.isVariable)
1964
- {
1965
- objTmp = parrVars[varTerm.val];
1966
- if (objTmp == undefined || objTmp == null)
1967
- throw "Variable [" + varTerm.val + "] not defined";
1968
- else
1969
- varTerm = objTmp;
1970
- }
1971
- varFormat = arrArgs[0];
1972
- if (varFormat.isVariable)
1973
- {
1974
- objFormat = parrVars[varFormat.val];
1975
- if (objFormat == undefined || objFormat == null)
1976
- throw "Variable [" + varFormat.val + "] not defined";
1977
- else
1978
- varFormat = objFormat;
1979
- }
1980
-
1981
- var dateobj={};
1982
- if (
1983
- (!varTerm.isStringLiteral) ||
1984
- (!varFormat.isStringLiteral)
1985
- )
1986
- throw varTmp + " requires string type operands!";
1987
- else if (!Tokenizer.isDate(varTerm.val, varFormat.val, dateobj))
1988
- throw varTmp + " can not convert [" + varTerm.val + "] to a valid date with format [" + varFormat.val + "]!";
1989
- else
1990
- {
1991
- if (dateobj.date)
1992
- pStack.Push(Tokenizer.makeToken(dateobj.date,Tokenizer.TOKEN_TYPE.DATE));
1993
- else
1994
- throw varTmp + " unknown error";
1995
- }
1996
- break;
1997
- case "empty":
1998
- case "EMPTY":
1999
- if (arrArgs.length < 1)
2000
- throw varTmp + " requires at least one arguments!";
2001
- else if (arrArgs.length > 1)
2002
- throw varTmp + " requires only one arguments!";
2003
-
2004
- varFormat = arrArgs[0];
2005
-
2006
-
2007
- if( varFormat.isEmpty === true )
2008
- {
2009
- pStack.Push( Tokenizer.makeToken(true,Tokenizer.TOKEN_TYPE.BOOLEAN) );
2010
- }
2011
- else if( varFormat.isArray === true && varFormat.val.length === 0 )
2012
- {
2013
- pStack.Push( Tokenizer.makeToken(true,Tokenizer.TOKEN_TYPE.BOOLEAN) );
2014
- }
2015
- else if( varFormat.isStringLiteral === true && varFormat.val === "" )
2016
- {
2017
- pStack.Push( Tokenizer.makeToken(true,Tokenizer.TOKEN_TYPE.BOOLEAN) );
2018
- }
2019
- else if( varFormat.isDate && !varFormat.val )
2020
- {
2021
- pStack.Push( Tokenizer.makeToken(true,Tokenizer.TOKEN_TYPE.BOOLEAN) );
2022
- }
2023
- else
2024
- {
2025
- pStack.Push( Tokenizer.makeToken(false,Tokenizer.TOKEN_TYPE.BOOLEAN) );
2026
- }
2027
-
2028
-
2029
- break;
2030
- case "LEFT" :
2031
- case "RIGHT" :
2032
- if (arrArgs.length < 2)
2033
- throw varTmp + " requires at least two arguments!";
2034
- else if (arrArgs.length > 2)
2035
- throw varTmp + " requires only two arguments!";
2036
-
2037
- for (intCntr = 0; intCntr < arrArgs.length; intCntr++)
2038
- {
2039
- varTerm = arrArgs[intCntr];
2040
- if (varTerm.isVariable)
2041
- {
2042
- objTmp = parrVars[varTerm.val];
2043
- if (objTmp == undefined || objTmp == null)
2044
- throw "Variable [" + varTerm.val + "] not defined";
2045
- else
2046
- varTerm = objTmp;
2047
- }
2048
-
2049
- if( varTerm.isNumber )
2050
- {
2051
- arrArgs[1].val = arrArgs[1].val.toString()
2052
- varTerm.isStringLiteral = true;
2053
- }
2054
-
2055
- if (intCntr == 0 && !varTerm.isNumber)
2056
- throw varTmp + " operator requires numeric length!";
2057
- else if (intCntr == 1 && !varTerm.isStringLiteral)
2058
- throw varTmp + " operator requires a string operand!";
2059
- arrArgs[intCntr] = varTerm;
2060
- }
2061
- varTerm = arrArgs[1].val.toString();
2062
- objTmp = Tokenizer.toNumber(arrArgs[0].val);
2063
- if (varTmp == "LEFT")
2064
- {
2065
- pStack.Push(Tokenizer.makeToken(varTerm.substring(0, objTmp),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
2066
- }
2067
- else
2068
- {
2069
- pStack.Push(Tokenizer.makeToken(varTerm.substr((varTerm.length - objTmp), objTmp),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
2070
- }
2071
- break;
2072
- case "MID" :
2073
- case "IIF" :
2074
-
2075
- if (arrArgs.length < 3)
2076
- throw varTmp + " requires at least three arguments!";
2077
- else if (arrArgs.length > 3)
2078
- throw varTmp + " requires only three arguments!";
2079
-
2080
-
2081
-
2082
- for (intCntr = 0; intCntr < arrArgs.length; intCntr++)
2083
- {
2084
- varTerm = arrArgs[intCntr];
2085
- if (varTerm.isVariable)
2086
- {
2087
- objTmp = parrVars[varTerm.val];
2088
- if (objTmp == undefined || objTmp == null)
2089
- throw "Variable [" + varTerm.val + "] not defined";
2090
- else
2091
- varTerm = objTmp;
2092
- }
2093
-
2094
- if( varTerm.isNumber )
2095
- {
2096
- arrArgs[2].val = arrArgs[2].val.toString()
2097
- varTerm.isStringLiteral = true;
2098
- }
2099
-
2100
- if (varTmp == "MID" && intCntr <= 1 && !varTerm.isNumber)
2101
- throw varTmp + " operator requires numeric lengths!";
2102
- else if (varTmp == "MID" && intCntr == 2 && !varTerm.isStringLiteral)
2103
- throw varTmp + " operator requires a string input!";
2104
- //else if (varTmp == "IIF" && intCntr == 2 && !varTerm.isBoolean && !varTerm.isNumber)
2105
- //throw varTmp + " operator requires boolean condition!";
2106
- arrArgs[intCntr] = varTerm;
2107
- }
2108
- if (varTmp == "MID")
2109
- {
2110
- varTerm = arrArgs[2].val.toString();
2111
- objOp1 = Tokenizer.toNumber(arrArgs[1].val);
2112
- objOp2 = Tokenizer.toNumber(arrArgs[0].val);
2113
- pStack.Push(Tokenizer.makeToken(varTerm.substring(objOp1, objOp2),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
2114
- }
2115
- else
2116
- {
2117
-
2118
- varTerm = Tokenizer.toBoolean(arrArgs[2].val);
2119
-
2120
- if (varTerm)
2121
- {
2122
- objOp1 = arrArgs[1];
2123
- }
2124
-
2125
- else
2126
- {
2127
- objOp1 = arrArgs[0];
2128
- }
2129
-
2130
- pStack.Push(objOp1);
2131
- }
2132
- break;
2133
- case "AVG" :
2134
- case "MAX" :
2135
- case "MIN" :
2136
- if (arrArgs.length < 1)
2137
- throw varTmp + " requires at least one operand!";
2138
-
2139
- var _arr=[];
2140
- intCntr = arrArgs.length;
2141
- while (--intCntr>=0)
2142
- {
2143
- varTerm = arrArgs[intCntr];
2144
- if (varTerm.isVariable)
2145
- {
2146
- objTmp = parrVars[varTerm.val];
2147
- if (objTmp == undefined || objTmp == null)
2148
- throw "Variable [" + varTerm.val + "] not defined";
2149
- else
2150
- varTerm = objTmp;
2151
- }
2152
-
2153
- if( jQuery.isArray( varTerm.val ) )
2154
- {
2155
- varTerm.isArray = true;
2156
- }
2157
- else if( varTerm.val !== '' || isNaN( +varTerm.val ) === false )
2158
- {
2159
- varTerm.isNumber = true;
2160
- }
2161
-
2162
- if (!varTerm.isNumber && !varTerm.isArray)
2163
- throw varTmp + " requires numeric or array operands only!";
2164
-
2165
- if (!varTerm.isArray)
2166
- _arr=_arr.concat(Tokenizer.toArray(Tokenizer.toNumber(varTerm.val)));
2167
- else
2168
- _arr=_arr.concat(varTerm.val);
2169
- }
2170
- intCntr = -1;
2171
- objTmp = 0;
2172
- while (++intCntr < _arr.length)
2173
- {
2174
- varTerm = _arr[intCntr];
2175
- if (varTmp == "AVG")
2176
- objTmp += varTerm;
2177
- else if (varTmp == "MAX")
2178
- {
2179
- if (intCntr == 0)
2180
- objTmp = varTerm;
2181
- else if (objTmp < varTerm)
2182
- objTmp = varTerm;
2183
- }
2184
- else if (varTmp == "MIN")
2185
- {
2186
- if (intCntr == 0)
2187
- objTmp = varTerm;
2188
- else if (objTmp > varTerm)
2189
- objTmp = varTerm;
2190
- }
2191
- }
2192
- if (varTmp == "AVG" && _arr.length)
2193
- pStack.Push(Tokenizer.makeToken(objTmp/_arr.length,Tokenizer.TOKEN_TYPE.NUMBER));
2194
- else if (varTmp == "AVG")
2195
- pStack.Push(Tokenizer.makeToken(0,Tokenizer.TOKEN_TYPE.NUMBER));
2196
- else
2197
- pStack.Push(Tokenizer.makeToken(objTmp,Tokenizer.TOKEN_TYPE.NUMBER));
2198
- break;
2199
- }
2200
- };
2201
-
2202
- /*------------------------------------------------------------------------------
2203
- * NAME : InFixToPostFix
2204
- * PURPOSE : Convert an Infix expression into a postfix (RPN) equivalent
2205
- * PARAMETERS : Infix expression element array
2206
- * RETURNS : array containing postfix expression element tokens
2207
- *----------------------------------------------------------------------------*/
2208
- function _InFixToPostFix(arrToks)
2209
- {
2210
- //console.log('post');
2211
- var myStack;
2212
- var intCntr, intIndex;
2213
- var strTok, strTop, strNext, strPrev;
2214
- var blnStart;
2215
-
2216
- blnStart = false;
2217
- intIndex = 0;
2218
- arrPFix = new Array();
2219
- myStack = new Stack();
2220
-
2221
- // Infix to postfix converter
2222
- for (intCntr = 0; intCntr < arrToks.length; intCntr++)
2223
- {
2224
- //console.log(arrPFix);
2225
- //console.log(myStack.toString());
2226
- strTok = arrToks[intCntr];
2227
- switch (strTok.type)
2228
- {
2229
- case Tokenizer.TOKEN_TYPE.LEFT_PAREN :
2230
- if (myStack.Size() > 0 && myStack.Get(0).isFunction)
2231
- {
2232
- arrPFix[intIndex] = Tokenizer.ARG_TERMINAL;
2233
- intIndex++;
2234
- }
2235
- myStack.Push(strTok);
2236
- break;
2237
- case Tokenizer.TOKEN_TYPE.RIGHT_PAREN :
2238
- blnStart = true;
2239
- while (!myStack.IsEmpty())
2240
- {
2241
- strTok = myStack.Pop();
2242
- if (!strTok.isLeftParen)
2243
- {
2244
- arrPFix[intIndex] = strTok;
2245
- intIndex++;
2246
- }
2247
- else
2248
- {
2249
- blnStart = false;
2250
- break;
2251
- }
2252
- }
2253
- if (myStack.IsEmpty() && blnStart)
2254
- throw "Unbalanced parenthesis!";
2255
- break;
2256
- case Tokenizer.TOKEN_TYPE.COMMA :
2257
- while (!myStack.IsEmpty())
2258
- {
2259
- strTok = myStack.Get(0);
2260
- if (strTok.isLeftParen) break;
2261
- arrPFix[intIndex] = myStack.Pop();
2262
- intIndex++;
2263
- }
2264
- break;
2265
- //case Tokenizer.TOKEN_TYPE.UNARY_NEGATIVE :
2266
- //case Tokenizer.TOKEN_TYPE.UNARY_NEGATION :
2267
- case Tokenizer.TOKEN_TYPE.ARITHMETIC_OP :
2268
- case Tokenizer.TOKEN_TYPE.LOGICAL_OP :
2269
- case Tokenizer.TOKEN_TYPE.COMPARISON_OP :
2270
- switch (strTok.val)
2271
- {
2272
- /*case "-" :
2273
- case "+" :
2274
- case "NOT" :
2275
- case "!" :
2276
- case "^" :
2277
- case "*" :
2278
- case "/" :
2279
- case "%" :
2280
- case "AND" :
2281
- case "&" :
2282
- case "OR" :
2283
- case "|" :
2284
- case ">" :
2285
- case "<" :
2286
- case "=" :
2287
- case ">=" :
2288
- case "<=" :
2289
- case "<>" :*/
2290
- default:
2291
- if (strTok.val=='-')
2292
- {
2293
- // check for unary negative operator.
2294
- strPrev = null;
2295
- if (intCntr > 0)
2296
- strPrev = arrToks[intCntr - 1];
2297
- strNext = arrToks[intCntr + 1];
2298
- if (strPrev == null || strPrev.isArithmeticOp || strPrev.isLeftParen || strPrev.isComma)
2299
- {
2300
- strTok = Tokenizer.UNARY_NEGATIVE;
2301
- }
2302
- }
2303
- if (strTok.val=='+')
2304
- {
2305
- // check for unary + addition operator, we need to ignore this.
2306
- strPrev = null;
2307
- if (intCntr > 0)
2308
- strPrev = arrToks[intCntr - 1];
2309
- strNext = arrToks[intCntr + 1];
2310
- if (strPrev == null || strPrev.isArithmeticOp || strPrev.isLeftParen || strPrev.isComma)
2311
- {
2312
- break;
2313
- }
2314
- }
2315
- strTop = Tokenizer.EMPTY_TOKEN;
2316
- if (!myStack.IsEmpty()) strTop = myStack.Get(0);
2317
- if (myStack.IsEmpty() || (!myStack.IsEmpty() && strTop.isLeftParen))
2318
- {
2319
- myStack.Push(strTok);
2320
- }
2321
- else if (strTok.precedence >= strTop.precedence)
2322
- {
2323
- myStack.Push(strTok);
2324
- }
2325
- else
2326
- {
2327
- // Pop operators with precedence >= operator strTok
2328
- while (!myStack.IsEmpty())
2329
- {
2330
- strTop = myStack.Get(0);
2331
- if (strTop.isLeftParen || strTop.precedence < strTok.precedence)
2332
- {
2333
- break;
2334
- }
2335
- else
2336
- {
2337
- arrPFix[intIndex] = myStack.Pop();
2338
- intIndex++;
2339
- }
2340
- }
2341
- myStack.Push(strTok);
2342
- }
2343
- break;
2344
- }
2345
- break;
2346
- default :
2347
- if (strTok.type!=Tokenizer.TOKEN_TYPE.FUNCTION)
2348
- {
2349
- arrPFix[intIndex] = strTok;
2350
- intIndex++;
2351
- }
2352
- else
2353
- {
2354
- strTop = Tokenizer.EMPTY_TOKEN;
2355
- if (!myStack.IsEmpty()) strTop = myStack.Get(0);
2356
- if (myStack.IsEmpty() || (!myStack.IsEmpty() && strTop.isLeftParen))
2357
- {
2358
- myStack.Push(strTok);
2359
- }
2360
- else if (strTok.precedence >= strTop.precedence)
2361
- {
2362
- myStack.Push(strTok);
2363
- }
2364
- else
2365
- {
2366
- // Pop operators with precedence >= operator in strTok
2367
- while (!myStack.IsEmpty())
2368
- {
2369
- strTop = myStack.Get(0);
2370
- if (strTop.val == "(" || strTop.precedence < strTok.precedence)
2371
- {
2372
- break;
2373
- }
2374
- else
2375
- {
2376
- arrPFix[intIndex] = myStack.Pop();
2377
- intIndex++;
2378
- }
2379
- }
2380
- myStack.Push(strTok);
2381
- }
2382
- }
2383
- break;
2384
- }
2385
- }
2386
-
2387
- // Pop remaining operators from stack.
2388
- while (!myStack.IsEmpty())
2389
- {
2390
- arrPFix[intIndex] = myStack.Pop();
2391
- intIndex++;
2392
- }
2393
- //console.log(arrPFix);
2394
- return arrPFix;
2395
- };
2396
-
2397
- // public methods
2398
- return (function(Tokenizer,DateParser){
2399
-
2400
- return {
2401
- // delegate here
2402
- setParams : function(params)
2403
- {
2404
- Functions.setParams(params);
2405
- },
2406
-
2407
- Expression : function(pstrExp)
2408
- {
2409
- var strInFix = null;
2410
- var arrVars = [];
2411
- var arrTokens = null;
2412
- var arrPostFix = null;
2413
- var dtFormat = "d/m/Y";
2414
- var thiss=this;
2415
-
2416
- if (typeof(pstrExp)!='undefined' && pstrExp)
2417
- strInFix=pstrExp;
2418
-
2419
- // public methods
2420
- this.dateLocales=function(a,b,c){DateParser.setDateLocaleStrings(a,b,c); return thiss;}
2421
- this.dateFormat = function(df){dtFormat = df; return thiss;};
2422
- this.expression = function(exp){strInFix = exp; arrTokens=arrPostFix=null; return thiss;};
2423
- this.addVar = function(_var){_AddNewVariable(_var, arrVars); return thiss;};
2424
- this.parse = function(){arrPostFix=_ParseExpression(); return _dumpPostFix(arrPostFix);};
2425
- this.eval = function(){return _EvaluateExpression(arrPostFix, arrVars);};
2426
- this.reset = function(){arrVars = [];strInFix=arrTokens=arrPostFix=null; return thiss;};
2427
- this.dump = function(){return _dumpPostFix(arrPostFix);};
2428
- this.preCompile = function(_exp){if (typeof(_exp)=='undefined') _exp=strInFix; return _getPrecompiledExpression(_exp);};
2429
-
2430
- function _AddNewVariable(varObj, varArr)
2431
- {
2432
- if (typeof(varArr)=='undefined')
2433
- varArr = arrVars;
2434
-
2435
- if (varArr == null || varArr == undefined)
2436
- varArr = new Array();
2437
-
2438
- varName=varObj.name;
2439
- varToken=null;
2440
- if (varObj.withType)
2441
- {
2442
- switch(varObj.withType)
2443
- {
2444
- case 'boolean':
2445
- varToken=Tokenizer.makeToken(varObj.val,Tokenizer.TOKEN_TYPE.BOOLEAN); //Tokenizer.toBoolean(varObj.val);
2446
- break;
2447
- case 'number':
2448
- varToken=Tokenizer.makeToken(varObj.val,Tokenizer.TOKEN_TYPE.NUMBER); //Tokenizer.toNumber(varObj.val);
2449
- break;
2450
- case 'array':
2451
- varToken=Tokenizer.makeToken(varObj.val,Tokenizer.TOKEN_TYPE.ARRAY); //Tokenizer.toArray(varObj.val);
2452
- break;
2453
- case 'date':
2454
- var format;
2455
- if (varObj.format)
2456
- format=varObj.format;
2457
- else
2458
- format=dtFormat;
2459
- //varValue=DateParser.parseDate(varObj.val, format);
2460
- varToken=Tokenizer.makeToken(DateParser.parseDate(varObj.val, format),Tokenizer.TOKEN_TYPE.DATE); //
2461
- break;
2462
- case 'string':
2463
- default:
2464
- varToken=Tokenizer.makeToken(varObj.val,Tokenizer.TOKEN_TYPE.STRING_LITERAL); //
2465
- break;
2466
- }
2467
- }
2468
- else
2469
- varToken=Tokenizer.makeToken(varObj.val,Tokenizer.TOKEN_TYPE.STRING_LITERAL); //
2470
-
2471
- varArr[varName] = varToken;
2472
- }
2473
-
2474
- function _dumpPostFix(pf)
2475
- {
2476
- var out='';
2477
- for (var i=0; i<pf.length; i++)
2478
- out+=pf[i].val+',';
2479
- return out;
2480
- }
2481
-
2482
- function _clonePostFix(pf)
2483
- {
2484
- var newpf=new Array(pf.length);
2485
- for (var i=0; i<pf.length; i++)
2486
- newpf[i]=Tokenizer.cloneToken(pf[i]);
2487
- return newpf;
2488
- }
2489
-
2490
- function _createFunction(myarrPostFix)
2491
- {
2492
- return function(vars)
2493
- {
2494
- // init internal closure vars
2495
- var myvarsArray=[];
2496
- // add user vars at run-time
2497
- if (typeof(vars)!='undefined' && vars)
2498
- {
2499
- for (var i=0; i<vars.length; i++)
2500
- _AddNewVariable(vars[i], myvarsArray);
2501
- }
2502
- //console.log(_dumpPostFix(myarrPostFix));
2503
- // return evaluated result
2504
- return _EvaluateExpression(_clonePostFix(myarrPostFix), myvarsArray);
2505
- }
2506
- }
2507
-
2508
- function _getPrecompiledExpression(exp)
2509
- {
2510
- var myarrTokens = Tokenizer.Tokanize(exp);
2511
- if (myarrTokens == null || myarrTokens == undefined)
2512
- throw "Unable to tokanize the expression!";
2513
- if (myarrTokens.length <= 0)
2514
- throw "Unable to tokanize the expression!";
2515
-
2516
- var myarrPostFix0 = _InFixToPostFix(myarrTokens);
2517
- if (myarrPostFix0 == null || myarrPostFix0 == undefined)
2518
- throw "Unable to convert the expression to postfix form!";
2519
- if (myarrPostFix0.length <= 0)
2520
- throw "Unable to convert the expression to postfix form!";
2521
-
2522
- // return precompiled dynamic function
2523
- return _createFunction(myarrPostFix0);
2524
- }
2525
-
2526
- function _ParseExpression()
2527
- {
2528
- arrTokens = Tokenizer.Tokanize(strInFix);
2529
- if (arrTokens == null || arrTokens == undefined)
2530
- throw "Unable to tokanize the expression!";
2531
- if (arrTokens.length <= 0)
2532
- throw "Unable to tokanize the expression!";
2533
-
2534
- var myarrPostFix = _InFixToPostFix(arrTokens);
2535
- if (myarrPostFix == null || myarrPostFix == undefined)
2536
- throw "Unable to convert the expression to postfix form!";
2537
- if (myarrPostFix.length <= 0)
2538
- throw "Unable to convert the expression to postfix form!";
2539
- return myarrPostFix;
2540
- }
2541
-
2542
- function _getVariable(strVarName, varArr)
2543
- {
2544
- var retVal;
2545
-
2546
- if (typeof(varArr)=='undefined')
2547
- varArr=arrVars;
2548
-
2549
- if (varArr == null || varArr == undefined)
2550
- throw "Variable values are not supplied!";
2551
-
2552
- retVal = varArr[strVarName];
2553
- if (typeof(varArr[strVarName])=='undefined' || retVal == undefined || retVal == null)
2554
- throw "Variable [" + strVarName + "] not defined";
2555
- return retVal;
2556
- }
2557
-
2558
- // postfix function evaluator
2559
- function _EvaluateExpression(myarrPostFix, myvarArr)
2560
- {
2561
-
2562
- var intIndex;
2563
- var myStack;
2564
- var strTok, strOp;
2565
- var objOp1, objOp2, objTmp1, objTmp2;
2566
- var dblNo, dblVal1, dblVal2;
2567
-
2568
- if (myarrPostFix == null || myarrPostFix == undefined)
2569
- myarrPostFix=_ParseExpression();
2570
- if (myarrPostFix.length == 0)
2571
- throw "Unable to parse the expression!";
2572
- if (myarrPostFix == null || myarrPostFix == undefined || myarrPostFix.length == 0)
2573
- {
2574
- throw "Invalid postfix expression!";
2575
- return;
2576
- }
2577
-
2578
- intIndex = 0;
2579
- myStack = new Stack();
2580
- //console.log(myarrPostFix);
2581
- while (intIndex < myarrPostFix.length)
2582
- {
2583
- //console.log(myStack.toString());
2584
- strTok = myarrPostFix[intIndex];
2585
- switch (strTok.type)
2586
- {
2587
- case Tokenizer.TOKEN_TYPE.ARG_TERMINAL :
2588
- myStack.Push(strTok);
2589
- break;
2590
- case Tokenizer.TOKEN_TYPE.UNARY_NEGATIVE :
2591
- if (myStack.IsEmpty())
2592
- throw "No operand to negate!";
2593
-
2594
- objOp1 = null;
2595
- objOp2 = null;
2596
- objOp1 = myStack.Pop();
2597
- if (objOp1.isVariable)
2598
- objOp1 = _getVariable(objOp1.val, myvarArr);
2599
-
2600
- dblNo = Tokenizer.toNumber(objOp1.val);
2601
- if (isNaN(dblNo))
2602
- throw "Not a numeric value!";
2603
- else
2604
- {
2605
- dblNo = (0 - dblNo);
2606
- myStack.Push(Tokenizer.makeToken(dblNo,Tokenizer.TOKEN_TYPE.NUMBER));
2607
- }
2608
- break;
2609
- case Tokenizer.TOKEN_TYPE.UNARY_NEGATION :
2610
- if (myStack.IsEmpty())
2611
- throw "No operand on stack!";
2612
-
2613
- objOp1 = null;
2614
- objOp2 = null;
2615
- objOp1 = myStack.Pop();
2616
- if (objOp1.isVariable)
2617
- objOp1 = _getVariable(objOp1.val, myvarArr);
2618
-
2619
- objOp1 = Tokenizer.toBoolean(objOp1.val);
2620
- if (objOp1 == null)
2621
- throw strTok.val + " applied not on a boolean value!";
2622
- else
2623
- myStack.Push(Tokenizer.makeToken(!(objOp1),Tokenizer.TOKEN_TYPE.BOOLEAN));
2624
- break;
2625
- case Tokenizer.TOKEN_TYPE.ARITHMETIC_OP :
2626
- switch(strTok.val)
2627
- {
2628
- case "*" :
2629
- case "/" :
2630
- case "%" :
2631
- case "^" :
2632
- if (myStack.IsEmpty() || myStack.Size() < 2)
2633
- throw "Stack is empty, can not perform [" + strTok.val + "]";
2634
- objOp1 = null;
2635
- objOp2 = null;
2636
- objTmp = null;
2637
- objOp2 = myStack.Pop();
2638
- objOp1 = myStack.Pop();
2639
- if (objOp1.isVariable)
2640
- objOp1 = _getVariable(objOp1.val, myvarArr);
2641
- if (objOp2.isVariable)
2642
- objOp2 = _getVariable(objOp2.val, myvarArr);
2643
-
2644
- if (!objOp1.iNumber || !objOp2.isNumber)
2645
- throw "Either one of the operand is not a number can not perform [" + strTok.val + "]";
2646
-
2647
- dblVal1 = Tokenizer.toNumber(objOp1.val);
2648
- dblVal2 = Tokenizer.toNumber(objOp2.val);
2649
- if (isNaN(dblVal1) || isNaN(dblVal2))
2650
- throw "Either one of the operand is not a number can not perform [" + strTok.val + "]";
2651
-
2652
- if (strTok.val == "^")
2653
- myStack.Push(Tokenizer.makeToken(Math.pow(dblVal1, dblVal2),Tokenizer.TOKEN_TYPE.NUMBER));
2654
- else if (strTok.val == "*")
2655
- myStack.Push(Tokenizer.makeToken((dblVal1 * dblVal2),Tokenizer.TOKEN_TYPE.NUMBER));
2656
- else if (strTok.val == "/")
2657
- myStack.Push(Tokenizer.makeToken((dblVal1 / dblVal2),Tokenizer.TOKEN_TYPE.NUMBER));
2658
- else
2659
- myStack.Push(Tokenizer.makeToken((dblVal1 % dblVal2),Tokenizer.TOKEN_TYPE.NUMBER));
2660
- break;
2661
- case "+" :
2662
- case "-" :
2663
- if (myStack.IsEmpty() || myStack.Size() < 2)
2664
- throw "Stack is empty, can not perform [" + strTok.val + "]";
2665
-
2666
- objOp1 = null;
2667
- objOp2 = null;
2668
- objTmp1 = null;
2669
- objTmp2 = null;
2670
- strOp = ((strTok.val == "+") ? "Addition" : "Substraction");
2671
- objOp2 = myStack.Pop();
2672
- objOp1 = myStack.Pop();
2673
- if (objOp1.isVariable)
2674
- objOp1 = _getVariable(objOp1.val, myvarArr);
2675
- if (objOp2.isVariable)
2676
- objOp2 = _getVariable(objOp2.val, myvarArr);
2677
-
2678
- if (objOp1.isNumber && objOp2.isNumber)
2679
- {
2680
- // Number addition
2681
- dblVal1 = Tokenizer.toNumber(objOp1.val);
2682
- dblVal2 = Tokenizer.toNumber(objOp2.val);
2683
- if (strTok.val == "+")
2684
- myStack.Push(Tokenizer.makeToken((dblVal1 + dblVal2),Tokenizer.TOKEN_TYPE.NUMBER));
2685
- else
2686
- myStack.Push(Tokenizer.makeToken((dblVal1 - dblVal2),Tokenizer.TOKEN_TYPE.NUMBER));
2687
- }
2688
- else if (objOp1.isStringLiteral && objOp2.isStringLiteral)
2689
- {
2690
- if (strTok.val == "+")
2691
- myStack.Push(Tokenizer.makeToken((objOp1.val + objOp2.val),Tokenizer.TOKEN_TYPE.STRING_LITERAL));
2692
- else
2693
- throw strOp + " not supported for strings!"
2694
- }
2695
- else
2696
- throw strOp + " not supported for other types than numbers and strings!"
2697
- break;
2698
- }
2699
- break;
2700
- case Tokenizer.TOKEN_TYPE.COMPARISON_OP :
2701
- switch(strTok.val)
2702
- {
2703
- case "=" :
2704
- case "<" :
2705
- case ">" :
2706
- case "<>" :
2707
- case "<=" :
2708
- case ">=" :
2709
- case "eq" :
2710
- case "lt" :
2711
- case "gt" :
2712
- case "ne" :
2713
- case "lte" :
2714
- case "gte" :
2715
- if (myStack.IsEmpty() || myStack.Size() < 2)
2716
- throw "Stack is empty, can not perform [" + strTok.val + "]";
2717
- objOp1 = null;
2718
- objOp2 = null;
2719
- objTmp1 = null;
2720
- objTmp2 = null;
2721
- objOp2 = myStack.Pop();
2722
- objOp1 = myStack.Pop();
2723
-
2724
- if (objOp1.isVariable)
2725
- objOp1 = _getVariable(objOp1.val, myvarArr);
2726
- if (objOp2.isVariable)
2727
- objOp2 = _getVariable(objOp2.val, myvarArr);
2728
-
2729
- if (objOp1.isStringLiteral && objOp2.isNumber)
2730
- {
2731
- dblVal1 = objOp1.val.toString();
2732
- dblVal2 = objOp2.val.toString();
2733
- }
2734
- else if (objOp1.isNumber && objOp2.isStringLiteral)
2735
- {
2736
- dblVal1 = objOp1.val.toString();
2737
- dblVal2 = objOp2.val.toString();
2738
- }
2739
- else if (objOp1.isNumber && objOp2.isNumber)
2740
- {
2741
- dblVal1 = Tokenizer.toNumber(objOp1.val);
2742
- dblVal2 = Tokenizer.toNumber(objOp2.val);
2743
- }
2744
- else if (objOp1.isNumber && objOp2.isBoolean)
2745
- {
2746
- dblVal1 = Tokenizer.toNumber(objOp1.val);
2747
- dblVal2 = Tokenizer.toNumber(objOp2.val);
2748
- }
2749
- else if (objOp2.isNumber && objOp1.isBoolean)
2750
- {
2751
- dblVal1 = Tokenizer.toNumber(objOp1.val);
2752
- dblVal2 = Tokenizer.toNumber(objOp2.val);
2753
- }
2754
- else if (objOp1.isDate && objOp2.isDate)
2755
- {
2756
- dblVal1 = objOp1.val.getTime();
2757
- dblVal2 = objOp2.val.getTime();
2758
- }
2759
- else if (objOp1.isStringLiteral && objOp2.isStringLiteral)
2760
- {
2761
- dblVal1=objOp1.val.toString();
2762
- dblVal2=objOp2.val.toString();
2763
- /*
2764
- if (!isNaN(dblVal1))
2765
- {
2766
- dblVal1=parseFloat(dblVal1);
2767
- }
2768
- if (!isNaN(dblVal2))
2769
- {
2770
- dblVal2=parseFloat(dblVal2);
2771
- }
2772
- dblVal1=parseFloat(objOp1.val.toString());
2773
- dblVal2=parseFloat(objOp2.val.toString());
2774
- */
2775
- }
2776
- else if (objOp1.isBoolean && objOp2.isBoolean)
2777
- {
2778
- if (strTok.val == "=" || strTok.val == "<>" || strTok.val == "eq" || strTok.val == "ne")
2779
- {
2780
- dblVal1 = Tokenizer.toBoolean(objOp1.val);
2781
- dblVal2 = Tokenizer.toBoolean(objOp2.val);
2782
- }
2783
- else
2784
- throw strTok.val + " not supported for boolean values!";
2785
- }
2786
- else if (
2787
- (strTok.val=='=' || strTok.val=='<>' || strTok.val=='eq' || strTok.val=='ne') &&
2788
- (objOp1.isStringLiteral && objOp2.isRegex)
2789
- )
2790
- {
2791
- if (strTok.val=='=' || strTok.val=='eq')
2792
- myStack.Push(Tokenizer.makeToken((objOp2.val.test(objOp1.val.toString())),Tokenizer.TOKEN_TYPE.BOOLEAN));
2793
- else
2794
- myStack.Push(Tokenizer.makeToken(!(objOp2.val.test(objOp1.val.toString())),Tokenizer.TOKEN_TYPE.BOOLEAN));
2795
- break;
2796
- }
2797
- else if (
2798
- (strTok.val=='=' || strTok.val=='<>' || strTok.val=='eq' || strTok.val=='ne') &&
2799
- (objOp2.isStringLiteral && objOp1.isRegex)
2800
- )
2801
- {
2802
- if (strTok.val=='=' || strTok.val=='eq')
2803
- myStack.Push(Tokenizer.makeToken((objOp1.val.test(objOp2.val.toString())),Tokenizer.TOKEN_TYPE.BOOLEAN));
2804
- else
2805
- myStack.Push(Tokenizer.makeToken(!(objOp1.val.test(objOp2.val.toString())),Tokenizer.TOKEN_TYPE.BOOLEAN));
2806
- break;
2807
- }
2808
- else if (
2809
- (strTok.val=='=' || strTok.val=='<>' || strTok.val=='eq' || strTok.val=='ne') &&
2810
- (objOp1.isArray && (objOp2.isStringLiteral || objOp2.isNumber))
2811
- )
2812
- {
2813
- if (strTok.val=='=' || strTok.val=='eq')
2814
- myStack.Push(Tokenizer.makeToken(Functions.Contains(objOp1.val,objOp2.val),Tokenizer.TOKEN_TYPE.BOOLEAN));
2815
- else
2816
- myStack.Push(Tokenizer.makeToken(!Functions.Contains(objOp1.val,objOp2.val),Tokenizer.TOKEN_TYPE.BOOLEAN));
2817
- break;
2818
- }
2819
- else if (
2820
- (strTok.val=='=' || strTok.val=='<>' || strTok.val=='eq' || strTok.val=='ne') &&
2821
- (objOp2.isArray && (objOp1.isStringLiteral || objOp1.isNumber))
2822
- )
2823
- {
2824
- if (strTok.val=='=' || strTok.val=='eq')
2825
- myStack.Push(Tokenizer.makeToken(Functions.Contains(objOp2.val,objOp1.val),Tokenizer.TOKEN_TYPE.BOOLEAN));
2826
- else
2827
- myStack.Push(Tokenizer.makeToken(!Functions.Contains(objOp2.val,objOp1.val),Tokenizer.TOKEN_TYPE.BOOLEAN));
2828
- break;
2829
- }
2830
- else
2831
- throw "For " + strTok.val + " operator LHS & RHS should be of same data type!";
2832
-
2833
- if (strTok.val=='=' || strTok.val=='eq')// TODO check here, might need to use === instead of ==
2834
- myStack.Push(Tokenizer.makeToken((dblVal1 == dblVal2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2835
- else if (strTok.val == "<>" || strTok.val == "ne")// TODO check here, might need to use !== instead of !=
2836
- myStack.Push(Tokenizer.makeToken((dblVal1 != dblVal2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2837
- else if (strTok.val == ">" || strTok.val == "gt")
2838
- myStack.Push(Tokenizer.makeToken((dblVal1 > dblVal2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2839
- else if (strTok.val == "<" || strTok.val == "lt")
2840
- myStack.Push(Tokenizer.makeToken((dblVal1 < dblVal2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2841
- else if (strTok.val == "<=" || strTok.val == "lte")
2842
- myStack.Push(Tokenizer.makeToken((dblVal1 <= dblVal2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2843
- else if (strTok.val == ">=" || strTok.val == "gte")
2844
- myStack.Push(Tokenizer.makeToken((dblVal1 >= dblVal2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2845
- break;
2846
- }
2847
- break;
2848
- case Tokenizer.TOKEN_TYPE.LOGICAL_OP :
2849
- switch(strTok.val)
2850
- {
2851
- case 'NOT' :
2852
- case '!' :
2853
- if (myStack.IsEmpty())
2854
- throw "No operand on stack!";
2855
-
2856
- objOp1 = null;
2857
- objOp2 = null;
2858
- objOp1 = myStack.Pop();
2859
- if (objOp1.isVariable)
2860
- objOp1 = _getVariable(objOp1.val, myvarArr);
2861
-
2862
- objOp1 = Tokenizer.toBoolean(objOp1.val);
2863
- if (objOp1 == null)
2864
- throw strTok.val + " applied not on a boolean value!";
2865
- else
2866
- myStack.Push(Tokenizer.makeToken(!(objOp1),Tokenizer.TOKEN_TYPE.BOOLEAN));
2867
- break;
2868
- case "AND" :
2869
- case "&" :
2870
- case "OR" :
2871
- case "|" :
2872
- if (myStack.IsEmpty() || myStack.Size() < 2)
2873
- throw "Stack is empty, can not perform [" + strTok.val + "]";
2874
- objOp1 = null;
2875
- objOp2 = null;
2876
- objTmp1 = null;
2877
- objTmp2 = null;
2878
- objOp2 = myStack.Pop();
2879
- objOp1 = myStack.Pop();
2880
- if (objOp1.isVariable)
2881
- objOp1 = _getVariable(objOp1.val, myvarArr);
2882
- if (objOp2.isVariable)
2883
- objOp2 = _getVariable(objOp2.val, myvarArr);
2884
-
2885
- if (
2886
- (objOp1.isBoolean && objOp2.isBoolean) ||
2887
- (objOp1.isNumber && objOp2.isNumber) ||
2888
- (objOp1.isNumber && objOp2.isBoolean) ||
2889
- (objOp1.isBoolean && objOp2.isNumber)
2890
- )
2891
- {
2892
- objTmp1 = Tokenizer.toBoolean(objOp1.val);
2893
- objTmp2 = Tokenizer.toBoolean(objOp2.val);
2894
- if (strTok.val == "AND" || strTok.val == "&")
2895
- myStack.Push(Tokenizer.makeToken((objTmp1 && objTmp2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2896
- else if (strTok.val == "OR" || strTok.val == "|")
2897
- myStack.Push(Tokenizer.makeToken((objTmp1 || objTmp2),Tokenizer.TOKEN_TYPE.BOOLEAN));
2898
- }
2899
- else
2900
- throw "Logical operator requires LHS & RHS of boolean type!";
2901
- break;
2902
- }
2903
- break;
2904
- case Tokenizer.TOKEN_TYPE.FUNCTION :
2905
- _HandleFunctions(strTok, myStack, dtFormat, myvarArr);
2906
- break;
2907
- default :
2908
- myStack.Push(strTok);
2909
- break;
2910
- }
2911
- intIndex++;
2912
- }
2913
- if (myStack.IsEmpty() || myStack.Size() > 1 || myStack.Get(0).isVariable)
2914
- throw "Unable to evaluate expression!";
2915
- else
2916
- return myStack.Pop().val;
2917
- }
2918
- }
2919
- };})(Tokenizer,DateParser);
2920
- })(window);
2921
-
2922
-
2923
- })(window);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/expression-parser/parser.php DELETED
@@ -1,2892 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * Toolset Parser, advanced parser for arithmetic,logical and comparision expressions
5
- * by Nikos M. <nikos.m@icanlocalize.com>
6
- *
7
- * Main Features:
8
- * + user variables
9
- * + support mathematical, and date functions
10
- * + limited date parsing
11
- *
12
- * Additional Features:
13
- * + typed tokens
14
- * + typed user variables
15
- * + added string literals
16
- * + support advanced mathematical, string and date functions
17
- * + support advanced date operations (like (date + 3 days) or (3 days=date1-date2)) (not yet)
18
- * + support typecasting
19
- * + can parse and format every localized PHP date format
20
- * + precompilation of expressions into functions
21
- * + faster, optimized code
22
- * + use of closures for encapsulation and better access
23
- * + heavy refactoring, and various bug fixes
24
- *
25
- * adapted to PHP form Toolset_Parser js version
26
- * inspired by JS Expression Evaluator by Prasad P. Khandekar
27
- *
28
- **/
29
-
30
- class Toolset_Regex
31
- {
32
- private $_regex='';
33
-
34
- public function Toolset_Regex($rx,$opts='')
35
- {
36
- // remove flags not supported by PHP
37
- $this->_regex='/'.$rx.'/'.str_replace('g','',$opts); // PHP does not support 'g' modifier
38
- }
39
-
40
- public function test($str)
41
- {
42
- return (preg_match($this->_regex,$str)==1);
43
- }
44
- }
45
-
46
- class Toolset_Functions
47
- {
48
- private static $_cookies=null;
49
- private static $_regexs=array();
50
- private static $_params=array(
51
- 'user'=>array(
52
- 'ID'=>0,
53
- 'role'=>'',
54
- 'roles'=>array(),
55
- 'login'=>'',
56
- 'display_name'=>''
57
- )
58
- );
59
-
60
- public static function setParams($params)
61
- {
62
- self::$_params=array_merge(self::$_params,$params);
63
- }
64
-
65
- public static function Cookie($name)
66
- {
67
- if (!isset($_cookies)) $_cookies=&$_COOKIE;
68
-
69
- return (isset($_cookies[$name]))?$_cookies[$name]:'';
70
- }
71
-
72
- public static function User($att='')
73
- {
74
- $att=strtoupper($att);
75
-
76
- switch ($att)
77
- {
78
- case 'ID':
79
- return (string)(self::$_params['user']['ID'].'');
80
- case 'NAME':
81
- return self::$_params['user']['display_name'];
82
- case 'ROLE':
83
- return self::$_params['user']['role'];
84
- case 'LOGIN':
85
- return self::$_params['user']['login'];
86
- default:
87
- return '';
88
- }
89
- return '';
90
- }
91
-
92
- public static function Regex($rx, $opts='') {return new Toolset_Regex($rx, $opts);}
93
-
94
- public static function Contains(&$a, $v) {return in_array($v,$a);}
95
- }
96
-
97
- class Toolset_Date
98
- {
99
- private $_timestamp;
100
-
101
- /* getdate params
102
- "seconds" Numeric representation of seconds 0 to 59
103
- "minutes" Numeric representation of minutes 0 to 59
104
- "hours" Numeric representation of hours 0 to 23
105
- "mday" Numeric representation of the day of the month 1 to 31
106
- "wday" Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
107
- "mon" Numeric representation of a month 1 through 12
108
- "year" A full numeric representation of a year, 4 digits Examples: 1999 or 2003
109
- "yday" Numeric representation of the day of the year 0 through 365
110
- "weekday" A full textual representation of the day of the week Sunday through Saturday
111
- "month" A full textual representation of a month, such as January or March
112
- */
113
- private $_date=array(
114
- 'hour'=>0,
115
- 'min'=>0,
116
- 'sec'=>0,
117
- 'day_of_month'=>0,
118
- 'day_of_week'=>0,
119
- 'day_of_year'=>0,
120
- 'day_of_week_string'=>'',
121
- 'month_string'=>'',
122
- 'month'=>0,
123
- 'year'=>0
124
- );
125
-
126
- private static $_today=false;
127
-
128
- public static function setToday($date)
129
- {
130
- self::$_today=$date;
131
- }
132
-
133
- public static function getToday()
134
- {
135
- if (self::$_today)
136
- return new Toolset_Date(self::$_today);
137
-
138
- $today=new Toolset_Date();
139
- return $today->setDateByTimestamp();
140
- }
141
-
142
- public function Toolset_Date($date=null)
143
- {
144
- if (isset($date))
145
- $this->setDate($date);
146
- }
147
-
148
-
149
- public function getDate($key=null)
150
- {
151
- if (!isset($key) || !in_array($key, array_keys($this->_date)))
152
- return $this->_date;
153
- else
154
- return $this->_date[$key];
155
- }
156
-
157
- public function setDate($date)
158
- {
159
- $hasYear=false;
160
- $hasMonth=false;
161
- $hasDay=false;
162
-
163
- foreach ($date as $k=>$v)
164
- {
165
- if ($k=='year') $hasYear=true;
166
- if ($k=='month') $hasMonth=true;
167
- if ($k=='day_of_year') $hasDay=true;
168
-
169
- if (isset($this->_date[$k]))
170
- $this->_date[$k]=$v;
171
- }
172
-
173
- // fill all values
174
- if ($hasYear && $hasMonth && $hasDay)
175
- $this->setDateByTimestamp($this->getTimestamp());
176
-
177
- return $this;
178
- }
179
-
180
- public function getTimestamp()
181
- {
182
- if (class_exists("DateTime")) {
183
- $date = new DateTime("{$this->_date['year']}-{$this->_date['month']}-{$this->_date['day_of_month']} {$this->_date['hour']}:{$this->_date['min']}:{$this->_date['sec']}");
184
- return (method_exists('DateTime', 'getTimestamp')) ? $date->getTimestamp() : $date->format('U');
185
- } else
186
- return mktime ($this->_date['hour'], $this->_date['min'], $this->_date['sec'], $this->_date['month'], $this->_date['day_of_month'], $this->_date['year'] /*[, int $is_dst = -1 ]*/);
187
- }
188
-
189
- public function getNormalizedTimestamp()
190
- {
191
- if (class_exists("DateTime")) {
192
- $date = new DateTime("{$this->_date['year']}-{$this->_date['month']}-{$this->_date['day_of_month']}");
193
- return (method_exists('DateTime', 'getTimestamp')) ? $date->getTimestamp() : $date->format('U');
194
- } else
195
- return mktime (0, 0, 0, $this->_date['day_of_month'], $this->_date['month'], $this->_date['year'] /*[, int $is_dst = -1 ]*/);
196
- }
197
-
198
- public function setDateByTimestamp($time=null)
199
- {
200
- if (!isset($time)) $time=time();
201
-
202
- $dat=getdate($time);
203
- $date=array(
204
- 'hour'=>0,
205
- 'min'=>0,
206
- 'sec'=>0,
207
- 'month'=>$dat['mon'],
208
- 'month_string'=>$dat['month'],
209
- 'day_of_month'=>$dat['mday'],
210
- 'day_of_week'=>$dat['wday'],
211
- 'day_of_week_string'=>$dat['weekday'],
212
- 'day_of_year'=>$dat['yday'],
213
- 'year'=>$dat['year']
214
- );
215
-
216
- $this->_date=$date;
217
-
218
- return $this;
219
- }
220
-
221
- public function format($format)
222
- {
223
- //return date($format, $this->getTimestamp());
224
-
225
- // handle localized format
226
- return Toolset_DateParser::formatDate($this, $format);
227
- }
228
- }
229
-
230
- class Toolset_DateParser
231
- {
232
- private static $_ZONE_NAMES = array('AM' => 'AM','PM' => 'PM');
233
- private static $_MONTH_NAMES = array('January','February','March','April','May','June','July','August','September','October','November','December');
234
- private static $_DAY_NAMES = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
235
- private static $_ENGLISH_MONTH_NAMES = array('January','February','March','April','May','June','July','August','September','October','November','December');
236
- private static $_ENGLISH_DAY_NAMES = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
237
-
238
- private static function _to_int($str)
239
- {
240
- // return the integer representation of the string given as argument
241
- return intval($str);
242
- }
243
-
244
- private static function _escape_regexp($str)
245
- {
246
- // return string with special characters escaped
247
- //return preg_replace('#([\-\.\*\+\?\^\$\{\}\(\)\|\[\]\/\\])#', '\\$1', $str);
248
- return preg_quote($str, "/");
249
- }
250
-
251
- private static function _str_pad($n, $c)
252
- {
253
- if (strlen($n = $n . '') < $c)
254
- {
255
- return implode('0',array_fill((++$c) - strlen($n))). $n;
256
- }
257
- return $n;
258
- }
259
-
260
- private static function _is_string($s)
261
- {
262
- return is_string($s)?true:false;
263
- }
264
-
265
- public static function cmp($a, $b){ return $a['position'] - $b['position']; }
266
-
267
- public static function parseDate($date, $supposed_format)
268
- {
269
- // if already a date object
270
- if ($date instanceof Toolset_Date)
271
- {
272
- $date->setDate(array('hour'=>0,'min'=>0,'sec'=>0)); // normalize time part
273
- return $date;
274
- }
275
-
276
- if (
277
- !isset($date) ||
278
- !self::_is_string($date) ||
279
- !isset($supposed_format) ||
280
- !self::_is_string($supposed_format)
281
- )
282
- return false;
283
-
284
- // treat argument as a string
285
- $str_date = (string)$date . '';
286
- $supposed_format = (string)$supposed_format.'';
287
-
288
- // if value is given
289
- if ($str_date != '' && $supposed_format != '')
290
- {
291
- //echo '<br/>Date given<br />';
292
- // prepare the format by removing white space from it
293
- // and also escape characters that could have special meaning in a regular expression
294
- $format = self::_escape_regexp(preg_replace('/\s/','',$supposed_format));
295
-
296
- // allowed characters in date's format
297
- $format_chars = array('d','D','j','l','N','S','w','F','m','M','n','Y','y');
298
-
299
- // "matches" will contain the characters defining the date's format
300
- $matches = array();
301
-
302
- // "regexp" will contain the regular expression built for each of the characters used in the date's format
303
- $regexp = array();
304
-
305
- // iterate through the allowed characters in date's format
306
- for ($i = 0; $i < count($format_chars); $i++)
307
- {
308
- // if character is found in the date's format
309
- if (($position = strpos($format,$format_chars[$i])) > -1)
310
-
311
- // save it, alongside the character's position
312
- $matches[]=array('character'=> $format_chars[$i], 'position'=> $position);
313
- }
314
-
315
- // sort characters defining the date's format based on their position, ascending
316
- usort($matches,array('Toolset_DateParser','cmp'));
317
-
318
- // iterate through the characters defining the date's format
319
- for ($index=0; $index<count($matches); $index++)
320
- {
321
- $match=$matches[$index];
322
-
323
- // add to the array of regular expressions, based on the character
324
- switch ($match['character'])
325
- {
326
-
327
- case 'd': $regexp[]='0[1-9]|[12][0-9]|3[01]'; break;
328
- case 'D': $regexp[]='[a-z]{3}'; break;
329
- case 'j': $regexp[]='[1-9]|[12][0-9]|3[01]'; break;
330
- case 'l': $regexp[]='[a-z]+'; break;
331
- case 'N': $regexp[]='[1-7]'; break;
332
- case 'S': $regexp[]='st|nd|rd|th'; break;
333
- case 'w': $regexp[]='[0-6]'; break;
334
- case 'F': $regexp[]='[a-z]+'; break;
335
- case 'm': $regexp[]='0[1-9]|1[012]+'; break;
336
- case 'M': $regexp[]='[a-z]{3}'; break;
337
- case 'n': $regexp[]='[1-9]|1[012]'; break;
338
- case 'Y': $regexp[]='[0-9]{4}'; break;
339
- case 'y': $regexp[]='[0-9]{2}'; break;
340
-
341
- }
342
- }
343
-
344
- // if we have an array of regular expressions
345
- if (!empty($regexp))
346
- {
347
-
348
- // we will replace characters in the date's format in reversed order
349
- $matches=array_reverse($matches);
350
-
351
- // iterate through the characters in date's format
352
- for ($index=0; $index<count($matches); $index++)
353
- {
354
- $match=$matches[$index];
355
-
356
- // replace each character with the appropriate regular expression
357
- $format = str_replace($match['character'],'(' . $regexp[count($regexp) - $index - 1] . ')', $format);
358
- }
359
-
360
- // the final regular expression
361
- //$regexp = '/^' . $format . '$/ig';
362
- $regexp = '/^' . $format . '$/i';
363
-
364
- //echo '<br /><textarea>'.$regexp.'</textarea><br />';
365
-
366
- //preg_match_all('/^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012]+)\/([0-9]{2})$/i','13/10/12',$foo);
367
- //print_r($foo);
368
-
369
- // if regular expression was matched
370
- if (preg_match_all($regexp, preg_replace('/\s/', '', $str_date),$segments))
371
- {
372
- //echo '<br/>Regex matched<br />';
373
- //print_r($segments);
374
-
375
- // check if date is a valid date (i.e. there's no February 31)
376
- $english_days = self::$_ENGLISH_DAY_NAMES;
377
- $english_months = self::$_ENGLISH_MONTH_NAMES;
378
-
379
- // by default, we assume the date is valid
380
- $valid = true;
381
-
382
- // reverse back the characters in the date's format
383
- $matches=array_reverse($matches);
384
-
385
- // iterate through the characters in the date's format
386
- for ($index=0; $index<count($matches); $index++)
387
- {
388
- $match=$matches[$index];
389
-
390
- // if the date is not valid, don't look further
391
- if (!$valid) break; //return true;
392
-
393
- // based on the character
394
- switch ($match['character'])
395
- {
396
-
397
- case 'm':
398
- case 'n':
399
-
400
- // extract the month from the value entered by the user
401
- $original_month = self::_to_int($segments[$index+1][0]);
402
-
403
- break;
404
-
405
- case 'd':
406
- case 'j':
407
-
408
- // extract the day from the value entered by the user
409
- $original_day = self::_to_int($segments[$index+1][0]);
410
-
411
- break;
412
-
413
- case 'D':
414
- case 'l':
415
- case 'F':
416
- case 'M':
417
-
418
- // if day is given as day name, we'll check against the names in the used language
419
- if ($match['character'] == 'D' || $match['character'] == 'l') $iterable = self::$_DAY_NAMES;
420
-
421
- // if month is given as month name, we'll check against the names in the used language
422
- else $iterable = self::$_MONTH_NAMES;
423
-
424
- // by default, we assume the day or month was not entered correctly
425
- $valid = false;
426
-
427
- // iterate through the month/days in the used language
428
- for ($key=0; $key<count($iterable); $key++)
429
- {
430
- // if month/day was entered correctly, don't look further
431
- if ($valid) break; //return true;
432
-
433
- $value=$iterable[$key];
434
-
435
- // if month/day was entered correctly
436
- if (strtolower($segments[$index+1][0]) == strtolower(substr($value, 0, ($match['character'] == 'D' || $match['character'] == 'M' ? 3 : strlen($value)))))
437
- {
438
-
439
- // extract the day/month from the value entered by the user
440
- switch ($match['character'])
441
- {
442
-
443
- case 'D': $segments[$index+1][0] = substr($english_days[$key],0, 3); break;
444
- case 'l': $segments[$index+1][0] = $english_days[$key]; break;
445
- case 'F': $segments[$index+1][0] = $english_months[$key]; $original_month = $key + 1; break;
446
- case 'M': $segments[$index+1][0] = substr($english_months[$key],0, 3); $original_month = $key + 1; break;
447
-
448
- }
449
-
450
- // day/month value is valid
451
- $valid = true;
452
-
453
- }
454
-
455
- }
456
-
457
- break;
458
-
459
- case 'Y':
460
-
461
- // extract the year from the value entered by the user
462
- $original_year = self::_to_int($segments[$index+1][0]);
463
-
464
- break;
465
-
466
- case 'y':
467
-
468
- // extract the year from the value entered by the user
469
- $original_year = '19' + self::_to_int($segments[$index+1][0]);
470
-
471
- break;
472
-
473
- }
474
- }
475
-
476
- // if everything is ok so far
477
- if ($valid)
478
- {
479
- //echo '<br/>Date valid 1<br />';
480
-
481
- // generate a Date object using the values entered by the user
482
- // (handle also the case when original_month and/or original_day are undefined - i.e date format is "Y-m" or "Y")
483
- /* print_r(array(
484
- 'year'=>$original_year,
485
- 'month'=>$original_month,
486
- 'day'=>$original_day,
487
- ));*/
488
-
489
- // if, after that, the date is the same as the date entered by the user
490
- //if (date.getFullYear() == original_year && date.getDate() == (original_day || 1) && date.getMonth() == ((original_month || 1) - 1))
491
- //var_dump(checkdate(10, 12, 2012));
492
- if (checkdate ((int)$original_month, (int)$original_day, (int)$original_year))
493
- {
494
- // normalize time part, only date part checked
495
- $date = new Toolset_Date(array(
496
- 'year'=>$original_year,
497
- 'month'=>$original_month,
498
- 'day_of_month'=>$original_day,
499
- ));
500
- $date->setDate(array('hour'=>0,'min'=>0,'sec'=>0));
501
- // return the date as our date object
502
- //echo '<br/>Date valid 2<br />';
503
- return $date;
504
- }
505
- }
506
- }
507
- }
508
- }
509
- // if script gets this far, return false as something must've went wrong
510
- return false;
511
- }
512
-
513
- public static function formatDate($date, $format, $isTimestamp=false)
514
- {
515
-
516
- // if not a date object
517
- /*if (!isset($date) || !($date instanceof Toolset_Date))
518
- {
519
- return '';
520
- }
521
- $date->setDate(array('hour'=>0,'min'=>0,'sec'=>0)); // normalize time
522
- return $date->format($format);*/
523
-
524
- if ($isTimestamp)
525
- {
526
- $dat=new Toolset_Date();
527
- $date=$dat->setDateByTimestamp($date);
528
- }
529
-
530
- // if not a date object
531
- if (!isset($date) || !($date instanceof Toolset_Date))
532
- {
533
- return '';
534
- }
535
-
536
- $date->setDate(array('hour'=>0,'min'=>0,'sec'=>0)); // normalize time part
537
-
538
- $result = '';
539
-
540
- // extract parts of the date:
541
- // day number, 1 - 31
542
- $j = $date->getDate('day_of_month');
543
-
544
- // day of the week, 0 - 6, Sunday - Saturday
545
- $w = $date->getDate('day_of_week');
546
-
547
- // the name of the day of the week Sunday - Saturday
548
- $l = self::$_DAY_NAMES[$w];
549
-
550
- // the month number, 1 - 12
551
- $n = $date->getDate('month');// + 1;
552
-
553
- // the month name, January - December
554
- $f = self::$_MONTH_NAMES[$n - 1];
555
-
556
- // the year (as a string)
557
- $y = (string)$date->getDate('year') . '';
558
-
559
- // iterate through the characters in the format
560
- for ($i = 0; $i < strlen($format); $i++)
561
- {
562
-
563
- // extract the current character
564
- $chr = $format[$i];
565
-
566
- // see what character it is
567
- switch($chr)
568
- {
569
- // year as two digits
570
- case 'y': $y = substr($y,2);
571
-
572
- // year as four digits
573
- case 'Y': $result .= $y; break;
574
-
575
- // month number, prefixed with 0
576
- case 'm': $n = self::_str_pad($n, 2);
577
-
578
- // month number, not prefixed with 0
579
- case 'n': $result .= $n; break;
580
-
581
- // month name, three letters
582
- case 'M': $f = substr($f,0,3);
583
-
584
- // full month name
585
- case 'F': $result .= $f; break;
586
-
587
- // day number, prefixed with 0
588
- case 'd': $j = self::_str_pad($j, 2);
589
-
590
- // day number not prefixed with 0
591
- case 'j': $result .= $j; break;
592
-
593
- // day name, three letters
594
- case 'D': $l = substr($l, 0, 3);
595
-
596
- // full day name
597
- case 'l': $result .= $l; break;
598
-
599
- // ISO-8601 numeric representation of the day of the week, 1 - 7
600
- case 'N': $w++;
601
-
602
- // day of the week, 0 - 6
603
- case 'w': $result .= $w; break;
604
-
605
- // English ordinal suffix for the day of the month, 2 characters
606
- // (st, nd, rd or th (works well with j))
607
- case 'S':
608
-
609
- if ($j % 10 == 1 && $j != '11') $result .= 'st';
610
-
611
- else if ($j % 10 == 2 && $j != '12') $result .= 'nd';
612
-
613
- else if ($j % 10 == 3 && $j != '13') $result .= 'rd';
614
-
615
- else $result .= 'th';
616
-
617
- break;
618
-
619
- // this is probably the separator
620
- default: $result .= $chr;
621
-
622
- }
623
-
624
- }
625
- // return formated date
626
- return $result;
627
- }
628
-
629
- public static function setDateLocaleStrings($dn=null, $mn=null, $zn=null)
630
- {
631
- if (isset($mn))
632
- {
633
- self::$_MONTH_NAMES = $mn;
634
- }
635
- if (isset($dn))
636
- {
637
- self::$_DAY_NAMES = $dn;
638
- }
639
- if (isset($zn))
640
- self::$_ZONE_NAMES = $zn;
641
- }
642
-
643
- public static function isDate($val, $format, &$getDate=null)
644
- {
645
- $date=self::parseDate($val,$format);
646
- if ($date!==false)
647
- {
648
- //echo '<hr />Date correct<hr />';
649
- if (isset($getDate))
650
- {
651
- $getDate['date']=$date;
652
- }
653
- return true;
654
- }
655
- return false;
656
- }
657
-
658
- public static function currentDate()
659
- {
660
- return Toolset_Date::getToday();
661
- }
662
- }
663
-
664
- class Toolset_Stack
665
- {
666
- // Stack object constructor
667
- private $arrStack=array();
668
- private $intIndex=0;
669
-
670
- // Converts stack contents into a comma separated string
671
- public function toString()
672
- {
673
- $intCntr = 0;
674
- $strRet = "";
675
- if ($this->intIndex == 0) return null;
676
- for ($intCntr = 0; $intCntr < $this->intIndex; $intCntr++)
677
- {
678
- if ($strRet == '')
679
- $strRet .= print_r($this->arrStack[$intCntr]->val,true);
680
- else
681
- $strRet .= "," . print_r($this->arrStack[$intCntr]->val,true);
682
- }
683
- return $strRet;
684
- }
685
-
686
- // Returns size of stack
687
- public function Size()
688
- {
689
- return $this->intIndex;
690
- }
691
-
692
- // This method tells us if this Stack object is empty
693
- public function IsEmpty()
694
- {
695
- return ($this->intIndex == 0)?true:false;
696
- }
697
-
698
- // This method pushes a new element onto the top of the stack
699
- public function Push($newData)
700
- {
701
- $this->arrStack[$this->intIndex++] = $newData;
702
- }
703
-
704
- // This method pops the top element off of the stack
705
- public function Pop()
706
- {
707
- $retVal = null;
708
- if ($this->intIndex > 0)
709
- {
710
- $retVal = $this->arrStack[--$this->intIndex];
711
- }
712
- return $retVal;
713
- }
714
-
715
- // Gets an element at a particular offset from top of the stack
716
- function Get($intPos)
717
- {
718
- if ($intPos >= 0 && $intPos < $this->intIndex)
719
- $retVal = $this->arrStack[$this->intIndex - $intPos - 1];
720
- return $retVal;
721
- }
722
- }
723
-
724
- class Toolset_Tokenizer
725
- {
726
-
727
- // private members
728
- private static $_tok_map_prefix = '__TOKEN_MAP_PREFIX__';
729
- private static $_Alpha = '';
730
- private static $_lstAlpha = '';
731
- private static $_lstVariablePrefix = '';
732
- private static $_lstDigits = "0123456789";
733
- private static $_lstArithOps = array("^","*","/","%","+","-");
734
- private static $_lstLogicOps = array("NOT","!","OR","|","AND","&");
735
- private static $_lstCompaOps = array("<","<=",">",">=","<>","=","lt","lte","gt","gte","ne","eq");
736
- private static $_lstFuncOps = array(
737
- "AVG","ABS","ACOS","ARRAY","ASC","ASIN","ATAN",
738
- "CHR","CONTAINS","COOKIE","COS",
739
- "DATE","FIX","HEX","IIF","LCASE","LEN","LEFT","LOG",
740
- "MAX","MID","MIN","NUM","RAND","REGEX","RIGHT","ROUND",
741
- "SIN","SQRT","STR","TAN","TODAY","UCASE","USER", "EMPTY", "empty"
742
- );
743
-
744
- private static $_UNARY_NEGATIVE = "-";
745
- private static $_UNARY_NEGATION = "!";
746
- private static $_ARG_TERMINAL = "?";
747
- private static $_EMPTY_TOKEN;
748
- private static $_EMPTY_STRING;
749
- private static $_TOKEN_TYPES = array(
750
- '__DEFAULT__'=>0,
751
- 'STRING_LITERAL'=>8,
752
- 'REGEX'=> 83,
753
- 'ARRAY'=>81,
754
- 'ARRAY_LITERAL'=>82,
755
- 'DATE'=>1,
756
- 'ARITHMETIC_OP'=>2,
757
- 'LOGICAL_OP'=>3,
758
- 'COMPARISON_OP'=>4,
759
- 'NUMBER'=>5,
760
- 'BOOLEAN'=>6,
761
- 'VARIABLE'=>7,
762
- 'FUNCTION'=>9,
763
- 'COMMA'=>10,
764
- 'LEFT_PAREN'=>11,
765
- 'LEFT_BRACKET'=>111,
766
- 'RIGHT_PAREN'=>12,
767
- 'RIGHT_BRACKET'=>122,
768
- 'ARG_TERMINAL'=>13,
769
- 'UNARY_NEGATIVE'=>14,
770
- 'UNARY_NEGATION'=>15,
771
- 'EMPTY_TOKEN'=>30,
772
- 'UNKNOWN'=>40
773
- );
774
-
775
- public static $TOKEN_TYPE;
776
- public static $EMPTY_TOKEN;
777
- public static $EMPTY_STRING;
778
- public static $UNARY_NEGATIVE;
779
- public static $UNARY_NEGATION;
780
- public static $ARG_TERMINAL;
781
-
782
- private static function _isDefined($s)
783
- {
784
- return (isset($s));
785
- }
786
-
787
- private static function _isDigit($c)
788
- {
789
- if (!self::_isDefined($c))
790
- return false;
791
- return (($c!='' && strpos(self::$_lstDigits,$c) >= 0)?true:false);
792
- }
793
-
794
- private static function _isAlpha($c)
795
- {
796
- if (!self::_isDefined($c))
797
- return false;
798
- return (($c!='' && strpos(self::$_lstAlpha,$c) >= 0)?true:false);
799
- }
800
-
801
- private static function _isOperator($s)
802
- {
803
- if (!self::_isDefined($s))
804
- return false;
805
- return (in_array($s,self::$_lstArithOps)?true:false);
806
- }
807
-
808
- private static function _isLogicOperator($s)
809
- {
810
- if (!self::_isDefined($s))
811
- return false;
812
- return (in_array($s,self::$_lstLogicOps)?true:false);
813
- }
814
-
815
- private static function _isCompOperator($s)
816
- {
817
- if (!self::_isDefined($s))
818
- return false;
819
- return (in_array($s,self::$_lstCompaOps)?true:false);
820
- }
821
-
822
- private static function _isFunction($s)
823
- {
824
- if (!self::_isDefined($s))
825
- return false;
826
- return (in_array($s,self::$_lstFuncOps)?true:false);
827
- }
828
-
829
- private static function _isVariableName($s)
830
- {
831
- if (!self::_isDefined($s))
832
- return false;
833
- $c=($s=='')?'':$s{0};
834
- return (($c!='' && strpos(self::$_lstVariablePrefix,$c) >= 0)?true:false);
835
- }
836
-
837
- public static function isDateInstance($s)
838
- {
839
- if (!self::_isDefined($s))
840
- return false;
841
- if ($s instanceof Toolset_Date)
842
- return true;
843
- return false;
844
- }
845
-
846
- public static function isArrayInstance($s)
847
- {
848
- if (!self::_isDefined($s))
849
- return false;
850
- if (is_array($s))
851
- return true;
852
- return false;
853
- }
854
-
855
- public static function isRegExpInstance($s)
856
- {
857
- if (!self::_isDefined($s))
858
- return false;
859
- if ($s instanceof Toolset_Regex)
860
- return true;
861
- return false;
862
- }
863
-
864
- public static function isNumber($s)
865
- {
866
- if (!self::_isDefined($s)) return false;
867
- //if (_isDateInstance(s) || _isRegExpInstance(s) || _isArrayInstance(s)) return false;
868
- if (is_numeric($s) && !is_nan((float)$s))
869
- return true;
870
- return false;
871
- }
872
-
873
- public static function isBoolean($s)
874
- {
875
- if (!self::_isDefined($s))
876
- return false;
877
-
878
- if (is_bool($s)) return true;
879
-
880
- if (strtoupper((string)$s)=='TRUE' || strtoupper((string)$s)=='FALSE')
881
- return true;
882
-
883
- return false;
884
- }
885
-
886
- private static function _ltrim($s, $ch=' ')
887
- {
888
- return ltrim($s,$ch);
889
- }
890
-
891
- private static function _rtrim($s, $ch=' ')
892
- {
893
- return rtrim($s,$ch);
894
- }
895
-
896
- private static function _trim($s, $ch=' ')
897
- {
898
- return trim($s,$ch);
899
- }
900
-
901
- // build maps for fast lookup
902
- private static function _buildMaps()
903
- {
904
- self::$_Alpha = "abcdefghijklmnopqrstuvwxyz";
905
- self::$_lstAlpha = self::$_Alpha . strtoupper(self::$_Alpha);
906
- self::$_lstVariablePrefix = '_$' . self::$_lstAlpha;
907
- }
908
-
909
- public static function init()
910
- {
911
- static $isInited=false;
912
-
913
- if (!$isInited)
914
- {
915
- self::_buildMaps();
916
- self::$TOKEN_TYPE = self::$_TOKEN_TYPES;
917
- self::$_EMPTY_TOKEN = self::makeToken('', self::$_TOKEN_TYPES['EMPTY_TOKEN']);
918
- self::$_EMPTY_STRING = self::makeToken('', self::$_TOKEN_TYPES['STRING_LITERAL']);
919
- self::$EMPTY_TOKEN = self::$_EMPTY_TOKEN;
920
- self::$EMPTY_STRING = self::$_EMPTY_STRING;
921
- self::$UNARY_NEGATIVE = self::makeToken(self::$_UNARY_NEGATIVE, self::$_TOKEN_TYPES['UNARY_NEGATIVE']);
922
- self::$UNARY_NEGATION = self::makeToken(self::$_UNARY_NEGATION, self::$_TOKEN_TYPES['UNARY_NEGATION']);
923
- self::$ARG_TERMINAL = self::makeToken(self::$_ARG_TERMINAL, self::$_TOKEN_TYPES['ARG_TERMINAL']);
924
- $isInited=true;
925
- }
926
- }
927
-
928
- public static function makeToken($tok, $force_type=null/*, $debug=false*/)
929
- {
930
- /*if ($debug)
931
- {
932
- cred_log($force_type);
933
- }*/
934
- $token=(object)array(
935
- 'val'=>$tok,
936
- 'type'=>self::$_TOKEN_TYPES['UNKNOWN'],
937
- 'isStringLiteral'=>false,
938
- 'isArray'=>false,
939
- 'isRegex'=>false,
940
- 'isDate'=>false,
941
- 'isFunction'=>false,
942
- 'isNumber'=>false,
943
- 'isBoolean'=>false,
944
- 'isOp'=>false,
945
- 'isArithmeticOp'=>false,
946
- 'isLogicOp'=>false,
947
- 'isCompOp'=>false,
948
- 'isParen'=>false,
949
- 'isLeftParen'=>false,
950
- 'isRightParen'=>false,
951
- 'isComma'=>false,
952
- 'isVariable'=>false,
953
- 'isArgTerminal'=>false,
954
- 'isUnaryNegative'=>false,
955
- 'isUnaryNegation'=>false,
956
- 'isEmpty'=>false,
957
- );
958
-
959
- if (!isset($force_type))
960
- $force_type=self::$_TOKEN_TYPES['__DEFAULT__'];
961
-
962
- switch ($force_type)
963
- {
964
- case self::$_TOKEN_TYPES['EMPTY_TOKEN']:
965
- $token->type=self::$_TOKEN_TYPES['EMPTY_TOKEN'];
966
- $token->isEmpty=true;
967
- $token->val='';
968
- break;
969
- case self::$_TOKEN_TYPES['STRING_LITERAL']:
970
- $token->type=self::$_TOKEN_TYPES['STRING_LITERAL'];
971
- $token->isStringLiteral=true;
972
- $token->val=(string)$tok;
973
- /*if ($debug)
974
- {
975
- cred_log('---------');
976
- cred_log($token);
977
- cred_log('---------');
978
- }*/
979
- break;
980
- case self::$_TOKEN_TYPES['DATE']:
981
- if (self::isDateInstance($tok))
982
- {
983
- $token->type=self::$_TOKEN_TYPES['DATE'];
984
- $token->isDate=true;
985
- }
986
- break;
987
- case self::$_TOKEN_TYPES['ARRAY']:
988
- if (!self::isArrayInstance($tok))
989
- {
990
- $token->val=array($tok);
991
- }
992
- $token->type=self::$_TOKEN_TYPES['ARRAY'];
993
- $token->isArray=true;
994
- break;
995
- case self::$_TOKEN_TYPES['REGEX']:
996
- if (!self::isRegExpInstance($tok))
997
- {
998
- $token->val=new Toolset_Regex($tok);
999
- }
1000
- $token->type=self::$_TOKEN_TYPES['REGEX'];
1001
- $token->isRegex=true;
1002
- break;
1003
- case self::$_TOKEN_TYPES['COMMA']:
1004
- $token->type=self::$_TOKEN_TYPES['COMMA'];
1005
- $token->isComma=true;
1006
- $token->val=',';
1007
- break;
1008
- case self::$_TOKEN_TYPES['LEFT_PAREN']:
1009
- $token->type=self::$_TOKEN_TYPES['LEFT_PAREN'];
1010
- $token->isLeftParen=true;
1011
- $token->isParen=true;
1012
- $token->val='(';
1013
- break;
1014
- case self::$_TOKEN_TYPES['RIGHT_PAREN']:
1015
- $token->type=self::$_TOKEN_TYPES['RIGHT_PAREN'];
1016
- $token->isRightParen=true;
1017
- $token->isParen=true;
1018
- $token->val=')';
1019
- break;
1020
- case self::$_TOKEN_TYPES['ARG_TERMINAL']:
1021
- $token->type=self::$_TOKEN_TYPES['ARG_TERMINAL'];
1022
- $token->isArgTerminal=true;
1023
- $token->val=self::$_ARG_TERMINAL;
1024
- break;
1025
- case self::$_TOKEN_TYPES['UNARY_NEGATIVE']:
1026
- $token->type=self::$_TOKEN_TYPES['UNARY_NEGATIVE'];
1027
- $token->isUnaryNegative=true;
1028
- $token->val=self::$_UNARY_NEGATIVE;
1029
- $token->isArithmeticOp=true;
1030
- $token->isOp=true;
1031
- break;
1032
- case self::$_TOKEN_TYPES['UNARY_NEGATION']:
1033
- $token->type=self::$_TOKEN_TYPES['UNARY_NEGATION'];
1034
- $token->isUnaryNegation=true;
1035
- $token->val=self::$_UNARY_NEGATION;
1036
- $token->isLogicOp=true;
1037
- $token->isOp=true;
1038
- break;
1039
- case self::$_TOKEN_TYPES['NUMBER']:
1040
- $token->type=self::$_TOKEN_TYPES['NUMBER'];
1041
- $token->isNumber=true;
1042
- if (is_string($tok))
1043
- $token->val=(float)($tok);
1044
- elseif (is_bool($tok))
1045
- $token->val=((bool)$tok===true)?1:0;
1046
- else
1047
- $token->val=(float)$tok;
1048
- break;
1049
- case self::$_TOKEN_TYPES['BOOLEAN']:
1050
- $token->type=self::$_TOKEN_TYPES['BOOLEAN'];
1051
- $token->isBoolean=true;
1052
- if (is_bool($tok))
1053
- $token->val=(bool)$tok;
1054
- elseif (is_string($tok))
1055
- $token->val=(strtoupper($tok)=='TRUE')?true:false;
1056
- elseif (is_numeric($tok))
1057
- $token->val=((float)$tok != 0)?true:false;
1058
- else
1059
- $token->val=(bool)$tok;
1060
- break;
1061
- case self::$_TOKEN_TYPES['VARIABLE']:
1062
- $token->type=self::$_TOKEN_TYPES['VARIABLE'];
1063
- $token->isVariable=true;
1064
- break;
1065
- case self::$_TOKEN_TYPES['__DEFAULT__']:
1066
- default:
1067
- if (
1068
- (is_object($tok) && isset($tok->_isStringLiteral) && $tok->_isStringLiteral)
1069
- )
1070
- {
1071
- $token->type=self::$_TOKEN_TYPES['STRING_LITERAL'];
1072
- $token->isStringLiteral=true;
1073
- $token->val=(string)$tok->val;
1074
- }
1075
- // date token
1076
- elseif (self::isDateInstance($tok))
1077
- {
1078
- $token->type=self::$_TOKEN_TYPES['DATE'];
1079
- $token->isDate=true;
1080
- }
1081
- // array token
1082
- elseif (self::isArrayInstance($tok))
1083
- {
1084
- $token->type=self::$_TOKEN_TYPES['ARRAY'];
1085
- $token->isArray=true;
1086
- }
1087
- // regex token
1088
- elseif (self::isRegExpInstance($tok))
1089
- {
1090
- $token->type=self::$_TOKEN_TYPES['REGEX'];
1091
- $token->isRegex=true;
1092
- }
1093
- elseif ($tok==',')
1094
- {
1095
- $token->type=self::$_TOKEN_TYPES['COMMA'];
1096
- $token->isComma=true;
1097
- $token->val=',';
1098
- }
1099
- elseif ($tok=='(')
1100
- {
1101
- $token->type=self::$_TOKEN_TYPES['LEFT_PAREN'];
1102
- $token->isLeftParen=true;
1103
- $token->isParen=true;
1104
- $token->val='(';
1105
- $token->isOp=true;
1106
- }
1107
- elseif ($tok==')')
1108
- {
1109
- $token->type=self::$_TOKEN_TYPES['RIGHT_PAREN'];
1110
- $token->isRightParen=true;
1111
- $token->isParen=true;
1112
- $token->val=')';
1113
- //token.isOp=true;
1114
- }
1115
- /*else if (tok=='{')
1116
- {
1117
- token.type=_TOKEN_TYPES.LEFT_BRACKET;
1118
- token.isLeftBracket=true;
1119
- token.isBracket=true;
1120
- token.val='{';
1121
- token.isOp=true;
1122
- }
1123
- else if (tok=='}')
1124
- {
1125
- token.type=_TOKEN_TYPES.RIGHT_BRACKET;
1126
- token.isRightBracket=true;
1127
- token.isBracket=true;
1128
- token.val='}';
1129
- //token.isOp=true;
1130
- }*/
1131
- elseif (self::isNumber($tok))
1132
- {
1133
- $token->type=self::$_TOKEN_TYPES['NUMBER'];
1134
- $token->isNumber=true;
1135
- if (is_string($tok))
1136
- $token->val=(float)($tok);
1137
- else if (is_bool($tok))
1138
- $token->val=((bool)$tok===true)?1:0;
1139
- else
1140
- $token->val=(float)$tok;
1141
- }
1142
- elseif (self::isBoolean($tok))
1143
- {
1144
- $token->type=self::$_TOKEN_TYPES['BOOLEAN'];
1145
- $token->isBoolean=true;
1146
- if (is_bool($tok))
1147
- $token->val=(bool)$tok;
1148
- else if (is_string($tok))
1149
- $token->val=(strtoupper($tok)=='TRUE')?true:false;
1150
- else if (is_numeric($tok))
1151
- $token->val=((float)$tok != 0)?true:false;
1152
- else
1153
- $token->val=(bool)$tok;
1154
- }
1155
- elseif (self::_isOperator($tok))
1156
- {
1157
- $token->type=self::$_TOKEN_TYPES['ARITHMETIC_OP'];
1158
- $token->isArithmeticOp=true;
1159
- $token->isOp=true;
1160
-
1161
- }
1162
- elseif (self::_isLogicOperator($tok))
1163
- {
1164
- $token->type=self::$_TOKEN_TYPES['LOGICAL_OP'];
1165
- $token->isLogicOp=true;
1166
- $token->isOp=true;
1167
- }
1168
- elseif (self::_isCompOperator($tok))
1169
- {
1170
- $token->type=self::$_TOKEN_TYPES['COMPARISON_OP'];
1171
- $token->isCompOp=true;
1172
- $token->isOp=true;
1173
- }
1174
- elseif (self::_isFunction($tok))
1175
- {
1176
- $token->type=self::$_TOKEN_TYPES['FUNCTION'];
1177
- $token->isFunction=true;
1178
- $token->val=(string)$tok;
1179
- }
1180
- elseif (self::_isVariableName($tok))
1181
- {
1182
- $token->type=self::$_TOKEN_TYPES['VARIABLE'];
1183
- $token->isVariable=true;
1184
- }
1185
- break;
1186
- }
1187
- if ($token->isOp || $token->isFunction)
1188
- {
1189
- $intRet = 0;
1190
-
1191
- switch($token->val)
1192
- {
1193
- case "+" :
1194
- case "-" :
1195
- $intRet = 50;
1196
- break;
1197
- case "*" :
1198
- case "/" :
1199
- case "%" :
1200
- $intRet = 60;
1201
- break;
1202
- case "^" :
1203
- $intRet = 70;
1204
- break;
1205
- case self::$_UNARY_NEGATIVE:
1206
- case self::$_UNARY_NEGATION:
1207
- case "!" :
1208
- case "NOT" :
1209
- $intRet = 100;
1210
- break;
1211
- case "(" :
1212
- $intRet = 1000;
1213
- break;
1214
- /*case "{" :
1215
- intRet = 500; // as function
1216
- break;*/
1217
- case "AND" :
1218
- case "&" :
1219
- $intRet = 35;
1220
- break;
1221
- case "OR" :
1222
- case "|" :
1223
- $intRet = 30;
1224
- break;
1225
- case ">" :
1226
- case ">=" :
1227
- case "<" :
1228
- case "<=" :
1229
- case "=" :
1230
- case "<>" :
1231
- case "gt" :
1232
- case "gte" :
1233
- case "lt" :
1234
- case "lte" :
1235
- case "eq" :
1236
- case "ne" :
1237
- $intRet = 40;
1238
- break;
1239
- default :
1240
- if ($token->isFunction)
1241
- $intRet = 500;
1242
- else
1243
- $intRet = 0;
1244
- break;
1245
- }
1246
- $token->precedence=$intRet;
1247
- }
1248
- else
1249
- $token->precedence=0;
1250
- return $token;
1251
- }
1252
-
1253
- public static function cloneToken($tok)
1254
- {
1255
- $newtok=(object)array();
1256
-
1257
- foreach ($tok as $at=>$val)
1258
- {
1259
- if (self::isDateInstance($tok->$at))
1260
- $newtok->$at=new Toolset_Date($tok->$at->getDate());
1261
- else
1262
- $newtok->$at=$tok->$at;
1263
- }
1264
- return $newtok;
1265
- }
1266
-
1267
- public static function isString($a)
1268
- {
1269
- if (!self::_isDefined($a)) return false;
1270
- return (is_string($a))?true:false;
1271
- }
1272
-
1273
- public static function isDate($pstrVal, $format, &$getDate)
1274
- {
1275
- if (!self::_isDefined($pstrVal))
1276
- return false;
1277
- if (self::isDateInstance($pstrVal))
1278
- {
1279
- if (isset($getDate))
1280
- $getDate['date']=$pstrVal;
1281
- return true;
1282
- }
1283
- return Toolset_DateParser::isDate($pstrVal, $format, $getDate);
1284
- }
1285
-
1286
- public static function toArray($v)
1287
- {
1288
- if (self::isArrayInstance($v))
1289
- return $v;
1290
- else return array($v);
1291
- }
1292
-
1293
- public static function toNumber($pobjVal)
1294
- {
1295
- if (is_numeric($pobjVal))
1296
- return (float)$pobjVal;
1297
- else
1298
- {
1299
- $dblRet = (float)$pobjVal;
1300
- return $dblRet;
1301
- }
1302
- }
1303
-
1304
- public static function toBoolean($pobjVal)
1305
- {
1306
- //var_dump($pobjVal);
1307
- if (!isset($pobjVal))
1308
- throw new Exception("Boolean value is not defined!");
1309
- else if (is_bool($pobjVal))
1310
- return(bool)$pobjVal;
1311
- else if (is_numeric($pobjVal))
1312
- return (bool)(((float)$pobjVal) != 0.0);
1313
- else if (strtoupper((string)$pobjVal)=='TRUE')
1314
- return true;
1315
- else if (strtoupper((string)$pobjVal)=='FALSE')
1316
- return false;
1317
- return null;
1318
- }
1319
-
1320
- public static function Tokanize($pstrExpression)
1321
- {
1322
- // build fast lookup maps
1323
- self::init();
1324
-
1325
- $intCntr = 0;
1326
- $intBraces = 0;
1327
- $intBrackets = 0;
1328
- $intIndex = 0;
1329
- $strToken = "";
1330
- $arrTokens = array();
1331
- $pstrExpression = self::_trim($pstrExpression);
1332
- while ($intCntr < strlen($pstrExpression))
1333
- {
1334
- $prevToken = self::$_EMPTY_TOKEN;
1335
- $chrChar = substr($pstrExpression,$intCntr, 1);
1336
- switch ($chrChar)
1337
- {
1338
- case " " :
1339
- if ($strToken!= '')
1340
- {
1341
- $arrTokens[$intIndex] = self::makeToken($strToken);
1342
- $intIndex++;
1343
- $strToken = "";
1344
- }
1345
- break;
1346
- //case "{":
1347
- case "(":
1348
- //(chrChar=='(')?intBraces++:intBrackets++;
1349
- $intBraces++;
1350
- if ($strToken!='')
1351
- {
1352
- $arrTokens[$intIndex] = self::makeToken($strToken);
1353
- $intIndex++;
1354
- $strToken = "";
1355
- }
1356
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1357
- $intIndex++;
1358
- break;
1359
- //case "}" :
1360
- case ")" :
1361
- //(chrChar==')')?intBraces--:intBrackets--;
1362
- $intBraces--;
1363
- if ($strToken!='')
1364
- {
1365
- $arrTokens[$intIndex] = self::makeToken($strToken);
1366
- $intIndex++;
1367
- $strToken = "";
1368
- }
1369
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1370
- $intIndex++;
1371
- break;
1372
- case "^" :
1373
- case "*" :
1374
- case "/" :
1375
- case "%" :
1376
- case "&" :
1377
- case "|" :
1378
- case "," :
1379
- case "!" :
1380
- if ($strToken!='')
1381
- {
1382
- $arrTokens[$intIndex] = self::makeToken($strToken);
1383
- $intIndex++;
1384
- $strToken = "";
1385
- }
1386
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1387
- $intIndex++;
1388
- break;
1389
- case "-" :
1390
- if ($strToken!='')
1391
- {
1392
- $arrTokens[$intIndex] = self::makeToken($strToken);
1393
- $intIndex++;
1394
- $strToken = "";
1395
- }
1396
- $chrNext = substr($pstrExpression,$intCntr + 1, 1);
1397
- if (count($arrTokens) > 0)
1398
- $prevToken = $arrTokens[$intIndex - 1];
1399
- if (/*intCntr == 0 ||*/(($prevToken->isArithmeticOp ||
1400
- $prevToken->isLeftParen || $prevToken->isComma) &&
1401
- (self::_isDigit($chrNext) || $chrNext == "(")))
1402
- {
1403
- // Negative Number
1404
- $strToken .= $chrChar;
1405
- }
1406
- else
1407
- {
1408
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1409
- $intIndex++;
1410
- $strToken = "";
1411
- }
1412
- break;
1413
- case "+" :
1414
- if ($strToken!='')
1415
- {
1416
- $arrTokens[$intIndex] = self::makeToken($strToken);
1417
- $intIndex++;
1418
- $strToken = "";
1419
- }
1420
- $chrNext = substr($pstrExpression,$intCntr + 1, 1);
1421
- if (count($arrTokens) > 0)
1422
- $prevToken = $arrTokens[$intIndex - 1];
1423
- if (/*intCntr == 0 ||*/ (($prevToken->isArithmeticOp ||
1424
- $prevToken->isLeftParen || $prevToken->isComma) &&
1425
- (self::_isDigit($chrNext) || $chrNext == "(")))
1426
- {
1427
- // positive Number
1428
- $strToken .= $chrChar;
1429
- }
1430
- else
1431
- {
1432
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1433
- $intIndex++;
1434
- $strToken = "";
1435
- }
1436
- break;
1437
- case "<" :
1438
- $chrNext = substr($pstrExpression,$intCntr + 1, 1);
1439
- if ($strToken!='')
1440
- {
1441
- $arrTokens[$intIndex] = self::makeToken($strToken);
1442
- $intIndex++;
1443
- $strToken = "";
1444
- }
1445
- if ($chrNext == "=")
1446
- {
1447
- $arrTokens[$intIndex] = self::makeToken($chrChar . "=");
1448
- $intIndex++;
1449
- $intCntr++;
1450
- }
1451
- else if ($chrNext == ">")
1452
- {
1453
- $arrTokens[$intIndex] = self::makeToken($chrChar . ">");
1454
- $intIndex++;
1455
- $intCntr++;
1456
- }
1457
- else
1458
- {
1459
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1460
- $intIndex++;
1461
- }
1462
- break;
1463
- case ">" :
1464
- $chrNext = substr($pstrExpression,$intCntr + 1, 1);
1465
- if ($strToken!='')
1466
- {
1467
- $arrTokens[$intIndex] = self::makeToken($strToken);
1468
- $intIndex++;
1469
- $strToken = "";
1470
- }
1471
- if ($chrNext == "=")
1472
- {
1473
- $arrTokens[$intIndex] = self::makeToken($chrChar . "=");
1474
- $intIndex++;
1475
- $intCntr++;
1476
- }
1477
- else
1478
- {
1479
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1480
- $intIndex++;
1481
- }
1482
- break;
1483
- case "=" :
1484
- if ($strToken!='')
1485
- {
1486
- $arrTokens[$intIndex] = self::makeToken($strToken);
1487
- $intIndex++;
1488
- $strToken = "";
1489
- }
1490
- $arrTokens[$intIndex] = self::makeToken($chrChar);
1491
- $intIndex++;
1492
- break;
1493
- case "'" :
1494
- case "\"" :
1495
- if ($strToken!='')
1496
- {
1497
- $arrTokens[$intIndex] = self::makeToken($strToken);
1498
- $intIndex++;
1499
- $strToken = "";
1500
- }
1501
- /*
1502
- var found=false;
1503
- var initCnt=intCntr;
1504
- while (!found)
1505
- {
1506
- intPos = pstrExpression.indexOf(chrChar, intCntr + 1);
1507
- if (intPos < 0)
1508
- throw "Unterminated string constant";
1509
- else
1510
- {
1511
- if (pstrExpression.charAt(intPos-1)!='\\') // not escape quote
1512
- {
1513
- found=true;
1514
- strToken += pstrExpression.substring(initCnt + 1, intPos);
1515
- // replace all escaped quotes inside string
1516
- var strTok2=strToken.replace('\\'+chrChar,chrChar);
1517
- while (strToken!=strTok2)
1518
- {
1519
- strToken=strTok2
1520
- strTok2=strToken.replace('\\'+chrChar,chrChar);
1521
- }
1522
- strToken=new String(strTok2);
1523
- strToken._isStringLiteral=true;
1524
- arrTokens[intIndex] = _makeToken(strToken);
1525
- intIndex++;
1526
- strToken = "";
1527
- intCntr = intPos;
1528
- }
1529
- else
1530
- {
1531
- intCntr=intPos;
1532
- }
1533
- }
1534
- }*/
1535
- $intPos = strpos($pstrExpression,$chrChar, $intCntr + 1);
1536
- if ($intPos < 0)
1537
- throw new Exception("Unterminated string constant");
1538
- else
1539
- {
1540
- $strToken .= substr($pstrExpression,$intCntr + 1, $intPos-$intCntr-1);
1541
- $strToken=(object)array('val'=>$strToken,'_isStringLiteral'=>true);
1542
- $arrTokens[$intIndex] = self::makeToken($strToken);
1543
- $intIndex++;
1544
- $strToken = "";
1545
- $intCntr = $intPos;
1546
- }
1547
- break;
1548
- default :
1549
- $strToken .= $chrChar;
1550
- break;
1551
- }
1552
- $intCntr++;
1553
- }
1554
- if ($intBraces > 0)
1555
- throw new Exception("Unbalanced parenthesis!");
1556
-
1557
- if ($strToken!='')
1558
- $arrTokens[$intIndex] = self::makeToken($strToken);
1559
- return $arrTokens;
1560
- }
1561
- }
1562
-
1563
-
1564
-
1565
- class Toolset_Parser
1566
- {
1567
-
1568
- private $strInFix = null;
1569
- private $arrVars = array();
1570
- private $arrTokens = null;
1571
- private $arrPostFix = null;
1572
- private $dtFormat = "d/m/Y";
1573
-
1574
- /*------------------------------------------------------------------------------
1575
- * NAME : HandleFunctions
1576
- * PURPOSE : Execute built-in functions
1577
- * PARAMETERS : pstrTok - The current function name
1578
- * pStack - Operand stack
1579
- * RETURNS : Nothing, the result is pushed back onto the stack.
1580
- *----------------------------------------------------------------------------*/
1581
- private function _HandleFunctions($pstrTok, &$pStack, $pdtFormat, &$parrVars)
1582
- {
1583
- if (!$pstrTok->isFunction)
1584
- throw new Exception("Unsupported function token [" . $pstrTok->val . "]");
1585
-
1586
- $varTmp = $pstrTok->val;
1587
- $arrArgs = array();
1588
- $varTerm = Toolset_Tokenizer::$ARG_TERMINAL;
1589
- while (!$pStack->IsEmpty())
1590
- {
1591
- $varTerm = $pStack->Pop();
1592
- if (!$varTerm->isArgTerminal)
1593
- $arrArgs[] = $varTerm;
1594
- else
1595
- break;
1596
- }
1597
-
1598
- switch ($varTmp)
1599
- {
1600
- case "ARRAY" :
1601
-
1602
- $arrArray=array();
1603
-
1604
- $objTmp = 0;
1605
- $intCntr = count($arrArgs);
1606
- while (--$intCntr >= 0)
1607
- {
1608
- $varTerm = $arrArgs[$intCntr];
1609
- if ($varTerm->isVariable)
1610
- {
1611
- if (!isset($parrVars[$varTerm->val]))
1612
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1613
- else
1614
- $varTerm = $parrVars[$varTerm->val];
1615
- }
1616
- $arrArray=array_merge($arrArray,Toolset_Tokenizer::toArray($varTerm->val));
1617
- }
1618
- $pStack->Push(Toolset_Tokenizer::makeToken($arrArray,Toolset_Tokenizer::$TOKEN_TYPE['ARRAY']));
1619
- break;
1620
- case "TODAY" :
1621
- $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_DateParser::currentDate(), Toolset_Tokenizer::$TOKEN_TYPE['DATE']));
1622
- break;
1623
- case "ACOS" :
1624
- case "ASIN" :
1625
- case "ATAN" :
1626
- throw new Exception("Function [" . $varTmp . "] is not implemented!");
1627
- break;
1628
- case "ABS" :
1629
- case "CHR" :
1630
- case "COS" :
1631
- case "FIX" :
1632
- case "HEX" :
1633
- case "LOG" :
1634
- case "RAND" :
1635
- case "ROUND" :
1636
- case "SIN" :
1637
- case "SQRT" :
1638
- case "TAN" :
1639
- if ($varTmp != "RAND")
1640
- {
1641
- if (count($arrArgs) < 1)
1642
- throw new Exception($varTmp . " requires at least one argument!");
1643
- else if (count($arrArgs) > 1)
1644
- throw new Exception($varTmp . " requires only one argument!");
1645
- }
1646
- else
1647
- {
1648
- if (count($arrArgs) < 1)
1649
- throw new Exception($varTmp . " requires at least one argument!");
1650
- else if (count($arrArgs) > 2)
1651
- throw new Exception($varTmp . " requires at most two arguments!");
1652
- }
1653
- $varTerm = $arrArgs[0];
1654
- if ($varTerm->isVariable)
1655
- {
1656
- if (!isset($parrVars[$varTerm->val]))
1657
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1658
- else
1659
- $varTerm = $parrVars[$varTerm->val];
1660
- }
1661
-
1662
- $objTmp=$varTerm->val;
1663
-
1664
- $rand_min=$rand_max=0;
1665
-
1666
- if ( is_numeric( $objTmp ) === false )
1667
- throw new Exception($varTmp . " operates on numeric operands only!");
1668
- else
1669
- {
1670
- $objTmp = Toolset_Tokenizer::toNumber($varTerm->val);
1671
- if ($varTmp == "RAND")
1672
- {
1673
- $rand_max=floor($objTmp);
1674
- if (count($arrArgs) == 2)
1675
- {
1676
- $varTerm = $arrArgs[1];
1677
- if ($varTerm->isVariable)
1678
- {
1679
- if (!isset($parrVars[$varTerm->val]))
1680
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1681
- else
1682
- $varTerm = $parrVars[$varTerm->val];
1683
- }
1684
-
1685
- if (!$varTerm->isNumber)
1686
- throw new Exception($varTmp . " operates on numeric operands only!");
1687
-
1688
- $objTmp = Toolset_Tokenizer::toNumber($varTerm->val);
1689
-
1690
- $rand_min=floor($objTmp);
1691
- }
1692
- }
1693
- }
1694
-
1695
- if ($varTmp == "ABS")
1696
- $pStack->Push(Toolset_Tokenizer::makeToken(abs($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1697
- else if ($varTmp == "CHR")// TODO check what happens when $objTmp is empty; what does chr() return?
1698
- $pStack->Push(Toolset_Tokenizer::makeToken(chr($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1699
- else if ($varTmp == "COS")
1700
- $pStack->Push(Toolset_Tokenizer::makeToken(cos($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1701
- else if ($varTmp == "FIX")
1702
- $pStack->Push(Toolset_Tokenizer::makeToken(floor($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1703
- else if ($varTmp == "HEX")
1704
- $pStack->Push(Toolset_Tokenizer::makeToken(dechex($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1705
- else if ($varTmp == "LOG")
1706
- $pStack->Push(Toolset_Tokenizer::makeToken(log($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1707
- else if ($varTmp == "RAND")
1708
- $pStack->Push(Toolset_Tokenizer::makeToken(mt_rand($rand_min,$rand_max),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1709
- else if ($varTmp == "ROUND")
1710
- $pStack->Push(Toolset_Tokenizer::makeToken(round($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1711
- else if ($varTmp == "SIN")
1712
- $pStack->Push(Toolset_Tokenizer::makeToken(sin($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1713
- else if ($varTmp == "SQRT")
1714
- $pStack->Push(Toolset_Tokenizer::makeToken(sqrt($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1715
- else if ($varTmp == "TAN")
1716
- $pStack->Push(Toolset_Tokenizer::makeToken(tan($objTmp),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1717
- break;
1718
- case "STR" :
1719
- if (count($arrArgs) < 1)
1720
- throw new Exception($varTmp . " requires at least one argument!");
1721
- else if (count($arrArgs) > 2)
1722
- throw new Exception($varTmp . " requires at most two arguments!");
1723
- $varTerm = $arrArgs[count($arrArgs)-1];
1724
- if ($varTerm->isVariable)
1725
- {
1726
- if (!isset($parrVars[$varTerm->val]))
1727
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1728
- else
1729
- $varTerm = $parrVars[$varTerm->val];
1730
- }
1731
- // if date, output formated date string
1732
- if ($varTerm->isDate)
1733
- {
1734
- $format='';
1735
- if (count($arrArgs)==2)
1736
- {
1737
- $varFormat = $arrArgs[0];
1738
- if ($varFormat->isVariable)
1739
- {
1740
- if (!isset($parrVars[$varFormat->val]))
1741
- throw new Exception("Variable [" . $varFormat->val . "] not defined");
1742
- else
1743
- $varFormat = $parrVars[$varFormat->val];
1744
- }
1745
-
1746
- if (!$varFormat->isStringLiteral)
1747
- throw new Exception("format argument for " . $varTmp . " must be a string!");
1748
- $format=$varFormat->val;
1749
- }
1750
- $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_DateParser::formatDate($varTerm->val, $format),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1751
- }
1752
- else // just convert to string
1753
- $pStack->Push(Toolset_Tokenizer::makeToken((string)$varTerm->val.'',Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1754
- break;
1755
- case "ASC" :
1756
- if (count($arrArgs) > 1)
1757
- throw new Exception($varTmp . " requires only one argument!");
1758
- else if (count($arrArgs) < 1)
1759
- throw new Exception($varTmp . " requires at least one argument!");
1760
- $varTerm = $arrArgs[0];
1761
- if ($varTerm->isVariable)
1762
- {
1763
- if (!isset($parrVars[$varTerm->val]))
1764
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1765
- else
1766
- $varTerm = $parrVars[$varTerm]->val;
1767
- }
1768
-
1769
- if( $varTerm->isNumber )
1770
- {
1771
- $varTerm->val = (string) $varTerm->val;
1772
- $varTerm->isStringLiteral = true;
1773
- }
1774
-
1775
- if (!$varTerm->isStringLiteral)
1776
- {
1777
- throw new Exception($varTmp . " requires a string type operand!");
1778
- }
1779
- else
1780
- {
1781
- if ( strlen( $varTerm->val ) > 0 )
1782
- {
1783
- $ascii_char = ord($varTerm->val{0});
1784
- }
1785
- else
1786
- {
1787
- $ascii_char = 0;
1788
- }
1789
- $pStack->Push(Toolset_Tokenizer::makeToken($ascii_char,Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1790
- }
1791
- break;
1792
- case "REGEX" :
1793
- if (count($arrArgs) < 1)
1794
- throw new Exception($varTmp . " requires at least one argument!");
1795
- else if (count($arrArgs) > 2)
1796
- throw new Exception($varTmp . " requires at most two arguments!");
1797
-
1798
- $varTerm = $arrArgs[count($arrArgs)-1];
1799
- if ($varTerm->isVariable)
1800
- {
1801
- if (!isset($parrVars[$varTerm->val]))
1802
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1803
- else
1804
- $varTerm = $parrVars[$varTerm->val];
1805
- }
1806
-
1807
- if (!$varTerm->isStringLiteral)
1808
- throw new Exception($varTmp . " operates on string type operands!");
1809
-
1810
- $opts=Toolset_Tokenizer::$EMPTY_STRING;
1811
- if (count($arrArgs)==2)
1812
- {
1813
- $opts = $arrArgs[0];
1814
- if ($opts->isVariable)
1815
- {
1816
- if (!isset($parrVars[$opts->val]))
1817
- throw new Exception("Variable [" . $opts->val . "] not defined");
1818
- else
1819
- $opts = $parrVars[$opts->val];
1820
- }
1821
-
1822
- if (!$opts->isStringLiteral)
1823
- throw new Exception($varTmp . " operates on string type operands!");
1824
- }
1825
- $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::Regex($varTerm->val, $opts->val),Toolset_Tokenizer::$TOKEN_TYPE['REGEX']));
1826
- break;
1827
- case "LCASE" :
1828
- case "UCASE" :
1829
- case "NUM" :
1830
- if (count($arrArgs) < 1)
1831
- throw new Exception($varTmp . " requires at least one argument!");
1832
- else if (count($arrArgs) > 1)
1833
- throw new Exception($varTmp . " requires only one argument!");
1834
-
1835
- $varTerm = $arrArgs[0];
1836
- if ($varTerm->isVariable)
1837
- {
1838
- if (!isset($parrVars[$varTerm->val]))
1839
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1840
- else
1841
- $varTerm = $parrVars[$varTerm->val];
1842
- }
1843
-
1844
- if( $varTerm->isNumber )
1845
- {
1846
- $varTerm->val = (string) $varTerm->val;
1847
- $varTerm->isStringLiteral = true;
1848
- }
1849
-
1850
- if (!$varTerm->isStringLiteral && $varTmp != "NUM")
1851
- throw new Exception($varTmp . " requires a string type operand!");
1852
- else
1853
- {
1854
- if ($varTmp == "LCASE")
1855
- {
1856
- $pStack->Push(Toolset_Tokenizer::makeToken(strtolower($varTerm->val),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1857
- }
1858
- else if ($varTmp == "UCASE")
1859
- {
1860
- $pStack->Push(Toolset_Tokenizer::makeToken(strtoupper($varTerm->val),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1861
- }
1862
- else if ($varTmp == "NUM")
1863
- {
1864
- $objTmp=Toolset_Tokenizer::toNumber($varTerm->val)+0.0;
1865
- if (is_nan($objTmp))
1866
- throw new Exception($varTmp . " cannot convert [" . $varTerm->val . "] to number!");
1867
- $pStack->Push(Toolset_Tokenizer::makeToken($objTmp,Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1868
- }
1869
- }
1870
- break;
1871
- case "LEN" :
1872
- if (count($arrArgs) < 1)
1873
- throw new Exception($varTmp . " requires at least one argument!");
1874
- else if (count($arrArgs) > 1)
1875
- throw new Exception($varTmp . " requires only one argument!");
1876
-
1877
- $varTerm = $arrArgs[0];
1878
- if ($varTerm->isVariable)
1879
- {
1880
- if (!isset($parrVars[$varTerm->val]))
1881
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1882
- else
1883
- $varTerm = $parrVars[$varTerm->val];
1884
- }
1885
-
1886
- if (!$varTerm->isArray && !$varTerm->isStringLiteral)
1887
- throw new Exception($varTmp . " requires a string or array type operand!");
1888
- else
1889
- {
1890
- if ($varTerm->isStringLiteral)
1891
- $pStack->Push(Toolset_Tokenizer::makeToken(strlen($varTerm->val),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1892
- else
1893
- $pStack->Push(Toolset_Tokenizer::makeToken(count($varTerm->val),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
1894
- }
1895
- break;
1896
- case "USER" :
1897
- if (count($arrArgs) < 1)
1898
- throw new Exception($varTmp . " requires at least one argument!");
1899
- else if (count($arrArgs) > 1)
1900
- throw new Exception($varTmp . " requires only one argument!");
1901
-
1902
- $varTerm = $arrArgs[0];
1903
- if ($varTerm->isVariable)
1904
- {
1905
- if (!isset($parrVars[$varTerm->val]))
1906
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1907
- else
1908
- $varTerm = $parrVars[$varTerm->val];
1909
- }
1910
-
1911
- if (!$varTerm->isStringLiteral)
1912
- throw new Exception($varTmp . " requires a string type operand!");
1913
- else
1914
- {
1915
- $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::User($varTerm->val),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1916
- }
1917
- break;
1918
- case "COOKIE" :
1919
- if (count($arrArgs) < 1)
1920
- throw new Exception($varTmp . " requires at least one argument!");
1921
- else if (count($arrArgs) > 1)
1922
- throw new Exception($varTmp . " requires only one argument!");
1923
-
1924
- $varTerm = $arrArgs[0];
1925
- if ($varTerm->isVariable)
1926
- {
1927
- if (!isset($parrVars[$varTerm->val]))
1928
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1929
- else
1930
- $varTerm = $parrVars[$varTerm->val];
1931
- }
1932
-
1933
- if (!$varTerm->isStringLiteral)
1934
- throw new Exception($varTmp . " requires a string type operand!");
1935
- else
1936
- {
1937
- $pStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::Cookie($varTerm->val),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
1938
- }
1939
- break;
1940
- case "CONTAINS" :
1941
- if (count($arrArgs) < 2)
1942
- throw new Exception($varTmp . " requires at least two arguments!");
1943
- else if (count($arrArgs) > 2)
1944
- throw new Exception($varTmp . " requires only two arguments!");
1945
-
1946
- $varTerm = $arrArgs[1];
1947
- if ($varTerm->isVariable)
1948
- {
1949
- if (!isset($parrVars[$varTerm->val]))
1950
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1951
- else
1952
- $varTerm = $parrVars[$varTerm->val];
1953
- }
1954
- $varTerm2 = $arrArgs[0];
1955
- if ($varTerm2->isVariable)
1956
- {
1957
- if (!isset($parrVars[$varTerm2->val]))
1958
- throw new Exception("Variable [" . $varTerm2->val . "] not defined");
1959
- else
1960
- $varTerm2 = $parrVars[$varTerm2->val];
1961
- }
1962
-
1963
- if ( !$varTerm->isArray )
1964
- throw new Exception($varTmp . " requires an array as first argument!");
1965
- else
1966
- {
1967
- $found=Toolset_Functions::Contains($varTerm->val, $varTerm2->val); //in_array($varTerm2->val,$varTerm->val);
1968
- $pStack->Push(Toolset_Tokenizer::makeToken($found,Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
1969
- }
1970
- break;
1971
- case "DATE" :
1972
- if (count($arrArgs) < 2)
1973
- throw new Exception($varTmp . " requires at least two arguments!");
1974
- else if (count($arrArgs) > 2)
1975
- throw new Exception($varTmp . " requires only two arguments!");
1976
-
1977
- $varTerm = $arrArgs[1];
1978
- if ($varTerm->isVariable)
1979
- {
1980
- if (!isset($parrVars[$varTerm->val]))
1981
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
1982
- else
1983
- $varTerm = $parrVars[$varTerm->val];
1984
- }
1985
- $varFormat = $arrArgs[0];
1986
- if ($varFormat->isVariable)
1987
- {
1988
- if (!isset($parrVars[$varFormat->val]))
1989
- throw new Exception("Variable [" . $varFormat->val . "] not defined");
1990
- else
1991
- $varFormat = $parrVars[$varFormat->val];
1992
- }
1993
-
1994
- $dateobj=array();
1995
- if (
1996
- (!$varTerm->isStringLiteral) ||
1997
- (!$varFormat->isStringLiteral)
1998
- )
1999
- throw new Exception($varTmp . " requires string type operands!");
2000
- else if (!Toolset_Tokenizer::isDate($varTerm->val, $varFormat->val, $dateobj))
2001
- throw new Exception($varTmp . " can not convert [" . $varTerm->val . "] to a valid date with format [" . $varFormat->val . "]!");
2002
- else
2003
- {
2004
- if (isset($dateobj['date']))
2005
- $pStack->Push(Toolset_Tokenizer::makeToken($dateobj['date'],Toolset_Tokenizer::$TOKEN_TYPE['DATE']));
2006
- else
2007
- throw new Exception($varTmp . " unknown error");
2008
- }
2009
- break;
2010
- case "empty" :
2011
- case "EMPTY" :
2012
- if (count($arrArgs) < 1)
2013
- throw new Exception($varTmp . " requires at least one argument!");
2014
- else if (count($arrArgs) > 1)
2015
- throw new Exception($varTmp . " requires only one arguments!");
2016
-
2017
- $varFormat = $arrArgs[0];
2018
-
2019
- if( $varFormat->isEmpty )
2020
- {
2021
- $pStack->Push(Toolset_Tokenizer::makeToken(true,Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2022
- }
2023
- elseif( $varFormat->isStringLiteral && $varFormat->val === '' )
2024
- {
2025
- $pStack->Push(Toolset_Tokenizer::makeToken(true,Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2026
- }
2027
- elseif( $varFormat->isArray && count( $varFormat->val ) === 0 )
2028
- {
2029
- $pStack->Push(Toolset_Tokenizer::makeToken(true,Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2030
- }
2031
- elseif( $varFormat->isDate && !$varFormat->val )
2032
- {
2033
- $pStack->Push(Toolset_Tokenizer::makeToken(true,Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2034
- }
2035
- else
2036
- {
2037
- $pStack->Push(Toolset_Tokenizer::makeToken(false,Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2038
- }
2039
-
2040
- break;
2041
- case "LEFT" :
2042
- case "RIGHT" :
2043
- if (count($arrArgs) < 2)
2044
- throw new Exception($varTmp . " requires at least two arguments!");
2045
- else if (count($arrArgs) > 2)
2046
- throw new Exception($varTmp . " requires only two arguments!");
2047
-
2048
- for ($intCntr = 0; $intCntr < count($arrArgs); $intCntr++)
2049
- {
2050
- $varTerm = $arrArgs[$intCntr];
2051
- if ($varTerm->isVariable)
2052
- {
2053
- if (!isset($parrVars[$varTerm->val]))
2054
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
2055
- else
2056
- $varTerm = $parrVars[$varTerm->val];
2057
- }
2058
-
2059
- if( $varTerm->isNumber )
2060
- {
2061
- $arrArgs[1]->val = (string) $arrArgs[1]->val;
2062
- $varTerm->isStringLiteral = true;
2063
- }
2064
-
2065
- if ($intCntr == 0 && !$varTerm->isNumber)
2066
- throw new Exception($varTmp . " operator requires numeric length!");
2067
- else if ($intCntr == 1 && !$varTerm->isStringLiteral)
2068
- throw new Exception($varTmp . " operator requires a string operand!");
2069
- $arrArgs[$intCntr] = $varTerm;
2070
- }
2071
- $varTerm = $arrArgs[1]->val;
2072
- $objTmp = Toolset_Tokenizer::toNumber($arrArgs[0]->val);
2073
- if ($varTmp == "LEFT")
2074
- {
2075
- $pStack->Push(Toolset_Tokenizer::makeToken(substr($varTerm,0, $objTmp),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
2076
- }
2077
- else
2078
- {
2079
- $pStack->Push(Toolset_Tokenizer::makeToken(substr($varTerm,(strlen($varTerm) - $objTmp), $objTmp),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
2080
- }
2081
- break;
2082
- case "MID" :
2083
- case "IIF" :
2084
- if (count($arrArgs) < 3)
2085
- throw new Exception($varTmp . " requires at least three arguments!");
2086
- else if (count($arrArgs) > 3)
2087
- throw new Exception($varTmp . " requires only three arguments!");
2088
-
2089
- for ($intCntr = 0; $intCntr < count($arrArgs); $intCntr++)
2090
- {
2091
- $varTerm = $arrArgs[$intCntr];
2092
- if ($varTerm->isVariable)
2093
- {
2094
- if (!isset($parrVars[$varTerm->val]))
2095
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
2096
- else
2097
- $varTerm = $parrVars[$varTerm->val];
2098
- }
2099
-
2100
- if( $varTerm->isNumber )
2101
- {
2102
- $arrArgs[2]->val = (string) $arrArgs[2]->val;
2103
- $varTerm->isStringLiteral = true;
2104
- }
2105
-
2106
- if ($varTmp == "MID" && $intCntr <= 1 && !$varTerm->isNumber)
2107
- throw new Exception($varTmp . " operator requires numeric lengths!");
2108
- else if ($varTmp == "MID" && $intCntr == 2 && !$varTerm->isStringLiteral)
2109
- throw new Exception($varTmp . " operator requires a string input!");
2110
- // else if ($varTmp == "IIF" && $intCntr == 2 && !$varTerm->isBoolean && !$varTerm->isNumber)
2111
- // throw new Exception($varTmp . " operator requires boolean condition!");
2112
- $arrArgs[$intCntr] = $varTerm;
2113
- }
2114
- if ($varTmp == "MID")
2115
- {
2116
- $varTerm = $arrArgs[2]->val;
2117
- $objOp1 = Toolset_Tokenizer::toNumber($arrArgs[1]->val);
2118
- $objOp2 = Toolset_Tokenizer::toNumber($arrArgs[0]->val);
2119
- $pStack->Push(Toolset_Tokenizer::makeToken(substr($varTerm,$objOp1, $objOp2-$objOp1),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
2120
- }
2121
- else
2122
- {
2123
- $varTerm = Toolset_Tokenizer::toBoolean($arrArgs[2]->val);
2124
- if ($varTerm)
2125
- $objOp1 = $arrArgs[1];
2126
- else
2127
- $objOp1 = $arrArgs[0];
2128
- $pStack->Push($objOp1);
2129
- }
2130
- break;
2131
- case "AVG" :
2132
- case "MAX" :
2133
- case "MIN" :
2134
- if (count($arrArgs) < 1)
2135
- throw new Exception($varTmp . " requires at least one operand!");
2136
-
2137
- $_arr=array();
2138
- $intCntr = count($arrArgs);
2139
- while (--$intCntr>=0)
2140
- {
2141
- $varTerm = $arrArgs[$intCntr];
2142
- if ($varTerm->isVariable)
2143
- {
2144
- if (!isset($parrVars[$varTerm->val]))
2145
- throw new Exception("Variable [" . $varTerm->val . "] not defined");
2146
- else
2147
- $varTerm = $parrVars[$varTerm->val];
2148
- }
2149
- if (!$varTerm->isNumber && !$varTerm->isArray)
2150
- throw new Exception($varTmp . " requires numeric or array operands only!");
2151
-
2152
- if (!$varTerm->isArray)
2153
- $_arr=array_merge($_arr,Toolset_Tokenizer::toArray(Toolset_Tokenizer::toNumber($varTerm->val)));
2154
- else
2155
- $_arr=array_merge($_arr,$varTerm->val);
2156
- }
2157
- $intCntr = -1;
2158
- $objTmp = 0;
2159
- while (++$intCntr < count($_arr))
2160
- {
2161
- $varTerm = $_arr[$intCntr];
2162
- if ($varTmp == "AVG")
2163
- $objTmp += $varTerm;
2164
- else if ($varTmp == "MAX")
2165
- {
2166
- if ($intCntr == 0)
2167
- $objTmp = $varTerm;
2168
- else if ($objTmp < $varTerm)
2169
- $objTmp = $varTerm;
2170
- }
2171
- else if ($varTmp == "MIN")
2172
- {
2173
- if ($intCntr == 0)
2174
- $objTmp = $varTerm;
2175
- else if ($objTmp > $varTerm)
2176
- $objTmp = $varTerm;
2177
- }
2178
- }
2179
- if ($varTmp == "AVG" && !empty($_arr))
2180
- $pStack->Push(Toolset_Tokenizer::makeToken($objTmp/count($_arr),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2181
- else if ($varTmp == "AVG")
2182
- $pStack->Push(Toolset_Tokenizer::makeToken(0,Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2183
- else
2184
- $pStack->Push(Toolset_Tokenizer::makeToken($objTmp,Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2185
- unset($_arr);
2186
- break;
2187
- }
2188
- }
2189
-
2190
- /*------------------------------------------------------------------------------
2191
- * NAME : InFixToPostFix
2192
- * PURPOSE : Convert an Infix expression into a postfix (RPN) equivalent
2193
- * PARAMETERS : Infix expression element array
2194
- * RETURNS : array containing postfix expression element tokens
2195
- *----------------------------------------------------------------------------*/
2196
- private function _InFixToPostFix($arrToks)
2197
- {
2198
- $blnStart = false;
2199
- $intIndex = 0;
2200
- $arrPFix = array();
2201
- $myStack = new Toolset_Stack();
2202
-
2203
- // Infix to postfix converter
2204
- for ($intCntr = 0; $intCntr < count($arrToks); $intCntr++)
2205
- {
2206
- /*echo '<br />Tok: <br />';
2207
- print_r($arrToks);
2208
- echo '<br />PF: <br />';
2209
- print_r($arrPFix);
2210
- echo '<br />';*/
2211
-
2212
- $strTok = $arrToks[$intCntr];
2213
- switch ($strTok->type)
2214
- {
2215
- case Toolset_Tokenizer::$TOKEN_TYPE['LEFT_PAREN'] :
2216
- if ($myStack->Size() > 0 && $myStack->Get(0)->isFunction)
2217
- {
2218
- $arrPFix[$intIndex] = Toolset_Tokenizer::$ARG_TERMINAL;
2219
- $intIndex++;
2220
- }
2221
- $myStack->Push($strTok);
2222
- break;
2223
- case Toolset_Tokenizer::$TOKEN_TYPE['RIGHT_PAREN'] :
2224
- $blnStart = true;
2225
- while (!$myStack->IsEmpty())
2226
- {
2227
- $strTok = $myStack->Pop();
2228
- if (!$strTok->isLeftParen)
2229
- {
2230
- $arrPFix[$intIndex] = $strTok;
2231
- $intIndex++;
2232
- }
2233
- else
2234
- {
2235
- $blnStart = false;
2236
- break;
2237
- }
2238
- }
2239
- if ($myStack->IsEmpty() && $blnStart)
2240
- throw new Exception("Unbalanced parenthesis!");
2241
- break;
2242
- case Toolset_Tokenizer::$TOKEN_TYPE['COMMA'] :
2243
- while (!$myStack->IsEmpty())
2244
- {
2245
- $strTok = $myStack->Get(0);
2246
- if ($strTok->isLeftParen) break;
2247
- $arrPFix[$intIndex] = $myStack->Pop();
2248
- $intIndex++;
2249
- }
2250
- break;
2251
- //case Tokenizer.TOKEN_TYPE.UNARY_NEGATIVE :
2252
- //case Tokenizer.TOKEN_TYPE.UNARY_NEGATION :
2253
- case Toolset_Tokenizer::$TOKEN_TYPE['ARITHMETIC_OP'] :
2254
- case Toolset_Tokenizer::$TOKEN_TYPE['LOGICAL_OP'] :
2255
- case Toolset_Tokenizer::$TOKEN_TYPE['COMPARISON_OP'] :
2256
- switch ($strTok->val)
2257
- {
2258
- /*case "-" :
2259
- case "+" :
2260
- case "NOT" :
2261
- case "!" :
2262
- case "^" :
2263
- case "*" :
2264
- case "/" :
2265
- case "%" :
2266
- case "AND" :
2267
- case "&" :
2268
- case "OR" :
2269
- case "|" :
2270
- case ">" :
2271
- case "<" :
2272
- case "=" :
2273
- case ">=" :
2274
- case "<=" :
2275
- case "<>" :*/
2276
- default:
2277
- if ($strTok->val=='-')
2278
- {
2279
- // check for unary negative operator.
2280
- $strPrev = null;
2281
- if ($intCntr > 0)
2282
- $strPrev = $arrToks[$intCntr - 1];
2283
- //$strNext = $arrToks[$intCntr + 1];
2284
- if ($strPrev === null || $strPrev->isArithmeticOp || $strPrev->isLeftParen || $strPrev->isComma)
2285
- {
2286
- $strTok = Toolset_Tokenizer::$UNARY_NEGATIVE;
2287
- }
2288
- }
2289
- if ($strTok->val=='+')
2290
- {
2291
- // check for unary + addition operator, we need to ignore this.
2292
- $strPrev = null;
2293
- if ($intCntr > 0)
2294
- $strPrev = $arrToks[$intCntr - 1];
2295
- //$strNext = $arrToks[$intCntr + 1];
2296
- if ($strPrev === null || $strPrev->isArithmeticOp || $strPrev->isLeftParen || $strPrev->isComma)
2297
- {
2298
- break;
2299
- }
2300
- }
2301
- $strTop = Toolset_Tokenizer::$EMPTY_TOKEN;
2302
- if (!$myStack->IsEmpty()) $strTop = $myStack->Get(0);
2303
- if ($myStack->IsEmpty() || (!$myStack->IsEmpty() && $strTop->isLeftParen))
2304
- {
2305
- $myStack->Push($strTok);
2306
- }
2307
- else if ($strTok->precedence >= $strTop->precedence)
2308
- {
2309
- $myStack->Push($strTok);
2310
- }
2311
- else
2312
- {
2313
- // Pop operators with precedence >= operator strTok
2314
- while (!$myStack->IsEmpty())
2315
- {
2316
- $strTop = $myStack->Get(0);
2317
- if ($strTop->isLeftParen || $strTop->precedence < $strTok->precedence)
2318
- {
2319
- break;
2320
- }
2321
- else
2322
- {
2323
- $arrPFix[$intIndex] = $myStack->Pop();
2324
- $intIndex++;
2325
- }
2326
- }
2327
- $myStack->Push($strTok);
2328
- }
2329
- break;
2330
- }
2331
- break;
2332
- default :
2333
- if ($strTok->type!=Toolset_Tokenizer::$TOKEN_TYPE['FUNCTION'])
2334
- {
2335
- $arrPFix[$intIndex] = $strTok;
2336
- $intIndex++;
2337
- }
2338
- else
2339
- {
2340
- $strTop = Toolset_Tokenizer::$EMPTY_TOKEN;
2341
- if (!$myStack->IsEmpty()) $strTop = $myStack->Get(0);
2342
- if ($myStack->IsEmpty() || (!$myStack->IsEmpty() && $strTop->isLeftParen))
2343
- {
2344
- $myStack->Push($strTok);
2345
- }
2346
- else if ($strTok->precedence >= $strTop->precedence)
2347
- {
2348
- $myStack->Push($strTok);
2349
- }
2350
- else
2351
- {
2352
- // Pop operators with precedence >= operator in strTok
2353
- while (!$myStack->IsEmpty())
2354
- {
2355
- $strTop = $myStack->Get(0);
2356
- if ($strTop->val == "(" || $strTop->precedence < $strTok->precedence)
2357
- {
2358
- break;
2359
- }
2360
- else
2361
- {
2362
- $arrPFix[$intIndex] = $myStack->Pop();
2363
- $intIndex++;
2364
- }
2365
- }
2366
- $myStack->Push($strTok);
2367
- }
2368
- }
2369
- break;
2370
- }
2371
- }
2372
-
2373
- // Pop remaining operators from stack.
2374
- while (!$myStack->IsEmpty())
2375
- {
2376
- $arrPFix[$intIndex] = $myStack->Pop();
2377
- $intIndex++;
2378
- }
2379
- return $arrPFix;
2380
- }
2381
-
2382
- private function _AddNewVariable($varObj, &$varArr=null)
2383
- {
2384
- //cred_log($varObj);
2385
- if (!isset($varArr))
2386
- $varArr = &$this->arrVars;
2387
-
2388
- if (!isset($varArr))
2389
- $varArr = array();
2390
-
2391
- $varName=$varObj['name'];
2392
- $varToken=null;
2393
- if (isset($varObj['withType']))
2394
- {
2395
- //cred_log($varObj['withType']);
2396
- switch($varObj['withType'])
2397
- {
2398
- case 'boolean':
2399
- $varToken=Toolset_Tokenizer::makeToken($varObj['val'],Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']);
2400
- break;
2401
- case 'number':
2402
- $varToken=Toolset_Tokenizer::makeToken($varObj['val'],Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']);
2403
- break;
2404
- case 'array':
2405
- $varToken=Toolset_Tokenizer::makeToken($varObj['val'],Toolset_Tokenizer::$TOKEN_TYPE['ARRAY']);
2406
- break;
2407
- case 'date':
2408
- if (isset($varObj['format']))
2409
- $format=$varObj['format'];
2410
- else
2411
- $format=$this->dtFormat;
2412
- $varToken=Toolset_Tokenizer::makeToken(Toolset_DateParser::parseDate($varObj['val'], $format),Toolset_Tokenizer::$TOKEN_TYPE['DATE']);
2413
- break;
2414
- case 'string':
2415
- default:
2416
- //cred_log('STRING');
2417
- //cred_log(Toolset_Tokenizer::$TOKEN_TYPE);
2418
- $varToken=Toolset_Tokenizer::makeToken($varObj['val'],Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']/*, true*/);
2419
- break;
2420
- }
2421
- }
2422
- else
2423
- $varToken=Toolset_Tokenizer::makeToken($varObj['val'],Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']);
2424
-
2425
- //cred_log($varToken);
2426
- $varArr[$varName] = $varToken;
2427
- }
2428
-
2429
- private function _dumpPostFix($pf)
2430
- {
2431
- $out='';
2432
- for ($i=0; $i<count($pf); $i++)
2433
- $out.=$pf[$i]->val.',';
2434
- return $out;
2435
- }
2436
-
2437
- private function _clonePostFix($pf)
2438
- {
2439
- $newpf=array();
2440
- for ($i=0; $i<count($pf); $i++)
2441
- $newpf[$i]=Toolset_Tokenizer::cloneToken($pf[$i]);
2442
- return $newpf;
2443
- }
2444
-
2445
- private function _ParseExpression()
2446
- {
2447
- $arrTokens = Toolset_Tokenizer::Tokanize($this->strInFix);
2448
- if (!isset($arrTokens))
2449
- throw new Exception("Unable to tokanize the expression!");
2450
- if (count($arrTokens) <= 0)
2451
- throw new Exception("Unable to tokanize the expression!");
2452
-
2453
- //print_r($arrTokens);
2454
-
2455
- $myarrPostFix = $this->_InFixToPostFix($arrTokens);
2456
- if (!isset($myarrPostFix))
2457
- throw new Exception("Unable to convert the expression to postfix form!");
2458
- if (count($myarrPostFix) <= 0)
2459
- throw new Exception("Unable to convert the expression to postfix form!");
2460
- //print_r($myarrPostFix);
2461
- return $myarrPostFix;
2462
- }
2463
-
2464
- private function _getVariable($strVarName, &$varArr=null)
2465
- {
2466
- if (!isset($varArr))
2467
- $varArr=$this->arrVars;
2468
-
2469
- if (!isset($varArr))
2470
- throw new Exception("Variable values are not supplied!");
2471
-
2472
- if (!isset($varArr[$strVarName]))
2473
- throw new Exception("Variable [" . $strVarName . "] not defined");
2474
-
2475
- //cred_log($varArr);
2476
- return $varArr[$strVarName];
2477
- }
2478
-
2479
- // postfix function evaluator
2480
- private function _EvaluateExpression(&$myarrPostFix, &$myvarArr)
2481
- {
2482
- if (!isset($myarrPostFix))
2483
- $myarrPostFix=$this->_ParseExpression();
2484
- if (count($myarrPostFix) == 0)
2485
- throw new Exception("Unable to parse the expression!");
2486
- if (!isset($myarrPostFix) || count($myarrPostFix)==0)
2487
- {
2488
- throw new Exception("Invalid postfix expression!");
2489
- }
2490
-
2491
- $intIndex = 0;
2492
- $myStack = new Toolset_Stack();
2493
-
2494
- //echo $this->_dumpPostFix($myarrPostFix);
2495
-
2496
- while ($intIndex < count($myarrPostFix))
2497
- {
2498
- //echo $myStack->toString();
2499
-
2500
- $strTok = $myarrPostFix[$intIndex];
2501
- switch ($strTok->type)
2502
- {
2503
- case Toolset_Tokenizer::$TOKEN_TYPE['ARG_TERMINAL'] :
2504
- $myStack->Push($strTok);
2505
- break;
2506
- case Toolset_Tokenizer::$TOKEN_TYPE['UNARY_NEGATIVE'] :
2507
- if ($myStack->IsEmpty())
2508
- throw new Exception("No operand to negate!");
2509
-
2510
- $objOp1 = null;
2511
- $objOp2 = null;
2512
- $objOp1 = $myStack->Pop();
2513
- if ($objOp1->isVariable)
2514
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2515
-
2516
- $dblNo = Toolset_Tokenizer::toNumber($objOp1->val);
2517
- if (is_nan($dblNo))
2518
- throw new Exception("Not a numeric value!");
2519
- else
2520
- {
2521
- $dblNo = (0 - $dblNo);
2522
- $myStack->Push(Toolset_Tokenizer::makeToken($dblNo,Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2523
- }
2524
- break;
2525
- case Toolset_Tokenizer::$TOKEN_TYPE['UNARY_NEGATION'] :
2526
- if ($myStack->IsEmpty())
2527
- throw new Exception("No operand on stack!");
2528
-
2529
- $objOp1 = null;
2530
- $objOp2 = null;
2531
- $objOp1 = $myStack->Pop();
2532
- if ($objOp1->isVariable)
2533
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2534
-
2535
- $objOp1 = Toolset_Tokenizer::toBoolean($objOp1->val);
2536
- if ($objOp1 === null)
2537
- throw new Exception($strTok->val . " applied not on a boolean value!");
2538
- else
2539
- $myStack->Push(Toolset_Tokenizer::makeToken(!($objOp1),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2540
- break;
2541
- case Toolset_Tokenizer::$TOKEN_TYPE['ARITHMETIC_OP'] :
2542
- switch($strTok->val)
2543
- {
2544
- case "*" :
2545
- case "/" :
2546
- case "%" :
2547
- case "^" :
2548
- if ($myStack->IsEmpty() || $myStack->Size() < 2)
2549
- throw new Exception("Stack is empty, can not perform [" . $strTok->val . "]");
2550
- $objOp1 = null;
2551
- $objOp2 = null;
2552
- $objTmp = null;
2553
- $objOp2 = $myStack->Pop();
2554
- $objOp1 = $myStack->Pop();
2555
- if ($objOp1->isVariable)
2556
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2557
- if ($objOp2->isVariable)
2558
- $objOp2 = $this->_getVariable($objOp2->val, $myvarArr);
2559
-
2560
- if (!$objOp1->isNumber || !$objOp2->isNumber)
2561
- throw new Exception("Either one of the operand is not a number can not perform [" . $strTok->val . "]");
2562
-
2563
- $dblVal1 = Toolset_Tokenizer::toNumber($objOp1->val);
2564
- $dblVal2 = Toolset_Tokenizer::toNumber($objOp2->val);
2565
- if (is_nan($dblVal1) || is_nan($dblVal2))
2566
- throw new Exception("Either one of the operand is not a number can not perform [" . $strTok->val . "]");
2567
-
2568
- if ($strTok->val == "^")
2569
- $myStack->Push(Toolset_Tokenizer::makeToken(pow($dblVal1, $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2570
- else if ($strTok->val == "*")
2571
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 * $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2572
- else if ($strTok->val == "/")
2573
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 / $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2574
- else
2575
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 % $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2576
- break;
2577
- case "+" :
2578
- case "-" :
2579
- if ($myStack->IsEmpty() || $myStack->Size() < 2)
2580
- throw new Exception("Stack is empty, can not perform [" . $strTok->val . "]");
2581
-
2582
- $objOp1 = null;
2583
- $objOp2 = null;
2584
- $objTmp1 = null;
2585
- $objTmp2 = null;
2586
- $strOp = (($strTok->val == "+") ? "Addition" : "Substraction");
2587
- $objOp2 = $myStack->Pop();
2588
- $objOp1 = $myStack->Pop();
2589
- if ($objOp1->isVariable)
2590
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2591
- if ($objOp2->isVariable)
2592
- $objOp2 = $this->_getVariable($objOp2->val, $myvarArr);
2593
-
2594
- if ($objOp1->isNumber && $objOp2->isNumber)
2595
- {
2596
- // Number addition
2597
- $dblVal1 = Toolset_Tokenizer::toNumber($objOp1->val);
2598
- $dblVal2 = Toolset_Tokenizer::toNumber($objOp2->val);
2599
- if ($strTok->val == "+")
2600
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 + $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2601
- else
2602
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 - $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['NUMBER']));
2603
- }
2604
- else if ($objOp1->isStringLiteral && $objOp2->isStringLiteral)
2605
- {
2606
- if ($strTok->val == "+")
2607
- $myStack->Push(Toolset_Tokenizer::makeToken(($objOp1->val . $objOp2->val),Toolset_Tokenizer::$TOKEN_TYPE['STRING_LITERAL']));
2608
- else
2609
- throw new Exception($strOp . " not supported for strings!");
2610
- }
2611
- else
2612
- throw new Exception($strOp . " not supported for other types than numbers and strings!");
2613
- break;
2614
- }
2615
- break;
2616
- case Toolset_Tokenizer::$TOKEN_TYPE['COMPARISON_OP'] :
2617
- switch($strTok->val)
2618
- {
2619
- case "=" :
2620
- case "<" :
2621
- case ">" :
2622
- case "<>" :
2623
- case "<=" :
2624
- case ">=" :
2625
- case "eq" :
2626
- case "lt" :
2627
- case "gt" :
2628
- case "ne" :
2629
- case "lte" :
2630
- case "gte" :
2631
-
2632
- if ($myStack->IsEmpty() || $myStack->Size() < 2)
2633
- throw new Exception("Stack is empty, can not perform [" . $strTok->val . "]");
2634
- $objOp1 = null;
2635
- $objOp2 = null;
2636
- $objTmp1 = null;
2637
- $objTmp2 = null;
2638
- $objOp2 = $myStack->Pop();
2639
- $objOp1 = $myStack->Pop();
2640
- //cred_log(array($objOp1, $objOp2));
2641
- if ($objOp1->isVariable)
2642
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2643
- if ($objOp2->isVariable)
2644
- $objOp2 = $this->_getVariable($objOp2->val, $myvarArr);
2645
-
2646
- //cred_log(array($objOp1, $objOp2));
2647
- if ($objOp1->isStringLiteral && $objOp2->isNumber)
2648
- {
2649
- $dblVal1 = (string)$objOp1->val;
2650
- $dblVal2 = (string)$objOp2->val;
2651
- }
2652
- else if ($objOp1->isNumber && $objOp2->isStringLiteral)
2653
- {
2654
- $dblVal1 = (string)$objOp1->val;
2655
- $dblVal2 = (string)$objOp2->val;
2656
- }
2657
- else if ($objOp1->isNumber && $objOp2->isNumber)
2658
- {
2659
- $dblVal1 = Toolset_Tokenizer::toNumber($objOp1->val);
2660
- $dblVal2 = Toolset_Tokenizer::toNumber($objOp2->val);
2661
- }
2662
- else if ($objOp1->isNumber && $objOp2->isBoolean)
2663
- {
2664
- $dblVal1 = Toolset_Tokenizer::toNumber($objOp1->val);
2665
- $dblVal2 = Toolset_Tokenizer::toNumber($objOp2->val);
2666
- }
2667
- else if ($objOp2->isNumber && $objOp1->isBoolean)
2668
- {
2669
- $dblVal1 = Toolset_Tokenizer::toNumber($objOp1->val);
2670
- $dblVal2 = Toolset_Tokenizer::toNumber($objOp2->val);
2671
- }
2672
- else if ($objOp1->isDate && $objOp2->isDate)
2673
- {
2674
- $dblVal1 = $objOp1->val->getNormalizedTimestamp();
2675
- $dblVal2 = $objOp2->val->getNormalizedTimestamp();
2676
- }
2677
- else if ($objOp1->isStringLiteral && $objOp2->isStringLiteral)
2678
- {
2679
- $dblVal1=(string)$objOp1->val;
2680
- $dblVal2=(string)$objOp2->val;
2681
- }
2682
- else if ($objOp1->isBoolean && $objOp2->isBoolean)
2683
- {
2684
- if ($strTok->val == "=" || $strTok->val == "<>" || $strTok->val == "eq" || $strTok->val == "ne")
2685
- {
2686
- $dblVal1 = Toolset_Tokenizer::toBoolean($objOp1->val);
2687
- $dblVal2 = Toolset_Tokenizer::toBoolean($objOp2->val);
2688
- }
2689
- else
2690
- throw new Exception($strTok->val + " not supported for boolean values!");
2691
- }
2692
- else if (
2693
- ($strTok->val=='=' || $strTok->val=='<>' || $strTok->val=='eq' || $strTok->val=='ne') &&
2694
- ($objOp1->isStringLiteral && $objOp2->isRegex)
2695
- )
2696
- {
2697
- if ($strTok->val=='=' || $strTok->val=='eq')
2698
- $myStack->Push(Toolset_Tokenizer::makeToken(($objOp2->val->test((string)$objOp1->val)),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2699
- else
2700
- $myStack->Push(Toolset_Tokenizer::makeToken(!($objOp2->val->test((string)$objOp1->val)),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2701
- break;
2702
- }
2703
- else if (
2704
- ($strTok->val=='=' || $strTok->val=='<>' || $strTok->val=='eq' || $strTok->val=='ne') &&
2705
- ($objOp2->isStringLiteral && $objOp1->isRegex)
2706
- )
2707
- {
2708
- if ($strTok->val=='=' || $strTok->val=='eq')
2709
- $myStack->Push(Toolset_Tokenizer::makeToken(($objOp1->val->test((string)$objOp2->val)),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2710
- else
2711
- $myStack->Push(Toolset_Tokenizer::makeToken(!($objOp1->val->test((string)$objOp2->val)),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2712
- break;
2713
- }
2714
- else if (
2715
- ($strTok->val=='=' || $strTok->val=='<>' || $strTok->val=='eq' || $strTok->val=='ne') &&
2716
- ($objOp1->isArray && ($objOp2->isStringLiteral || $objOp2->isNumber))
2717
- )
2718
- {
2719
- if ($strTok->val=='=' || $strTok->val=='eq')
2720
- $myStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::Contains($objOp1->val,$objOp2->val),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2721
- else
2722
- $myStack->Push(Toolset_Tokenizer::makeToken(!Toolset_Functions::Contains($objOp1->val,$objOp2->val),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2723
- break;
2724
- }
2725
- else if (
2726
- ($strTok->val=='=' || $strTok->val=='<>' || $strTok->val=='eq' || $strTok->val=='ne') &&
2727
- ($objOp2->isArray && ($objOp1->isStringLiteral || $objOp1->isNumber))
2728
- )
2729
- {
2730
- if ($strTok->val=='=' || $strTok->val=='eq')
2731
- $myStack->Push(Toolset_Tokenizer::makeToken(Toolset_Functions::Contains($objOp2->val,$objOp1->val),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2732
- else
2733
- $myStack->Push(Toolset_Tokenizer::makeToken(!Toolset_Functions::Contains($objOp2->val,$objOp1->val),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2734
- break;
2735
- }
2736
- else
2737
- throw new Exception("For " . $strTok->val . " operator LHS & RHS should be of same data type!");
2738
-
2739
- if ($strTok->val == "=" || $strTok->val == "eq")
2740
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 == $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2741
- else if ($strTok->val == "<>" || $strTok->val == "ne")
2742
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 != $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2743
- else if ($strTok->val == ">" || $strTok->val == "gt")
2744
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 > $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2745
- else if ($strTok->val == "<" || $strTok->val == "lt")
2746
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 < $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2747
- else if ($strTok->val == "<=" || $strTok->val == "lte")
2748
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 <= $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2749
- else if ($strTok->val == ">=" || $strTok->val == "gte")
2750
- $myStack->Push(Toolset_Tokenizer::makeToken(($dblVal1 >= $dblVal2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2751
- break;
2752
- }
2753
- break;
2754
- case Toolset_Tokenizer::$TOKEN_TYPE['LOGICAL_OP'] :
2755
- switch($strTok->val)
2756
- {
2757
- case 'NOT' :
2758
- case '!' :
2759
- if ($myStack->IsEmpty())
2760
- throw new Exception("No operand on stack!");
2761
-
2762
- $objOp1 = null;
2763
- $objOp2 = null;
2764
- $objOp1 = $myStack->Pop();
2765
- if ($objOp1->isVariable)
2766
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2767
-
2768
- $objOp1 = Toolset_Tokenizer::toBoolean($objOp1->val);
2769
- if ($objOp1 === null)
2770
- throw new Exception($strTok->val . " applied not on a boolean value!");
2771
- else
2772
- $myStack->Push(Toolset_Tokenizer::makeToken(!($objOp1),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2773
- break;
2774
- case "AND" :
2775
- case "&" :
2776
- case "OR" :
2777
- case "|" :
2778
- if ($myStack->IsEmpty() || $myStack->Size() < 2)
2779
- throw new Exception("Stack is empty, can not perform [" . $strTok->val . "]");
2780
- $objOp1 = null;
2781
- $objOp2 = null;
2782
- $objTmp1 = null;
2783
- $objTmp2 = null;
2784
- $objOp2 = $myStack->Pop();
2785
- $objOp1 = $myStack->Pop();
2786
- if ($objOp1->isVariable)
2787
- $objOp1 = $this->_getVariable($objOp1->val, $myvarArr);
2788
- if ($objOp2->isVariable)
2789
- $objOp2 = $this->_getVariable($objOp2->val, $myvarArr);
2790
-
2791
- if (
2792
- ($objOp1->isBoolean && $objOp2->isBoolean) ||
2793
- ($objOp1->isNumber && $objOp2->isNumber) ||
2794
- ($objOp1->isNumber && $objOp2->isBoolean) ||
2795
- ($objOp1->isBoolean && $objOp2->isNumber)
2796
- )
2797
- {
2798
- $objTmp1 = Toolset_Tokenizer::toBoolean($objOp1->val);
2799
- $objTmp2 = Toolset_Tokenizer::toBoolean($objOp2->val);
2800
- if ($strTok->val == "AND" || $strTok->val == "&")
2801
- $myStack->Push(Toolset_Tokenizer::makeToken(($objTmp1 && $objTmp2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2802
- else if ($strTok->val == "OR" || $strTok->val == "|")
2803
- $myStack->Push(Toolset_Tokenizer::makeToken(($objTmp1 || $objTmp2),Toolset_Tokenizer::$TOKEN_TYPE['BOOLEAN']));
2804
- }
2805
- else
2806
- throw new Exception("Logical operator requires LHS & RHS of boolean type!");
2807
- break;
2808
- }
2809
- break;
2810
- case Toolset_Tokenizer::$TOKEN_TYPE['FUNCTION'] :
2811
- $this->_HandleFunctions($strTok, $myStack, $this->dtFormat, $myvarArr);
2812
- break;
2813
- default :
2814
- $myStack->Push($strTok);
2815
- break;
2816
- }
2817
- $intIndex++;
2818
-
2819
- //echo (string)$myStack->toString();
2820
- }
2821
- if ($myStack->IsEmpty() || $myStack->Size() > 1 || $myStack->Get(0)->isVariable)
2822
- throw new Exception("Unable to evaluate expression!");
2823
- else
2824
- return $myStack->Pop()->val;
2825
- }
2826
-
2827
- // delegate here
2828
- public static function setParams($params)
2829
- {
2830
- Toolset_Functions::setParams((array)$params);
2831
- }
2832
-
2833
- public function Toolset_Parser($exp=null)
2834
- {
2835
- if (isset($exp) && $exp!==null)
2836
- {
2837
- $this->strInFix = $exp;
2838
- $this->arrTokens=$this->arrPostFix=null;
2839
- }
2840
- // init tokenizer here, else tokens become undefined on addVar
2841
- Toolset_Tokenizer::init();
2842
- }
2843
-
2844
- public function dateLocales($a=null,$b=null,$c=null)
2845
- {
2846
- Toolset_DateParser::setDateLocaleStrings($a,$b,$c);
2847
- return $this;
2848
- }
2849
-
2850
- public function dateFormat($df)
2851
- {
2852
- $this->dtFormat = $df;
2853
- return $this;
2854
- }
2855
-
2856
- public function expression($exp)
2857
- {
2858
- $this->strInFix = $exp;
2859
- $this->arrTokens=$this->arrPostFix=null;
2860
- return $this;
2861
- }
2862
-
2863
- public function addVar($_var)
2864
- {
2865
- $this->_AddNewVariable($_var, $this->arrVars);
2866
- return $this;
2867
- }
2868
-
2869
- public function parse()
2870
- {
2871
- $this->arrPostFix=$this->_ParseExpression();
2872
- return $this->_dumpPostFix($this->arrPostFix);
2873
- }
2874
-
2875
- public function evaluate()
2876
- {
2877
- return $this->_EvaluateExpression($this->arrPostFix, $this->arrVars);
2878
- }
2879
-
2880
- public function reset()
2881
- {
2882
- $this->arrVars = array();
2883
- $this->strInFix=$this->arrTokens=$this->arrPostFix=null;
2884
- return $this;
2885
- }
2886
-
2887
- public function dump()
2888
- {
2889
- return $this->_dumpPostFix($this->arrPostFix);
2890
- }
2891
- //this.preCompile = function(_exp){if (typeof(_exp)=='undefined') _exp=strInFix; return _getPrecompiledExpression(_exp);};
2892
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/functions.php DELETED
@@ -1,622 +0,0 @@
1
- <?php
2
- /*
3
- * Common functions.
4
- */
5
- define( 'ICL_COMMON_FUNCTIONS', true );
6
-
7
- // for retro compatibility with WP < 3.5
8
- if( !function_exists('wp_normalize_path') ){
9
- function wp_normalize_path( $path ) {
10
- $path = str_replace( '\\', '/', $path );
11
- $path = preg_replace( '|/+|','/', $path );
12
- return $path;
13
- }
14
- }
15
-
16
- /**
17
- * Calculates relative path for given file.
18
- *
19
- * @param type $file Absolute path to file
20
- * @return string Relative path
21
- */
22
- function icl_get_file_relpath( $file ) {
23
- // website url form DB
24
- $url = get_option('siteurl');
25
- // fix the protocol
26
- $base_root = set_url_scheme( $url );
27
-
28
- // normalise windows paths
29
- $path_to_file = wp_normalize_path($file);
30
- // get file directory
31
- $file_dir = wp_normalize_path( dirname( $path_to_file ) );
32
- // get the path to 'wp-content'
33
- $from_content_dir = wp_normalize_path( realpath( WP_CONTENT_DIR ) );
34
- // get wp-content dirname
35
- $content_dir = wp_normalize_path( basename(WP_CONTENT_DIR) );
36
-
37
- // remove absolute path part until 'wp-content' folder
38
- $path = str_replace( $from_content_dir, '', $file_dir);
39
- // add wp-content dir to path
40
- $path = wp_normalize_path( $content_dir.$path );
41
-
42
- // build url
43
- $relpath = $base_root . '/' . $path;
44
-
45
- return $relpath;
46
- }
47
-
48
- /**
49
- * Fix WP's multiarray parsing.
50
- *
51
- * @param type $arg
52
- * @param type $defaults
53
- * @return type
54
- */
55
- function wpv_parse_args_recursive( $arg, $defaults ) {
56
- $temp = false;
57
- if ( isset( $arg[0] ) ) {
58
- $temp = $arg[0];
59
- } else if ( isset( $defaults[0] ) ) {
60
- $temp = $defaults[0];
61
- }
62
- $arg = wp_parse_args( $arg, $defaults );
63
- if ( $temp ) {
64
- $arg[0] = $temp;
65
- }
66
- foreach ( $defaults as $default_setting_parent => $default_setting ) {
67
- if ( !is_array( $default_setting ) ) {
68
- if ( !isset( $arg[$default_setting_parent] ) ) {
69
- $arg[$default_setting_parent] = $default_setting;
70
- }
71
- continue;
72
- }
73
- if ( !isset( $arg[$default_setting_parent] ) ) {
74
- $arg[$default_setting_parent] = $defaults[$default_setting_parent];
75
- }
76
- $arg[$default_setting_parent] = wpv_parse_args_recursive( $arg[$default_setting_parent],
77
- $defaults[$default_setting_parent] );
78
- }
79
-
80
- return $arg;
81
- }
82
-
83
- /*
84
- * Extra check for date for shortcode in shortcode. Called as filter in wpv_condition bellow.
85
- *
86
- * @note As of 1.9 this is not used in Views anymore
87
- */
88
-
89
- function wpv_add_time_functions( $value ) {
90
- return wpv_filter_parse_date( $value );
91
- }
92
-
93
- /**
94
- * Condition function to evaluate and display given block based on expressions
95
- * 'args' => arguments for evaluation fields
96
- *
97
- * Supported actions and symbols:
98
- *
99
- * Integer and floating-point numbers
100
- * Math operators: +, -, *, /
101
- * Comparison operators: &lt;, &gt;, =, &lt;=, &gt;=, !=
102
- * Boolean operators: AND, OR, NOT
103
- * Nested expressions - several levels of brackets
104
- * Variables defined as shortcode parameters starting with a dollar sign
105
- * empty() function that checks for blank or non-existing fields
106
- *
107
- *
108
- * @note As of 1.9, this is not used in Views anymore, seems to be used on the toolset-forms library
109
- */
110
- function wpv_condition( $atts, $post_to_check = null ) {
111
- extract(
112
- shortcode_atts( array('evaluate' => FALSE), $atts )
113
- );
114
-
115
- // Do not overwrite global post
116
- // global $post;
117
-
118
- // if in admin, get the post from the URL
119
- if ( is_admin() ) {
120
- if ( empty($post_to_check->ID) ) {
121
- // Get post
122
- if ( isset( $_GET['post'] ) ) {
123
- $post_id = (int) $_GET['post'];
124
- } else if ( isset( $_POST['post_ID'] ) ) {
125
- $post_id = (int) $_POST['post_ID'];
126
- } else {
127
- $post_id = 0;
128
- }
129
- if ( $post_id ) {
130
- $post = get_post( $post_id );
131
- }
132
- } else {
133
- $post = $post_to_check;
134
- }
135
- }
136
- if ( empty($post->ID) ) {
137
- global $post;
138
- }
139
- $has_post = true;
140
- if ( empty($post->ID) ) {
141
- // Will not execute any condition that involves custom fields
142
- $has_post = false;
143
- }
144
-
145
- global $wplogger;
146
-
147
- if ( $has_post ) {
148
- do_action( 'wpv_condition', $post );
149
- }
150
-
151
- $logging_string = "Original expression: " . $evaluate;
152
-
153
- add_filter( 'wpv-extra-condition-filters', 'wpv_add_time_functions' );
154
- $evaluate = apply_filters( 'wpv-extra-condition-filters', $evaluate );
155
-
156
- $logging_string .= "; After extra conditions: " . $evaluate;
157
-
158
- // evaluate empty() statements for variables
159
- if ( $has_post ) {
160
- $empties = preg_match_all( "/empty\(\s*\\$(\w+)\s*\)/", $evaluate, $matches );
161
- if ( $empties && $empties > 0 ) {
162
- for ( $i = 0; $i < $empties; $i++ ) {
163
- $match_var = get_post_meta( $post->ID, $atts[$matches[1][$i]], true );
164
- $is_empty = '1=0';
165
-
166
- // mark as empty only nulls and ""
167
- // if ( is_null( $match_var ) || strlen( $match_var ) == 0 ) {
168
- if ( is_null( $match_var )
169
- || ( is_string( $match_var ) && strlen( $match_var ) == 0 )
170
- || ( is_array( $match_var ) && empty( $match_var ) ) ) {
171
- $is_empty = '1=1';
172
- }
173
- $evaluate = str_replace( $matches[0][$i], $is_empty, $evaluate );
174
- $logging_string .= "; After empty: " . $evaluate;
175
- }
176
- }
177
- }
178
-
179
- // find variables that are to be used as strings.
180
- // eg '$f1'
181
- // will replace $f1 with the actual field value
182
- if ( $has_post ) {
183
- $strings_count = preg_match_all( '/(\'[\$\w^\']*\')/', $evaluate, $matches );
184
- if ( $strings_count && $strings_count > 0 ) {
185
- for ( $i = 0; $i < $strings_count; $i++ ) {
186
- $string = $matches[1][$i];
187
- // remove single quotes from string literals to get value only
188
- $string = (strpos( $string, '\'' ) === 0) ? substr( $string, 1,
189
- strlen( $string ) - 2 ) : $string;
190
- if ( strpos( $string, '$' ) === 0 ) {
191
- $variable_name = substr( $string, 1 ); // omit dollar sign
192
- if ( isset( $atts[$variable_name] ) ) {
193
- $string = get_post_meta( $post->ID, $atts[$variable_name], true );
194
- $evaluate = str_replace( $matches[1][$i], "'" . $string . "'", $evaluate );
195
- $logging_string .= "; After variables I: " . $evaluate;
196
- }
197
- }
198
- }
199
- }
200
- }
201
-
202
- // find string variables and evaluate
203
- $strings_count = preg_match_all( '/((\$\w+)|(\'[^\']*\'))\s*([\!<>\=]+)\s*((\$\w+)|(\'[^\']*\'))/',
204
- $evaluate, $matches );
205
-
206
- // get all string comparisons - with variables and/or literals
207
- if ( $strings_count && $strings_count > 0 ) {
208
- for ( $i = 0; $i < $strings_count; $i++ ) {
209
-
210
- // get both sides and sign
211
- $first_string = $matches[1][$i];
212
- $second_string = $matches[5][$i];
213
- $math_sign = $matches[4][$i];
214
-
215
- // remove single quotes from string literals to get value only
216
- $first_string = (strpos( $first_string, '\'' ) === 0) ? substr( $first_string,
217
- 1, strlen( $first_string ) - 2 ) : $first_string;
218
- $second_string = (strpos( $second_string, '\'' ) === 0) ? substr( $second_string,
219
- 1, strlen( $second_string ) - 2 ) : $second_string;
220
-
221
- // replace variables with text representation
222
- if ( strpos( $first_string, '$' ) === 0 && $has_post ) {
223
- $variable_name = substr( $first_string, 1 ); // omit dollar sign
224
- if ( isset( $atts[$variable_name] ) ) {
225
- $first_string = get_post_meta( $post->ID,
226
- $atts[$variable_name], true );
227
- } else {
228
- $first_string = '';
229
- }
230
- }
231
- if ( strpos( $second_string, '$' ) === 0 && $has_post ) {
232
- $variable_name = substr( $second_string, 1 );
233
- if ( isset( $atts[$variable_name] ) ) {
234
- $second_string = get_post_meta( $post->ID,
235
- $atts[$variable_name], true );
236
- } else {
237
- $second_string = '';
238
- }
239
- }
240
-
241
- // don't do string comparison if variables are numbers
242
- if ( !(is_numeric( $first_string ) && is_numeric( $second_string )) ) {
243
- // compare string and return true or false
244
- $compared_str_result = wpv_compare_strings( $first_string,
245
- $second_string, $math_sign );
246
-
247
- if ( $compared_str_result ) {
248
- $evaluate = str_replace( $matches[0][$i], '1=1', $evaluate );
249
- } else {
250
- $evaluate = str_replace( $matches[0][$i], '1=0', $evaluate );
251
- }
252
- } else {
253
- $evaluate = str_replace( $matches[1][$i], $first_string, $evaluate );
254
- $evaluate = str_replace( $matches[5][$i], $second_string, $evaluate );
255
- }
256
- $logging_string .= "; After variables II: " . $evaluate;
257
- }
258
- }
259
-
260
- // find remaining strings that maybe numeric values.
261
- // This handles 1='1'
262
- $strings_count = preg_match_all( '/(\'[^\']*\')/', $evaluate, $matches );
263
- if ( $strings_count && $strings_count > 0 ) {
264
- for ( $i = 0; $i < $strings_count; $i++ ) {
265
- $string = $matches[1][$i];
266
- // remove single quotes from string literals to get value only
267
- $string = (strpos( $string, '\'' ) === 0) ? substr( $string, 1, strlen( $string ) - 2 ) : $string;
268
- if ( is_numeric( $string ) ) {
269
- $evaluate = str_replace( $matches[1][$i], $string, $evaluate );
270
- $logging_string .= "; After variables III: " . $evaluate;
271
- }
272
- }
273
- }
274
-
275
-
276
- // find all variable placeholders in expression
277
- if ( $has_post ) {
278
- $count = preg_match_all( '/\$(\w+)/', $evaluate, $matches );
279
-
280
- $logging_string .= "; Variable placeholders: " . var_export( $matches[1],
281
- true );
282
-
283
- // replace all variables with their values listed as shortcode parameters
284
- if ( $count && $count > 0 ) {
285
- // sort array by length desc, fix str_replace incorrect replacement
286
- $matches[1] = wpv_sort_matches_by_length( $matches[1] );
287
-
288
- foreach ( $matches[1] as $match ) {
289
- if ( isset( $atts[$match] ) ) {
290
- $meta = get_post_meta( $post->ID, $atts[$match], true );
291
- if ( empty( $meta ) ) {
292
- $meta = "0";
293
- }
294
- } else {
295
- $meta = "0";
296
- }
297
- $evaluate = str_replace( '$' . $match, $meta, $evaluate );
298
- $logging_string .= "; After variables IV: " . $evaluate;
299
- }
300
- }
301
- }
302
-
303
- $logging_string .= "; End evaluated expression: " . $evaluate;
304
-
305
- $wplogger->log( $logging_string, WPLOG_DEBUG );
306
- // evaluate the prepared expression using the custom eval script
307
- $result = wpv_evaluate_expression( $evaluate );
308
-
309
- if ( $has_post ) {
310
- do_action( 'wpv_condition_end', $post );
311
- }
312
-
313
- // return true, false or error string to the conditional caller
314
- return $result;
315
- }
316
-
317
- function wpv_eval_check_syntax( $code ) {
318
- return @eval( 'return true;' . $code );
319
- }
320
-
321
- /**
322
- *
323
- * Sort matches array by length so evaluate longest variable names first
324
- *
325
- * Otherwise the str_replace would break a field named $f11 if there is another field named $f1
326
- *
327
- * @param array $matches all variable names
328
- */
329
- function wpv_sort_matches_by_length( $matches ) {
330
- $length = count( $matches );
331
- for ( $i = 0; $i < $length; $i++ ) {
332
- $max = strlen( $matches[$i] );
333
- $max_index = $i;
334
-
335
- // find the longest variable
336
- for ( $j = $i + 1; $j < $length; $j++ ) {
337
- if ( strlen( $matches[$j] ) > $max ) {
338
- $max = $matches[$j];
339
- $max_index = $j;
340
- }
341
- }
342
-
343
- // swap
344
- $temp = $matches[$i];
345
- $matches[$i] = $matches[$max_index];
346
- $matches[$max_index] = $temp;
347
- }
348
-
349
- return $matches;
350
-
351
- }
352
-
353
- /**
354
- * Boolean function for string comparison
355
- *
356
- * @param string $first first string to be compared
357
- * @param string $second second string for comparison
358
- *
359
- *
360
- */
361
- function wpv_compare_strings( $first, $second, $sign ) {
362
- // get comparison results
363
- $comparison = strcmp( $first, $second );
364
-
365
- // verify cases 'less than' and 'less than or equal': <, <=
366
- if ( $comparison < 0 && ($sign == '<' || $sign == '<=') ) {
367
- return true;
368
- }
369
-
370
- // verify cases 'greater than' and 'greater than or equal': >, >=
371
- if ( $comparison > 0 && ($sign == '>' || $sign == '>=') ) {
372
- return true;
373
- }
374
-
375
- // verify equal cases: =, <=, >=
376
- if ( $comparison == 0 && ($sign == '=' || $sign == '<=' || $sign == '>=') ) {
377
- return true;
378
- }
379
-
380
- // verify != case
381
- if ( $comparison != 0 && $sign == '!=' ) {
382
- return true;
383
- }
384
-
385
- // or result is incorrect
386
- return false;
387
- }
388
-
389
- /**
390
- *
391
- * Function that prepares the expression and calls eval()
392
- * Validates the input for a list of whitechars and handles internal errors if any
393
- *
394
- * @param string $expression the expression to be evaluated
395
- */
396
- function wpv_evaluate_expression( $expression ){
397
- //Replace AND, OR, ==
398
- $expression = strtoupper( $expression );
399
- $expression = str_replace( "AND", "&&", $expression );
400
- $expression = str_replace( "OR", "||", $expression );
401
- $expression = str_replace( "NOT", "!", $expression );
402
- $expression = str_replace( "=", "==", $expression );
403
- $expression = str_replace( "<==", "<=", $expression );
404
- $expression = str_replace( ">==", ">=", $expression );
405
- $expression = str_replace( "!==", "!=", $expression ); // due to the line above
406
- // validate against allowed input characters
407
- $count = preg_match( '/[0-9+-\=\*\/<>&\!\|\s\(\)]+/', $expression, $matches );
408
-
409
- // find out if there is full match for the entire expression
410
- if ( $count > 0 ) {
411
- if ( strlen( $matches[0] ) == strlen( $expression ) ) {
412
- $valid_eval = wpv_eval_check_syntax( "return $expression;" );
413
- if ( $valid_eval ) {
414
- return eval( "return $expression;" );
415
- } else {
416
- return __( "Error while parsing the evaluate expression",
417
- 'wpv-views' );
418
- }
419
- } else {
420
- return __( "Conditional expression includes illegal characters",
421
- 'wpv-views' );
422
- }
423
- } else {
424
- return __( "Correct conditional expression has not been found",
425
- 'wpv-views' );
426
- }
427
-
428
- }
429
-
430
- /**
431
- * class WPV_wpcf_switch_post_from_attr_id
432
- *
433
- * This class handles the "id" attribute in a wpv-post-xxxxx shortcode
434
- * and sets the global $id, $post, and $authordata
435
- *
436
- * It also handles types. eg [types field='my-field' id='233']
437
- *
438
- * id can be a integer to refer directly to a post
439
- * id can be $parent to refer to the parent
440
- * id can be $current_page or refer to the current page
441
- *
442
- * id can also refer to a related post type
443
- * eg. for a stay the related post types could be guest and room
444
- * [types field='my-field' id='$guest']
445
- * [types field='my-field' id='$room']
446
- */
447
- class WPV_wpcf_switch_post_from_attr_id
448
- {
449
-
450
- function __construct( $atts ){
451
- $this->found = false;
452
-
453
- if ( isset( $atts['id'] ) ) {
454
-
455
- global $post, $authordata, $id, $WPV_wpcf_post_relationship;
456
-
457
- $post_id = 0;
458
-
459
- if ( strpos( $atts['id'], '$' ) === 0 ) {
460
- // Handle the parent if the id is $parent
461
- if ( $atts['id'] == '$parent' && isset( $post->post_parent ) ) {
462
- $post_id = $post->post_parent;
463
- } else if ( $atts['id'] == '$current_page' ) {
464
- if ( is_single() || is_page() ) {
465
- global $wp_query;
466
-
467
- if ( isset( $wp_query->posts[0] ) ) {
468
- $current_post = $wp_query->posts[0];
469
- $post_id = $current_post->ID;
470
- }
471
- }
472
- } else {
473
- // See if Views has the variable
474
- global $WP_Views;
475
- if ( isset( $WP_Views ) ) {
476
- $post_id = $WP_Views->get_variable( $atts['id'] . '_id' );
477
- }
478
- if ( $post_id == 0 ) {
479
- // Try the local storage.
480
- if ( isset( $WPV_wpcf_post_relationship[$atts['id'] . '_id'] ) ) {
481
- $post_id = $WPV_wpcf_post_relationship[$atts['id'] . '_id'];
482
- }
483
- }
484
- }
485
- } else {
486
- $post_id = intval( $atts['id'] );
487
- }
488
-
489
- if ( $post_id > 0 ) {
490
-
491
- $this->found = true;
492
-
493
- // save original post
494
- $this->post = ( isset( $post ) && ( $post instanceof WP_Post ) ) ? clone $post : null;
495
- if ( $authordata ) {
496
- $this->authordata = clone $authordata;
497
- } else {
498
- $this->authordata = null;
499
- }
500
- $this->id = $id;
501
-
502
- // set the global post values
503
- $id = $post_id;
504
- $post = get_post( $id );
505
- $authordata = new WP_User( $post->post_author );
506
- }
507
- }
508
-
509
- }
510
-
511
- function __destruct(){
512
- if ( $this->found ) {
513
- global $post, $authordata, $id;
514
-
515
- // restore the global post values.
516
- $post = ( isset( $this->post ) && ( $this->post instanceof WP_Post ) ) ? clone $this->post : null;
517
- if ( $this->authordata ) {
518
- $authordata = clone $this->authordata;
519
- } else {
520
- $authordata = null;
521
- }
522
- $id = $this->id;
523
- }
524
-
525
- }
526
-
527
- }
528
-
529
- // Add a filter on the content so that we can record any related posts.
530
- // These can then be used ine id of Types and Views shortcodes
531
- // eg. for a stay we can have
532
- // [types field='my-field' id="$room"] displays my-field from the related room
533
- // [wpv-post-title id="$room"] display the title of the related room
534
-
535
- add_filter( 'the_content', 'WPV_wpcf_record_post_relationship_belongs', 0, 1 );
536
-
537
- $WPV_wpcf_post_relationship = Array();
538
-
539
- function WPV_wpcf_record_post_relationship_belongs( $content ) {
540
-
541
- global $post, $WPV_wpcf_post_relationship;
542
- static $related = array();
543
-
544
- if ( !empty( $post->ID ) && function_exists( 'wpcf_pr_get_belongs' ) ) {
545
-
546
- if ( !isset( $related[$post->post_type] ) ) {
547
- $related[$post->post_type] = wpcf_pr_get_belongs( $post->post_type );
548
- }
549
- if ( is_array( $related[$post->post_type] ) ) {
550
- foreach ( $related[$post->post_type] as $post_type => $data ) {
551
- $related_id = wpcf_pr_post_get_belongs( $post->ID, $post_type );
552
- if ( $related_id ) {
553
- $WPV_wpcf_post_relationship['$' . $post_type . '_id'] = $related_id;
554
- } else {
555
- $WPV_wpcf_post_relationship['$' . $post_type . '_id'] = 0;
556
- }
557
- }
558
- }
559
- }
560
-
561
-
562
- return $content;
563
- }
564
-
565
- /**
566
- * Form for Enlimbo calls for wpv-control shortcode calls
567
- *
568
- * @param mixed $elements
569
- * @return string
570
- */
571
- function wpv_form_control( $elements ) {
572
- static $form = NULL;
573
- require_once 'classes/control_forms.php';
574
- if ( is_null( $form ) ) {
575
- $form = new Enlimbo_Control_Forms();
576
- }
577
- return $form->renderElements( $elements );
578
- }
579
-
580
- /**
581
- * Dismiss message.
582
- *
583
- * @param type $message_id
584
- * @param string $message
585
- * @param type $class
586
- */
587
- function wpv_add_dismiss_message( $message_id, $message,
588
- $clear_dismissed = false, $class = 'updated' ) {
589
- $dismissed_messages = get_option( 'wpv-dismissed-messages', array() );
590
- if ( $clear_dismissed ) {
591
- if ( isset( $dismissed_messages[$message_id] ) ) {
592
- unset( $dismissed_messages[$message_id] );
593
- update_option( 'wpv-dismissed-messages', $dismissed_messages );
594
- }
595
- }
596
- if ( !array_key_exists( $message_id, $dismissed_messages ) ) {
597
- $message = $message . '<div style="float:right; margin:-15px 0 0 15px;"><a onclick="jQuery(this).parent().parent().fadeOut();jQuery.get(\''
598
- . admin_url( 'admin-ajax.php?action=wpv_dismiss_message&amp;message_id='
599
- . $message_id . '&amp;_wpnonce='
600
- . wp_create_nonce( 'dismiss_message' ) ) . '\');return false;"'
601
- . 'class="button-secondary" href="javascript:void(0);">'
602
- . __( "Don't show this message again", 'wpv-views' ) . '</a></div>';
603
- wpv_admin_message_store( $message_id, $message, false );
604
- }
605
- }
606
-
607
- add_action( 'wp_ajax_wpv_dismiss_message', 'wpv_dismiss_message_ajax' );
608
-
609
- /**
610
- * Dismiss message AJAX.
611
- */
612
- function wpv_dismiss_message_ajax() {
613
- if ( isset( $_GET['message_id'] ) && isset( $_GET['_wpnonce'] )
614
- && wp_verify_nonce( $_GET['_wpnonce'], 'dismiss_message' ) ) {
615
- $dismissed_messages = get_option( 'wpv-dismissed-messages', array() );
616
- $dismissed_image_val = isset( $_GET['timestamp'] ) ? $_GET['timestamp'] : 1;
617
- $dismissed_messages[strval( $_GET['message_id'] )] = $dismissed_image_val;
618
- update_option( 'wpv-dismissed-messages', $dismissed_messages );
619
- }
620
- die( 'ajax' );
621
- }
622
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/localization/locale/orig/views.po DELETED
@@ -1,4528 +0,0 @@
1
- # This file was generated by WPML
2
- # WPML is a WordPress plugin that can turn any WordPress site into a full featured multilingual content management system.
3
- # https://wpml.org
4
- msgid ""
5
- msgstr ""
6
- "Content-Type: text/plain; charset=utf-8\n"
7
- "Content-Transfer-Encoding: 8bit\n"
8
- "Project-Id-Version: \n"
9
- "POT-Creation-Date: \n"
10
- "PO-Revision-Date: \n"
11
- "Last-Translator: \n"
12
- "Language-Team: \n"
13
- "MIME-Version: 1.0\n"
14
-
15
- msgid "Required"
16
- msgstr ""
17
-
18
- msgid "Email"
19
- msgstr ""
20
-
21
- msgid "Date"
22
- msgstr ""
23
-
24
- msgid "Digits"
25
- msgstr ""
26
-
27
- msgid "Numeric"
28
- msgstr ""
29
-
30
- msgid "You must define the $operator parameter for Wpcf_Cake_Validation::comparison()"
31
- msgstr ""
32
-
33
- msgid "You must define a regular expression for Wpcf_Cake_Validation::custom()"
34
- msgstr ""
35
-
36
- msgid "Could not find %s class, unable to complete validation."
37
- msgstr ""
38
-
39
- msgid "Method %s does not exist on %s unable to complete validation."
40
- msgstr ""
41
-
42
- msgid "Error while parsing the evaluate expression"
43
- msgstr ""
44
-
45
- msgid "Conditional expression includes illegal characters"
46
- msgstr ""
47
-
48
- msgid "Correct conditional expression has not been found"
49
- msgstr ""
50
-
51
- msgid "Don't show this message again"
52
- msgstr ""
53
-
54
- msgid "Clear"
55
- msgstr ""
56
-
57
- msgid "Default"
58
- msgstr ""
59
-
60
- msgid "Select Color"
61
- msgstr ""
62
-
63
- msgid "Delete"
64
- msgstr ""
65
-
66
- msgid "Hour"
67
- msgstr ""
68
-
69
- msgid "Minute"
70
- msgstr ""
71
-
72
- msgid "Select date"
73
- msgstr ""
74
-
75
- msgid "Input format: %s"
76
- msgstr ""
77
-
78
- msgid "Select file"
79
- msgstr ""
80
-
81
- msgid "Select %s"
82
- msgstr ""
83
-
84
- msgid "Toolset"
85
- msgstr ""
86
-
87
- msgid "Use as field value"
88
- msgstr ""
89
-
90
- msgid "Please note that not all video and audio formats are supported by the WordPress media player. Before you upload media files, have a look at %ssupported media formats%s."
91
- msgstr ""
92
-
93
- msgid "Edit Skype button"
94
- msgstr ""
95
-
96
- msgid "Enter your Skype Name"
97
- msgstr ""
98
-
99
- msgid "Select a button from below"
100
- msgstr ""
101
-
102
- msgid "Skype buttons with status"
103
- msgstr ""
104
-
105
- msgid "If you choose to show your Skype status, your Skype button will always reflect your availability on Skype. This status will be shown to everyone, whether they’re in your contact list or not."
106
- msgstr ""
107
-
108
- msgid "Save"
109
- msgstr ""
110
-
111
- msgid "You must define the $operator parameter for WPToolset_Cake_Validation::comparison()"
112
- msgstr ""
113
-
114
- msgid "You must define a regular expression for WPToolset_Cake_Validation::custom()"
115
- msgstr ""
116
-
117
- msgid "Delete %s"
118
- msgstr ""
119
-
120
- msgid "Add new %s"
121
- msgstr ""
122
-
123
- msgid "Get Types and Views"
124
- msgstr ""
125
-
126
- msgid "Once you have installed the full versions of Types and Views you'll be able to create and edit your own content types, layouts and listings."
127
- msgstr ""
128
-
129
- msgid "<a href=\"%s\" target=\"_blank\">Learn more</a>"
130
- msgstr ""
131
-
132
- msgid "Your theme was created using <strong>Types</strong> and <strong>Views</strong>. Developers use these two plugins to build complex websites, without coding."
133
- msgstr ""
134
-
135
- msgid "Right now, you're using the embedded version, which creates the layout but doesn't include the editing interface. You can upgrade to the full version and customize your site yourself - you don't even need to know how to program!"
136
- msgstr ""
137
-
138
- msgid "Every purchase of Views entitles you to commercial-grade support and upgrades for one year."
139
- msgstr ""
140
-
141
- msgid "You can use Types and Views for as many themes and websites as you like."
142
- msgstr ""
143
-
144
- msgid "View templates"
145
- msgstr ""
146
-
147
- msgid "Post View"
148
- msgstr ""
149
-
150
- msgid "Taxonomy View"
151
- msgstr ""
152
-
153
- msgid "User View"
154
- msgstr ""
155
-
156
- msgid "Views"
157
- msgstr ""
158
-
159
- msgid "Types"
160
- msgstr ""
161
-
162
- msgid "Fields"
163
- msgstr ""
164
-
165
- msgid "Go to"
166
- msgstr ""
167
-
168
- msgid "User ID"
169
- msgstr ""
170
-
171
- msgid "Basic"
172
- msgstr ""
173
-
174
- msgid "User Email"
175
- msgstr ""
176
-
177
- msgid "User Login"
178
- msgstr ""
179
-
180
- msgid "First Name"
181
- msgstr ""
182
-
183
- msgid "Last Name"
184
- msgstr ""
185
-
186
- msgid "Nickname"
187
- msgstr ""
188
-
189
- msgid "Display Name"
190
- msgstr ""
191
-
192
- msgid "Description"
193
- msgstr ""
194
-
195
- msgid "Yahoo IM"
196
- msgstr ""
197
-
198
- msgid "Jabber"
199
- msgstr ""
200
-
201
- msgid "AIM"
202
- msgstr ""
203
-
204
- msgid "User Url"
205
- msgstr ""
206
-
207
- msgid "Registration Date"
208
- msgstr ""
209
-
210
- msgid "User Status"
211
- msgstr ""
212
-
213
- msgid "User Spam Status"
214
- msgstr ""
215
-
216
- msgid "Translatable string"
217
- msgstr ""
218
-
219
- msgid "Users fields"
220
- msgstr ""
221
-
222
- msgid "User fields"
223
- msgstr ""
224
-
225
- msgid "Types fields"
226
- msgstr ""
227
-
228
- msgid "Post View"
229
- msgstr ""
230
-
231
- msgid "Taxonomy View"
232
- msgstr ""
233
-
234
- msgid "User View"
235
- msgstr ""
236
-
237
- msgid "Field"
238
- msgstr ""
239
-
240
- msgid "View"
241
- msgstr ""
242
-
243
- msgid "Taxonomy"
244
- msgstr ""
245
-
246
- msgid "Other Fields"
247
- msgstr ""
248
-
249
- msgid "Search"
250
- msgstr ""
251
-
252
- msgid "Clear"
253
- msgstr ""
254
-
255
- msgid "Some pointer hints have been hidden on this page. %sShow them again%s"
256
- msgstr ""
257
-
258
- msgid "Do you want to apply to all?"
259
- msgstr ""
260
-
261
- msgid "%d %s uses a different Content Template."
262
- msgstr ""
263
-
264
- msgid "%d %s use a different Content Template."
265
- msgstr ""
266
-
267
- msgid "Update %s now"
268
- msgstr ""
269
-
270
- msgid "Success!"
271
- msgstr ""
272
-
273
- msgid "All %ss were updated"
274
- msgstr ""
275
-
276
- msgid "Close"
277
- msgstr ""
278
-
279
- msgid "This View does not list posts"
280
- msgstr ""
281
-
282
- msgid "Filter MetaHTML is empty"
283
- msgstr ""
284
-
285
- msgid "Something on the filter_controls_mode is broken"
286
- msgstr ""
287
-
288
- msgid "post relationship"
289
- msgstr ""
290
-
291
- msgid "Your View contains more URL based filters than parametric search controls in the Filter HTML textarea"
292
- msgstr ""
293
-
294
- msgid "Your View contains more parametric search controls in the Filter HTML textarea than URL based filters"
295
- msgstr ""
296
-
297
- msgid "Cancel"
298
- msgstr ""
299
-
300
- msgid "Add New Content Template"
301
- msgstr ""
302
-
303
- msgid "Edit Content Template"
304
- msgstr ""
305
-
306
- msgid "New Content Template"
307
- msgstr ""
308
-
309
- msgid "View Views-Templates"
310
- msgstr ""
311
-
312
- msgid "Search Content Templates"
313
- msgstr ""
314
-
315
- msgid "No Content Templates found"
316
- msgstr ""
317
-
318
- msgid "No Content Templates found in Trash"
319
- msgstr ""
320
-
321
- msgid "Content Template"
322
- msgstr ""
323
-
324
- msgid "None"
325
- msgstr ""
326
-
327
- msgid "<strong>Content template debug: </strong>Calling function is <strong>%s</strong>"
328
- msgstr ""
329
-
330
- msgid "Insert Views Shortcode"
331
- msgstr ""
332
-
333
- msgid "Convert URLs to point to translated content in Views and Content Templates"
334
- msgstr ""
335
-
336
- msgid "Save"
337
- msgstr ""
338
-
339
- msgid "Settings Saved"
340
- msgstr ""
341
-
342
- msgid "A View loads content from the database and displays it anyway you choose."
343
- msgstr ""
344
-
345
- msgid "The Query section lets you choose the content to load."
346
- msgstr ""
347
-
348
- msgid "A basic query selects all items of a chosen type."
349
- msgstr ""
350
-
351
- msgid "You can refine the selection by adding filters."
352
- msgstr ""
353
-
354
- msgid "At the bottom of this page you will find the Layout section, where you control the output."
355
- msgstr ""
356
-
357
- msgid "The Front-end Filter section includes the pagination controls, allowing visitors to choose which results page to show."
358
- msgstr ""
359
-
360
- msgid "Creating paginated listings with Views"
361
- msgstr ""
362
-
363
- msgid "The Front-end Filter section includes the slider controls, allowing visitors switch between slides."
364
- msgstr ""
365
-
366
- msgid "At the bottom of this page you will find a slide Content Template, where you design slides."
367
- msgstr ""
368
-
369
- msgid "Creating sliders with Views"
370
- msgstr ""
371
-
372
- msgid "Building a View for a parametric search:"
373
- msgstr ""
374
-
375
- msgid "Select which content to load in the 'Content selection' section."
376
- msgstr ""
377
-
378
- msgid "Add filter inputs to the 'Filter HTML/CSS/JS' section."
379
- msgstr ""
380
-
381
- msgid "Select advanced search options in the 'Parametric search settings' section."
382
- msgstr ""
383
-
384
- msgid "Design the search results output in the 'Layout HTML/CSS/JS' section."
385
- msgstr ""
386
-
387
- msgid "Remember to click on Update after you complete each section and before you continue to the next section."
388
- msgstr ""
389
-
390
- msgid "Creating parametric searches with Views"
391
- msgstr ""
392
-
393
- msgid "The Front-end filter section lets you add pagination, slider controls and parametric search to the View."
394
- msgstr ""
395
-
396
- msgid "The pagination section lets you break the results into separate pages."
397
- msgstr ""
398
-
399
- msgid "This way, you can display a large number of results, in shorter pages."
400
- msgstr ""
401
-
402
- msgid "You can insert next/previous links and page selectors, for navigating directly to a specific page."
403
- msgstr ""
404
-
405
- msgid "The first part of this section lets you choose how pagination works."
406
- msgstr ""
407
-
408
- msgid "Select how many results to show in each page and how pages transition."
409
- msgstr ""
410
-
411
- msgid "The second part of this section lets you design the pagination controls that would appear on the page for visitors."
412
- msgstr ""
413
-
414
- msgid "The toolbar above the HTML editor includes buttons for inserting various controls."
415
- msgstr ""
416
-
417
- msgid "Besides pagination, you can also insert parametric search filters and content search controls."
418
- msgstr ""
419
-
420
- msgid "The pagination section lets you build sliders with Views."
421
- msgstr ""
422
-
423
- msgid "The View will display each slide at a time and allow visitors to switch between slides using next/previous links and slide selectors."
424
- msgstr ""
425
-
426
- msgid "The first part of this section lets you choose how the slider pagination works."
427
- msgstr ""
428
-
429
- msgid "Select how many results to show in each slide and how slides transition."
430
- msgstr ""
431
-
432
- msgid "The second part of this section lets you design the transition controls for the slider."
433
- msgstr ""
434
-
435
- msgid "The toolbar above the HTML editor includes buttons for inserting the slide transition controls."
436
- msgstr ""
437
-
438
- msgid "Using pagination you can also implement sliders."
439
- msgstr ""
440
-
441
- msgid "Learn how to create sliders with Views."
442
- msgstr ""
443
-
444
- msgid "Besides pagination and slider transition controls, you can also insert parametric search filters and content search controls."
445
- msgstr ""
446
-
447
- msgid "Learn how to create parametric searches with Views."
448
- msgstr ""
449
-
450
- msgid "To create a parametric search, position the cursor between the %s and %s shortcodes and click on the ‘Filters’ button to insert filter elements."
451
- msgstr ""
452
-
453
- msgid "Your parametric search can contain any custom field or taxonomy that this View queries."
454
- msgstr ""
455
-
456
- msgid "You can also click on the \"Search\" button to add a search box for visitors"
457
- msgstr ""
458
-
459
- msgid "Use HTML and CSS to style the filter."
460
- msgstr ""
461
-
462
- msgid "Remember to include the ‘Submit’ button for the form."
463
- msgstr ""
464
-
465
- msgid "This View uses pagination, but pagination controls are still not inserted into the filter HTML section."
466
- msgstr ""
467
-
468
- msgid "Would you like to insert them now?"
469
- msgstr ""
470
-
471
- msgid "Automatically insert pagination controls"
472
- msgstr ""
473
-
474
- msgid "No - I will add pagination controls manually"
475
- msgstr ""
476
-
477
- msgid "This View uses AJAX pagination to implement a slider."
478
- msgstr ""
479
-
480
- msgid "However, pagination controls are still not inserted into the filter HTML section."
481
- msgstr ""
482
-
483
- msgid "We've just inserted shortcodes that display the pagination."
484
- msgstr ""
485
-
486
- msgid "You will see the following shortcodes inside the filter HTML box below."
487
- msgstr ""
488
-
489
- msgid "To style the pagination, add your HTML around the pagination shortcodes."
490
- msgstr ""
491
-
492
- msgid "You can always insert these shortcodes manually by clicking on the ‘Pagination’ button below."
493
- msgstr ""
494
-
495
- msgid "The layout HTML box lets you output your View results and style them on your page."
496
- msgstr ""
497
-
498
- msgid "Click on the Layout Wizard to select the style of your Views loop and the fields you want to display."
499
- msgstr ""
500
-
501
- msgid "You can also insert fields manually by positioning the cursor inside between the %s and %s tags, and clicking on the Fields button."
502
- msgstr ""
503
-
504
- msgid "The Content Template button will let you add, or even create, a Content template to insert directly into your view."
505
- msgstr ""
506
-
507
- msgid "Learn more about layouts and building your View loop"
508
- msgstr ""
509
-
510
- msgid "Layout wizard"
511
- msgstr ""
512
-
513
- msgid "a guided wizard that lets you create layouts, with different styles and content."
514
- msgstr ""
515
-
516
- msgid "Recommended if you are new to Views."
517
- msgstr ""
518
-
519
- msgid "once you know how the layout loop works, add any field to it, using any formating style."
520
- msgstr ""
521
-
522
- msgid "Good for building your own unique loops."
523
- msgstr ""
524
-
525
- msgid "add complete blocks into the View loop using Content Templates."
526
- msgstr ""
527
-
528
- msgid "This method makes it easy to create complex layouts with simple editing."
529
- msgstr ""
530
-
531
- msgid "Media"
532
- msgstr ""
533
-
534
- msgid "add images and other media items to the View."
535
- msgstr ""
536
-
537
- msgid "Besides these buttons, you can edit the HTML content yourself by writing your own HTML and CSS."
538
- msgstr ""
539
-
540
- msgid "The View will iterate through the the results and display them one by one."
541
- msgstr ""
542
-
543
- msgid "Learn more by reading the %sViews Loop documentation%s."
544
- msgstr ""
545
-
546
- msgid "Hide these instructions"
547
- msgstr ""
548
-
549
- msgid "The Layout Wizard just added shortcodes for the fields that you selected to the HTML box."
550
- msgstr ""
551
-
552
- msgid "See how the shortcodes appear inside the loop."
553
- msgstr ""
554
-
555
- msgid "You can change the appearance by adding HTML and CSS around these shortcodes."
556
- msgstr ""
557
-
558
- msgid "You can add HTML code, fields, media and entire Content Templates to the editor."
559
- msgstr ""
560
-
561
- msgid "You just added a shortcode for a Content Template to this View."
562
- msgstr ""
563
-
564
- msgid "A Content Template works like a subroutine."
565
- msgstr ""
566
-
567
- msgid "You can edit its content in one place and use it in several places in the View."
568
- msgstr ""
569
-
570
- msgid "You just connected a Content Template to this View."
571
- msgstr ""
572
-
573
- msgid "Edit the new Content Template"
574
- msgstr ""
575
-
576
- msgid "This Content Template lets you design slides in this slider. Add any field you need to display and design them using HTML and CSS. To style the slide transition controls, scroll up the the filter section."
577
- msgstr ""
578
-
579
- msgid "This Content Template lets you design how each item in this grid will be displayed. A default shortcode that displays the post link has been added. You can edit this and add any field you need to display and design them using HTML and CSS."
580
- msgstr ""
581
-
582
- msgid "To change what gets displayed, scroll up the the filter section."
583
- msgstr ""
584
-
585
- msgid "You are viewing the read-only version of this View. To edit it, you need to get Views plugin."
586
- msgstr ""
587
-
588
- msgid "Get Views"
589
- msgstr ""
590
-
591
- msgid "You are viewing the read-only version of this Content Template. To edit it, you need to get Views plugin."
592
- msgstr ""
593
-
594
- msgid "This Content Template replaces the content area of the posts that you assign it to."
595
- msgstr ""
596
-
597
- msgid "It can be used to tweak the content of a post when it is displayed alone or in an archive page."
598
- msgstr ""
599
-
600
- msgid "You can also call this Template using a shortcode [wpv-post-body view_template=\"XX\"] to render specific information about the current post."
601
- msgstr ""
602
-
603
- msgid "You can add shortcodes to post fields, and also your own HTML and CSS to style the fields and design the page template."
604
- msgstr ""
605
-
606
- msgid "Content Template documentation"
607
- msgstr ""
608
-
609
- msgid "TwoYou are viewing the read-only version of this WordPress Archive. To edit it, you need to get Views plugin."
610
- msgstr ""
611
-
612
- msgid "This WordPress Archive replaces the natural archive loops created by WordPress."
613
- msgstr ""
614
-
615
- msgid "WordPress Archives documentation"
616
- msgstr ""
617
-
618
- msgid "OneYou are viewing the read-only version of this WordPress Archive. To edit it, you need to get Views plugin."
619
- msgstr ""
620
-
621
- msgid "Views will provide a Layout Wizard to select the style of your Views loop and the fields you want to display."
622
- msgstr ""
623
-
624
- msgid "You can also insert fields manually."
625
- msgstr ""
626
-
627
- msgid "The full Views plugin will let you add, or even create, a Content template to insert directly into your Layout."
628
- msgstr ""
629
-
630
- msgid "Besides these helpers, you can edit the HTML content yourself by writing your own HTML and CSS."
631
- msgstr ""
632
-
633
- msgid "Title and description"
634
- msgstr ""
635
-
636
- msgid "Each View has a title and an optional description. These are used for you, to identify different Views. The title and the description don't appear anywhere on the site's public pages."
637
- msgstr ""
638
-
639
- msgid "Content to load"
640
- msgstr ""
641
-
642
- msgid "Choose between posts, taxonomy and users and then select the specific content type to load. For posts, you can select multiple content types."
643
- msgstr ""
644
-
645
- msgid "Query options"
646
- msgstr ""
647
-
648
- msgid "This section includes additional options for what content to load. You will see different options for posts, taxonomy and users."
649
- msgstr ""
650
-
651
- msgid "Ordering"
652
- msgstr ""
653
-
654
- msgid "Choose how to order the results that the View gets from the database. You can select the sorting key and direction."
655
- msgstr ""
656
-
657
- msgid "Limit and offset"
658
- msgstr ""
659
-
660
- msgid "You can limit the number of results returned by the query and set an offset. Please note that this option is not intended for pagination and sliders, but for static limit and offset settings."
661
- msgstr ""
662
-
663
- msgid "Query filter"
664
- msgstr ""
665
-
666
- msgid "You can filter the View query by status, custom fields, taxonomy, users fields and even content search depending on the content that you are going to load. Click on 'Add another filter' and then select the filter type. A View may have as many filters as you like."
667
- msgstr ""
668
-
669
- msgid "Pagination and sliders settings"
670
- msgstr ""
671
-
672
- msgid "You can use a View to display paginated results and sliders. Both are built using 'Pagination'. For paginated listings, choose to update the entire page. For sliders, choose to update only the View."
673
- msgstr ""
674
-
675
- msgid "Filter HTML/CSS/JS"
676
- msgstr ""
677
-
678
- msgid "In this section you can add pagination controls, slider controls and parametric searches. If you enabled pagination, you need to insert the pagination controls here. They are used for both paged results and sliders. For parametric searches, insert 'filter' elements. The output of this section is displayed via the [wpv-filter-meta-html] shortcode in the Combined Output section."
679
- msgstr ""
680
-
681
- msgid "Parametric search"
682
- msgstr ""
683
-
684
- msgid "In this section you can choose when to refresh the Views results and which options to show in form inputs."
685
- msgstr ""
686
-
687
- msgid "View HTML output"
688
- msgstr ""
689
-
690
- msgid "This HTML determines what the View outputs for the query results. Use the Layout wizard to create a new layout. Then, edit it by adding fields, HTML, media and anything else in the toolbar. The output of this section is displayed via the [wpv-layout-meta-html] in the Combined Output section."
691
- msgstr ""
692
-
693
- msgid "Templates for this View"
694
- msgstr ""
695
-
696
- msgid "A View may include templates. These templates make it easy to output complex structures without having to repeat them in the View HTML. Click on the 'Content Template' button in the Layout HTML section to add Content Templates here."
697
- msgstr ""
698
-
699
- msgid "Combined Output"
700
- msgstr ""
701
-
702
- msgid "This HTML box lets you control how the Filter and Layout sections of this Views are displayed. The [wpv-filter-meta-html] shortcode displays the output of the Filter section. The [wpv-layout-meta-html] shortcode displays the output of the Layout section. You can add your HTML and fields to rearrange and style the output."
703
- msgstr ""
704
-
705
- msgid "Loop selection"
706
- msgstr ""
707
-
708
- msgid "Choose which listing page to customize. The WordPress archive will display the exact same content as WordPress normally does, but you can design it using the View HTML."
709
- msgstr ""
710
-
711
- msgid "Module Manager"
712
- msgstr ""
713
-
714
- msgid "With Modules, you can easily reuse your designs in different websites and create your own library of building blocks."
715
- msgstr ""
716
-
717
- msgid "Home/Blog"
718
- msgstr ""
719
-
720
- msgid "Search results"
721
- msgstr ""
722
-
723
- msgid "Author archives"
724
- msgstr ""
725
-
726
- msgid "Year archives"
727
- msgstr ""
728
-
729
- msgid "Month archives"
730
- msgstr ""
731
-
732
- msgid "Day archives"
733
- msgstr ""
734
-
735
- msgid "%s using \"%s\""
736
- msgstr ""
737
-
738
- msgid "There are no Views being used for Post Type archive loops."
739
- msgstr ""
740
-
741
- msgid "Edit"
742
- msgstr ""
743
-
744
- msgid "Create a new View for this listing page"
745
- msgstr ""
746
-
747
- msgid "There are no Views being used for Taxonomy archive loops."
748
- msgstr ""
749
-
750
- msgid "post type <strong>%s</strong>"
751
- msgstr ""
752
-
753
- msgid "taxonomy <strong>%s</strong>"
754
- msgstr ""
755
-
756
- msgid "This View isn't being used for any archive loops."
757
- msgstr ""
758
-
759
- msgid "This View is being used for these archive loops: %s"
760
- msgstr ""
761
-
762
- msgid "OK"
763
- msgstr ""
764
-
765
- msgid "<span style=\"color:red\">*</span> A different WordPress Archive is already assigned to this item"
766
- msgstr ""
767
-
768
- msgid "A WordPress Archive with that name already exists. Please use another name."
769
- msgstr ""
770
-
771
- msgid "Loop"
772
- msgstr ""
773
-
774
- msgid "Use this View"
775
- msgstr ""
776
-
777
- msgid "Use this View for these archive loops:"
778
- msgstr ""
779
-
780
- msgid "Post type loops"
781
- msgstr ""
782
-
783
- msgid "Taxonomy loops"
784
- msgstr ""
785
-
786
- msgid "Add new WordPress Archive"
787
- msgstr ""
788
-
789
- msgid "What loop will this Archive be used for?"
790
- msgstr ""
791
-
792
- msgid "WordPress Native Archives"
793
- msgstr ""
794
-
795
- msgid "Post Type Archives"
796
- msgstr ""
797
-
798
- msgid "Taxonomy Archives"
799
- msgstr ""
800
-
801
- msgid "Name this WordPress Archive"
802
- msgstr ""
803
-
804
- msgid "WordPress Archive name"
805
- msgstr ""
806
-
807
- msgid "Add new Archive"
808
- msgstr ""
809
-
810
- msgid "Accept"
811
- msgstr ""
812
-
813
- msgid "custom field"
814
- msgstr ""
815
-
816
- msgid "taxonomy"
817
- msgstr ""
818
-
819
- msgid "The url_param is missing from the wpv-control shortcode argument."
820
- msgstr ""
821
-
822
- msgid "The \"type\" or \"field\" needs to be set in the wpv-control shortcode argument."
823
- msgstr ""
824
-
825
- msgid "Types plugin is required."
826
- msgstr ""
827
-
828
- msgid "Empty field values or incorrect field defined. "
829
- msgstr ""
830
-
831
- msgid "Select date"
832
- msgstr ""
833
-
834
- msgid "You need the Types plugin to render this parametric search control"
835
- msgstr ""
836
-
837
- msgid "The url_param argument is missing from the wpv-control-set shortcode."
838
- msgstr ""
839
-
840
- msgid "The ancestors argument is missing from the wpv-control-set shortcode."
841
- msgstr ""
842
-
843
- msgid "The type argument needs to be set in the wpv-control-item shortcode."
844
- msgstr ""
845
-
846
- msgid "The ancestor_type argument is missing from the wpv-control-item shortcode."
847
- msgstr ""
848
-
849
- msgid "The post types listed in this View do not have ancestors."
850
- msgstr ""
851
-
852
- msgid "The ancestor_type argument refers to a post type that is not included in the ancestors tree."
853
- msgstr ""
854
-
855
- msgid "The ancestors argument does not end with a valid parent for the returned post types on this View."
856
- msgstr ""
857
-
858
- msgid "There seems to be some kind of infinite loop happening."
859
- msgstr ""
860
-
861
- msgid "Reset"
862
- msgstr ""
863
-
864
- msgid "This View uses an auxiliar query: it has pagination and limit&offset settings, and WordPress can not perform a single Query to handle both."
865
- msgstr ""
866
-
867
- msgid "Export"
868
- msgstr ""
869
-
870
- msgid "Import"
871
- msgstr ""
872
-
873
- msgid "Could not read the Views import file."
874
- msgstr ""
875
-
876
- msgid "Unable to open zip file"
877
- msgstr ""
878
-
879
- msgid "The Simple XML library is missing."
880
- msgstr ""
881
-
882
- msgid "The XML file (%s) could not be read."
883
- msgstr ""
884
-
885
- msgid "The XML could not be read."
886
- msgstr ""
887
-
888
- msgid "Failed to update view-template - %s."
889
- msgstr ""
890
-
891
- msgid "Failed to update Content Template - %s."
892
- msgstr ""
893
-
894
- msgid "Failed to create Content Template - %s."
895
- msgstr ""
896
-
897
- msgid "%d Content Templates found in the file. %d have been created and %d have been over written."
898
- msgstr ""
899
-
900
- msgid "%d existing Content Templates were deleted."
901
- msgstr ""
902
-
903
- msgid "Failed to update view - %s."
904
- msgstr ""
905
-
906
- msgid "Failed to create view - %s."
907
- msgstr ""
908
-
909
- msgid "%d Views found in the file. %d have been created and %d have been over written."
910
- msgstr ""
911
-
912
- msgid "%d existing Views were deleted."
913
- msgstr ""
914
-
915
- msgid "This Views have filters by IDs that were not correctly imported because they filter by posts that do not exist. Please review them: "
916
- msgstr ""
917
-
918
- msgid "This Views filter by post IDs using a shortcode attribute. You may need to modify the Views shortcodes if post IDs have changed during import: "
919
- msgstr ""
920
-
921
- msgid "%s could not be found"
922
- msgstr ""
923
-
924
- msgid "Settings updated"
925
- msgstr ""
926
-
927
- msgid "WordPress Archives and Content Templates settings updated"
928
- msgstr ""
929
-
930
- msgid "Import Views, WordPress Archives and Content Templates for your Theme"
931
- msgstr ""
932
-
933
- msgid "Import Views, WordPress Archives and Content Templates"
934
- msgstr ""
935
-
936
- msgid "Settings"
937
- msgstr ""
938
-
939
- msgid "Bulk overwrite if View or WordPress Archive exists"
940
- msgstr ""
941
-
942
- msgid "Delete any existing Views or WordPress Archives that are not in the import"
943
- msgstr ""
944
-
945
- msgid "Bulk overwrite if Content Template exists"
946
- msgstr ""
947
-
948
- msgid "Delete any existing Content Templates that are not in the import"
949
- msgstr ""
950
-
951
- msgid "Overwrite Views settings"
952
- msgstr ""
953
-
954
- msgid "Import the Views XML file placed in the Views Embedded folder"
955
- msgstr ""
956
-
957
- msgid "Select the Views XML file to upload from your computer"
958
- msgstr ""
959
-
960
- msgid "Upload file"
961
- msgstr ""
962
-
963
- msgid "Content Templates"
964
- msgstr ""
965
-
966
- msgid "Error during View import"
967
- msgstr ""
968
-
969
- msgid "Error during Content Template import"
970
- msgstr ""
971
-
972
- msgid "Views elements in this Module"
973
- msgstr ""
974
-
975
- msgid "Page %s"
976
- msgstr ""
977
-
978
- msgid "Current post body"
979
- msgstr ""
980
-
981
- msgid "Title"
982
- msgstr ""
983
-
984
- msgid "ID"
985
- msgstr ""
986
-
987
- msgid "Name"
988
- msgstr ""
989
-
990
- msgid "User"
991
- msgstr ""
992
-
993
- msgid "Object received from cache. MySQL query was cached in"
994
- msgstr ""
995
-
996
- msgid "Enable line breaks"
997
- msgstr ""
998
-
999
- msgid "Enable syntax higlighter"
1000
- msgstr ""
1001
-
1002
- msgid "Notice: Syntax higlighter can cause performance issues for large blocks of code"
1003
- msgstr ""
1004
-
1005
- msgid "Page info"
1006
- msgstr ""
1007
-
1008
- msgid "Current page"
1009
- msgstr ""
1010
-
1011
- msgid "Total memory used"
1012
- msgstr ""
1013
-
1014
- msgid "Render time"
1015
- msgstr ""
1016
-
1017
- msgid "Total MySQL queries"
1018
- msgstr ""
1019
-
1020
- msgid "CPU usage"
1021
- msgstr ""
1022
-
1023
- msgid "Elements info"
1024
- msgstr ""
1025
-
1026
- msgid "Post body"
1027
- msgstr ""
1028
-
1029
- msgid "WordPress Archive"
1030
- msgstr ""
1031
-
1032
- msgid "Kind of element"
1033
- msgstr ""
1034
-
1035
- msgid "Memory used"
1036
- msgstr ""
1037
-
1038
- msgid "Summary"
1039
- msgstr ""
1040
-
1041
- msgid "Additional info"
1042
- msgstr ""
1043
-
1044
- msgid "Query args"
1045
- msgstr ""
1046
-
1047
- msgid "Loading"
1048
- msgstr ""
1049
-
1050
- msgid "Hide"
1051
- msgstr ""
1052
-
1053
- msgid "Show"
1054
- msgstr ""
1055
-
1056
- msgid "MySQL query"
1057
- msgstr ""
1058
-
1059
- msgid "Items found"
1060
- msgstr ""
1061
-
1062
- msgid "Query results"
1063
- msgstr ""
1064
-
1065
- msgid "Filters"
1066
- msgstr ""
1067
-
1068
- msgid "Loop"
1069
- msgstr ""
1070
-
1071
- msgid "Template results"
1072
- msgstr ""
1073
-
1074
- msgid "Post body data"
1075
- msgstr ""
1076
-
1077
- msgid "Received array"
1078
- msgstr ""
1079
-
1080
- msgid "Original content"
1081
- msgstr ""
1082
-
1083
- msgid "Shortcodes"
1084
- msgstr ""
1085
-
1086
- msgid "Attributes"
1087
- msgstr ""
1088
-
1089
- msgid "Query"
1090
- msgstr ""
1091
-
1092
- msgid "Info"
1093
- msgstr ""
1094
-
1095
- msgid "Output"
1096
- msgstr ""
1097
-
1098
- msgid "Nested elements"
1099
- msgstr ""
1100
-
1101
- msgid "Output (RAW)"
1102
- msgstr ""
1103
-
1104
- msgid "Views/Content Templates debug information"
1105
- msgstr ""
1106
-
1107
- msgid "You attempted to edit a View that doesn&#8217;t exist. Perhaps it was deleted?"
1108
- msgstr ""
1109
-
1110
- msgid "You can�t edit this View because it is in the Trash. Please restore it and try again."
1111
- msgstr ""
1112
-
1113
- msgid "Preview View"
1114
- msgstr ""
1115
-
1116
- msgid "Learn how to display Views"
1117
- msgstr ""
1118
-
1119
- msgid "Preview Content Template"
1120
- msgstr ""
1121
-
1122
- msgid "Preview WordPress Archive"
1123
- msgstr ""
1124
-
1125
- msgid "Preview Layouts Loop View"
1126
- msgstr ""
1127
-
1128
- msgid " (post type archive)"
1129
- msgstr ""
1130
-
1131
- msgid " (taxonomy archive)"
1132
- msgstr ""
1133
-
1134
- msgid "This View loads <strong>%s</strong>"
1135
- msgstr ""
1136
-
1137
- msgid "Results are "
1138
- msgstr ""
1139
-
1140
- msgid "Select posts with custom field:"
1141
- msgstr ""
1142
-
1143
- msgid "Select posts with taxonomy:"
1144
- msgstr ""
1145
-
1146
- msgid "Select users with usermeta field:"
1147
- msgstr ""
1148
-
1149
- msgid ""
1150
- msgstr ""
1151
-
1152
- msgid "Slug of this View: "
1153
- msgstr ""
1154
-
1155
- msgid "The query section determines what content the View loads from the database"
1156
- msgstr ""
1157
-
1158
- msgid "The filter section lets you set up pagination and parametric search, which let visitors control the View query"
1159
- msgstr ""
1160
-
1161
- msgid "The layout section styles the View output on the page."
1162
- msgstr ""
1163
-
1164
- msgid "What to see this in action?"
1165
- msgstr ""
1166
-
1167
- msgid "Slug of this Content Template: "
1168
- msgstr ""
1169
-
1170
- msgid "Slug of this WordPress Archive: "
1171
- msgstr ""
1172
-
1173
- msgid "The loop section determines which listing page to customize"
1174
- msgstr ""
1175
-
1176
- msgid "This WordPress Archive is not used on any archive loops"
1177
- msgstr ""
1178
-
1179
- msgid "This WordPress Archive is used in the following archive loops: "
1180
- msgstr ""
1181
-
1182
- msgid "Content selection"
1183
- msgstr ""
1184
-
1185
- msgid "No filters set"
1186
- msgstr ""
1187
-
1188
- msgid "Pagination and Slider settings"
1189
- msgstr ""
1190
-
1191
- msgid "Filter HTML"
1192
- msgstr ""
1193
-
1194
- msgid "Layout HTML"
1195
- msgstr ""
1196
-
1197
- msgid "Insert search form from View - %s"
1198
- msgstr ""
1199
-
1200
- msgid "No target posts were found that use this View"
1201
- msgstr ""
1202
-
1203
- msgid "You first need to insert the View named %s in a post or page to show its results"
1204
- msgstr ""
1205
-
1206
- msgid "When the form is submitted, go to the results page:"
1207
- msgstr ""
1208
-
1209
- msgid "Insert shortcode"
1210
- msgstr ""
1211
-
1212
- msgid "Insert translatable string"
1213
- msgstr ""
1214
-
1215
- msgid "Insert search term shortcode"
1216
- msgstr ""
1217
-
1218
- msgid "Delete"
1219
- msgstr ""
1220
-
1221
- msgid "String to translate"
1222
- msgstr ""
1223
-
1224
- msgid "WPML context"
1225
- msgstr ""
1226
-
1227
- msgid "URL parameter to watch (optional)"
1228
- msgstr ""
1229
-
1230
- msgid "Slug"
1231
- msgstr ""
1232
-
1233
- msgid "Title with a link"
1234
- msgstr ""
1235
-
1236
- msgid "Body"
1237
- msgstr ""
1238
-
1239
- msgid "Excerpt"
1240
- msgstr ""
1241
-
1242
- msgid "Author"
1243
- msgstr ""
1244
-
1245
- msgid "Date"
1246
- msgstr ""
1247
-
1248
- msgid "URL"
1249
- msgstr ""
1250
-
1251
- msgid "Featured image"
1252
- msgstr ""
1253
-
1254
- msgid "Comments number"
1255
- msgstr ""
1256
-
1257
- msgid "Edit Link"
1258
- msgstr ""
1259
-
1260
- msgid "Post type"
1261
- msgstr ""
1262
-
1263
- msgid "Post status"
1264
- msgstr ""
1265
-
1266
- msgid "Post class"
1267
- msgstr ""
1268
-
1269
- msgid "Comment title"
1270
- msgstr ""
1271
-
1272
- msgid "Comment body"
1273
- msgstr ""
1274
-
1275
- msgid "Comment Author"
1276
- msgstr ""
1277
-
1278
- msgid "Comment Date"
1279
- msgstr ""
1280
-
1281
- msgid "Taxonomy title"
1282
- msgstr ""
1283
-
1284
- msgid "Taxonomy title with a link"
1285
- msgstr ""
1286
-
1287
- msgid "Taxonomy URL"
1288
- msgstr ""
1289
-
1290
- msgid "Taxonomy slug"
1291
- msgstr ""
1292
-
1293
- msgid "Taxonomy description"
1294
- msgstr ""
1295
-
1296
- msgid "Taxonomy post count"
1297
- msgstr ""
1298
-
1299
- msgid "Taxonomy page info"
1300
- msgstr ""
1301
-
1302
- msgid "Bloginfo value"
1303
- msgstr ""
1304
-
1305
- msgid "Search term"
1306
- msgstr ""
1307
-
1308
- msgid "Archive link"
1309
- msgstr ""
1310
-
1311
- msgid "Current user info"
1312
- msgstr ""
1313
-
1314
- msgid "Show user data"
1315
- msgstr ""
1316
-
1317
- msgid "Add to cart button"
1318
- msgstr ""
1319
-
1320
- msgid "Add to cart box"
1321
- msgstr ""
1322
-
1323
- msgid "Edit "
1324
- msgstr ""
1325
-
1326
- msgid "Edit This"
1327
- msgstr ""
1328
-
1329
- msgid "No Comments"
1330
- msgstr ""
1331
-
1332
- msgid "1 Comment"
1333
- msgstr ""
1334
-
1335
- msgid "% Comments"
1336
- msgstr ""
1337
-
1338
- msgid "Content template"
1339
- msgstr ""
1340
-
1341
- msgid "Archive"
1342
- msgstr ""
1343
-
1344
- msgid "Parametric search form"
1345
- msgstr ""
1346
-
1347
- msgid "Category"
1348
- msgstr ""
1349
-
1350
- msgid "all post types"
1351
- msgstr ""
1352
-
1353
- msgid "All post types"
1354
- msgstr ""
1355
-
1356
- msgid "%s"
1357
- msgstr ""
1358
-
1359
- msgid "terms of the taxonomy %s"
1360
- msgstr ""
1361
-
1362
- msgid "This View selects terms of the taxonomy %s"
1363
- msgstr ""
1364
-
1365
- msgid "terms of a taxonomy that no longer exists"
1366
- msgstr ""
1367
-
1368
- msgid "This View selects terms of a taxonomy that no longer exists"
1369
- msgstr ""
1370
-
1371
- msgid "users with any role"
1372
- msgstr ""
1373
-
1374
- msgid "users with role %s"
1375
- msgstr ""
1376
-
1377
- msgid "This View selects users with any role"
1378
- msgstr ""
1379
-
1380
- msgid "This View selects users with role %s"
1381
- msgstr ""
1382
-
1383
- msgid "post date"
1384
- msgstr ""
1385
-
1386
- msgid "post title"
1387
- msgstr ""
1388
-
1389
- msgid "post ID"
1390
- msgstr ""
1391
-
1392
- msgid "menu order"
1393
- msgstr ""
1394
-
1395
- msgid "random order"
1396
- msgstr ""
1397
-
1398
- msgid "Field - %s"
1399
- msgstr ""
1400
-
1401
- msgid "descending"
1402
- msgstr ""
1403
-
1404
- msgid "ascending"
1405
- msgstr ""
1406
-
1407
- msgid "term count"
1408
- msgstr ""
1409
-
1410
- msgid "term name"
1411
- msgstr ""
1412
-
1413
- msgid "term slug"
1414
- msgstr ""
1415
-
1416
- msgid "term group"
1417
- msgstr ""
1418
-
1419
- msgid "no specific criteria"
1420
- msgstr ""
1421
-
1422
- msgid "user login"
1423
- msgstr ""
1424
-
1425
- msgid "user ID"
1426
- msgstr ""
1427
-
1428
- msgid "user name"
1429
- msgstr ""
1430
-
1431
- msgid "display name"
1432
- msgstr ""
1433
-
1434
- msgid "user nicename"
1435
- msgstr ""
1436
-
1437
- msgid "user email"
1438
- msgstr ""
1439
-
1440
- msgid "user url"
1441
- msgstr ""
1442
-
1443
- msgid "user registered date"
1444
- msgstr ""
1445
-
1446
- msgid "user post count"
1447
- msgstr ""
1448
-
1449
- msgid "ordered by <strong>%s</strong> in <strong>%s</strong> order"
1450
- msgstr ""
1451
-
1452
- msgid " ordered by %s, %s"
1453
- msgstr ""
1454
-
1455
- msgid "All results loaded"
1456
- msgstr ""
1457
-
1458
- msgid "Fade"
1459
- msgstr ""
1460
-
1461
- msgid "Slide horizontally"
1462
- msgstr ""
1463
-
1464
- msgid "Slide vertically"
1465
- msgstr ""
1466
-
1467
- msgid "Slide Left"
1468
- msgstr ""
1469
-
1470
- msgid "Slide Right"
1471
- msgstr ""
1472
-
1473
- msgid "Slide Up"
1474
- msgstr ""
1475
-
1476
- msgid "Slide Down"
1477
- msgstr ""
1478
-
1479
- msgid "No pagination"
1480
- msgstr ""
1481
-
1482
- msgid "Select posts with <strong>%s</strong> as the <strong>author</strong>."
1483
- msgstr ""
1484
-
1485
- msgid "None set"
1486
- msgstr ""
1487
-
1488
- msgid "Select posts with the author's <strong>%s</strong> determined by the URL parameter <strong>\"%s\"</strong>"
1489
- msgstr ""
1490
-
1491
- msgid " eg. yoursite/page-with-this-view/?<strong>%s</strong>=%s"
1492
- msgstr ""
1493
-
1494
- msgid "Select posts which author's <strong>%s</strong> is set by the View shortcode attribute <strong>\"%s\"</strong>"
1495
- msgstr ""
1496
-
1497
- msgid " eg. [wpv-view name=\"%s\" <strong>%s</strong>=\"%s\"]"
1498
- msgstr ""
1499
-
1500
- msgid " OR"
1501
- msgstr ""
1502
-
1503
- msgid " AND"
1504
- msgstr ""
1505
-
1506
- msgid " OR "
1507
- msgstr ""
1508
-
1509
- msgid " AND "
1510
- msgstr ""
1511
-
1512
- msgid "Categories"
1513
- msgstr ""
1514
-
1515
- msgid "is <strong>One</strong> of these"
1516
- msgstr ""
1517
-
1518
- msgid "is <strong>All</strong> of these"
1519
- msgstr ""
1520
-
1521
- msgid "is <strong>Not one</strong> of these"
1522
- msgstr ""
1523
-
1524
- msgid "the same as the <strong>current page</strong>"
1525
- msgstr ""
1526
-
1527
- msgid "set by the View shortcode attribute "
1528
- msgstr ""
1529
-
1530
- msgid "set by the URL parameter "
1531
- msgstr ""
1532
-
1533
- msgid "set by the parent view."
1534
- msgstr ""
1535
-
1536
- msgid "using the operator"
1537
- msgstr ""
1538
-
1539
- msgid "eg. [wpv-view name=\"view-name\" <strong>%s=\"xxxx\"</strong>]"
1540
- msgstr ""
1541
-
1542
- msgid "eg. http://www.example.com/page/?<strong>%s=xxxx</strong>"
1543
- msgstr ""
1544
-
1545
- msgid "Select posts that are <strong>children</strong> of the <strong>Post with ID set by the shortcode attribute %s</strong>."
1546
- msgstr ""
1547
-
1548
- msgid " eg. [wpv-view name=\"view-name\" <strong>%s=\"123\"</strong>]"
1549
- msgstr ""
1550
-
1551
- msgid "Select posts that are <strong>children</strong> of the <strong>Post with ID set by the URL parameter %s</strong>."
1552
- msgstr ""
1553
-
1554
- msgid " eg. http://www.example.com/my-page/?<strong>%s=123</strong>"
1555
- msgstr ""
1556
-
1557
- msgid "Select posts that are children of <strong>%s</strong>."
1558
- msgstr ""
1559
-
1560
- msgid "Include only posts "
1561
- msgstr ""
1562
-
1563
- msgid "Exclude posts "
1564
- msgstr ""
1565
-
1566
- msgid "with the following <strong>IDs</strong>: %s"
1567
- msgstr ""
1568
-
1569
- msgid "with IDs determined by the URL parameter <strong>\"%s\"</strong>"
1570
- msgstr ""
1571
-
1572
- msgid " eg. yoursite/page-with-this-view/?<strong>%s</strong>=1"
1573
- msgstr ""
1574
-
1575
- msgid "which IDs is set by the View shortcode attribute <strong>\"%s\"</strong>"
1576
- msgstr ""
1577
-
1578
- msgid " eg. [wpv-view name=\"%s\" <strong>%s</strong>=\"1\"]"
1579
- msgstr ""
1580
-
1581
- msgid "parent is <strong>%s</strong>"
1582
- msgstr ""
1583
-
1584
- msgid "Select posts whose parent is <strong>%s</strong>."
1585
- msgstr ""
1586
-
1587
- msgid "Select taxonomy whose parent is <strong>%s</strong>."
1588
- msgstr ""
1589
-
1590
- msgid "Filter by <strong>search</strong> term: <strong>%s</strong>"
1591
- msgstr ""
1592
-
1593
- msgid "Filter by this search term: <strong>%s</strong>."
1594
- msgstr ""
1595
-
1596
- msgid "Show a <strong>search box</strong> for visitors"
1597
- msgstr ""
1598
-
1599
- msgid "Show a <strong>search box</strong> for visitors."
1600
- msgstr ""
1601
-
1602
- msgid "Filter by <strong>search box</strong>"
1603
- msgstr ""
1604
-
1605
- msgid "The search box will be added <strong>manually</strong>.<br /><code>eg. [wpv-filter-search-box]</code>"
1606
- msgstr ""
1607
-
1608
- msgid "Taxonomy is <strong>One</strong> of these"
1609
- msgstr ""
1610
-
1611
- msgid "Taxonomy is set by the current page"
1612
- msgstr ""
1613
-
1614
- msgid "Select users <strong>(%s)</strong> who have role <strong>%s</strong>"
1615
- msgstr ""
1616
-
1617
- msgid "Select all users with role <strong>%s</strong>, except of <strong>(%s)</strong>"
1618
- msgstr ""
1619
-
1620
- msgid "Select all users with role <strong>%s</strong>"
1621
- msgstr ""
1622
-
1623
- msgid "Select users with the <strong>%s</strong> determined by the URL parameter <strong>\"%s\"</strong> and with role <strong>\"%s\"</strong>"
1624
- msgstr ""
1625
-
1626
- msgid "Select all users with role <strong>%s</strong>, except of <strong>%s</strong> determined by the URL parameter <strong>\"%s\"</strong>"
1627
- msgstr ""
1628
-
1629
- msgid "Select users with <strong>%s</strong> set by the View shortcode attribute <strong>\"%s\"</strong> and with role <strong>\"%s\"</strong>"
1630
- msgstr ""
1631
-
1632
- msgid "Select all users with role <strong>%s</strong>, except of <strong>%s</strong> set by the View shortcode attribute <strong>\"%s\"</strong>"
1633
- msgstr ""
1634
-
1635
- msgid "status of "
1636
- msgstr ""
1637
-
1638
- msgid "Select posts with status of "
1639
- msgstr ""
1640
-
1641
- msgid " or "
1642
- msgstr ""
1643
-
1644
- msgid "any status."
1645
- msgstr ""
1646
-
1647
- msgid "Do not apply any filter based on status."
1648
- msgstr ""
1649
-
1650
- msgid "Select posts with the <strong>author</strong> the same as the <strong>current logged in user</strong>."
1651
- msgstr ""
1652
-
1653
- msgid "Select posts with the <strong>author set by the parent View</strong>."
1654
- msgstr ""
1655
-
1656
- msgid "Select posts with the <strong>author the same as the current page</strong>."
1657
- msgstr ""
1658
-
1659
- msgid "Select posts that are <strong>children</strong> of the <strong>Post where this View is inserted</strong>."
1660
- msgstr ""
1661
-
1662
- msgid "Select posts that are a <strong>children</strong> of the <strong>Post set by parent View</strong>."
1663
- msgstr ""
1664
-
1665
- msgid "parent is the <strong>current page</strong>"
1666
- msgstr ""
1667
-
1668
- msgid "Select posts whose parent is the <strong>current page</strong>."
1669
- msgstr ""
1670
-
1671
- msgid "Select taxonomy whose parent is the value set by the <strong>parent view</strong>."
1672
- msgstr ""
1673
-
1674
- msgid "Displays a View"
1675
- msgstr ""
1676
-
1677
- msgid "WP Views"
1678
- msgstr ""
1679
-
1680
- msgid "No Views defined. You can add them <a%s>here</a>."
1681
- msgstr ""
1682
-
1683
- msgid "Displays the filter section of a View."
1684
- msgstr ""
1685
-
1686
- msgid "WP Views Filter"
1687
- msgstr ""
1688
-
1689
- msgid "No Views with frontend forms defined. You can add them <a%s>here</a>."
1690
- msgstr ""
1691
-
1692
- msgid "Edit view"
1693
- msgstr ""
1694
-
1695
- msgid "Title:"
1696
- msgstr ""
1697
-
1698
- msgid "View:"
1699
- msgstr ""
1700
-
1701
- msgid "Target page:"
1702
- msgstr ""
1703
-
1704
- msgid "You have <strong>Views</strong> import pending. %sClick here to import%s | %sDismiss this message%s"
1705
- msgstr ""
1706
-
1707
- msgid "Add New View"
1708
- msgstr ""
1709
-
1710
- msgid "Edit View"
1711
- msgstr ""
1712
-
1713
- msgid "New View"
1714
- msgstr ""
1715
-
1716
- msgid "View Views"
1717
- msgstr ""
1718
-
1719
- msgid "Search Views"
1720
- msgstr ""
1721
-
1722
- msgid "No views found"
1723
- msgstr ""
1724
-
1725
- msgid "No views found in Trash"
1726
- msgstr ""
1727
-
1728
- msgid "Embedded View"
1729
- msgstr ""
1730
-
1731
- msgid "Embedded Content Template"
1732
- msgstr ""
1733
-
1734
- msgid "Embedded WordPress Archive"
1735
- msgstr ""
1736
-
1737
- msgid "Import Views for theme"
1738
- msgstr ""
1739
-
1740
- msgid "View not found"
1741
- msgstr ""
1742
-
1743
- msgid "Insert Views Shortcodes"
1744
- msgstr ""
1745
-
1746
- msgid "Thumbnail"
1747
- msgstr ""
1748
-
1749
- msgid "Got it! Don't show this message again"
1750
- msgstr ""
1751
-
1752
- msgid "Getting started"
1753
- msgstr ""
1754
-
1755
- msgid "Views Import"
1756
- msgstr ""
1757
-
1758
- msgid "Views import complete"
1759
- msgstr ""
1760
-
1761
- msgid "WP Views Embedded was <strong>deactivated</strong>! You are already running the complete WP Views plugin, so this one is not needed anymore."
1762
- msgstr ""
1763
-
1764
- msgid "Views are lists and groups of content, like a listing or showcase page. On your theme the following Views are defined:"
1765
- msgstr ""
1766
-
1767
- msgid "Content Templates are applied to pages to create different layouts. On your theme the following Content Templates are defined:"
1768
- msgstr ""
1769
-
1770
- msgid "If you want to edit these or create your own you can purchase the full version of <strong>Views</strong> from %s"
1771
- msgstr ""
1772
-
1773
- msgid "Select one %s"
1774
- msgstr ""
1775
-
1776
- msgid "Any %s"
1777
- msgstr ""
1778
-
1779
- msgid "Types ancestors tree not valid."
1780
- msgstr ""
1781
-
1782
- msgid "Please follow the tip hint below. "
1783
- msgstr ""
1784
-
1785
- msgid "The post types selected in this View do not have Types ancestors"
1786
- msgstr ""
1787
-
1788
- msgid "Post relationship"
1789
- msgstr ""
1790
-
1791
- msgid "The view has been succesfully updated"
1792
- msgstr ""
1793
-
1794
- msgid "Please make a valid selection."
1795
- msgstr ""
1796
-
1797
- msgid "Something bad happend with shortcode building, check the console"
1798
- msgstr ""
1799
-
1800
- msgid "The value for \"Refer to this field as\" is mandatory, please provide one."
1801
- msgstr ""
1802
-
1803
- msgid "Please make a valid tree selection."
1804
- msgstr ""
1805
-
1806
- msgid "This field can not be left empty"
1807
- msgstr ""
1808
-
1809
- msgid "\" is a reserved word for "
1810
- msgstr ""
1811
-
1812
- msgid "Change this value to avoid conflicts"
1813
- msgstr ""
1814
-
1815
- msgid "Error: AJAX returned "
1816
- msgstr ""
1817
-
1818
- msgid "Error: "
1819
- msgstr ""
1820
-
1821
- msgid "There are problems inserting your data. Check the console. "
1822
- msgstr ""
1823
-
1824
- msgid "Please select at least one post type to fiter by."
1825
- msgstr ""
1826
-
1827
- msgid "Something went wrong loading data "
1828
- msgstr ""
1829
-
1830
- msgid "Something went wrong while bulding model."
1831
- msgstr ""
1832
-
1833
- msgid "the same as set by the URL parameter"
1834
- msgstr ""
1835
-
1836
- msgid "Something went wrong in building the filter "
1837
- msgstr ""
1838
-
1839
- msgid "Basic filters"
1840
- msgstr ""
1841
-
1842
- msgid "Select one tree"
1843
- msgstr ""
1844
-
1845
- msgid "Submit button"
1846
- msgstr ""
1847
-
1848
- msgid "Insert input"
1849
- msgstr ""
1850
-
1851
- msgid "Create a submit button for this parametric search."
1852
- msgstr ""
1853
-
1854
- msgid "Clear form"
1855
- msgstr ""
1856
-
1857
- msgid "Consider adding a label before inserting the button."
1858
- msgstr ""
1859
-
1860
- msgid "Spinner"
1861
- msgstr ""
1862
-
1863
- msgid "Place cursor within the [wpv-filter-controls][/wpv-filter-controls] tags."
1864
- msgstr ""
1865
-
1866
- msgid "Place cursor within the [wpv-filter-start][wpv-filter-end] tags."
1867
- msgstr ""
1868
-
1869
- msgid "Place your cursor inside [wpv-control] tags."
1870
- msgstr ""
1871
-
1872
- msgid "You should select a [wpv-control] short tag instead of "
1873
- msgstr ""
1874
-
1875
- msgid "Place your cursor over a [wpv-control] or a [wpv-control-set] tag to edit it."
1876
- msgstr ""
1877
-
1878
- msgid "To edit this filter, place your cursor over the [wpv-control-set] tag."
1879
- msgstr ""
1880
-
1881
- msgid "Warning: the cursor is inside another short code, this may cause problems."
1882
- msgstr ""
1883
-
1884
- msgid "Edit filter field"
1885
- msgstr ""
1886
-
1887
- msgid "Update input"
1888
- msgstr ""
1889
-
1890
- msgid "There are problems inserting the shortcode."
1891
- msgstr ""
1892
-
1893
- msgid "Button label:"
1894
- msgstr ""
1895
-
1896
- msgid "Button classname:"
1897
- msgstr ""
1898
-
1899
- msgid "Expand"
1900
- msgstr ""
1901
-
1902
- msgid "Please provide at least one non-empty value, you are free to live some of them empty."
1903
- msgstr ""
1904
-
1905
- msgid "You should define a callback for your ajax call to async load data"
1906
- msgstr ""
1907
-
1908
- msgid "This View already has a content search filter. If you insert a search control to the HTML, the existing search filter will be removed."
1909
- msgstr ""
1910
-
1911
- msgid "Post author"
1912
- msgstr ""
1913
-
1914
- msgid "Edit this filter"
1915
- msgstr ""
1916
-
1917
- msgid "Delete this filter"
1918
- msgstr ""
1919
-
1920
- msgid "Post Author"
1921
- msgstr ""
1922
-
1923
- msgid "Updated"
1924
- msgstr ""
1925
-
1926
- msgid "Not saved"
1927
- msgstr ""
1928
-
1929
- msgid "%sLearn about filtering by Post Author%s"
1930
- msgstr ""
1931
-
1932
- msgid "Post author is the same as the logged in user"
1933
- msgstr ""
1934
-
1935
- msgid "Post author is "
1936
- msgstr ""
1937
-
1938
- msgid "Post author is set by the parent View"
1939
- msgstr ""
1940
-
1941
- msgid "Post author is the author of the current page"
1942
- msgstr ""
1943
-
1944
- msgid "Post author's "
1945
- msgstr ""
1946
-
1947
- msgid " is set by this URL parameter: "
1948
- msgstr ""
1949
-
1950
- msgid " is set by this View shortcode attribute: "
1951
- msgstr ""
1952
-
1953
- msgid " is not a valid taxonomy for the post types you are trying to display."
1954
- msgstr ""
1955
-
1956
- msgid "%sLearn about filtering by taxonomy%s"
1957
- msgstr ""
1958
-
1959
- msgid "Delete this filter by %s"
1960
- msgstr ""
1961
-
1962
- msgid "Value: "
1963
- msgstr ""
1964
-
1965
- msgid "Taxonomy name"
1966
- msgstr ""
1967
-
1968
- msgid "Shortcode attribute"
1969
- msgstr ""
1970
-
1971
- msgid "URL parameter"
1972
- msgstr ""
1973
-
1974
- msgid "Operator"
1975
- msgstr ""
1976
-
1977
- msgid "IN"
1978
- msgstr ""
1979
-
1980
- msgid "NOT IN"
1981
- msgstr ""
1982
-
1983
- msgid "AND"
1984
- msgstr ""
1985
-
1986
- msgid "Select posts with taxonomy: "
1987
- msgstr ""
1988
-
1989
- msgid "Taxonomy relationship:"
1990
- msgstr ""
1991
-
1992
- msgid "Relationship to use when querying with multiple taxonomies:"
1993
- msgstr ""
1994
-
1995
- msgid "OR"
1996
- msgstr ""
1997
-
1998
- msgid "Taxonomy is:"
1999
- msgstr ""
2000
-
2001
- msgid "Any of the following"
2002
- msgstr ""
2003
-
2004
- msgid "NOT one of the following"
2005
- msgstr ""
2006
-
2007
- msgid "All of the following"
2008
- msgstr ""
2009
-
2010
- msgid "Value set by the current page"
2011
- msgstr ""
2012
-
2013
- msgid "Value set by View shortcode attribute"
2014
- msgstr ""
2015
-
2016
- msgid "Value set by URL parameter"
2017
- msgstr ""
2018
-
2019
- msgid "Value set by parent view"
2020
- msgstr ""
2021
-
2022
- msgid "Custom field - %s"
2023
- msgstr ""
2024
-
2025
- msgid "%sLearn about filtering by custom fields%s"
2026
- msgstr ""
2027
-
2028
- msgid "Custom field"
2029
- msgstr ""
2030
-
2031
- msgid "Constant"
2032
- msgstr ""
2033
-
2034
- msgid "Remove"
2035
- msgstr ""
2036
-
2037
- msgid "Add another value"
2038
- msgstr ""
2039
-
2040
- msgid "%1$s%2$s, %3$s"
2041
- msgstr ""
2042
-
2043
- msgid "Select posts with custom field: "
2044
- msgstr ""
2045
-
2046
- msgid "Custom field relationship:"
2047
- msgstr ""
2048
-
2049
- msgid "Relationship to use when querying with multiple custom fields:"
2050
- msgstr ""
2051
-
2052
- msgid "Comparison function:"
2053
- msgstr ""
2054
-
2055
- msgid "Post id"
2056
- msgstr ""
2057
-
2058
- msgid "Post Ids"
2059
- msgstr ""
2060
-
2061
- msgid "%sLearn about filtering by Post ID%s"
2062
- msgstr ""
2063
-
2064
- msgid "The View will filter posts to"
2065
- msgstr ""
2066
-
2067
- msgid "include"
2068
- msgstr ""
2069
-
2070
- msgid "exclude"
2071
- msgstr ""
2072
-
2073
- msgid "Posts with those IDs: "
2074
- msgstr ""
2075
-
2076
- msgid "Posts with IDs set by this URL parameter: "
2077
- msgstr ""
2078
-
2079
- msgid "Posts with IDs set by the View shortcode attribute: "
2080
- msgstr ""
2081
-
2082
- msgid "Post parent"
2083
- msgstr ""
2084
-
2085
- msgid "%sLearn about filtering by Post Parent%s"
2086
- msgstr ""
2087
-
2088
- msgid "Taxonomy parent"
2089
- msgstr ""
2090
-
2091
- msgid "This View has a filter for a taxonomy that no longer exists. Please select one taxonomy and update the Content selection section."
2092
- msgstr ""
2093
-
2094
- msgid "This mode is not available. Please select one taxonomy and update the Content selection section."
2095
- msgstr ""
2096
-
2097
- msgid "Parent is the current page"
2098
- msgstr ""
2099
-
2100
- msgid "Parent is:"
2101
- msgstr ""
2102
-
2103
- msgid "Parent is the taxonomy selected by the <strong>parent view</strong>"
2104
- msgstr ""
2105
-
2106
- msgid "Post relationship - Post is a child of"
2107
- msgstr ""
2108
-
2109
- msgid "Post Relationship - Post is a child of"
2110
- msgstr ""
2111
-
2112
- msgid "There is no post type selected in the Content selection setion"
2113
- msgstr ""
2114
-
2115
- msgid "Post type <strong>%s</strong> doesn't belong to any other post type"
2116
- msgstr ""
2117
-
2118
- msgid "Post type <strong>%s</strong> is a child of <strong>%s</strong> post type"
2119
- msgstr ""
2120
-
2121
- msgid " and "
2122
- msgstr ""
2123
-
2124
- msgid "Post type <strong>%s</strong> is a child of <strong>%s</strong> post types"
2125
- msgstr ""
2126
-
2127
- msgid "Post where this View is inserted"
2128
- msgstr ""
2129
-
2130
- msgid "Post set by parent View"
2131
- msgstr ""
2132
-
2133
- msgid "Post with ID set by the shortcode attribute"
2134
- msgstr ""
2135
-
2136
- msgid "Post with ID set by the URL parameter"
2137
- msgstr ""
2138
-
2139
- msgid "Specific:"
2140
- msgstr ""
2141
-
2142
- msgid "Querying and Displaying Child Posts"
2143
- msgstr ""
2144
-
2145
- msgid "Post search"
2146
- msgstr ""
2147
-
2148
- msgid "%sLearn about filtering for a specific text string%s"
2149
- msgstr ""
2150
-
2151
- msgid "Taxonomy search"
2152
- msgstr ""
2153
-
2154
- msgid "Where to search: "
2155
- msgstr ""
2156
-
2157
- msgid "Post content and title"
2158
- msgstr ""
2159
-
2160
- msgid "Just post titles"
2161
- msgstr ""
2162
-
2163
- msgid "Search for a specific text:"
2164
- msgstr ""
2165
-
2166
- msgid "I’ll add the search box to the HTML manually"
2167
- msgstr ""
2168
-
2169
- msgid "Post Status"
2170
- msgstr ""
2171
-
2172
- msgid "Taxonomy term"
2173
- msgstr ""
2174
-
2175
- msgid "Remove this filter"
2176
- msgstr ""
2177
-
2178
- msgid "Taxonomy term: "
2179
- msgstr ""
2180
-
2181
- msgid "is one of these"
2182
- msgstr ""
2183
-
2184
- msgid "set by the current page"
2185
- msgstr ""
2186
-
2187
- msgid "User field - %s"
2188
- msgstr ""
2189
-
2190
- msgid "%sLearn about filtering by user fields%s"
2191
- msgstr ""
2192
-
2193
- msgid "User field"
2194
- msgstr ""
2195
-
2196
- msgid "Select users with usermeta field: "
2197
- msgstr ""
2198
-
2199
- msgid "Usermeta field relationship:"
2200
- msgstr ""
2201
-
2202
- msgid "Relationship to use when querying with multiple user fields:"
2203
- msgstr ""
2204
-
2205
- msgid "Specific users"
2206
- msgstr ""
2207
-
2208
- msgid "username"
2209
- msgstr ""
2210
-
2211
- msgid " and "
2212
- msgstr ""
2213
-
2214
- msgid " ordered by "
2215
- msgstr ""
2216
-
2217
- msgid ", limit to 1 item"
2218
- msgstr ""
2219
-
2220
- msgid ", limit to %d items"
2221
- msgstr ""
2222
-
2223
- msgid ", skip first item"
2224
- msgstr ""
2225
-
2226
- msgid ", skip %d items"
2227
- msgstr ""
2228
-
2229
- msgid "This View displays"
2230
- msgstr ""
2231
-
2232
- msgid "Users with this display name "
2233
- msgstr ""
2234
-
2235
- msgid "Users with "
2236
- msgstr ""
2237
-
2238
- msgid " set by this URL parameter: "
2239
- msgstr ""
2240
-
2241
- msgid " set by this View shortcode attribute: "
2242
- msgstr ""
2243
-
2244
- msgid "Type for search users"
2245
- msgstr ""
2246
-
2247
- msgid "No users matched your criteria"
2248
- msgstr ""
2249
-
2250
- msgid "Searching"
2251
- msgstr ""
2252
-
2253
- msgid "View updated."
2254
- msgstr ""
2255
-
2256
- msgid "Custom field updated."
2257
- msgstr ""
2258
-
2259
- msgid "Custom field deleted."
2260
- msgstr ""
2261
-
2262
- msgid "View restored to revision from %s"
2263
- msgstr ""
2264
-
2265
- msgid "View published."
2266
- msgstr ""
2267
-
2268
- msgid "View saved."
2269
- msgstr ""
2270
-
2271
- msgid "View submitted."
2272
- msgstr ""
2273
-
2274
- msgid "View scheduled for: <strong>%1$s</strong>."
2275
- msgstr ""
2276
-
2277
- msgid "M j, Y @ G:i"
2278
- msgstr ""
2279
-
2280
- msgid "View draft updated"
2281
- msgstr ""
2282
-
2283
- msgid "Content template updated."
2284
- msgstr ""
2285
-
2286
- msgid "Content template restored to revision from %s"
2287
- msgstr ""
2288
-
2289
- msgid "Content template published."
2290
- msgstr ""
2291
-
2292
- msgid "Content template saved."
2293
- msgstr ""
2294
-
2295
- msgid "Content template submitted."
2296
- msgstr ""
2297
-
2298
- msgid "Content template scheduled for: <strong>%1$s</strong>."
2299
- msgstr ""
2300
-
2301
- msgid "Content template draft updated"
2302
- msgstr ""
2303
-
2304
- msgid "Previous page"
2305
- msgstr ""
2306
-
2307
- msgid "Next page"
2308
- msgstr ""
2309
-
2310
- msgid "Unnamed View"
2311
- msgstr ""
2312
-
2313
- msgid "A View with that name already exists. Please use another name."
2314
- msgstr ""
2315
-
2316
- msgid "slide"
2317
- msgstr ""
2318
-
2319
- msgid "grid"
2320
- msgstr ""
2321
-
2322
- msgid "The View could not be created."
2323
- msgstr ""
2324
-
2325
- msgid "Displaying "
2326
- msgstr ""
2327
-
2328
- msgid " of "
2329
- msgstr ""
2330
-
2331
- msgid "Items per page"
2332
- msgstr ""
2333
-
2334
- msgid "Display all items"
2335
- msgstr ""
2336
-
2337
- msgid "Display 20 items per page"
2338
- msgstr ""
2339
-
2340
- msgid "<a href='%s' target='_blank'>Go to the Settings page &raquo;</a>"
2341
- msgstr ""
2342
-
2343
- msgid "Learn about different layouts"
2344
- msgstr ""
2345
-
2346
- msgid "Can't insert content in to shortcode"
2347
- msgstr ""
2348
-
2349
- msgid "Error occured"
2350
- msgstr ""
2351
-
2352
- msgid "Insert"
2353
- msgstr ""
2354
-
2355
- msgid "Next"
2356
- msgstr ""
2357
-
2358
- msgid "Insert a layout"
2359
- msgstr ""
2360
-
2361
- msgid "Layout style"
2362
- msgstr ""
2363
-
2364
- msgid "Choose fields"
2365
- msgstr ""
2366
-
2367
- msgid "Insert to the view"
2368
- msgstr ""
2369
-
2370
- msgid "Select the style of the layout to insert"
2371
- msgstr ""
2372
-
2373
- msgid "Unformatted"
2374
- msgstr ""
2375
-
2376
- msgid "Bootstrap grid"
2377
- msgstr ""
2378
-
2379
- msgid "You need to set the Bootstrap version used in your theme."
2380
- msgstr ""
2381
-
2382
- msgid "Table-based grid"
2383
- msgstr ""
2384
-
2385
- msgid "Table"
2386
- msgstr ""
2387
-
2388
- msgid "Unordered list"
2389
- msgstr ""
2390
-
2391
- msgid "Ordered list"
2392
- msgstr ""
2393
-
2394
- msgid "Bootstrap grid options"
2395
- msgstr ""
2396
-
2397
- msgid "Number of columns"
2398
- msgstr ""
2399
-
2400
- msgid "Add container"
2401
- msgstr ""
2402
-
2403
- msgid "Add .row class"
2404
- msgstr ""
2405
-
2406
- msgid "Compact HTML structure"
2407
- msgstr ""
2408
-
2409
- msgid "Detailed HTML structure"
2410
- msgstr ""
2411
-
2412
- msgid "Table-based grid options"
2413
- msgstr ""
2414
-
2415
- msgid "Table options"
2416
- msgstr ""
2417
-
2418
- msgid "Include field names in table headings"
2419
- msgstr ""
2420
-
2421
- msgid "Select the fields to include in the layout"
2422
- msgstr ""
2423
-
2424
- msgid "Add field"
2425
- msgstr ""
2426
-
2427
- msgid "Where do you want to insert this layout?"
2428
- msgstr ""
2429
-
2430
- msgid "In the current cursor position"
2431
- msgstr ""
2432
-
2433
- msgid "Replace existing layout"
2434
- msgstr ""
2435
-
2436
- msgid "Previous"
2437
- msgstr ""
2438
-
2439
- msgid "Next"
2440
- msgstr ""
2441
-
2442
- msgid "Insert a filter field"
2443
- msgstr ""
2444
-
2445
- msgid "Preview"
2446
- msgstr ""
2447
-
2448
- msgid "Select what to filter to see the preview here"
2449
- msgstr ""
2450
-
2451
- msgid "Defaults"
2452
- msgstr ""
2453
-
2454
- msgid "Select what to filter by :"
2455
- msgstr ""
2456
-
2457
- msgid "--- Please select ---"
2458
- msgstr ""
2459
-
2460
- msgid "Use this kind of input:"
2461
- msgstr ""
2462
-
2463
- msgid "Types ancestors:"
2464
- msgstr ""
2465
-
2466
- msgid "Checkbox label:"
2467
- msgstr ""
2468
-
2469
- msgid "When the checkbox is not checked:"
2470
- msgstr ""
2471
-
2472
- msgid "Return all results"
2473
- msgstr ""
2474
-
2475
- msgid "Return only results with this field unchecked"
2476
- msgstr ""
2477
-
2478
- msgid "Default label:"
2479
- msgstr ""
2480
-
2481
- msgid "Options for this input:"
2482
- msgstr ""
2483
-
2484
- msgid "Use existing custom field values"
2485
- msgstr ""
2486
-
2487
- msgid "Use manually entered values"
2488
- msgstr ""
2489
-
2490
- msgid "Values:"
2491
- msgstr ""
2492
-
2493
- msgid "Display values:"
2494
- msgstr ""
2495
-
2496
- msgid "Default value:"
2497
- msgstr ""
2498
-
2499
- msgid "Leave blank for no default"
2500
- msgstr ""
2501
-
2502
- msgid "Format of the options:"
2503
- msgstr ""
2504
-
2505
- msgid "You can use placeholders like %%NAME%% or %%COUNT%%"
2506
- msgstr ""
2507
-
2508
- msgid "Leave empty to display just the option name"
2509
- msgstr ""
2510
-
2511
- msgid "Sort values:"
2512
- msgstr ""
2513
-
2514
- msgid "Taxonomy order:"
2515
- msgstr ""
2516
-
2517
- msgid "Taxonomy order by:"
2518
- msgstr ""
2519
-
2520
- msgid "Hide empty terms:"
2521
- msgstr ""
2522
-
2523
- msgid "Do not show taxonomy terms with no posts attached"
2524
- msgstr ""
2525
-
2526
- msgid "Advanced:"
2527
- msgstr ""
2528
-
2529
- msgid "Refer to this field as:"
2530
- msgstr ""
2531
-
2532
- msgid "Compare this values as:"
2533
- msgstr ""
2534
-
2535
- msgid "Search results for \"%s\""
2536
- msgstr ""
2537
-
2538
- msgid "Search results for \"%s\" in trashed WordPress Archives"
2539
- msgstr ""
2540
-
2541
- msgid "Search WordPress Archives"
2542
- msgstr ""
2543
-
2544
- msgid "This WordPress Archive isn't being used for any loops."
2545
- msgstr ""
2546
-
2547
- msgid "No WordPress Archives in trash matched your criteria."
2548
- msgstr ""
2549
-
2550
- msgid "No WordPress Archives in trash."
2551
- msgstr ""
2552
-
2553
- msgid "No WordPress Archives matched your criteria."
2554
- msgstr ""
2555
-
2556
- msgid "WordPress Archives"
2557
- msgstr ""
2558
-
2559
- msgid "WordPress Archive moved to the Trash"
2560
- msgstr ""
2561
-
2562
- msgid "Undo"
2563
- msgstr ""
2564
-
2565
- msgid "WordPress Archive restored from the Trash"
2566
- msgstr ""
2567
-
2568
- msgid "WordPress Archive permanently deleted"
2569
- msgstr ""
2570
-
2571
- msgid "All loops have a WordPress Archive assigned"
2572
- msgstr ""
2573
-
2574
- msgid "Arrange by"
2575
- msgstr ""
2576
-
2577
- msgid "Usage"
2578
- msgstr ""
2579
-
2580
- msgid "WordPress Archives let you customize the output of standard Archive pages."
2581
- msgstr ""
2582
-
2583
- msgid "Create your first WordPress Archive"
2584
- msgstr ""
2585
-
2586
- msgid "Published"
2587
- msgstr ""
2588
-
2589
- msgid "Trash"
2590
- msgstr ""
2591
-
2592
- msgid "Archive usage"
2593
- msgstr ""
2594
-
2595
- msgid "Action"
2596
- msgstr ""
2597
-
2598
- msgid "Choose"
2599
- msgstr ""
2600
-
2601
- msgid "Change archive usage"
2602
- msgstr ""
2603
-
2604
- msgid "Move to trash"
2605
- msgstr ""
2606
-
2607
- msgid "Restore from trash"
2608
- msgstr ""
2609
-
2610
- msgid "Return"
2611
- msgstr ""
2612
-
2613
- msgid "Archive loop"
2614
- msgstr ""
2615
-
2616
- msgid "WordPress Archive used"
2617
- msgstr ""
2618
-
2619
- msgid "Used for"
2620
- msgstr ""
2621
-
2622
- msgid "Create a WordPres Archive for this loop"
2623
- msgstr ""
2624
-
2625
- msgid "Change"
2626
- msgstr ""
2627
-
2628
- msgid "Search results for \"%s\" in trashed Content Templates"
2629
- msgstr ""
2630
-
2631
- msgid "No Content Templates in trash matched your criteria."
2632
- msgstr ""
2633
-
2634
- msgid "No Content Templates matched your criteria."
2635
- msgstr ""
2636
-
2637
- msgid "No Content Templates in trash."
2638
- msgstr ""
2639
-
2640
- msgid "Enter new title"
2641
- msgstr ""
2642
-
2643
- msgid "There are %s single posts that are currently using this template."
2644
- msgstr ""
2645
-
2646
- msgid "Clear single %s"
2647
- msgstr ""
2648
-
2649
- msgid "There is no general Content Template asigned to single %s, but %s individual %s have a Content Template asigned to them."
2650
- msgstr ""
2651
-
2652
- msgid "Would you like to clear them?"
2653
- msgstr ""
2654
-
2655
- msgid " (single)"
2656
- msgstr ""
2657
-
2658
- msgid "Bind %u %s "
2659
- msgstr ""
2660
-
2661
- msgid "No Post types/Taxonomies assigned"
2662
- msgstr ""
2663
-
2664
- msgid "Content template for "
2665
- msgstr ""
2666
-
2667
- msgid "Create a Content Template for single %s"
2668
- msgstr ""
2669
-
2670
- msgid "Clear %d %s"
2671
- msgstr ""
2672
-
2673
- msgid "Add a new Content Template for this post type"
2674
- msgstr ""
2675
-
2676
- msgid "Add a new Content Template for this taxonomy"
2677
- msgstr ""
2678
-
2679
- msgid "Content Template moved to the Trash"
2680
- msgstr ""
2681
-
2682
- msgid "Content Template restored from the Trash"
2683
- msgstr ""
2684
-
2685
- msgid "Content Template permanently deleted"
2686
- msgstr ""
2687
-
2688
- msgid "Usage for single page"
2689
- msgstr ""
2690
-
2691
- msgid "Usage for custom post archives"
2692
- msgstr ""
2693
-
2694
- msgid "Usage for taxonomy archives"
2695
- msgstr ""
2696
-
2697
- msgid "Search Views:"
2698
- msgstr ""
2699
-
2700
- msgid "Content Templates let you design single pages."
2701
- msgstr ""
2702
-
2703
- msgid "Add new Content Template"
2704
- msgstr ""
2705
-
2706
- msgid "Used on"
2707
- msgstr ""
2708
-
2709
- msgid "Change template usage"
2710
- msgstr ""
2711
-
2712
- msgid "Duplicate"
2713
- msgstr ""
2714
-
2715
- msgid "Delete Content Template"
2716
- msgstr ""
2717
-
2718
- msgid "Are you sure you want to delete it?"
2719
- msgstr ""
2720
-
2721
- msgid "Duplicate Content Template"
2722
- msgstr ""
2723
-
2724
- msgid "Name this Content Template"
2725
- msgstr ""
2726
-
2727
- msgid "Enter name here"
2728
- msgstr ""
2729
-
2730
- msgid "Template used"
2731
- msgstr ""
2732
-
2733
- msgid "Change Content Template"
2734
- msgstr ""
2735
-
2736
- msgid "Content updated"
2737
- msgstr ""
2738
-
2739
- msgid "Content not saved"
2740
- msgstr ""
2741
-
2742
- msgid "Update"
2743
- msgstr ""
2744
-
2745
- msgid "Open CSS editor"
2746
- msgstr ""
2747
-
2748
- msgid "Close CSS editor"
2749
- msgstr ""
2750
-
2751
- msgid "Open JS editor"
2752
- msgstr ""
2753
-
2754
- msgid "Close JS editor"
2755
- msgstr ""
2756
-
2757
- msgid "Data updated"
2758
- msgstr ""
2759
-
2760
- msgid "Data not saved"
2761
- msgstr ""
2762
-
2763
- msgid "Filter by <strong>%s</strong>"
2764
- msgstr ""
2765
-
2766
- msgid "Your %s filters are using an internal \"OR\" kind of relationship, and dependant parametric search for that filters needs \"AND\" relationships."
2767
- msgstr ""
2768
-
2769
- msgid "Close advanced options"
2770
- msgstr ""
2771
-
2772
- msgid "Advanced options"
2773
- msgstr ""
2774
-
2775
- msgid "Pagination"
2776
- msgstr ""
2777
-
2778
- msgid "Parametric search settings"
2779
- msgstr ""
2780
-
2781
- msgid "Would you like to make this parametric search a dependant one?"
2782
- msgstr ""
2783
-
2784
- msgid "Insert submit button"
2785
- msgstr ""
2786
-
2787
- msgid "Create a reset button for this parametric search."
2788
- msgstr ""
2789
-
2790
- msgid "Insert clear form button"
2791
- msgstr ""
2792
-
2793
- msgid "Create a spinner container for this parametric search."
2794
- msgstr ""
2795
-
2796
- msgid "Container type:"
2797
- msgstr ""
2798
-
2799
- msgid "Division"
2800
- msgstr ""
2801
-
2802
- msgid "Paragraph"
2803
- msgstr ""
2804
-
2805
- msgid "Span"
2806
- msgstr ""
2807
-
2808
- msgid "Container classname:"
2809
- msgstr ""
2810
-
2811
- msgid "Spinner:"
2812
- msgstr ""
2813
-
2814
- msgid "Do not show the spinner"
2815
- msgstr ""
2816
-
2817
- msgid "Show the spinner before the text"
2818
- msgstr ""
2819
-
2820
- msgid "Show the spinner after the text"
2821
- msgstr ""
2822
-
2823
- msgid "Content:"
2824
- msgstr ""
2825
-
2826
- msgid "Insert spinner container"
2827
- msgstr ""
2828
-
2829
- msgid "Only Views listing posts can have parametric search inputs."
2830
- msgstr ""
2831
-
2832
- msgid "This View has some query filters that are missing from the form. Maybe you have removed them:"
2833
- msgstr ""
2834
-
2835
- msgid "Can they also be removed from the query filtering?"
2836
- msgstr ""
2837
-
2838
- msgid "Yes (recommended)"
2839
- msgstr ""
2840
-
2841
- msgid "No"
2842
- msgstr ""
2843
-
2844
- msgid "When to update the Views results"
2845
- msgstr ""
2846
-
2847
- msgid "Update the View results only when submitting the form"
2848
- msgstr ""
2849
-
2850
- msgid "Update the View results every time an input changes"
2851
- msgstr ""
2852
-
2853
- msgid "Which options to display in the form inputs"
2854
- msgstr ""
2855
-
2856
- msgid "Fix filters relationship"
2857
- msgstr ""
2858
-
2859
- msgid "Always show all values for inputs"
2860
- msgstr ""
2861
-
2862
- msgid "Show only available options for each input"
2863
- msgstr ""
2864
-
2865
- msgid "Choose if you want to hide or disable irrelevant options for inputs:"
2866
- msgstr ""
2867
-
2868
- msgid "Input type"
2869
- msgstr ""
2870
-
2871
- msgid "Disable / Hide"
2872
- msgstr ""
2873
-
2874
- msgid "Select dropdown"
2875
- msgstr ""
2876
-
2877
- msgid "Disable"
2878
- msgstr ""
2879
-
2880
- msgid "Multi-select"
2881
- msgstr ""
2882
-
2883
- msgid "Radio inputs"
2884
- msgstr ""
2885
-
2886
- msgid "Checkboxes"
2887
- msgstr ""
2888
-
2889
- msgid "Spinners settings"
2890
- msgstr ""
2891
-
2892
- msgid "You can display a spinner when the View results update"
2893
- msgstr ""
2894
-
2895
- msgid "No spinner graphics"
2896
- msgstr ""
2897
-
2898
- msgid "Custom spinner graphics"
2899
- msgstr ""
2900
-
2901
- msgid "Upload Image"
2902
- msgstr ""
2903
-
2904
- msgid "Built in Views spinner graphics"
2905
- msgstr ""
2906
-
2907
- msgid "Javascript settings"
2908
- msgstr ""
2909
-
2910
- msgid "You can execute the following javascript callbacks before and after the View results are updated."
2911
- msgstr ""
2912
-
2913
- msgid "Javascript function to execute before every AJAX update:"
2914
- msgstr ""
2915
-
2916
- msgid "Javascript function to execute after every AJAX update:"
2917
- msgstr ""
2918
-
2919
- msgid "Submit button settings"
2920
- msgstr ""
2921
-
2922
- msgid "When the parametric search updates the results on the fly, how should the submit button work?"
2923
- msgstr ""
2924
-
2925
- msgid "Submit the form without reloading the page"
2926
- msgstr ""
2927
-
2928
- msgid "Submit the form and reload the page"
2929
- msgstr ""
2930
-
2931
- msgid "Do not show this button"
2932
- msgstr ""
2933
-
2934
- msgid "There are no parametric search inputs in this View."
2935
- msgstr ""
2936
-
2937
- msgid "Learn more about parametric search"
2938
- msgstr ""
2939
-
2940
- msgid "Filter the results"
2941
- msgstr ""
2942
-
2943
- msgid "%sLearn about filtering by usermeta fields%s"
2944
- msgstr ""
2945
-
2946
- msgid "Add a filter"
2947
- msgstr ""
2948
-
2949
- msgid "Add another filter"
2950
- msgstr ""
2951
-
2952
- msgid "This field can not be empty"
2953
- msgstr ""
2954
-
2955
- msgid "Only lowercase letters, numbers, hyphens and underscores allowed as URL parameters"
2956
- msgstr ""
2957
-
2958
- msgid "Only lowercase letters and numbers allowed as shortcode attributes"
2959
- msgstr ""
2960
-
2961
- msgid "This is a word reserved by WordPress"
2962
- msgstr ""
2963
-
2964
- msgid "This is a word reserved by any of the ToolSet plugins"
2965
- msgstr ""
2966
-
2967
- msgid "There is a post type named like that"
2968
- msgstr ""
2969
-
2970
- msgid "There is a taxonomy named like that"
2971
- msgstr ""
2972
-
2973
- msgid "The posts you want to display are not hierarchical, so this filter will not work"
2974
- msgstr ""
2975
-
2976
- msgid "The taxonomy you want to display has changed, so this filter needs some action"
2977
- msgstr ""
2978
-
2979
- msgid "or %sEdit the filter and delete specific taxonomy filters%s"
2980
- msgstr ""
2981
-
2982
- msgid "or %sEdit the filter and delete specific custom field filters%s"
2983
- msgstr ""
2984
-
2985
- msgid "or %sEdit the filter and delete specific usermeta field filters%s"
2986
- msgstr ""
2987
-
2988
- msgid "Relationship to use when querying with multiple usermeta fields:"
2989
- msgstr ""
2990
-
2991
- msgid "Select what to filter by:"
2992
- msgstr ""
2993
-
2994
- msgid "Add filter"
2995
- msgstr ""
2996
-
2997
- msgid "Delete taxonomy filters"
2998
- msgstr ""
2999
-
3000
- msgid "There are more than one taxonomy filters. What would you like to do?"
3001
- msgstr ""
3002
-
3003
- msgid "Delete all taxonomy filters"
3004
- msgstr ""
3005
-
3006
- msgid "Delete custom field filters"
3007
- msgstr ""
3008
-
3009
- msgid "There are more than one custom field filters. What would you like to do?"
3010
- msgstr ""
3011
-
3012
- msgid "Delete all custom field filters"
3013
- msgstr ""
3014
-
3015
- msgid "Delete usermeta field filters"
3016
- msgstr ""
3017
-
3018
- msgid "There are more than one usermeta field filters. What would you like to do?"
3019
- msgstr ""
3020
-
3021
- msgid "Delete all usermeta field filters"
3022
- msgstr ""
3023
-
3024
- msgid "Aditional Javascript files"
3025
- msgstr ""
3026
-
3027
- msgid "Data saved"
3028
- msgstr ""
3029
-
3030
- msgid "Additional Javascript files"
3031
- msgstr ""
3032
-
3033
- msgid "Pointer header"
3034
- msgstr ""
3035
-
3036
- msgid "Tooltip content. Lorem ipsum dolor et umni der lanos"
3037
- msgstr ""
3038
-
3039
- msgid "Additional Javascript files to be loaded with this View (comma separated): "
3040
- msgstr ""
3041
-
3042
- msgid "Layout HTML/CSS/JS"
3043
- msgstr ""
3044
-
3045
- msgid "Content Template was successfully assigned to view."
3046
- msgstr ""
3047
-
3048
- msgid "This Content Template already assigned to this view."
3049
- msgstr ""
3050
-
3051
- msgid "Content Template was successfully unassigned from view."
3052
- msgstr ""
3053
-
3054
- msgid "Content Template was successfully updated."
3055
- msgstr ""
3056
-
3057
- msgid "No Content Templates assigned to this view"
3058
- msgstr ""
3059
-
3060
- msgid "There are no Content Templates for this View. You can add a Content Template using the Content Template button in the Layout editor tool bar."
3061
- msgstr ""
3062
-
3063
- msgid "A Content Template with that name already exists. Please use another name."
3064
- msgstr ""
3065
-
3066
- msgid "Remove this Content Template"
3067
- msgstr ""
3068
-
3069
- msgid "Limit and offset options updated"
3070
- msgstr ""
3071
-
3072
- msgid "Limit and offset options not saved"
3073
- msgstr ""
3074
-
3075
- msgid "Display "
3076
- msgstr ""
3077
-
3078
- msgid "No limit"
3079
- msgstr ""
3080
-
3081
- msgid "items "
3082
- msgstr ""
3083
-
3084
- msgid "Skip first"
3085
- msgstr ""
3086
-
3087
- msgid "items"
3088
- msgstr ""
3089
-
3090
- msgid "Loops selection"
3091
- msgstr ""
3092
-
3093
- msgid "Loop selection updated"
3094
- msgstr ""
3095
-
3096
- msgid "Loop selection not saved"
3097
- msgstr ""
3098
-
3099
- msgid "ID"
3100
- msgstr ""
3101
-
3102
- msgid "Count"
3103
- msgstr ""
3104
-
3105
- msgid "Name"
3106
- msgstr ""
3107
-
3108
- msgid "Slug"
3109
- msgstr ""
3110
-
3111
- msgid "Term_group"
3112
- msgstr ""
3113
-
3114
- msgid "None"
3115
- msgstr ""
3116
-
3117
- msgid "user login"
3118
- msgstr ""
3119
-
3120
- msgid "user id"
3121
- msgstr ""
3122
-
3123
- msgid "user name"
3124
- msgstr ""
3125
-
3126
- msgid "user display name"
3127
- msgstr ""
3128
-
3129
- msgid "user nicename"
3130
- msgstr ""
3131
-
3132
- msgid "user email"
3133
- msgstr ""
3134
-
3135
- msgid "user url"
3136
- msgstr ""
3137
-
3138
- msgid "user registered date"
3139
- msgstr ""
3140
-
3141
- msgid "user post count"
3142
- msgstr ""
3143
-
3144
- msgid "Sorting options updated"
3145
- msgstr ""
3146
-
3147
- msgid "Sorting options not saved"
3148
- msgstr ""
3149
-
3150
- msgid "Order by: "
3151
- msgstr ""
3152
-
3153
- msgid "Pagination and random ordering do not work together and would produce unexpected results. Please disable pagination or random ordering."
3154
- msgstr ""
3155
-
3156
- msgid "post id"
3157
- msgstr ""
3158
-
3159
- msgid "last modified"
3160
- msgstr ""
3161
-
3162
- msgid "Descending"
3163
- msgstr ""
3164
-
3165
- msgid "Ascending"
3166
- msgstr ""
3167
-
3168
- msgid "This is a preview"
3169
- msgstr ""
3170
-
3171
- msgid "Choose pagination control type"
3172
- msgstr ""
3173
-
3174
- msgid "Showing page"
3175
- msgstr ""
3176
-
3177
- msgid "Choose page"
3178
- msgstr ""
3179
-
3180
- msgid "of"
3181
- msgstr ""
3182
-
3183
- msgid "Pagination and Sliders settings"
3184
- msgstr ""
3185
-
3186
- msgid "Fade fast"
3187
- msgstr ""
3188
-
3189
- msgid "Fade slow"
3190
- msgstr ""
3191
-
3192
- msgid "Pagination settings updated"
3193
- msgstr ""
3194
-
3195
- msgid "Pagination settings not saved"
3196
- msgstr ""
3197
-
3198
- msgid "All query results will display."
3199
- msgstr ""
3200
-
3201
- msgid "Pagination enabled with manual transition"
3202
- msgstr ""
3203
-
3204
- msgid "The query results will display in pages, which visitors will switch."
3205
- msgstr ""
3206
-
3207
- msgid "Pagination enabled with automatic transition"
3208
- msgstr ""
3209
-
3210
- msgid "The query results will display in pages, which will switch automatically (good for sliders)."
3211
- msgstr ""
3212
-
3213
- msgid "Options for manual pagination"
3214
- msgstr ""
3215
-
3216
- msgid "Number of items per page:"
3217
- msgstr ""
3218
-
3219
- msgid "Pagination updates the entire page"
3220
- msgstr ""
3221
-
3222
- msgid "Pagination updates only the view (use AJAX)"
3223
- msgstr ""
3224
-
3225
- msgid "Transition effect:"
3226
- msgstr ""
3227
-
3228
- msgid "with duration"
3229
- msgstr ""
3230
-
3231
- msgid "miliseconds"
3232
- msgstr ""
3233
-
3234
- msgid "Please add a numeric value"
3235
- msgstr ""
3236
-
3237
- msgid "Preload images before transition"
3238
- msgstr ""
3239
-
3240
- msgid "Options for automatic pagination"
3241
- msgstr ""
3242
-
3243
- msgid "Show each page for:"
3244
- msgstr ""
3245
-
3246
- msgid "seconds"
3247
- msgstr ""
3248
-
3249
- msgid " <- Please add a numeric value"
3250
- msgstr ""
3251
-
3252
- msgid "Cache pages"
3253
- msgstr ""
3254
-
3255
- msgid "Pre-load the next and previous pages - avoids loading delays when users move between pages"
3256
- msgstr ""
3257
-
3258
- msgid "Pages to pre-load: "
3259
- msgstr ""
3260
-
3261
- msgid "Spinners"
3262
- msgstr ""
3263
-
3264
- msgid "Spinner graphics from Views"
3265
- msgstr ""
3266
-
3267
- msgid "My custom spinner graphics"
3268
- msgstr ""
3269
-
3270
- msgid "Callback function"
3271
- msgstr ""
3272
-
3273
- msgid "Javascript function to execute after the pagination transition has been completed:"
3274
- msgstr ""
3275
-
3276
- msgid "Would you like to insert transition controls for the pagination?"
3277
- msgstr ""
3278
-
3279
- msgid "Pagination controls"
3280
- msgstr ""
3281
-
3282
- msgid "Current page number"
3283
- msgstr ""
3284
-
3285
- msgid "Number of pages"
3286
- msgstr ""
3287
-
3288
- msgid "Page selector using"
3289
- msgstr ""
3290
-
3291
- msgid "dropdown"
3292
- msgstr ""
3293
-
3294
- msgid "links"
3295
- msgstr ""
3296
-
3297
- msgid "Next and previous page controls"
3298
- msgstr ""
3299
-
3300
- msgid "Pagination display"
3301
- msgstr ""
3302
-
3303
- msgid "Don't show pagination controls if there is only one page"
3304
- msgstr ""
3305
-
3306
- msgid "Insert pagination"
3307
- msgstr ""
3308
-
3309
- msgid "What pagination controls would you like to insert?"
3310
- msgstr ""
3311
-
3312
- msgid "Query options updated"
3313
- msgstr ""
3314
-
3315
- msgid "Query options not saved"
3316
- msgstr ""
3317
-
3318
- msgid "Don't include current page in query result"
3319
- msgstr ""
3320
-
3321
- msgid "Don't show empty terms"
3322
- msgstr ""
3323
-
3324
- msgid "Include terms that have non-empty descendants"
3325
- msgstr ""
3326
-
3327
- msgid "Include children in the post count"
3328
- msgstr ""
3329
-
3330
- msgid "Don't show current logged user."
3331
- msgstr ""
3332
-
3333
- msgid "Content selection updated"
3334
- msgstr ""
3335
-
3336
- msgid "Content selection not saved"
3337
- msgstr ""
3338
-
3339
- msgid "This View will display:"
3340
- msgstr ""
3341
-
3342
- msgid "Post types"
3343
- msgstr ""
3344
-
3345
- msgid "Users"
3346
- msgstr ""
3347
-
3348
- msgid "Any role"
3349
- msgstr ""
3350
-
3351
- msgid "No post type has been selected, so this View will list posts of any type."
3352
- msgstr ""
3353
-
3354
- msgid "If this is not what you want to do, please select any post type from the checkboxes above."
3355
- msgstr ""
3356
-
3357
- msgid "No taxonomy has been selected, so this View will list nothing. Maybe the selected taxonomy no longer exists?"
3358
- msgstr ""
3359
-
3360
- msgid "Please select any of the available taxonomies from the list above."
3361
- msgstr ""
3362
-
3363
- msgid "Search results for \"%s\" in trashed Views"
3364
- msgstr ""
3365
-
3366
- msgid "Enter title here"
3367
- msgstr ""
3368
-
3369
- msgid "Now give this View a name"
3370
- msgstr ""
3371
-
3372
- msgid "No Views in trash matched your criteria."
3373
- msgstr ""
3374
-
3375
- msgid "No Views in trash."
3376
- msgstr ""
3377
-
3378
- msgid "No Views matched your criteria."
3379
- msgstr ""
3380
-
3381
- msgid "Add new View"
3382
- msgstr ""
3383
-
3384
- msgid "View moved to the Trash"
3385
- msgstr ""
3386
-
3387
- msgid "View restored from the Trash"
3388
- msgstr ""
3389
-
3390
- msgid "View permanently deleted"
3391
- msgstr ""
3392
-
3393
- msgid "Views load content from the database and display on the site."
3394
- msgstr ""
3395
-
3396
- msgid "Create your first View"
3397
- msgstr ""
3398
-
3399
- msgid "Add a new View"
3400
- msgstr ""
3401
-
3402
- msgid "A View loads content from the database and displays with your HTML."
3403
- msgstr ""
3404
-
3405
- msgid " What kind of display do you want to create?"
3406
- msgstr ""
3407
-
3408
- msgid "Display all results"
3409
- msgstr ""
3410
-
3411
- msgid "The View will output all the results returned from the query section."
3412
- msgstr ""
3413
-
3414
- msgid "Display the results with pagination"
3415
- msgstr ""
3416
-
3417
- msgid "The View will display the query results in pages."
3418
- msgstr ""
3419
-
3420
- msgid "Display the results as a slider"
3421
- msgstr ""
3422
-
3423
- msgid "The View will display the query results as slides."
3424
- msgstr ""
3425
-
3426
- msgid "Display the results as a parametric search"
3427
- msgstr ""
3428
-
3429
- msgid "Visitors will be able to search through your content using different search criteria."
3430
- msgstr ""
3431
-
3432
- msgid "Full custom display mode"
3433
- msgstr ""
3434
-
3435
- msgid "See all the View controls open and set up things manually.."
3436
- msgstr ""
3437
-
3438
- msgid "Name this View"
3439
- msgstr ""
3440
-
3441
- msgid "Create View"
3442
- msgstr ""
3443
-
3444
- msgid "Delete View"
3445
- msgstr ""
3446
-
3447
- msgid "Are you sure want delete this View? "
3448
- msgstr ""
3449
-
3450
- msgid "Please use the Scan button first to be sure that it is not used anywhere."
3451
- msgstr ""
3452
-
3453
- msgid "Duplicate View"
3454
- msgstr ""
3455
-
3456
- msgid "Scan"
3457
- msgstr ""
3458
-
3459
- msgid "Nothing found"
3460
- msgstr ""
3461
-
3462
- msgid "An Unexpected HTTP Error occurred during the API request."
3463
- msgstr ""
3464
-
3465
- msgid "An unknown error occurred."
3466
- msgstr ""
3467
-
3468
- msgid "No content templates found"
3469
- msgstr ""
3470
-
3471
- msgid "No content templates found in Trash"
3472
- msgstr ""
3473
-
3474
- msgid "Syntax Highlight On"
3475
- msgstr ""
3476
-
3477
- msgid "Syntax Highlight Off"
3478
- msgstr ""
3479
-
3480
- msgid "Content Template Settings"
3481
- msgstr ""
3482
-
3483
- msgid "Content Template CSS and JS"
3484
- msgstr ""
3485
-
3486
- msgid "Edit content template"
3487
- msgstr ""
3488
-
3489
- msgid "There are no Content Templates being used for single post types."
3490
- msgstr ""
3491
-
3492
- msgid "There are no Content Templates being used for post types in taxonomy archive loops."
3493
- msgstr ""
3494
-
3495
- msgid "%d %ss use a different template:"
3496
- msgstr ""
3497
-
3498
- msgid "Update all %ss now"
3499
- msgstr ""
3500
-
3501
- msgid "<span id=\"%s\">%d</span> %ss have updated to use this template."
3502
- msgstr ""
3503
-
3504
- msgid "All %s are using this template"
3505
- msgstr ""
3506
-
3507
- msgid "There are no %s"
3508
- msgstr ""
3509
-
3510
- msgid "There are no Content Templates being used for Taxonomy archive loops."
3511
- msgstr ""
3512
-
3513
- msgid "<strong>This template includes single-ended shortcodes</strong>. Please close all shortcodes to avoid processing errors. %sRead more%s"
3514
- msgstr ""
3515
-
3516
- msgid "Click to toggle"
3517
- msgstr ""
3518
-
3519
- msgid "All %ss were successfully updated"
3520
- msgstr ""
3521
-
3522
- msgid "This Content Template will display in the ‘content’ area of "
3523
- msgstr ""
3524
-
3525
- msgid " the content types you assign it to."
3526
- msgstr ""
3527
-
3528
- msgid "It starts empty and you should add fields to it. To add fields, click on the V icon below. You can add HTML and CSS to style the fields and design the page template."
3529
- msgstr ""
3530
-
3531
- msgid "Add description"
3532
- msgstr ""
3533
-
3534
- msgid "Describe this Content Template"
3535
- msgstr ""
3536
-
3537
- msgid "Here you can modify specific CSS and javascript to be used with this Content Template."
3538
- msgstr ""
3539
-
3540
- msgid "Open CSS editor"
3541
- msgstr ""
3542
-
3543
- msgid "CSS"
3544
- msgstr ""
3545
-
3546
- msgid "This is used to add custom CSS to a Content Template."
3547
- msgstr ""
3548
-
3549
- msgid "Close CSS editor"
3550
- msgstr ""
3551
-
3552
- msgid "Open JS editor"
3553
- msgstr ""
3554
-
3555
- msgid "JS"
3556
- msgstr ""
3557
-
3558
- msgid "This is used to add custom javascript to a Content Template."
3559
- msgstr ""
3560
-
3561
- msgid "Close JS editor"
3562
- msgstr ""
3563
-
3564
- msgid "Output mode"
3565
- msgstr ""
3566
-
3567
- msgid "Auto-insert paragraphs"
3568
- msgstr ""
3569
-
3570
- msgid "Manual paragraphs"
3571
- msgstr ""
3572
-
3573
- msgid "Automaticaly paragraph (Normal WordPress output) - add paragraphs an breaks and resolve shortcodes"
3574
- msgstr ""
3575
-
3576
- msgid "Manual paragraph (Raw output) - only resolve shortcodes without adding line breaks or paragraphs"
3577
- msgstr ""
3578
-
3579
- msgid "Note"
3580
- msgstr ""
3581
-
3582
- msgid "These settings are synced with the post in the origin language and you can't change them here. They can only be changed on the post in the original language."
3583
- msgstr ""
3584
-
3585
- msgid "Use this Content Template for:"
3586
- msgstr ""
3587
-
3588
- msgid "Editing instructions"
3589
- msgstr ""
3590
-
3591
- msgid "Theme support for Content Templates"
3592
- msgstr ""
3593
-
3594
- msgid "Content Templates modify the content when called from"
3595
- msgstr ""
3596
-
3597
- msgid "function. Some themes don't use"
3598
- msgstr ""
3599
-
3600
- msgid "function but define their own function."
3601
- msgstr ""
3602
-
3603
- msgid "If Content Templates don't work with your theme then you can enter the name of the function your theme uses here:"
3604
- msgstr ""
3605
-
3606
- msgid "Don't know the name of your theme function?"
3607
- msgstr ""
3608
-
3609
- msgid "Enable debugging and go to a page that should display a Content Template and Views will display the call function name."
3610
- msgstr ""
3611
-
3612
- msgid "Settings saved"
3613
- msgstr ""
3614
-
3615
- msgid "Translating with WPML"
3616
- msgstr ""
3617
-
3618
- msgid "Congratulations! You are running Views and WPML with the String Translation module, so you can easily translate everything."
3619
- msgstr ""
3620
-
3621
- msgid "To translate static texts, wrap them in <strong>[wpml-string][/wpml-string]</strong> shortcodes."
3622
- msgstr ""
3623
-
3624
- msgid "You are running Views and WPML, but missing the String Translation module."
3625
- msgstr ""
3626
-
3627
- msgid "The String Translation"
3628
- msgstr ""
3629
-
3630
- msgid "allows translating static texts in your Views and Content Templates."
3631
- msgstr ""
3632
-
3633
- msgid "How would you like to translate Content Templates?"
3634
- msgstr ""
3635
-
3636
- msgid "Use the same Content Templates for all languages"
3637
- msgstr ""
3638
-
3639
- msgid "Create different Content Templates for each language"
3640
- msgstr ""
3641
-
3642
- msgid "Need help?"
3643
- msgstr ""
3644
-
3645
- msgid "Translating Views and Content Templates with WPML"
3646
- msgstr ""
3647
-
3648
- msgid "For single:"
3649
- msgstr ""
3650
-
3651
- msgid "For archive loop:"
3652
- msgstr ""
3653
-
3654
- msgid "Post Types"
3655
- msgstr ""
3656
-
3657
- msgid "Use this Content Template (Single)"
3658
- msgstr ""
3659
-
3660
- msgid "Use this Content Template (Archive loop)"
3661
- msgstr ""
3662
-
3663
- msgid "Use this Content Template"
3664
- msgstr ""
3665
-
3666
- msgid "Single pages:"
3667
- msgstr ""
3668
-
3669
- msgid "Templates updated"
3670
- msgstr ""
3671
-
3672
- msgid "Post archives:"
3673
- msgstr ""
3674
-
3675
- msgid "There are no custom post types archives"
3676
- msgstr ""
3677
-
3678
- msgid "Taxonomy archives:"
3679
- msgstr ""
3680
-
3681
- msgid "<span style=\"color:red\">*</span> A different Content Template is already assigned to this item"
3682
- msgstr ""
3683
-
3684
- msgid "You can’t edit this View because it is in the Trash. Please restore it and try again."
3685
- msgstr ""
3686
-
3687
- msgid "Screen Options Tab"
3688
- msgstr ""
3689
-
3690
- msgid "The parametric search settings section has unsaved changes, so you can not hide it"
3691
- msgstr ""
3692
-
3693
- msgid "Pagination requires the Filter HTML section to be visible."
3694
- msgstr ""
3695
-
3696
- msgid "This section has unsaved changes, so you can not hide it"
3697
- msgstr ""
3698
-
3699
- msgid "Display Query section help"
3700
- msgstr ""
3701
-
3702
- msgid "Display Filter section help"
3703
- msgstr ""
3704
-
3705
- msgid "Display Layout section help"
3706
- msgstr ""
3707
-
3708
- msgid "View purpose"
3709
- msgstr ""
3710
-
3711
- msgid "All"
3712
- msgstr ""
3713
-
3714
- msgid "Slider"
3715
- msgstr ""
3716
-
3717
- msgid "Parametric"
3718
- msgstr ""
3719
-
3720
- msgid "Bootstrap Grid"
3721
- msgstr ""
3722
-
3723
- msgid "Full"
3724
- msgstr ""
3725
-
3726
- msgid "Note that those Screen Options are set per View."
3727
- msgstr ""
3728
-
3729
- msgid "Saved"
3730
- msgstr ""
3731
-
3732
- msgid "View saved"
3733
- msgstr ""
3734
-
3735
- msgid "View not saved"
3736
- msgstr ""
3737
-
3738
- msgid "View moved to trash"
3739
- msgstr ""
3740
-
3741
- msgid "View not moved to trash"
3742
- msgstr ""
3743
-
3744
- msgid "Title and description updated"
3745
- msgstr ""
3746
-
3747
- msgid "Title and description not saved"
3748
- msgstr ""
3749
-
3750
- msgid "Show on screen"
3751
- msgstr ""
3752
-
3753
- msgid "Query section"
3754
- msgstr ""
3755
-
3756
- msgid "Filter section"
3757
- msgstr ""
3758
-
3759
- msgid "Layout section"
3760
- msgstr ""
3761
-
3762
- msgid "Screen Options"
3763
- msgstr ""
3764
-
3765
- msgid "Return to the Layout"
3766
- msgstr ""
3767
-
3768
- msgid "Done editing this View?"
3769
- msgstr ""
3770
-
3771
- msgid "Close this window and return to the Layout"
3772
- msgstr ""
3773
-
3774
- msgid "Save all sections at once"
3775
- msgstr ""
3776
-
3777
- msgid "Enter title here"
3778
- msgstr ""
3779
-
3780
- msgid "Slug of this View"
3781
- msgstr ""
3782
-
3783
- msgid "Describe this View"
3784
- msgstr ""
3785
-
3786
- msgid "Done setting up this View?"
3787
- msgstr ""
3788
-
3789
- msgid "Taxonomy fields"
3790
- msgstr ""
3791
-
3792
- msgid "Using Content Template"
3793
- msgstr ""
3794
-
3795
- msgid "You can not leave the title empty."
3796
- msgstr ""
3797
-
3798
- msgid "You can not leave the slug empty."
3799
- msgstr ""
3800
-
3801
- msgid "The slug can only contain lowercase letters, numbers or dashes."
3802
- msgstr ""
3803
-
3804
- msgid "A %s with that name already exists. Please use another name."
3805
- msgstr ""
3806
-
3807
- msgid "A %s with that slug already exists. Please use another slug."
3808
- msgstr ""
3809
-
3810
- msgid "The View could not be created"
3811
- msgstr ""
3812
-
3813
- msgid "Slug not set in the AJAX call"
3814
- msgstr ""
3815
-
3816
- msgid "Single pages"
3817
- msgstr ""
3818
-
3819
- msgid "Post type archives"
3820
- msgstr ""
3821
-
3822
- msgid "Taxonomy archives"
3823
- msgstr ""
3824
-
3825
- msgid "Content template name"
3826
- msgstr ""
3827
-
3828
- msgid "Don’t use any Content Template for this Post Type"
3829
- msgstr ""
3830
-
3831
- msgid "Change Post Type"
3832
- msgstr ""
3833
-
3834
- msgid "Don’t use any Content Template for this Taxonomy"
3835
- msgstr ""
3836
-
3837
- msgid "Change Taxonomy"
3838
- msgstr ""
3839
-
3840
- msgid " use this content template. What do you want to do?"
3841
- msgstr ""
3842
-
3843
- msgid "Name of WordPress Archive for"
3844
- msgstr ""
3845
-
3846
- msgid "Select WordPress Archive For Loop"
3847
- msgstr ""
3848
-
3849
- msgid "Archive views"
3850
- msgstr ""
3851
-
3852
- msgid "Don't use a WordPress Archive for this loop"
3853
- msgstr ""
3854
-
3855
- msgid "What content will this template be for?"
3856
- msgstr ""
3857
-
3858
- msgid "Don't assign to any post type"
3859
- msgstr ""
3860
-
3861
- msgid "There are no single post types to assign Content Templates to"
3862
- msgstr ""
3863
-
3864
- msgid "There are no post type archives to assign Content Templates to"
3865
- msgstr ""
3866
-
3867
- msgid "There are no taxonomy archives to assign Content Templates to"
3868
- msgstr ""
3869
-
3870
- msgid "Create a template"
3871
- msgstr ""
3872
-
3873
- msgid "A Content Template that is already connected to this View"
3874
- msgstr ""
3875
-
3876
- msgid "Connect an existing Content template to this View"
3877
- msgstr ""
3878
-
3879
- msgid "Create a new Content Template for this View"
3880
- msgstr ""
3881
-
3882
- msgid "Insert shortcode to editor"
3883
- msgstr ""
3884
-
3885
- msgid "Add template"
3886
- msgstr ""
3887
-
3888
- msgid "Remove the Content Template from the view"
3889
- msgstr ""
3890
-
3891
- msgid "This will remove the link between your view and the Content Template. The Content Template will not be deleted."
3892
- msgstr ""
3893
-
3894
- msgid "Change Types"
3895
- msgstr ""
3896
-
3897
- msgid "Content template in use"
3898
- msgstr ""
3899
-
3900
- msgid "Choose a different content template for them: "
3901
- msgstr ""
3902
-
3903
- msgid "Select Content Template"
3904
- msgstr ""
3905
-
3906
- msgid "Don't use any content template for these items"
3907
- msgstr ""
3908
-
3909
- msgid "Ordered List"
3910
- msgstr ""
3911
-
3912
- msgid "Unordered List"
3913
- msgstr ""
3914
-
3915
- msgid "Grid"
3916
- msgstr ""
3917
-
3918
- msgid "Single view for "
3919
- msgstr ""
3920
-
3921
- msgid "Archive view for "
3922
- msgstr ""
3923
-
3924
- msgid "Loop view for "
3925
- msgstr ""
3926
-
3927
- msgid "This View displays results for an"
3928
- msgstr ""
3929
-
3930
- msgid "existing WordPress query"
3931
- msgstr ""
3932
-
3933
- msgid "No filters selected."
3934
- msgstr ""
3935
-
3936
- msgid "You attempted to edit a WordPress Archive that doesn&#8217;t exist. Perhaps it was deleted?"
3937
- msgstr ""
3938
-
3939
- msgid "You can’t edit this WordPress Archive because it is in the Trash. Please restore it and try again."
3940
- msgstr ""
3941
-
3942
- msgid "Edit WordPress Archive"
3943
- msgstr ""
3944
-
3945
- msgid "Edit Layouts Loop View"
3946
- msgstr ""
3947
-
3948
- msgid "Loop section"
3949
- msgstr ""
3950
-
3951
- msgid "Slug of this WordPress Archive"
3952
- msgstr ""
3953
-
3954
- msgid "The layout section styles the WordPress Archive output on the page."
3955
- msgstr ""
3956
-
3957
- msgid "The layout-style and fields that you selected generate meta HTML. This meta HTML includes shortcodes and HTML, which you can edit, to fully customize the appearance of this View's content output section."
3958
- msgstr ""
3959
-
3960
- msgid "Generate the new layout content"
3961
- msgstr ""
3962
-
3963
- msgid "dismiss"
3964
- msgstr ""
3965
-
3966
- msgid "The view layout settings will be copied from the original"
3967
- msgstr ""
3968
-
3969
- msgid "Using Content Template:"
3970
- msgstr ""
3971
-
3972
- msgid "Using Content template:"
3973
- msgstr ""
3974
-
3975
- msgid "Fields to include:"
3976
- msgstr ""
3977
-
3978
- msgid "Click on <strong>Add field</strong> to insert additional fields. Drag them to reorder, or delete fields that you don't need."
3979
- msgstr ""
3980
-
3981
- msgid "Click on <strong>Add field</strong> to insert fields to this View."
3982
- msgstr ""
3983
-
3984
- msgid "Prefix"
3985
- msgstr ""
3986
-
3987
- msgid "Row Title"
3988
- msgstr ""
3989
-
3990
- msgid "Suffix"
3991
- msgstr ""
3992
-
3993
- msgid "Want to add complex fields?"
3994
- msgstr ""
3995
-
3996
- msgid "Learn about using Content Templates to customize fields."
3997
- msgstr ""
3998
-
3999
- msgid "Want to display posts that belong to this taxonomy? Learn about %sinserting child Views to Taxonomy Views%s."
4000
- msgstr ""
4001
-
4002
- msgid "Are you sure you want to change the layout?"
4003
- msgstr ""
4004
-
4005
- msgid "It appears that you made modifications to the layout."
4006
- msgstr ""
4007
-
4008
- msgid " - Use to layout child taxonomy terms"
4009
- msgstr ""
4010
-
4011
- msgid " - Use to layout posts for the current taxonomy term"
4012
- msgstr ""
4013
-
4014
- msgid "This View selects Taxonomy of type %s"
4015
- msgstr ""
4016
-
4017
- msgid ", ordered by %s, %s"
4018
- msgstr ""
4019
-
4020
- msgid "Views Pagination"
4021
- msgstr ""
4022
-
4023
- msgid "Use as spinner image"
4024
- msgstr ""
4025
-
4026
- msgid "View/Edit Meta HTML"
4027
- msgstr ""
4028
-
4029
- msgid "<strong>Meta HTML</strong> - This is used to layout the posts found. It gets generated from the View Layout settings and can be modified to suit."
4030
- msgstr ""
4031
-
4032
- msgid "Changes can't be applied. It appears that you made manual modifications to the Meta HTML."
4033
- msgstr ""
4034
-
4035
- msgid "(your edits will be displayed and you can apply them again)"
4036
- msgstr ""
4037
-
4038
- msgid "<strong>Your edits are shown below:</strong>"
4039
- msgstr ""
4040
-
4041
- msgid "* These updates will take effect when you save the view."
4042
- msgstr ""
4043
-
4044
- msgid "Edit CSS"
4045
- msgstr ""
4046
-
4047
- msgid "<strong>CSS</strong> - This is used to add custom CSS to a View layout."
4048
- msgstr ""
4049
-
4050
- msgid "Edit JS"
4051
- msgstr ""
4052
-
4053
- msgid "<strong>JS</strong> - This is used to add custom javascript to a View layout."
4054
- msgstr ""
4055
-
4056
- msgid "Manage Media"
4057
- msgstr ""
4058
-
4059
- msgid "<strong>Media</strong> - This is used to add images to a View output."
4060
- msgstr ""
4061
-
4062
- msgid "Upload images"
4063
- msgstr ""
4064
-
4065
- msgid "Add Media"
4066
- msgstr ""
4067
-
4068
- msgid "Edit media items"
4069
- msgstr ""
4070
-
4071
- msgid "Edit media items"
4072
- msgstr ""
4073
-
4074
- msgid "Close Media manager"
4075
- msgstr ""
4076
-
4077
- msgid "Layout style:"
4078
- msgstr ""
4079
-
4080
- msgid "Layout the items using a HTML table"
4081
- msgstr ""
4082
-
4083
- msgid "Number of columns:"
4084
- msgstr ""
4085
-
4086
- msgid "Create a table of items with a column for each field"
4087
- msgstr ""
4088
-
4089
- msgid "Items are added to an ordered list"
4090
- msgstr ""
4091
-
4092
- msgid "Items are added to an unordered list"
4093
- msgstr ""
4094
-
4095
- msgid "* Views requires Types 1.0.2 or greater for best results when adding fields."
4096
- msgstr ""
4097
-
4098
- msgid "Log into <a href=\"%s\">your account</a> and go to <a href=\"%s\">affiliate settings</a> for details."
4099
- msgstr ""
4100
-
4101
- msgid "Views Import / Export"
4102
- msgstr ""
4103
-
4104
- msgid "Export Views, WordPress Archives and Content Templates"
4105
- msgstr ""
4106
-
4107
- msgid "Download all Views, WordPress Archives and Content Templates"
4108
- msgstr ""
4109
-
4110
- msgid "When importing to theme:"
4111
- msgstr ""
4112
-
4113
- msgid "ask user for approval"
4114
- msgstr ""
4115
-
4116
- msgid "import automatically"
4117
- msgstr ""
4118
-
4119
- msgid "Affiliate details for theme designers:"
4120
- msgstr ""
4121
-
4122
- msgid "Affiliate ID:"
4123
- msgstr ""
4124
-
4125
- msgid "Affiliate Key:"
4126
- msgstr ""
4127
-
4128
- msgid "You only need to enter affiliate settings if you are a theme designer and want to receive affiliate commission."
4129
- msgstr ""
4130
-
4131
- msgid "Filter"
4132
- msgstr ""
4133
-
4134
- msgid "This View displays results for an <strong>existing WordPress query</strong>"
4135
- msgstr ""
4136
-
4137
- msgid "How this Content Template is used"
4138
- msgstr ""
4139
-
4140
- msgid "Fields used"
4141
- msgstr ""
4142
-
4143
- msgid "Import/Export"
4144
- msgstr ""
4145
-
4146
- msgid "Help"
4147
- msgstr ""
4148
-
4149
- msgid "Use <strong>Content Templates</strong> to design single pages in your site. "
4150
- msgstr ""
4151
-
4152
- msgid "This page lists the <strong>Content Templates</strong> that you have created and allows you to create new ones."
4153
- msgstr ""
4154
-
4155
- msgid "The ‘arrange by’ line, at the top of the page, lets you list the <strong>Content Templates</strong> by their name or by how they are used in the site."
4156
- msgstr ""
4157
-
4158
- msgid "Click on the name of a Content Template to edit it or create new <strong>Content Templates</strong> using the ‘Add’ buttons."
4159
- msgstr ""
4160
-
4161
- msgid "Content Templates online help"
4162
- msgstr ""
4163
-
4164
- msgid "<strong>Content Templates</strong> let you design single pages in your site."
4165
- msgstr ""
4166
-
4167
- msgid "To Create a <strong>Content Template</strong>:"
4168
- msgstr ""
4169
-
4170
- msgid "Set the title."
4171
- msgstr ""
4172
-
4173
- msgid "Add fields to the body. Use the V icon to insert basic fields, custom fields, taxonomy and Views. If you are using CRED, use the C icon to insert CRED forms."
4174
- msgstr ""
4175
-
4176
- msgid "Style the output by adding HTML around shortcodes."
4177
- msgstr ""
4178
-
4179
- msgid "Use <strong>Views</strong> to load content from the database and display it anyway you choose."
4180
- msgstr ""
4181
-
4182
- msgid "This page lists the <strong>Views</strong> in your site. Under ‘actions’, you will find ‘duplicate’ and ‘delete’ for Views."
4183
- msgstr ""
4184
-
4185
- msgid "Click on a <strong>Views</strong> name to edit it or create new Views."
4186
- msgstr ""
4187
-
4188
- msgid "Views online help"
4189
- msgstr ""
4190
-
4191
- msgid "Use <strong>WordPress Archives</strong> to style and design standard listing and archive pages."
4192
- msgstr ""
4193
-
4194
- msgid "This page lists the <strong>WordPress Archives</strong> in your site."
4195
- msgstr ""
4196
-
4197
- msgid "The ‘arrange by’ line, at the top of the page, lets you list the <strong>WordPress Archives</strong> by their name or by how they are used in the site."
4198
- msgstr ""
4199
-
4200
- msgid "Click on the name of a <strong>WordPress Archives</strong> to edit it or create new WordPress Archives using the ‘Add’ buttons."
4201
- msgstr ""
4202
-
4203
- msgid "WordPress Archives online help"
4204
- msgstr ""
4205
-
4206
- msgid "Use <strong>Views</strong> to filter and display lists in complex and interesting ways. Read more about Views in our user guide:"
4207
- msgstr ""
4208
-
4209
- msgid "This page gives you an overview of the Views you have created."
4210
- msgstr ""
4211
-
4212
- msgid "It has the following options:"
4213
- msgstr ""
4214
-
4215
- msgid "<strong>Add New</strong>: Add a New View"
4216
- msgstr ""
4217
-
4218
- msgid "If you hover over a View's name you also have these options:"
4219
- msgstr ""
4220
-
4221
- msgid "<strong>Edit</strong>: Click to edit the View<br />\n"
4222
- msgstr ""
4223
-
4224
- msgid "<strong>Quick Edit</strong>: click to get quick editing options for the View, such as title, slug and date"
4225
- msgstr ""
4226
-
4227
- msgid "<strong>Trash</strong>: Move the View to Trash"
4228
- msgstr ""
4229
-
4230
- msgid "If you need additional help with Content Templates you can visit our <a href='%s' target='_blank'>support forum &raquo;</a>."
4231
- msgstr ""
4232
-
4233
- msgid "<strong>WordPress Archives</strong> let you style and design standard listing and archive pages."
4234
- msgstr ""
4235
-
4236
- msgid "To create a <strong>WordPress Archive</strong>:"
4237
- msgstr ""
4238
-
4239
- msgid "Set the title"
4240
- msgstr ""
4241
-
4242
- msgid "Select on which listing pages it displays"
4243
- msgstr ""
4244
-
4245
- msgid "Design the output for the View by inserting fields and styling with HTML"
4246
- msgstr ""
4247
-
4248
- msgid "<strong>Views</strong> load content from the database and display it anyway you choose."
4249
- msgstr ""
4250
-
4251
- msgid "To make it easier to use Views, we’ve created different preset usage modes for <strong>Views</strong>. Each usage mode emphasizes the features that you need and hides the ones that are not needed."
4252
- msgstr ""
4253
-
4254
- msgid "You can switch between the different <strong>Views</strong> usage mode by opening the ‘Screen options’ tab."
4255
- msgstr ""
4256
-
4257
- msgid "To create a <strong>View</strong>:"
4258
- msgstr ""
4259
-
4260
- msgid "Select the content to load"
4261
- msgstr ""
4262
-
4263
- msgid "Optionally, apply a filter to the query"
4264
- msgstr ""
4265
-
4266
- msgid "If needed, enable pagination and front-end filters"
4267
- msgstr ""
4268
-
4269
- msgid "When you are done, remember to add the <strong>View</strong> to your content. You can do that by inserting the <strong>View</strong> as a shortcode to content or displaying it as a widget."
4270
- msgstr ""
4271
-
4272
- msgid "This View was not saved correctly. You may need to increase the number of post variables allowed in PHP. <a href=\"%s\">How to increase max_post_vars setting</a>."
4273
- msgstr ""
4274
-
4275
- msgid "Views sync"
4276
- msgstr ""
4277
-
4278
- msgid "Duplicate view from original"
4279
- msgstr ""
4280
-
4281
- msgid "Duplicate view to translations"
4282
- msgstr ""
4283
-
4284
- msgid "You can get the details in the <a href=\"%s\" title=\"Documentation on the shortcodes within shortcodes\">documentation page</a>."
4285
- msgstr ""
4286
-
4287
- msgid "You can get the details in the <a href=\"%s\" title=\"Documentation on the Views debug tool\">documentation page</a>."
4288
- msgstr ""
4289
-
4290
- msgid "You can get the details in the <a href=\"%s\" title=\"Documentation on the Views Maps plugin\">documentation page</a>."
4291
- msgstr ""
4292
-
4293
- msgid "Bootstrap version overriden by the Layouts plugin settings to use Bootstrap v.%s"
4294
- msgstr ""
4295
-
4296
- msgid "You can get the details in the <a href=\"%s\" title=\"Documentation on the Bootstrap Layouts\">documentation page</a>."
4297
- msgstr ""
4298
-
4299
- msgid "You can only use an image file here"
4300
- msgstr ""
4301
-
4302
- msgid "You need to place your cursor between the [wpv-filter-start] and the [wpv-filter-end] shortcodes"
4303
- msgstr ""
4304
-
4305
- msgid "You need to place your cursor between the [wpv-layout-start] and the [wpv-layout-end] shortcodes"
4306
- msgstr ""
4307
-
4308
- msgid "This is an optional placeholder to wrap the pagination shortcodes. The content of this shortcode will only be displayed if there is more than one page of results."
4309
- msgstr ""
4310
-
4311
- msgid "Displays the current page number"
4312
- msgstr ""
4313
-
4314
- msgid "Displays the maximum number of pages found by the Views Query."
4315
- msgstr ""
4316
-
4317
- msgid "Displays a pager with the current page selected. Depending on the value of the <em>style</em> parameter it displays a list of links to the other pages or a drop-down list to select another page."
4318
- msgstr ""
4319
-
4320
- msgid "Display a <em>Previous</em> link to move to the previous page."
4321
- msgstr ""
4322
-
4323
- msgid "Display a <em>Next</em> link to move to the next page."
4324
- msgstr ""
4325
-
4326
- msgid "Views Settings"
4327
- msgstr ""
4328
-
4329
- msgid "Third-party shortcode arguments"
4330
- msgstr ""
4331
-
4332
- msgid "List of custom and third-party shortcodes you want to be able to use as Views shortcode arguments."
4333
- msgstr ""
4334
-
4335
- msgid "For example, to support [wpv-post-title id=\"[my-custom-shortcode]\"] add <strong>my-custom-shortcode</strong> as a third-party shortcode argument below."
4336
- msgstr ""
4337
-
4338
- msgid "Shortcode name"
4339
- msgstr ""
4340
-
4341
- msgid "Add"
4342
- msgstr ""
4343
-
4344
- msgid "Only letters, numbers, underscores and dashes"
4345
- msgstr ""
4346
-
4347
- msgid "That shortcode already exists"
4348
- msgstr ""
4349
-
4350
- msgid "An error ocurred"
4351
- msgstr ""
4352
-
4353
- msgid "Debug mode"
4354
- msgstr ""
4355
-
4356
- msgid "Enabling Views debug will open a popup on every page showing a Views element."
4357
- msgstr ""
4358
-
4359
- msgid "This popup will show usefull information about the elements being displayed: time needed to render, memory used, shortcodes details..."
4360
- msgstr ""
4361
-
4362
- msgid "There are two modes: compact and full. Compact mode will give you an overview of the elements rendered. The full mode will display a complete report with all the object involved on the page."
4363
- msgstr ""
4364
-
4365
- msgid "Enable Views debug mode"
4366
- msgstr ""
4367
-
4368
- msgid "Compact debug mode"
4369
- msgstr ""
4370
-
4371
- msgid "Full debug mode"
4372
- msgstr ""
4373
-
4374
- msgid "Did a new window just open?"
4375
- msgstr ""
4376
-
4377
- msgid "Yes, it worked"
4378
- msgstr ""
4379
-
4380
- msgid "No, nothing opened"
4381
- msgstr ""
4382
-
4383
- msgid "Views debugger is ready for use. Thanks for checking it"
4384
- msgstr ""
4385
-
4386
- msgid "Seems like your browser is blocking popups. You should allow all popup windows from this site to use the Views debugger."
4387
- msgstr ""
4388
-
4389
- msgid "Please refer to the following links for documentation related to the most used browsers:"
4390
- msgstr ""
4391
-
4392
- msgid "Views debugger will need to open a popup window. Your browser may block it, so let's check that it's working for you."
4393
- msgstr ""
4394
-
4395
- msgid "Test the debugger window"
4396
- msgstr ""
4397
-
4398
- msgid "It's OK, skip this test"
4399
- msgstr ""
4400
-
4401
- msgid "Test debugger window"
4402
- msgstr ""
4403
-
4404
- msgid "It works!"
4405
- msgstr ""
4406
-
4407
- msgid "You can close this window and click 'Yes, it worked' in the Views settings page."
4408
- msgstr ""
4409
-
4410
- msgid "Map plugin"
4411
- msgstr ""
4412
-
4413
- msgid "Enabling Views Maps will add the Google Maps API and the Views Maps plugin to your site."
4414
- msgstr ""
4415
-
4416
- msgid "This will let you create maps on your site and use Views to plot WordPress posts on a Google Map."
4417
- msgstr ""
4418
-
4419
- msgid "Enable Views Map Plugin"
4420
- msgstr ""
4421
-
4422
- msgid "Frontend Edit Links"
4423
- msgstr ""
4424
-
4425
- msgid "You can enable/disable the edit links on the frontend for Views, Content Templates and WordPress Archives. Remember that the frontend edit links are only visible to administrators."
4426
- msgstr ""
4427
-
4428
- msgid "Enable edit links on the frontend"
4429
- msgstr ""
4430
-
4431
- msgid "Bootstrap Layouts"
4432
- msgstr ""
4433
-
4434
- msgid "You can set here the Bootstrap version that you want to use, based on the one <strong>provided by your theme</strong>. We will then generate the right markup in the Views Layouts Wizard when using the Bootstrap Grid option."
4435
- msgstr ""
4436
-
4437
- msgid "Bootstrap version not set"
4438
- msgstr ""
4439
-
4440
- msgid "Bootstrap v. 2.0"
4441
- msgstr ""
4442
-
4443
- msgid "Bootstrap v. 3.0"
4444
- msgstr ""
4445
-
4446
- msgid "Hidden custom fields"
4447
- msgstr ""
4448
-
4449
- msgid "The following private custom fields are showing in the Views GUI:"
4450
- msgstr ""
4451
-
4452
- msgid "No private custom fields are showing in the Views GUI."
4453
- msgstr ""
4454
-
4455
- msgid "Views Help"
4456
- msgstr ""
4457
-
4458
- msgid "Building Websites with Views"
4459
- msgstr ""
4460
-
4461
- msgid "Views plugin lets you design single pages, display content from the database and customize standard listing pages."
4462
- msgstr ""
4463
-
4464
- msgid "Here are the things that you can create with Views plugin:"
4465
- msgstr ""
4466
-
4467
- msgid "A View loads content from the database and displays it anyway you choose. Use Views to create content lists, sliders, parametric searches and more.\n"
4468
- msgstr ""
4469
-
4470
- msgid "Create a new View"
4471
- msgstr ""
4472
-
4473
- msgid "Content Templates let you design single pages using fields, taxonomy and HTML. With Content Templates, you can design the output for posts, pages and custom post types."
4474
- msgstr ""
4475
-
4476
- msgid "Create a new Content Template"
4477
- msgstr ""
4478
-
4479
- msgid "WordPress Archives let you customize standard listing pages. You will be able to customize the blog, custom post archives, taxonomy pages and other standard listing pages."
4480
- msgstr ""
4481
-
4482
- msgid "Create a new WordPress Archive"
4483
- msgstr ""
4484
-
4485
- msgid "Learning Views"
4486
- msgstr ""
4487
-
4488
- msgid "Views Training"
4489
- msgstr ""
4490
-
4491
- msgid "an interactive course that takes you through the basics and advanced features of Views."
4492
- msgstr ""
4493
-
4494
- msgid "Learn by building a real site, using sample data and step-by-step tutorials that we’ve prepared for you."
4495
- msgstr ""
4496
-
4497
- msgid "Views Documentation"
4498
- msgstr ""
4499
-
4500
- msgid "a complete reference library for everything in Views."
4501
- msgstr ""
4502
-
4503
- msgid "Support forum"
4504
- msgstr ""
4505
-
4506
- msgid "need any technical help? Our support staff are waiting for you in our forum."
4507
- msgstr ""
4508
-
4509
- msgid "Views subscription"
4510
- msgstr ""
4511
-
4512
- msgid "wp-types.com subscription email"
4513
- msgstr ""
4514
-
4515
- msgid "wp-types.com subscription key"
4516
- msgstr ""
4517
-
4518
- msgid "Save subscription details"
4519
- msgstr ""
4520
-
4521
- msgid "Saving. Please wait..."
4522
- msgstr ""
4523
-
4524
- msgid "Views 1.3.1 is compatible with Types version 1.4.0.2 or greater. Please update Types. | <a href=\"%1$s\">Dismiss</a>"
4525
- msgstr ""
4526
-
4527
- msgid "Views 1.3.1 is compatible with CRED version 1.2.3 or greater. Please update CRED. | <a href=\"%1$s\">Dismiss</a>"
4528
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/localization/locale/views-ar.mo DELETED
Binary file
embedded/common/localization/locale/views-bg_BG.mo DELETED
Binary file
embedded/common/localization/locale/views-de_DE.mo DELETED
Binary file
embedded/common/localization/locale/views-el.mo DELETED
Binary file
embedded/common/localization/locale/views-es_ES.mo DELETED
Binary file
embedded/common/localization/locale/views-fr_FR.mo DELETED
Binary file
embedded/common/localization/locale/views-he_IL.mo DELETED
Binary file
embedded/common/localization/locale/views-it_IT.mo DELETED
Binary file
embedded/common/localization/locale/views-ja.mo DELETED
Binary file
embedded/common/localization/locale/views-ko_KR.mo DELETED
Binary file
embedded/common/localization/locale/views-nl_NL.mo DELETED
Binary file
embedded/common/localization/locale/views-pl_PL.mo DELETED
Binary file
embedded/common/localization/locale/views-pt_BR.mo DELETED
Binary file
embedded/common/localization/locale/views-pt_PT.mo DELETED
Binary file
embedded/common/localization/locale/views-ru_RU.mo DELETED
Binary file
embedded/common/localization/locale/views-sv_SE.mo DELETED
Binary file
embedded/common/localization/locale/views-uk.mo DELETED
Binary file
embedded/common/localization/locale/views-vi.mo DELETED
Binary file
embedded/common/localization/locale/views-zh_CN.mo DELETED
Binary file
embedded/common/localization/locale/views-zh_TW.mo DELETED
Binary file
embedded/common/localization/wpt-localization.php DELETED
@@ -1,61 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * wpt-localization.php
5
- *
6
- * Common localization for shared code on the Toolset and also common way for adding textdomains
7
- *
8
- * @since Jul 18 2014
9
- */
10
-
11
- if ( defined( 'WPT_LOCALIZATION' ) ) {
12
- return;
13
- }
14
-
15
- define( 'WPT_LOCALIZATION', true );
16
- define( 'WPT_LOCALIZATION_ABSPATH', dirname( __FILE__ ) . '/locale' );
17
-
18
- /*
19
- * WPToolset_Localization
20
- *
21
- * Methods for registering textdomains
22
- *
23
- */
24
-
25
- class WPToolset_Localization {
26
-
27
- /*
28
- * @param $textdomain (string) the textdomain to use
29
- * @param $path (string) the path to the folder containing the mo files
30
- * @param $mo_file (string) the .mo file name, using %s as a placeholder for the locale - do not add the .mo extension!
31
- */
32
-
33
- function __construct( $textdomain = 'wpv-views', $path = WPT_LOCALIZATION_ABSPATH, $mo_name = 'views-%s' ) {
34
- // Set instance properties
35
- $this->textdomain = $textdomain;
36
- $this->path = $path;
37
- $this->mo_name = $mo_name;
38
- $this->mo_processed_name = '';
39
- // Set init action
40
- add_action( 'init', array( $this, 'load_textdomain' ) );
41
- }
42
-
43
- /*
44
- * load_textdomain
45
- *
46
- * Initializes localization given a textdomain, a path and a .mo file name
47
- *
48
- * @uses load_textdomain
49
- *
50
- * @since July 18, 2014
51
- */
52
-
53
- function load_textdomain() {
54
- $locale = get_locale();
55
- $this->mo_processed_name = sprintf( $this->mo_name, $locale );
56
- load_textdomain( $this->textdomain, $this->path . '/' . $this->mo_processed_name . '.mo' );
57
- }
58
-
59
- }
60
-
61
- new WPToolset_Localization();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/res/css/colorbox.css DELETED
@@ -1,88 +0,0 @@
1
- /* -------- */
2
- /* Colorbox */
3
- /* -------- */
4
-
5
- /* This file contains styles for default Colorbox elements only */
6
- /* TODO: This file can be removed, we can load it from common */
7
-
8
- body.disable-scrollbar {
9
- overflow: hidden;
10
- }
11
-
12
- #colorbox,
13
- #cboxOverlay,
14
- #cboxWrapper {
15
- position:absolute;
16
- top:0;
17
- left:0;
18
- z-index:10000;
19
- /* overflow:hidden;*/
20
- }
21
-
22
- #cboxOverlay {
23
- position:fixed;
24
- width:100%;
25
- max-width: 100%;
26
- height:100%;
27
- background: #000;
28
- }
29
- #cboxMiddleLeft,
30
- #cboxBottomLeft {
31
- clear:left;
32
- }
33
- #cboxContent {
34
- position:relative;
35
- }
36
- #cboxLoadedContent {
37
- overflow:visible!important;
38
- -webkit-overflow-scrolling: touch;
39
- }
40
- #cboxTitle {
41
- margin:0;
42
- }
43
- #cboxLoadingOverlay,
44
- #cboxLoadingGraphic {
45
- position:absolute;
46
- top:0;
47
- left:0;
48
- width:100%;
49
- height:100%;
50
- }
51
- #cboxPrevious,
52
- #cboxNext,
53
- #cboxClose,
54
- #cboxSlideshow {
55
- cursor:pointer;
56
- }
57
- .cboxPhoto {
58
- display:block;
59
- float:left;
60
- margin:auto;
61
- max-width:none;
62
- border:0;
63
- -ms-interpolation-mode:bicubic;
64
- }
65
- .cboxIframe {
66
- display:block;
67
- width:100%;
68
- height:100%;
69
- border:0;
70
- }
71
- #colorbox,
72
- #cboxContent,
73
- #cboxLoadedContent {
74
- -webkit-box-sizing:content-box;
75
- -moz-box-sizing:content-box;
76
- box-sizing:content-box;
77
- }
78
-
79
- .cboxIE #cboxTopLeft,
80
- .cboxIE #cboxTopCenter,
81
- .cboxIE #cboxTopRight,
82
- .cboxIE #cboxBottomLeft,
83
- .cboxIE #cboxBottomCenter,
84
- .cboxIE #cboxBottomRight,
85
- .cboxIE #cboxMiddleLeft,
86
- .cboxIE #cboxMiddleRight {
87
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
88
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/res/css/toolset-common.css DELETED
@@ -1,74 +0,0 @@
1
- /* ----------------------------------------------------------------------------
2
- Common styles for all the Toolset family
3
- ---------------------------------------------------------------------------- */
4
-
5
- /* ----------------------------------------------------------------------------
6
- Toolset Primary Button Style - use with .button.button-primary-toolset classnames
7
- ---------------------------------------------------------------------------- */
8
-
9
- .wp-core-ui .button-primary-toolset {
10
- background: #f6921e;
11
- border-color: #EF6223;
12
- -webkit-box-shadow: inset 0 1px 0 rgba(239, 239, 239, 0.5), 0 1px 0 rgba(0,0,0,.15);
13
- box-shadow: inset 0 1px 0 rgba(239, 239, 239, 0.5), 0 1px 0 rgba(0,0,0,.15);
14
- color: #fff !important;
15
- text-decoration: none;
16
- }
17
-
18
- .wp-core-ui .button-primary-toolset.hover,
19
- .wp-core-ui .button-primary-toolset:hover,
20
- .wp-core-ui .button-primary-toolset.focus,
21
- .wp-core-ui .button-primary-toolset:focus {
22
- background: #EF6223;
23
- border-color: #EF6223;
24
- -webkit-box-shadow: inset 0 1px 0 rgba(239, 239, 239, 0.5);
25
- box-shadow: inset 0 1px 0 rgba(239, 239, 239, 0.5);
26
- color: #fff !important;
27
- }
28
-
29
- .wp-core-ui .button-primary-toolset.focus,
30
- .wp-core-ui .button-primary-toolset:focus {
31
- border-color: #EF6223;
32
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
33
- box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
34
- }
35
-
36
- .wp-core-ui .button-primary-toolset.active,
37
- .wp-core-ui .button-primary-toolset.active:hover,
38
- .wp-core-ui .button-primary-toolset.active:focus,
39
- .wp-core-ui .button-primary-toolset:active {
40
- background: #f6921e;
41
- border-color: #EF6223;
42
- color: rgba(255,255,255,0.95);
43
- -webkit-box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
44
- box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
45
- }
46
-
47
- .wp-core-ui .button-primary-toolset[disabled],
48
- .wp-core-ui .button-primary-toolset:disabled,
49
- .wp-core-ui .button-primary-toolset.disabled {
50
- color: #94cde7 !important;
51
- background: #298cba !important;
52
- border-color: #1b607f !important;
53
- -webkit-box-shadow: none !important;
54
- box-shadow: none !important;
55
- text-shadow: 0 -1px 0 rgba(0,0,0,0.1) !important;
56
- cursor: default;
57
- }
58
-
59
- /* ----------------------------------------------------------------------------
60
- Generic CSS to be applied anywhere
61
- ---------------------------------------------------------------------------- */
62
- .padding-top-30{padding-top:30px;}
63
-
64
- /* ----------------------------------------------------------------------------
65
- Design with Toolset icon
66
- ---------------------------------------------------------------------------- */
67
- #wpadminbar ul#wp-admin-bar-root-default> li.toolset-edit-link { white-space: nowrap; }
68
-
69
- #wpadminbar ul#wp-admin-bar-root-default> li.toolset-edit-link> a { position:relative; }
70
- #wpadminbar ul#wp-admin-bar-root-default> li.toolset-edit-link> a:before {
71
- font-family: "onthegosystems-icons"!important;
72
- content: "\f11a";
73
- top:2px;
74
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/res/css/toolset-menu-icon.css DELETED
@@ -1,29 +0,0 @@
1
- a[href="admin.php?page=dd_layouts"] .wp-menu-image img{
2
- position: relative;
3
- top: -2px;
4
- }
5
-
6
- a[href="admin.php?page=types_access"] .wp-menu-image img{
7
- position: relative;
8
- top: -3px;
9
- }
10
-
11
- a[href="admin.php?page=wpcf-ctt"] .wp-menu-image img{
12
- position: relative;
13
- top: -2px;
14
- }
15
-
16
- a[href="admin.php?page=ModuleManager_Modules"] .wp-menu-image img{
17
- position: relative;
18
- top: -4px;
19
- }
20
-
21
- a[href="admin.php?page=CRED_Forms"] .wp-menu-image img{
22
- position: relative;
23
- top: -2px;
24
- }
25
-
26
- a[href="admin.php?page=views"] .wp-menu-image img{
27
- position: relative;
28
- top: -1px;
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/res/css/toolset-promotion.css DELETED
@@ -1,164 +0,0 @@
1
-
2
- .toolset-modal
3
- {
4
- font-family: "Open Sans";
5
- font-size: 15px;
6
- width: 550px;
7
- background-color: #fff;
8
- padding: 45px 0 20px 0;
9
- position: relative;
10
-
11
- -webkit-box-shadow: 5px 5px 15px 0px rgba(50, 50, 50, 0.38);
12
- -moz-box-shadow: 5px 5px 15px 0px rgba(50, 50, 50, 0.38);
13
- box-shadow: 5px 5px 15px 0px rgba(50, 50, 50, 0.38);
14
-
15
- }
16
-
17
- .toolset-modal h2
18
- {
19
- color: #fff;
20
- position: relative;
21
- background-color: #333;
22
- padding: 10px 30px;
23
- font-size: 24px;
24
- line-height: 30px;
25
- font-weight: 300;
26
- margin: 0;
27
- }
28
-
29
- .toolset-modal .icon-toolset-logo
30
- {
31
- color: #f05a28;
32
- position: absolute;
33
- top: 6px;
34
- left: 23px;
35
- font-size: 53px;
36
- background: transparent url(../images/toolset.promotion/toolset.png) no-repeat 7px 3px;
37
- width: 55px;
38
- height: 55px;
39
- }
40
-
41
- .toolset-modal .icon-toolset-logo:before
42
- {
43
- content: none;
44
- display: none;
45
- }
46
-
47
- .toolset-modal ul:before
48
- {
49
- content: "";
50
- display: table;
51
- }
52
-
53
- .toolset-modal .content
54
- {
55
- padding: 0 28px;
56
- }
57
-
58
- .toolset-modal ul
59
- {
60
- display: table-row;
61
- }
62
-
63
- .toolset-modal li:first-child
64
- {
65
- min-width: 75px;
66
- }
67
-
68
- .toolset-modal li:last-child
69
- {
70
- padding-right: 0;
71
- min-width: 115px;
72
- }
73
-
74
- .toolset-modal li
75
- ,.js-close-promotional-message
76
- {
77
- background: transparent url(../images/toolset.promotion/icons.png) no-repeat;
78
- }
79
-
80
- .toolset-modal li
81
- {
82
- display: table-cell;
83
- font-size: 13px;
84
- font-weight: 700;
85
- height: 46px;
86
- padding: 0 20px 0 38px;
87
- }
88
-
89
-
90
- .toolset-modal li.layout{background-position: 0 -65px}
91
- .toolset-modal li.toolset-search{background-position: 0 -130px}
92
- .toolset-modal li.list {background-position: 0 -195px}
93
- .toolset-modal li.form {background-position: 0 -260px}
94
- .toolset-modal li.more {background-position: 0 -325px}
95
-
96
- .toolset-modal .full img
97
- {
98
- padding-bottom: 19px;
99
- }
100
-
101
- .toolset-modal .full
102
- {
103
- background: transparent url(../images/toolset.promotion/full.jpg) no-repeat;
104
- padding-left: 298px;
105
- min-height: 160px;
106
- font-size: 15px;
107
- margin: 10px 0 0 0;
108
- }
109
-
110
- .toolset-modal .icons
111
- {
112
- border: 1px solid #777;
113
- border-width: 1px 0;
114
- padding-top: 10px;
115
- }
116
-
117
- .toolset-modal .description
118
- {
119
- font-size: 13px;
120
- color: #4d4d4d;
121
- margin: 10px 0 20px 0;
122
- }
123
-
124
- .toolset-modal em
125
- {
126
- font-weight: 600;
127
- }
128
-
129
- .toolset-modal .button
130
- {
131
- padding: 10px 15px;
132
- background-color: #f05a28;
133
- color: #fff;
134
- text-decoration: none;
135
- margin-top: -10px;
136
- height: auto;
137
- font-size: 18px;
138
- line-height: 1em;
139
- }
140
-
141
- .toolset-modal .learn
142
- {
143
- font-size: 15px;
144
- color: #f05a28;
145
- display: inline-block;
146
- margin-left: 20px;
147
- }
148
-
149
- .ddl-dialogs-container
150
- {
151
- display: none;
152
- }
153
-
154
- .js-close-promotional-message
155
- {
156
- background-position: 0 -480px;
157
- cursor: pointer;
158
- display: block;
159
- height: 20px;
160
- position: absolute;
161
- right: -10px;
162
- top: -10px;
163
- width: 20px;
164
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/res/css/wpv-wp-pointer.css DELETED
@@ -1,4 +0,0 @@
1
- .wpv_wp_pointer_clear_ignores {
2
- margin-top : 20px;
3
- font-style : italic;
4
- }
 
 
 
 
embedded/common/res/images/question.png DELETED
Binary file
embedded/common/res/images/toolset.promotion/full.jpg DELETED
Binary file
embedded/common/res/images/toolset.promotion/icons.png DELETED
Binary file
embedded/common/res/images/toolset.promotion/toolset.png DELETED
Binary file
embedded/common/res/js/jquery.colorbox-min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- Colorbox v1.4.31 - 2013-09-25
3
- jQuery lightbox and modal window plugin
4
- (c) 2013 Jack Moore - http://www.jacklmoore.com/colorbox
5
- license: http://www.opensource.org/licenses/mit-license.php
6
- */
7
- (function(e,t,i){function o(i,o,n){var r=t.createElement(i);return o&&(r.id=Z+o),n&&(r.style.cssText=n),e(r)}function n(){return i.innerHeight?i.innerHeight:e(i).height()}function r(e){var t=k.length,i=(z+e)%t;return 0>i?t+i:i}function h(e,t){return Math.round((/%/.test(e)?("x"===t?E.width():n())/100:1)*parseInt(e,10))}function s(e,t){return e.photo||e.photoRegex.test(t)}function l(e,t){return e.retinaUrl&&i.devicePixelRatio>1?t.replace(e.photoRegex,e.retinaSuffix):t}function a(e){"contains"in g[0]&&!g[0].contains(e.target)&&(e.stopPropagation(),g.focus())}function d(){var t,i=e.data(N,Y);null==i?(B=e.extend({},X),console&&console.log&&console.log("Error: cboxElement missing settings object")):B=e.extend({},i);for(t in B)e.isFunction(B[t])&&"on"!==t.slice(0,2)&&(B[t]=B[t].call(N));B.rel=B.rel||N.rel||e(N).data("rel")||"nofollow",B.href=B.href||e(N).attr("href"),B.title=B.title||N.title,"string"==typeof B.href&&(B.href=e.trim(B.href))}function c(i,o){e(t).trigger(i),st.trigger(i),e.isFunction(o)&&o.call(N)}function u(i){q||(N=i,d(),k=e(N),z=0,"nofollow"!==B.rel&&(k=e("."+et).filter(function(){var t,i=e.data(this,Y);return i&&(t=e(this).data("rel")||i.rel||this.rel),t===B.rel}),z=k.index(N),-1===z&&(k=k.add(N),z=k.length-1)),w.css({opacity:parseFloat(B.opacity),cursor:B.overlayClose?"pointer":"auto",visibility:"visible"}).show(),J&&g.add(w).removeClass(J),B.className&&g.add(w).addClass(B.className),J=B.className,B.closeButton?K.html(B.close).appendTo(y):K.appendTo("<div/>"),U||(U=$=!0,g.css({visibility:"hidden",display:"block"}),H=o(lt,"LoadedContent","width:0; height:0; overflow:hidden"),y.css({width:"",height:""}).append(H),O=x.height()+C.height()+y.outerHeight(!0)-y.height(),_=b.width()+T.width()+y.outerWidth(!0)-y.width(),D=H.outerHeight(!0),A=H.outerWidth(!0),B.w=h(B.initialWidth,"x"),B.h=h(B.initialHeight,"y"),H.css({width:"",height:B.h}),Q.position(),c(tt,B.onOpen),P.add(L).hide(),g.focus(),B.trapFocus&&t.addEventListener&&(t.addEventListener("focus",a,!0),st.one(rt,function(){t.removeEventListener("focus",a,!0)})),B.returnFocus&&st.one(rt,function(){e(N).focus()})),m())}function f(){!g&&t.body&&(V=!1,E=e(i),g=o(lt).attr({id:Y,"class":e.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),w=o(lt,"Overlay").hide(),F=e([o(lt,"LoadingOverlay")[0],o(lt,"LoadingGraphic")[0]]),v=o(lt,"Wrapper"),y=o(lt,"Content").append(L=o(lt,"Title"),S=o(lt,"Current"),I=e('<button type="button"/>').attr({id:Z+"Previous"}),R=e('<button type="button"/>').attr({id:Z+"Next"}),M=o("button","Slideshow"),F),K=e('<button type="button"/>').attr({id:Z+"Close"}),v.append(o(lt).append(o(lt,"TopLeft"),x=o(lt,"TopCenter"),o(lt,"TopRight")),o(lt,!1,"clear:left").append(b=o(lt,"MiddleLeft"),y,T=o(lt,"MiddleRight")),o(lt,!1,"clear:left").append(o(lt,"BottomLeft"),C=o(lt,"BottomCenter"),o(lt,"BottomRight"))).find("div div").css({"float":"left"}),W=o(lt,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),P=R.add(I).add(S).add(M),e(t.body).append(w,g.append(v,W)))}function p(){function i(e){e.which>1||e.shiftKey||e.altKey||e.metaKey||e.ctrlKey||(e.preventDefault(),u(this))}return g?(V||(V=!0,R.click(function(){Q.next()}),I.click(function(){Q.prev()}),K.click(function(){Q.close()}),w.click(function(){B.overlayClose&&Q.close()}),e(t).bind("keydown."+Z,function(e){var t=e.keyCode;U&&B.escKey&&27===t&&(e.preventDefault(),Q.close()),U&&B.arrowKey&&k[1]&&!e.altKey&&(37===t?(e.preventDefault(),I.click()):39===t&&(e.preventDefault(),R.click()))}),e.isFunction(e.fn.on)?e(t).on("click."+Z,"."+et,i):e("."+et).live("click."+Z,i)),!0):!1}function m(){var n,r,a,u=Q.prep,f=++at;$=!0,j=!1,N=k[z],d(),c(ht),c(it,B.onLoad),B.h=B.height?h(B.height,"y")-D-O:B.innerHeight&&h(B.innerHeight,"y"),B.w=B.width?h(B.width,"x")-A-_:B.innerWidth&&h(B.innerWidth,"x"),B.mw=B.w,B.mh=B.h,B.maxWidth&&(B.mw=h(B.maxWidth,"x")-A-_,B.mw=B.w&&B.w<B.mw?B.w:B.mw),B.maxHeight&&(B.mh=h(B.maxHeight,"y")-D-O,B.mh=B.h&&B.h<B.mh?B.h:B.mh),n=B.href,G=setTimeout(function(){F.show()},100),B.inline?(a=o(lt).hide().insertBefore(e(n)[0]),st.one(ht,function(){a.replaceWith(H.children())}),u(e(n))):B.iframe?u(" "):B.html?u(B.html):s(B,n)?(n=l(B,n),j=t.createElement("img"),e(j).addClass(Z+"Photo").bind("error",function(){B.title=!1,u(o(lt,"Error").html(B.imgError))}).one("load",function(){var t;f===at&&(e.each(["alt","longdesc","aria-describedby"],function(t,i){var o=e(N).attr(i)||e(N).attr("data-"+i);o&&j.setAttribute(i,o)}),B.retinaImage&&i.devicePixelRatio>1&&(j.height=j.height/i.devicePixelRatio,j.width=j.width/i.devicePixelRatio),B.scalePhotos&&(r=function(){j.height-=j.height*t,j.width-=j.width*t},B.mw&&j.width>B.mw&&(t=(j.width-B.mw)/j.width,r()),B.mh&&j.height>B.mh&&(t=(j.height-B.mh)/j.height,r())),B.h&&(j.style.marginTop=Math.max(B.mh-j.height,0)/2+"px"),k[1]&&(B.loop||k[z+1])&&(j.style.cursor="pointer",j.onclick=function(){Q.next()}),j.style.width=j.width+"px",j.style.height=j.height+"px",setTimeout(function(){u(j)},1))}),setTimeout(function(){j.src=n},1)):n&&W.load(n,B.data,function(t,i){f===at&&u("error"===i?o(lt,"Error").html(B.xhrError):e(this).contents())})}var w,g,v,y,x,b,T,C,k,E,H,W,F,L,S,M,R,I,K,P,B,O,_,D,A,N,z,j,U,$,q,G,Q,J,V,X={html:!1,photo:!1,iframe:!1,inline:!1,transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0,fastIframe:!0,open:!1,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp)((#|\?).*)?$/i,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",returnFocus:!0,trapFocus:!0,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1},Y="colorbox",Z="cbox",et=Z+"Element",tt=Z+"_open",it=Z+"_load",ot=Z+"_complete",nt=Z+"_cleanup",rt=Z+"_closed",ht=Z+"_purge",st=e("<a/>"),lt="div",at=0,dt={},ct=function(){function e(){clearTimeout(h)}function t(){(B.loop||k[z+1])&&(e(),h=setTimeout(Q.next,B.slideshowSpeed))}function i(){M.html(B.slideshowStop).unbind(l).one(l,o),st.bind(ot,t).bind(it,e),g.removeClass(s+"off").addClass(s+"on")}function o(){e(),st.unbind(ot,t).unbind(it,e),M.html(B.slideshowStart).unbind(l).one(l,function(){Q.next(),i()}),g.removeClass(s+"on").addClass(s+"off")}function n(){r=!1,M.hide(),e(),st.unbind(ot,t).unbind(it,e),g.removeClass(s+"off "+s+"on")}var r,h,s=Z+"Slideshow_",l="click."+Z;return function(){r?B.slideshow||(st.unbind(nt,n),n()):B.slideshow&&k[1]&&(r=!0,st.one(nt,n),B.slideshowAuto?i():o(),M.show())}}();e.colorbox||(e(f),Q=e.fn[Y]=e[Y]=function(t,i){var o=this;if(t=t||{},f(),p()){if(e.isFunction(o))o=e("<a/>"),t.open=!0;else if(!o[0])return o;i&&(t.onComplete=i),o.each(function(){e.data(this,Y,e.extend({},e.data(this,Y)||X,t))}).addClass(et),(e.isFunction(t.open)&&t.open.call(o)||t.open)&&u(o[0])}return o},Q.position=function(t,i){function o(){x[0].style.width=C[0].style.width=y[0].style.width=parseInt(g[0].style.width,10)-_+"px",y[0].style.height=b[0].style.height=T[0].style.height=parseInt(g[0].style.height,10)-O+"px"}var r,s,l,a=0,d=0,c=g.offset();if(E.unbind("resize."+Z),g.css({top:-9e4,left:-9e4}),s=E.scrollTop(),l=E.scrollLeft(),B.fixed?(c.top-=s,c.left-=l,g.css({position:"fixed"})):(a=s,d=l,g.css({position:"absolute"})),d+=B.right!==!1?Math.max(E.width()-B.w-A-_-h(B.right,"x"),0):B.left!==!1?h(B.left,"x"):Math.round(Math.max(E.width()-B.w-A-_,0)/2),a+=B.bottom!==!1?Math.max(n()-B.h-D-O-h(B.bottom,"y"),0):B.top!==!1?h(B.top,"y"):Math.round(Math.max(n()-B.h-D-O,0)/2),g.css({top:c.top,left:c.left,visibility:"visible"}),v[0].style.width=v[0].style.height="9999px",r={width:B.w+A+_,height:B.h+D+O,top:a,left:d},t){var u=0;e.each(r,function(e){return r[e]!==dt[e]?(u=t,void 0):void 0}),t=u}dt=r,t||g.css(r),g.dequeue().animate(r,{duration:t||0,complete:function(){o(),$=!1,v[0].style.width=B.w+A+_+"px",v[0].style.height=B.h+D+O+"px",B.reposition&&setTimeout(function(){E.bind("resize."+Z,Q.position)},1),i&&i()},step:o})},Q.resize=function(e){var t;U&&(e=e||{},e.width&&(B.w=h(e.width,"x")-A-_),e.innerWidth&&(B.w=h(e.innerWidth,"x")),H.css({width:B.w}),e.height&&(B.h=h(e.height,"y")-D-O),e.innerHeight&&(B.h=h(e.innerHeight,"y")),e.innerHeight||e.height||(t=H.scrollTop(),H.css({height:"auto"}),B.h=H.height()),H.css({height:B.h}),t&&H.scrollTop(t),Q.position("none"===B.transition?0:B.speed))},Q.prep=function(i){function n(){return B.w=B.w||H.width(),B.w=B.mw&&B.mw<B.w?B.mw:B.w,B.w}function h(){return B.h=B.h||H.height(),B.h=B.mh&&B.mh<B.h?B.mh:B.h,B.h}if(U){var a,d="none"===B.transition?0:B.speed;H.empty().remove(),H=o(lt,"LoadedContent").append(i),H.hide().appendTo(W.show()).css({width:n(),overflow:B.scrolling?"auto":"hidden"}).css({height:h()}).prependTo(y),W.hide(),e(j).css({"float":"none"}),a=function(){function i(){e.support.opacity===!1&&g[0].style.removeAttribute("filter")}var n,h,a=k.length,u="frameBorder",f="allowTransparency";U&&(h=function(){clearTimeout(G),F.hide(),c(ot,B.onComplete)},L.html(B.title).add(H).show(),a>1?("string"==typeof B.current&&S.html(B.current.replace("{current}",z+1).replace("{total}",a)).show(),R[B.loop||a-1>z?"show":"hide"]().html(B.next),I[B.loop||z?"show":"hide"]().html(B.previous),ct(),B.preloading&&e.each([r(-1),r(1)],function(){var i,o,n=k[this],r=e.data(n,Y);r&&r.href?(i=r.href,e.isFunction(i)&&(i=i.call(n))):i=e(n).attr("href"),i&&s(r,i)&&(i=l(r,i),o=t.createElement("img"),o.src=i)})):P.hide(),B.iframe?(n=o("iframe")[0],u in n&&(n[u]=0),f in n&&(n[f]="true"),B.scrolling||(n.scrolling="no"),e(n).attr({src:B.href,name:(new Date).getTime(),"class":Z+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",h).appendTo(H),st.one(ht,function(){n.src="//about:blank"}),B.fastIframe&&e(n).trigger("load")):h(),"fade"===B.transition?g.fadeTo(d,1,i):i())},"fade"===B.transition?g.fadeTo(d,0,function(){Q.position(0,a)}):Q.position(d,a)}},Q.next=function(){!$&&k[1]&&(B.loop||k[z+1])&&(z=r(1),u(k[z]))},Q.prev=function(){!$&&k[1]&&(B.loop||z)&&(z=r(-1),u(k[z]))},Q.close=function(){U&&!q&&(q=!0,U=!1,c(nt,B.onCleanup),E.unbind("."+Z),w.fadeTo(B.fadeOut||0,0),g.stop().fadeTo(B.fadeOut||0,0,function(){g.add(w).css({opacity:1,cursor:"auto"}).hide(),c(ht),H.empty().remove(),setTimeout(function(){q=!1,c(rt,B.onClosed)},1)}))},Q.remove=function(){g&&(g.stop(),e.colorbox.close(),g.stop().remove(),w.remove(),q=!1,g=null,e("."+et).removeData(Y).removeClass(et),e(t).unbind("click."+Z))},Q.element=function(){return e(N)},Q.settings=X)})(jQuery,document,window);
 
 
 
 
 
 
 
embedded/common/res/js/toolset-promotion.js DELETED
@@ -1,47 +0,0 @@
1
- var Toolset_Promotion = Toolset_Promotion || {};
2
-
3
- Toolset_Promotion = function($){
4
- var self = this;
5
-
6
- self.init = function(){
7
- self.toolset_open_promotional_message();
8
- };
9
-
10
- self.toolset_open_promotional_message = function(){
11
- var $el = $('.js-open-promotional-message')
12
- , template = $('#js-buy-toolset-embedded-message').html()
13
- , $container = $('#js-buy-toolset-embedded-message-wrap');
14
-
15
- $container.html( _.template( template ) );
16
-
17
- $(document).on('click', $el.selector, function(event){
18
- event.preventDefault();
19
- $.colorbox({
20
- href: $container.selector,
21
- inline: true,
22
- open: true,
23
- closeButton: false,
24
- fixed: true,
25
- top: false,
26
- width:'554px',
27
- onComplete: function() {
28
-
29
- },
30
- onCleanup: function() {
31
-
32
- },
33
- opacity: .2
34
- });
35
- })
36
- $('.js-close-promotional-message').on('click', function(){
37
- $.colorbox.close();
38
- });
39
- };
40
-
41
- self.init();
42
-
43
- };
44
-
45
- ;(function($){
46
- var toolset_promotion_message = new Toolset_Promotion($);
47
- }(jQuery));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/res/js/wpv-wp-pointer.js DELETED
@@ -1,17 +0,0 @@
1
- function wpv_wp_pointer_ignore( option, nonce, value, id ) {
2
-
3
- jQuery.ajaxSetup({async:false});
4
- jQuery.post(ajaxurl, {
5
- action: 'wpv_wp_pointer_set_ignore',
6
- option: option,
7
- wpv_nonce: nonce,
8
- value: value
9
- }, function(data) {
10
- }
11
- );
12
-
13
- if (value == 'ignore') {
14
- jQuery('#wpv_wp_pointer_clear_ignores_' + id).fadeIn();
15
- }
16
- }
17
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/api.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
-
8
- function wptoolset_form( $form_id, $config = array() ){
9
- global $wptoolset_forms;
10
- $html = $wptoolset_forms->form( $form_id, $config );
11
- return apply_filters( 'wptoolset_form', $html, $config );
12
- }
13
-
14
- function wptoolset_form_field( $form_id, $config, $value = array() ){
15
- global $wptoolset_forms;
16
- $html = $wptoolset_forms->field( $form_id, $config, $value );
17
- return apply_filters( 'wptoolset_fieldform', $html, $config, $form_id );
18
- }
19
-
20
- //function wptoolset_form_field_edit( $form_id, $config ){
21
- // global $wptoolset_forms;
22
- // $html = $wptoolset_forms->fieldEdit( $form_id, $config );
23
- // return apply_filters( 'wptoolset_fieldform_edit', $html, $config, $form_id );
24
- //}
25
-
26
- function wptoolset_form_validate_field( $form_id, $config, $value ){
27
- global $wptoolset_forms;
28
- return $wptoolset_forms->validate_field( $form_id, $config, $value );
29
- }
30
-
31
- function wptoolset_form_conditional_check( $config ){
32
- global $wptoolset_forms;
33
- return $wptoolset_forms->checkConditional( $config );
34
- }
35
-
36
- function wptoolset_form_add_conditional( $form_id, $config ){
37
- global $wptoolset_forms;
38
- return $wptoolset_forms->addConditional( $form_id, $config );
39
- }
40
-
41
- function wptoolset_form_filter_types_field( $field, $post_id = null, $_post_wpcf = array() ){
42
- global $wptoolset_forms;
43
- return $wptoolset_forms->filterTypesField( $field, $post_id, $_post_wpcf );
44
- }
45
-
46
- function wptoolset_form_field_add_filters( $type ){
47
- global $wptoolset_forms;
48
- $wptoolset_forms->addFieldFilters( $type );
49
- }
50
-
51
- function wptoolset_form_get_conditional_data( $post_id ){
52
- global $wptoolset_forms;
53
- return $wptoolset_forms->getConditionalData( $post_id );
54
- }
55
-
56
- function wptoolset_strtotime( $date, $format = null ){
57
- global $wptoolset_forms;
58
- return $wptoolset_forms->strtotime( $date, $format );
59
- }
60
-
61
- function wptoolset_timetodate( $timestamp, $format = null ){
62
- global $wptoolset_forms;
63
- return $wptoolset_forms->timetodate( $timestamp, $format );
64
- }
65
-
66
- /**
67
- * wptoolset_esc_like
68
- *
69
- * In WordPress 4.0, like_escape() was deprecated, due to incorrect
70
- * documentation and improper sanitization leading to a history of misuse
71
- * To maintain compatibility with versions of WP before 4.0, we duplicate the
72
- * logic of the replacement, wpdb::esc_like()
73
- *
74
- * @see wpdb::esc_like() for more details on proper use.
75
- *
76
- * @global object $wpdb
77
- *
78
- * @param string $text The raw text to be escaped.
79
- * @return string Text in the form of a LIKE phrase. Not SQL safe. Run through
80
- * wpdb::prepare() before use.
81
- */
82
- function wptoolset_esc_like( $like )
83
- {
84
- global $wpdb;
85
- if ( method_exists( $wpdb, 'esc_like' ) ) {
86
- return $wpdb->esc_like( $like );
87
- }
88
- if ( version_compare( get_bloginfo('version'), '4' ) < 0 ) {
89
- return like_escape( $like );
90
- }
91
- return addcslashes( $like, '_%\\' );
92
- }
93
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/bootstrap.php DELETED
@@ -1,300 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
- require_once 'api.php';
8
-
9
- define('WPTOOLSET_FORMS_VERSION', '0.1.1');
10
- define('WPTOOLSET_FORMS_ABSPATH', dirname(__FILE__));
11
-
12
- /**
13
- * check we are as a embedded?
14
- */
15
- if (defined('WPCF_RUNNING_EMBEDDED') && WPCF_RUNNING_EMBEDDED) {
16
- define('WPTOOLSET_FORMS_RELPATH', wpcf_get_file_url(__FILE__, false));
17
- }
18
- /**
19
- * setup WPTOOLSET_FORMS_RELPATH for plugin
20
- */
21
- if (!defined('WPTOOLSET_FORMS_RELPATH')) {
22
- define('WPTOOLSET_FORMS_RELPATH', plugins_url('', __FILE__));
23
- }
24
- if (!defined('WPTOOLSET_COMMON_PATH')) {
25
- define('WPTOOLSET_COMMON_PATH', plugin_dir_path(__FILE__));
26
- }
27
-
28
- class WPToolset_Forms_Bootstrap {
29
-
30
- private $__forms;
31
-
32
- public final function __construct() {
33
- // Custom conditinal AJAX check
34
- add_action('wp_ajax_wptoolset_custom_conditional', array($this, 'ajaxCustomConditional'));
35
-
36
- // Date conditinal AJAX check
37
- add_action('wp_ajax_wptoolset_conditional', array($this, 'ajaxConditional'));
38
-
39
- // Date extended localization AJAX callback
40
- add_action('wp_ajax_wpt_localize_extended_date', array($this, 'wpt_localize_extended_date'));
41
- add_action('wp_ajax_nopriv_wpt_localize_extended_date', array($this, 'wpt_localize_extended_date'));
42
-
43
- // Taxonomy term suggest AJAX callback
44
- add_action('wp_ajax_wpt_suggest_taxonomy_term', array($this, 'wpt_suggest_taxonomy_term'));
45
- add_action('wp_ajax_nopriv_wpt_suggest_taxonomy_term', array($this, 'wpt_suggest_taxonomy_term'));
46
-
47
- add_filter('sanitize_file_name', array($this, 'sanitize_file_name'));
48
-
49
- add_filter('wptoolset_filter_wptoolset_repdrag_image', array($this, 'set_default_repdrag_image'), 10, 1);
50
- /**
51
- * common class for calendar
52
- */
53
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.date.scripts.php';
54
- new WPToolset_Field_Date_Scripts();
55
-
56
- add_action('pre_get_posts', array($this, 'pre_get_posts'));
57
- }
58
-
59
- // returns HTML
60
- public function field($form_id, $config, $value) {
61
- $form = $this->form($form_id, array());
62
- return $form->metaform($config, $config['name'], $value);
63
- }
64
-
65
- // returns HTML
66
- // public function fieldEdit($form_id, $config) {
67
- // $form = $this->form( $form_id, array() );
68
- // return $form->editform( $config );
69
- // }
70
-
71
- public function form($form_id, $config = array()) {
72
- if (isset($this->__forms[$form_id])) {
73
- return $this->__forms[$form_id];
74
- }
75
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.form_factory.php';
76
- return $this->__forms[$form_id] = new FormFactory($form_id, $config);
77
- }
78
-
79
- public function validate_field($form_id, $config, $value) {
80
- if (empty($config['validation'])) {
81
- return true;
82
- }
83
- $form = $this->form($form_id, array());
84
- return $form->validateField($config, $value);
85
- }
86
-
87
- public function ajaxCustomConditional() {
88
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.conditional.php';
89
- WPToolset_Forms_Conditional::ajaxCustomConditional();
90
- }
91
-
92
- public function checkConditional($config) {
93
- if (empty($config['conditional'])) {
94
- return true;
95
- }
96
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.conditional.php';
97
- return WPToolset_Forms_Conditional::evaluate($config['conditional']);
98
- }
99
-
100
- public function addConditional($form_id, $config) {
101
- $this->form($form_id)->addConditional($config);
102
- }
103
-
104
- public function ajaxConditional() {
105
- $data = $_POST['conditions'];
106
- $data['values'] = $_POST['values'];
107
- echo $this->checkConditional(array('conditional' => $data));
108
- die();
109
- }
110
-
111
- public function wpt_localize_extended_date() {
112
- if (!isset($_POST['date'])) {
113
- die();
114
- }
115
- $date = $_POST['date'];
116
- $date_format = '';
117
- if (isset($_POST['date-format'])) {
118
- $date_format = $_POST['date-format'];
119
- }
120
- if ($date_format == '') {
121
- $date_format = get_option('date_format');
122
- }
123
- $date = adodb_mktime(0, 0, 0, substr($date, 2, 2), substr($date, 0, 2), substr($date, 4, 4));
124
- $date_format = str_replace('\\\\', '\\', $date_format);
125
- echo json_encode(array('display' => adodb_date($date_format, $date), 'timestamp' => $date));
126
- die();
127
- }
128
-
129
- /**
130
- * wpt_suggest_taxonomy_term
131
- *
132
- * Renders the suggestions when adding new flat taxonomy terms on a CRED form
133
- *
134
- * Needs a non-empty q attribute and can take an optional non-empty taxonomy attribute on the $_REQUEST
135
- *
136
- * @since 1.5.0
137
- */
138
- public function wpt_suggest_taxonomy_term() {
139
- if (
140
- !isset($_REQUEST['q']) || $_REQUEST['q'] == ''
141
- ) {
142
- die();
143
- }
144
- global $wpdb;
145
- $values_to_prepare = array();
146
- if (function_exists("wpv_esc_like")) {
147
- $term_name = '%' . wpv_esc_like($_REQUEST['q']) . '%';
148
- } else {
149
- if (function_exists("cred_wrap_esc_like")) {
150
- $term_name = '%' . cred_wrap_esc_like($_REQUEST['q']) . '%';
151
- }
152
- }
153
- $values_to_prepare[] = $term_name;
154
-
155
- $tax_join = "";
156
- $tax_where = "";
157
- if (
158
- isset($_REQUEST['taxonomy']) && $_REQUEST['taxonomy'] != ''
159
- ) {
160
- $tax_join = " JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id ";
161
- $tax_where = " AND tt.taxonomy = %s ";
162
- $values_to_prepare[] = $_REQUEST['taxonomy'];
163
- }
164
- //
165
- $results = $wpdb->get_results(
166
- $wpdb->prepare(
167
- "SELECT name FROM {$wpdb->terms} t {$tax_join}
168
- WHERE t.name LIKE %s
169
- {$tax_where}
170
- ORDER BY name DESC
171
- LIMIT 5", $values_to_prepare
172
- )
173
- );
174
- foreach ($results as $row) {
175
- echo $row->name . "\n";
176
- }
177
-
178
- die();
179
- }
180
-
181
- public function filterTypesField($field, $post_id = null, $_post_wpcf = array()) {
182
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.types.php';
183
- return WPToolset_Types::filterField($field, $post_id, $_post_wpcf);
184
- }
185
-
186
- public function addFieldFilters($type) {
187
- if ($class = $this->form('generic')->loadFieldClass($type)) {
188
- call_user_func(array($class, 'addFilters'));
189
- call_user_func(array($class, 'addActions'));
190
- }
191
- }
192
-
193
- public function getConditionalData($form_id) {
194
- return $this->form($form_id)->getConditionalClass()->getData();
195
- }
196
-
197
- public function strtotime($date, $format = null) {
198
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.date.php';
199
- return WPToolset_Field_Date::strtotime($date, $format);
200
- }
201
-
202
- public function timetodate($timestamp, $format = null) {
203
- require_once WPTOOLSET_FORMS_ABSPATH . '/classes/class.date.php';
204
- return WPToolset_Field_Date::timetodate($timestamp, $format);
205
- }
206
-
207
- public function sanitize_file_name($filename) {
208
- /**
209
- * replace german special characters
210
- */
211
- $de_from = array('ä', 'ö', 'ü', 'ß', 'Ä', 'Ö', 'Ü');
212
- $de_to = array('ae', 'oe', 'ue', 'ss', 'Ae', 'Oe', 'Ue');
213
- $filename = str_replace($de_from, $de_to, $filename);
214
- /**
215
- * replace polish special characters
216
- */
217
- $pl_from = array('ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż', 'Ą', 'Ć', 'Ę', 'Ł', 'Ń', 'Ó', 'Ś', 'Ź', 'Ż');
218
- $pl_to = array('a', 'c', 'e', 'l', 'n', 'o', 's', 'z', 'z', 'A', 'C', 'E', 'L', 'N', 'O', 'S', 'Z', 'Z');
219
- $filename = str_replace($pl_from, $pl_to, $filename);
220
- /**
221
- * remove special characters
222
- */
223
- $filename = preg_replace('/[^A-Za-z0-9\._@]/', '-', $filename);
224
- $filename = preg_replace('/%20/', '-', $filename);
225
- return $filename;
226
- }
227
-
228
- public function set_default_repdrag_image($image) {
229
- return WPTOOLSET_FORMS_RELPATH . '/images/move.png';
230
- }
231
-
232
- /**
233
- * add custom post type to query when they use category or tags taxonomy.
234
- */
235
- public function pre_get_posts($query) {
236
- if (is_admin()) {
237
- return;
238
- }
239
- /**
240
- * do that only for main query
241
- */
242
- if (!$query->is_main_query()) {
243
- return;
244
- }
245
- $types_cpt = get_option('wpcf-custom-types');
246
- if (!is_array($types_cpt) || empty($types_cpt)) {
247
- return;
248
- }
249
- $cpt_to_add = array();
250
- /**
251
- * check category
252
- */
253
- if (is_category()) {
254
- foreach ($types_cpt as $cpt_slug => $cpt) {
255
- if (array_key_exists('taxonomies', $cpt) && is_array($cpt['taxonomies'])) {
256
- foreach ($cpt['taxonomies'] as $tax_slug => $value) {
257
- if ('category' == $tax_slug && $value) {
258
- $cpt_to_add[] = $cpt_slug;
259
- }
260
- }
261
- }
262
- }
263
- }
264
- /**
265
- * check tags
266
- */
267
- if (is_tag()) {
268
- foreach ($types_cpt as $cpt_slug => $cpt) {
269
- if (array_key_exists('taxonomies', $cpt) && is_array($cpt['taxonomies'])) {
270
- foreach ($cpt['taxonomies'] as $tax_slug => $value) {
271
- if ('post_tag' == $tax_slug && $value) {
272
- $cpt_to_add[] = $cpt_slug;
273
- }
274
- }
275
- }
276
- }
277
- }
278
- /**
279
- * change query if some CPT use this
280
- */
281
- if (!empty($cpt_to_add)) {
282
- /**
283
- * remeber if is empty, then is post
284
- */
285
- $current_types = $query->get('post_type');
286
- if (empty($current_types)) {
287
- $cpt_to_add[] = 'post';
288
- } elseif (is_array($current_types)) {
289
- $cpt_to_add = array_merge($current_types, $cpt_to_add);
290
- } elseif (is_string($current_types)) {
291
- $cpt_to_add[] = $current_types;
292
- }
293
- $query->set('post_type', $cpt_to_add);
294
- }
295
- return;
296
- }
297
-
298
- }
299
-
300
- $GLOBALS['wptoolset_forms'] = new WPToolset_Forms_Bootstrap();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/abstract.field.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * Field Abstraction
5
- * @author onTheGo System
6
- *
7
- */
8
- abstract class FieldAbstract {
9
- //global name of field
10
- protected $_nameField;
11
- //field config
12
- protected $_data;
13
- //config for enlimbo
14
- protected $_metaform;
15
-
16
- abstract public function init();
17
- abstract public function set_nameField($nameField);
18
- abstract public function get_nameField();
19
- abstract public function set_data($data);
20
- abstract public function get_data();
21
- abstract public function set_metaform($metaform);
22
- abstract public function get_metaform();
23
-
24
- abstract public function getId();
25
- abstract public function getName();
26
- abstract public function getType();
27
- abstract public function getValue();
28
- abstract public function getAttr();
29
- abstract public function getTitle();
30
- abstract public function getDescription();
31
- abstract public function getData();
32
- abstract public function getValidationData();
33
- abstract public function setValidationData($validation);
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/abstract.form.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
-
3
- abstract class FormAbstract {
4
- /*
5
- * Create and return form as string
6
- */
7
- abstract public function createForm($nameForm);
8
- /*
9
- * Create and display form
10
- */
11
- abstract public function displayForm($nameForm);
12
- /*
13
- * Check id forms
14
- */
15
- abstract public function formNameExists(&$nameForm);
16
- /*
17
- * Get Field Object from type
18
- */
19
- abstract public function getFieldObject($data, $global_name_field, $value);
20
- /*
21
- * Add field to a form
22
- */
23
- abstract public function addFormField($data);
24
- /*
25
- * Loads field (queue script and styles)
26
- */
27
- abstract public function loadField( $data, $global_name_field, $value );
28
- /*
29
- * Single field form (not added to form fields)
30
- */
31
- abstract public function metaform( $config, $global_name_field, $value );
32
- /*
33
- * Single field edit form (not added to form fields)
34
- */
35
- // abstract public function editform( $config );
36
- /*
37
- * Checks if validation is required and inits it per form
38
- */
39
- abstract protected function _checkValidation( $config );
40
- /*
41
- * checkConditional
42
- */
43
- abstract protected function _checkConditional( $config );
44
- /*
45
- * repetitive
46
- */
47
- abstract protected function _repetitive();
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.audio.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- require_once 'class.file.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- *
9
- *
10
- */
11
- class WPToolset_Field_Audio extends WPToolset_Field_File
12
- {
13
- protected $_settings = array('min_wp_version' => '3.6');
14
-
15
- public function metaform()
16
- {
17
- $validation = $this->getValidationData();
18
- $validation = self::addTypeValidation($validation);
19
- $this->setValidationData($validation);
20
- return parent::metaform();
21
- }
22
-
23
- public static function addTypeValidation($validation) {
24
- $validation['extension'] = array(
25
- 'args' => array(
26
- 'extension',
27
- '16svx|2sf|8svx|aac|aif|aifc|aiff|amr|ape|asf|ast|au|aup|band|brstm|bwf|cdda|cust|dsf|dwd|flac|gsf|gsm|gym|it|jam|la|ly|m4a|m4p|mid|minipsf|mng|mod|mp1|mp2|mp3|mp4|mpc|mscz|mt2|mus|niff|nsf|off|ofr|ofs|ogg|ots|pac|psf|psf2|psflib|ptb|qsf|ra|raw|rka|rm|rmj|s3m|shn|sib|sid|smp|spc|spx|ssf|swa|tta|txm|usf|vgm|voc|vox|vqf|wav|wma|wv|xm|ym',
28
- ),
29
- 'message' => __( 'You can add only audio.', 'wpv-views' ),
30
- );
31
- return $validation;
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.button.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Franko
8
- */
9
- class WPToolset_Field_Button extends WPToolset_Field_Textfield
10
- {
11
-
12
- public function metaform() {
13
- $config = $this->_config;
14
- $metaform = array();
15
- $metaform[] = array(
16
- '#type' => 'button',
17
- '#title' => $this->title,
18
- '#description' => $this->description,
19
- '#name' => $this->name,
20
- '#value' => $this->value,
21
- '#validate' => $config['validation']
22
- );
23
- return $metaform;
24
- }
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.checkbox.php DELETED
@@ -1,66 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.field_factory.php';
7
-
8
- /**
9
- * Description of class
10
- *
11
- * @author Srdjan
12
- */
13
- class WPToolset_Field_Checkbox extends FieldFactory
14
- {
15
- public function metaform()
16
- {
17
- global $post;
18
- $value = $this->getValue();
19
- $data = $this->getData();
20
- $checked = null;
21
-
22
- /**
23
- * autocheck for new posts
24
- */
25
- if (isset($post) && 'auto-draft' == $post->post_status && array_key_exists( 'checked', $data ) && $data['checked']) {
26
- $checked = true;
27
- }
28
- /**
29
- * is checked?
30
- */
31
- if ( isset($data['options']) && array_key_exists( 'checked', $data['options'] ) ) {
32
- $checked = $data['options']['checked'];
33
- }
34
- /**
35
- * if is a default value, there value is 1 or default_value
36
- */
37
- if (
38
- array_key_exists('default_value', $data)
39
- && ( 'y' === $value || $value === $data['default_value'])
40
- ) {
41
- $checked = true;
42
- }
43
-
44
- // Comment out broken code. This tries to set the previous state after validation fails
45
- //if (!$checked&&$this->getValue()==1) {
46
- // $checked=true;
47
- //}
48
-
49
- /**
50
- * metaform
51
- */
52
- $form = array(
53
- '#type' => 'checkbox',
54
- '#value' => $value,
55
- '#default_value' => array_key_exists( 'default_value', $data )? $data['default_value']:null,
56
- '#name' => $this->getName(),
57
- '#description' => $this->getDescription(),
58
- '#title' => $this->getTitle(),
59
- '#validate' => $this->getValidationData(),
60
- '#after' => '<input type="hidden" name="_wptoolset_checkbox[' . $this->getId() . ']" value="1" />',
61
- '#checked' => $checked,
62
- '#repetitive' => $this->isRepetitive(),
63
- );
64
- return array($form);
65
- }
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.checkboxes.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
- /**
3
- * Description of class
4
- *
5
- * @author Srdjan
6
- *
7
- *
8
- */
9
-
10
- require_once 'class.field_factory.php';
11
-
12
- class WPToolset_Field_Checkboxes extends FieldFactory
13
- {
14
- public function metaform()
15
- {
16
- global $post;
17
- $value = $this->getValue();
18
- $data = $this->getData();
19
- $name = $this->getName();
20
-
21
- $form = array();
22
- $_options = array();
23
- if (isset($data['options'])) {
24
- foreach ( $data['options'] as $option_key => $option ) {
25
-
26
- $checked = isset( $option['checked'] ) ? $option['checked'] : !empty( $value[$option_key] );
27
-
28
- if (isset($post) && 'auto-draft' == $post->post_status && array_key_exists( 'checked', $option ) && $option['checked']) {
29
- $checked = true;
30
- }
31
-
32
- // Comment out broken code. This tries to set the previous state after validation fails
33
- //$_values=$this->getValue();
34
- //if (!$checked&&isset($value)&&!empty($value)&&is_array($value)&&in_array($option['value'],$value)) {
35
- // $checked=true;
36
- //}
37
-
38
- $_options[$option_key] = array(
39
- '#value' => $option['value'],
40
- '#title' => $option['title'],
41
- '#type' => 'checkbox',
42
- '#default_value' => $checked,
43
- '#name' => $option['name']."[]",
44
- //'#inline' => true,
45
- );
46
-
47
- if ( isset( $option['data-value'] ) ) {
48
- //Fixing https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/188528502/comments
49
- $_options[$option_key]['#attributes'] = array('data-value' => $option['data-value']);
50
- }
51
-
52
- if ( !is_admin() ) {// TODO maybe add a doing_ajax() check too, what if we want to load a form using AJAX?
53
- $clases = array(
54
- 'wpt-form-item',
55
- 'wpt-form-item-checkbox',
56
- 'checkbox-'.sanitize_title($option['title'])
57
- );
58
- /**
59
- * filter: cred_checkboxes_class
60
- * @param array $clases current array of classes
61
- * @parem array $option current option
62
- * @param string field type
63
- *
64
- * @return array
65
- */
66
- $clases = apply_filters( 'cred_item_li_class', $clases, $option, 'checkboxes' );
67
- $_options[$option_key]['#before'] = sprintf(
68
- '<li class="%s">',
69
- implode(' ', $clases)
70
- );
71
- $_options[$option_key]['#after'] = '</li>';
72
- $_options[$option_key]['#pattern'] = '<BEFORE><PREFIX><ELEMENT><LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
73
- }
74
- }
75
- }
76
- $metaform = array(
77
- '#type' => 'checkboxes',
78
- '#options' => $_options,
79
- '#description' => $this->getDescription(),
80
- );
81
- if ( is_admin() ) {
82
- $metaform['#title'] = $this->getTitle();
83
- $metaform['#after'] = '<input type="hidden" name="_wptoolset_checkbox[' . $this->getId() . ']" value="1" />';
84
- } else {
85
- $metaform['#before'] = '<ul class="wpt-form-set wpt-form-set-checkboxes wpt-form-set-checkboxes-' . $name . '">';
86
- $metaform['#after'] = '</ul>';
87
- }
88
- return array($metaform);
89
- }
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.colorpicker.php DELETED
@@ -1,106 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.field_factory.php';
7
-
8
- /**
9
- * Description of class
10
- *
11
- * @author Srdjan
12
- */
13
- class WPToolset_Field_Colorpicker extends FieldFactory
14
- {
15
- public function init()
16
- {
17
- if ( !is_admin() ) {
18
- wp_enqueue_style( 'wp-color-picker' );
19
- wp_enqueue_script(
20
- 'iris',
21
- admin_url( 'js/iris.min.js' ),
22
- array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ),
23
- false,
24
- 1
25
- );
26
- wp_enqueue_script(
27
- 'wp-color-picker',
28
- admin_url( 'js/color-picker.min.js' ),
29
- array( 'iris' ),
30
- false,
31
- 1
32
- );
33
- $colorpicker_l10n = array(
34
- 'clear' => __( 'Clear' ),
35
- 'defaultString' => __( 'Default', 'wpv-views' ),
36
- 'pick' => __( 'Select', 'wpv-views' )." Color"
37
- );
38
- wp_localize_script( 'wp-color-picker', 'wpColorPickerL10n', $colorpicker_l10n );
39
- }
40
- wp_register_script(
41
- 'wptoolset-field-colorpicker',
42
- WPTOOLSET_FORMS_RELPATH . '/js/colorpicker.js',
43
- array('iris'),
44
- WPTOOLSET_FORMS_VERSION,
45
- true
46
- );
47
- wp_enqueue_script( 'wptoolset-field-colorpicker' );
48
- $this->set_placeholder_as_attribute();
49
- }
50
-
51
- static public function registerScripts()
52
- {
53
- }
54
-
55
- public function enqueueScripts()
56
- {
57
-
58
- }
59
-
60
- public function addTypeValidation($validation) {
61
- $validation['hexadecimal'] = array(
62
- 'args' => array(
63
- 'hexadecimal'
64
- ),
65
- 'message' => __( 'You can add valid hexadecimal.', 'wpv-views' ),
66
- );
67
- return $validation;
68
- }
69
-
70
- public function metaform()
71
- {
72
- $validation = $this->getValidationData();
73
- $validation = $this->addTypeValidation($validation);
74
- $this->setValidationData($validation);
75
-
76
- $attributes = $this->getAttr();
77
- if ( isset($attributes['class'] ) ) {
78
- $attributes['class'] .= ' ';
79
- } else {
80
- $attributes['class'] = '';
81
- }
82
- $attributes['class'] = 'js-wpt-colorpicker';
83
-
84
- $form = array();
85
- $form['name'] = array(
86
- '#type' => 'textfield',
87
- '#title' => $this->getTitle(),
88
- '#description' => $this->getDescription(),
89
- '#value' => $this->getValue(),
90
- '#name' => $this->getName(),
91
- '#attributes' => $attributes,
92
- '#validate' => $validation,
93
- '#after' => '',
94
- '#repetitive' => $this->isRepetitive(),
95
- );
96
- return $form;
97
- }
98
-
99
- public static function filterValidationValue($value)
100
- {
101
- if ( isset( $value['datepicker'] ) ) {
102
- return $value['datepicker'];
103
- }
104
- return $value;
105
- }
106
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.conditional.php DELETED
@@ -1,534 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * - Checks conditionals when form is displayed and values changed
5
- * - Checks simple conditionals using JS
6
- * - Checks custom conditinals via AJAX/PHP
7
- * - PHP simple and custom checks available using class methods
8
- *
9
- * Simple conditionals
10
- *
11
- * Data
12
- * [id] - Trigger ID to match data-wpt-id
13
- * [type] - field type (trigger)
14
- * [operator] - operator
15
- * [args] - array(value, value2...)
16
- *
17
- * Example
18
- * $config['conditional'] = array(
19
- * 'relation' => 'OR'|'AND',
20
- * 'conditions' => array(
21
- * array(
22
- * 'id' => 'wpcf-text',
23
- * 'type' => 'textfield',
24
- * 'operator' => '==',
25
- * 'args' => array('show')
26
- * ),
27
- * array(
28
- * 'id' => 'wpcf-date',
29
- * 'type' => 'date',
30
- * 'operator' => 'beetween',
31
- * 'args' => array('21/01/2014', '24/01/2014') // Accepts timestamps or string date
32
- * )
33
- * ),
34
- * );
35
- *
36
- * Custom conditionals
37
- *
38
- * Variable name should match trigger ID - data-wpt-id
39
- * Example
40
- * $config['conditional'] = array(
41
- * 'custom' => '($wpcf-text = show) OR ($wpcf-date > '21-01-2014')'
42
- * );
43
- */
44
- if (!defined('ICL_COMMON_FUNCTIONS')) {
45
- require_once WPTOOLSET_COMMON_PATH . '/functions.php';
46
- }
47
- if (!function_exists('wpv_filter_parse_date')) {
48
- require_once WPTOOLSET_COMMON_PATH . '/wpv-filter-date-embedded.php';
49
- }
50
-
51
- require_once WPTOOLSET_COMMON_PATH . '/expression-parser/parser.php';
52
-
53
- /**
54
- * Class description
55
- *
56
- * @todo BUG common function wpv_condition has some flaws
57
- * (dashed names, mixed checks for string and numeric values causes failure)
58
- *
59
- * @author Srdjan
60
- */
61
- if ( !class_exists('WPToolset_Forms_Conditional') ){
62
- class WPToolset_Forms_Conditional {
63
-
64
- private $__formID;
65
- protected $_collected = array(), $_triggers = array(), $_fields = array(), $_custom_triggers = array(), $_custom_fields = array();
66
-
67
- /**
68
- * Register and enqueue scripts and actions.
69
- *
70
- * @param type $formID
71
- */
72
- public function __construct($formID) {
73
- $this->__formID = trim($formID, '#');
74
- // Register and enqueue
75
- wp_register_script('wptoolset-form-conditional', WPTOOLSET_FORMS_RELPATH . '/js/conditional.js', array('jquery', 'jquery-effects-scale'), WPTOOLSET_FORMS_VERSION, true);
76
- wp_enqueue_script('wptoolset-form-conditional');
77
- $js_data = array(
78
- 'ajaxurl' => admin_url('admin-ajax.php', null),
79
- );
80
- wp_localize_script('wptoolset-form-conditional', 'wptConditional', $js_data);
81
-
82
- wp_register_script('wptoolset-parser', icl_get_file_relpath(dirname(dirname(__FILE__))) . '/expression-parser/js/parser.js', array('jquery'), WPTOOLSET_FORMS_VERSION, true);
83
- wp_enqueue_script('wptoolset-parser');
84
- $js_data = array(
85
- 'ajaxurl' => admin_url('admin-ajax.php', null),
86
- );
87
- // Render settings
88
- add_action('admin_print_footer_scripts', array($this, 'renderJsonData'), 30);
89
- add_action('wp_footer', array($this, 'renderJsonData'), 30);
90
- // Check conditional and hide field
91
- add_action('wptoolset_field_class', array($this, 'actionFieldClass'));
92
- }
93
-
94
- /**
95
- * Collects data.
96
- *
97
- * Called from form_factory.
98
- *
99
- * @param type $config
100
- */
101
- public function add($config) {
102
- if (!empty($config['conditional'])) {
103
- $this->_collected[$config['id']] = $config['conditional'];
104
- return;
105
- }
106
- }
107
-
108
- /**
109
- * Sets JSON data to be used with conditional.js
110
- */
111
- protected function _parseData() {
112
- foreach ($this->_collected as $id => $config) {
113
- if (!empty($config['custom'])) {
114
-
115
- $evaluate = $config['custom'];
116
- //###############################################################################################
117
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/193583580/comments
118
- //Fix REGEX conditions that contains \ that is stripped out
119
- if (strpos($evaluate, "REGEX") === false) {
120
- $evaluate = wpv_filter_parse_date($evaluate);
121
- $evaluate = self::handle_user_function($evaluate);
122
- }
123
- //###############################################################################################
124
- $fields = self::extractFields($evaluate);
125
-
126
- foreach ($fields as $field) {
127
- $this->_custom_fields[$id]['custom'] = $evaluate;
128
- $this->_custom_fields[$id]['triggers'][] = $field;
129
- $this->_custom_triggers[$field][] = $id;
130
- }
131
- } else {
132
- if (isset($config) && isset($config['conditions'])) {
133
- if (isset($config) && isset($config['relation']))
134
- $this->_fields[$id]['relation'] = $config['relation'];
135
-
136
- foreach ($config['conditions'] as &$c) {
137
- /*
138
- * $c[id] - field id
139
- * $c[type] - field type
140
- * $c[operator] - operator
141
- * $c[args] - array(value, [value2]...)
142
- */
143
- if (!isset($this->_triggers[$c['id']]))
144
- $this->_triggers[$c['id']] = array();
145
- $c['args'] = apply_filters('wptoolset_conditional_args_js', $c['args'], $c['type']);
146
- $this->_fields[$id]['conditions'][] = $c;
147
- if (!in_array($id, $this->_triggers[$c['id']]))
148
- $this->_triggers[$c['id']][] = $id;
149
- }
150
- }
151
- }
152
- }
153
- }
154
-
155
- /**
156
- * Renders JSON data in footer to be used with conditional.js
157
- */
158
- public function renderJsonData() {
159
- $this->_parseData();
160
- if (!empty($this->_triggers)) {
161
- echo '<script type="text/javascript">wptCondTriggers["#'
162
- . $this->__formID . '"] = ' . json_encode($this->_triggers) . ';</script>';
163
- }
164
- if (!empty($this->_fields)) {
165
- echo '<script type="text/javascript">wptCondFields["#'
166
- . $this->__formID . '"] = ' . json_encode($this->_fields) . ';</script>';
167
- }
168
- if (!empty($this->_custom_triggers)) {
169
- echo '<script type="text/javascript">wptCondCustomTriggers["#'
170
- . $this->__formID . '"] = ' . json_encode($this->_custom_triggers) . ';</script>';
171
- }
172
- if (!empty($this->_custom_fields)) {
173
- echo '<script type="text/javascript">wptCondCustomFields["#'
174
- . $this->__formID . '"] = ' . json_encode($this->_custom_fields) . ';</script>';
175
- }
176
- }
177
-
178
- /**
179
- * Compares values.
180
- *
181
- * @param array $config
182
- * @param array $values
183
- * @return type
184
- */
185
- public static function evaluate($config) {
186
- // Custom conditional
187
- if (!empty($config['custom'])) {
188
- return self::evaluateCustom($config['custom'], $config['values']);
189
- }
190
-
191
- /**
192
- * check conditions
193
- */
194
- if (!array_key_exists('conditions', $config)) {
195
- return true;
196
- }
197
-
198
- $passedOne = false;
199
- $passedAll = true;
200
- $relation = $config['relation'];
201
-
202
- foreach ($config['conditions'] as $c) {
203
- // Add filters
204
- wptoolset_form_field_add_filters($c['type']);
205
- $c['args'] = apply_filters('wptoolset_conditional_args_php', $c['args'], $c['type']);
206
- $value = isset($config['values'][$c['id']]) ? $config['values'][$c['id']] : null;
207
- $value = apply_filters('wptoolset_conditional_value_php', $value, $c['type']);
208
- $compare = $c['args'][0];
209
- switch ($c['operator']) {
210
- case '=':
211
- case '==':
212
- $passed = $value == $compare;
213
- break;
214
-
215
- case '>':
216
- $passed = floatval($value) > floatval($compare);
217
- break;
218
-
219
- case '>=':
220
- $passed = floatval($value) >= floatval($compare);
221
- break;
222
-
223
- case '<':
224
- $passed = floatval($value) < floatval($compare);
225
- break;
226
-
227
- case '<=':
228
- $passed = floatval($value) <= floatval($compare);
229
- break;
230
-
231
- case '===':
232
- $passed = $value === $compare;
233
- break;
234
-
235
- case '!==':
236
- $passed = $value !== $compare;
237
- break;
238
-
239
- case '<>':
240
- $passed = $value <> $compare;
241
- break;
242
-
243
- case 'between':
244
- $passed = floatval($value) > floatval($compare) && floatval($value) < floatval($c['args'][1]);
245
- break;
246
-
247
- default:
248
- $passed = false;
249
- break;
250
- }
251
- if (!$passed) {
252
- $passedAll = false;
253
- } else {
254
- $passedOne = true;
255
- }
256
- }
257
- if ($relation == 'AND' && $passedAll) {
258
- return true;
259
- }
260
- if ($relation == 'OR' && $passedOne) {
261
- return true;
262
- }
263
- return false;
264
- }
265
-
266
- /**
267
- * Evaluates conditions using custom conditional statement.
268
- *
269
- * @uses wpv_condition()
270
- *
271
- * @param type $post
272
- * @param type $evaluate
273
- * @return boolean
274
- */
275
- public static function evaluateCustom($evaluate, $values) {
276
- //###############################################################################################
277
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/193583580/comments
278
- //Fix REGEX conditions that contains \ that is stripped out
279
- if (strpos($evaluate, "REGEX") === false) {
280
- $evaluate = trim(stripslashes($evaluate));
281
- // Check dates
282
- $evaluate = wpv_filter_parse_date($evaluate);
283
- $evaluate = self::handle_user_function($evaluate);
284
- }
285
-
286
- $fields = self::extractFields($evaluate);
287
- $evaluate = self::_update_values_in_expression($evaluate, $fields, $values);
288
-
289
- $check = false;
290
- try {
291
- $parser = new Toolset_Parser($evaluate);
292
- $parser->parse();
293
- $check = $parser->evaluate();
294
- } catch (Exception $e) {
295
- $check = false;
296
- }
297
- return $check;
298
- }
299
-
300
- static function sortByLength($a, $b) {
301
- return strlen($b) - strlen($a);
302
- }
303
-
304
- private static function _update_values_in_expression($evaluate, $fields, $values) {
305
- // use string replace to replace any fields with their values.
306
- // Sort by length just in case a field name contians a shorter version of another field name.
307
- // eg. $my-field and $my-field-2
308
-
309
- $keys = array_keys($fields);
310
- usort($keys, 'WPToolset_Forms_Conditional::sortByLength');
311
-
312
- foreach ($keys as $key) {
313
- $is_numeric = false;
314
- $is_array = false;
315
- $value = isset($values[$fields[$key]]) ? $values[$fields[$key]] : '';
316
- if ($value == '') {
317
- $value = "''";
318
- }
319
- if (is_numeric($value)) {
320
- $value = '\'' . $value . '\'';
321
- $is_numeric = true;
322
- }
323
-
324
- if ('array' === gettype($value)) {
325
- $is_array = true;
326
- // workaround for datepicker data to cover all cases
327
- if (array_key_exists('timestamp', $value)) {
328
- if (is_numeric($value['timestamp'])) {
329
- $value = $value['timestamp'];
330
- } else if (is_array($value['timestamp'])) {
331
- $value = implode(',', array_values($value['timestamp']));
332
- }
333
- } else if (array_key_exists('datepicker', $value)) {
334
- if (is_numeric($value['datepicker'])) {
335
- $value = $value['datepicker'];
336
- } else if (is_array($value['datepicker'])) {
337
- $value = implode(',', array_values($value['datepicker']));
338
- }
339
- } else {
340
- $value = implode(',', array_values($value));
341
- }
342
- }
343
-
344
- if (!empty($value) && $value != "''" && !$is_numeric && !$is_array) {
345
- $value = '\'' . $value . '\'';
346
- }
347
-
348
- // First replace the $(field_name) format
349
- $evaluate = str_replace('$(' . $fields[$key] . ')', $value, $evaluate);
350
- // next replace the $field_name format
351
- $evaluate = str_replace('$' . $fields[$key], $value, $evaluate);
352
- }
353
- return $evaluate;
354
- }
355
-
356
- /**
357
- * Extracts fields from custom conditional statement.
358
- *
359
- * @param type $evaluate
360
- * @return type
361
- */
362
- public static function extractFields($evaluate) {
363
- //###############################################################################################
364
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/193583580/comments
365
- //Fix REGEX conditions that contains \ that is stripped out
366
- if (strpos($evaluate, "REGEX") === false) {
367
- $evaluate = trim(stripslashes($evaluate));
368
- // Check dates
369
- $evaluate = wpv_filter_parse_date($evaluate);
370
- $evaluate = self::handle_user_function($evaluate);
371
- }
372
-
373
- // Add quotes = > < >= <= === <> !==
374
- $strings_count = preg_match_all('/[=|==|===|<=|<==|<===|>=|>==|>===|\!===|\!==|\!=|<>]\s(?!\$)(\w*)[\)|\$|\W]/', $evaluate, $matches);
375
-
376
- if (!empty($matches[1])) {
377
- foreach ($matches[1] as $temp_match) {
378
- $temp_replace = is_numeric($temp_match) ? $temp_match : '\'' . $temp_match . '\'';
379
- $evaluate = str_replace(' ' . $temp_match . ')', ' ' . $temp_replace . ')', $evaluate);
380
- }
381
- }
382
- // if new version $(field-value) use this regex
383
- if (preg_match('/\$\(([^()]+)\)/', $evaluate)) {
384
- preg_match_all('/\$\(([^()]+)\)/', $evaluate, $matches);
385
- }
386
- // if old version $field-value use this other
387
- else {
388
- preg_match_all('/\$([^\s]*)/', $evaluate, $matches);
389
- }
390
-
391
-
392
- $fields = array();
393
- if (!empty($matches)) {
394
- foreach ($matches[1] as $field_name) {
395
- $fields[trim($field_name, '()')] = trim($field_name, '()');
396
- }
397
- }
398
-
399
- return $fields;
400
- }
401
-
402
- public static function handle_user_function($evaluate) {
403
- $evaluate = stripcslashes($evaluate);
404
- $occurrences = preg_match_all('/(\\w+)\(([^\)]*)\)/', $evaluate, $matches);
405
-
406
- if ($occurrences > 0) {
407
- for ($i = 0; $i < $occurrences; $i++) {
408
- $result = false;
409
- $function = $matches[1][$i];
410
- $field = isset($matches[2]) ? rtrim($matches[2][$i], ',') : '';
411
-
412
- if ($function === 'USER') {
413
- $result = WPV_Handle_Users_Functions::get_user_field($field);
414
- }
415
-
416
- if ($result) {
417
- $evaluate = str_replace($matches[0][$i], $result, $evaluate);
418
- }
419
- }
420
- }
421
-
422
- return $evaluate;
423
- }
424
-
425
- /**
426
- * Custom conditional AJAX check (called from bootstrap.php)
427
- */
428
- public static function ajaxCustomConditional() {
429
- $res = array('passed' => array(), 'failed' => array());
430
- $conditional = stripslashes_deep($_POST['conditions']);
431
- foreach ($conditional as $k => $c) {
432
- $post_values = stripslashes_deep($_POST['values']);
433
- $values = array();
434
- foreach ($post_values as $fid => $value) {
435
- if (isset($_POST['field_types'][$fid])) {
436
- $field_type = stripslashes_deep($_POST['field_types'][$fid]);
437
- wptoolset_form_field_add_filters($field_type);
438
- $value = apply_filters('wptoolset_conditional_value_php', $value, $field_type);
439
- }
440
- $values[$fid] = $value;
441
- }
442
- if ($passed = self::evaluateCustom($c, $values)) {
443
- $res['passed'][] = $k;
444
- } else {
445
- $res['failed'][] = $k;
446
- }
447
- }
448
- echo json_encode($res);
449
- die();
450
- }
451
-
452
- /**
453
- * Checks conditional and hides field.
454
- *
455
- * @param type $config
456
- */
457
- public function actionFieldClass($config) {
458
- if (
459
- !empty($config['conditional']) && array_key_exists('conditions', $config['conditional']) && !self::evaluate($config['conditional'])
460
- ) {
461
- echo ' wpt-hidden js-wpt-remove-on-submit js-wpt-validation-ignore';
462
- }
463
- }
464
-
465
- /**
466
- * Returns collected JSON data
467
- *
468
- * @return type
469
- */
470
- public function getData() {
471
- $this->_parseData();
472
- return array(
473
- 'triggers' => $this->_triggers,
474
- 'fields' => $this->_fields,
475
- 'custom_triggers' => $this->_custom_triggers,
476
- 'custom_fields' => $this->_custom_fields,
477
- );
478
- }
479
-
480
- }
481
- }
482
-
483
- if (!class_exists('WPV_Handle_Users_Functions')) {
484
-
485
- class WPV_Handle_Users_Functions {
486
-
487
- private static $field;
488
-
489
- public static function get_user_field($field) {
490
- if (!$field)
491
- return false;
492
-
493
- self::$field = str_replace("'", '', $field);
494
-
495
- $ret = self::get_info();
496
-
497
- if ($ret !== false)
498
- return "'" . $ret . "'";
499
-
500
- return false;
501
- }
502
-
503
- private static function get_info() {
504
- if (!is_user_logged_in()) {
505
- return false;
506
- }
507
- global $current_user;
508
-
509
- get_currentuserinfo();
510
-
511
- switch (self::$field) {
512
- case 'role':
513
- return isset($current_user->roles[0]) ? $current_user->roles[0] : 'Subscriber';
514
- break;
515
- case 'login':
516
- return $current_user->data->user_login;
517
- break;
518
- case 'name':
519
- return $current_user->data->display_name;
520
- break;
521
- case 'id':
522
- return $current_user->data->ID;
523
- break;
524
- default:
525
- return $current_user->data->ID;
526
- break;
527
- }
528
-
529
- return false;
530
- }
531
-
532
- }
533
-
534
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.cred.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
- /*
3
- * Types fields specific
4
- */
5
- require_once 'class.types.php';
6
- require_once 'class.conditional.php';
7
-
8
- /**
9
- * Class description
10
- *
11
- * @author Srdjan
12
- */
13
- if ( !class_exists('WPToolset_Cred') ){
14
- class WPToolset_Cred
15
- {
16
-
17
- /**
18
- * Filters validation.
19
- *
20
- * Loop over validation settings and create array of validation rules.
21
- * array( $rule => array( 'args' => array, 'message' => string ), ... )
22
- *
23
- * @param array|string $field settings array (as stored in DB) or field ID
24
- * @return array array( $rule => array( 'args' => array, 'message' => string ), ... )
25
- */
26
- public static function filterValidation( $config ){
27
- /* Placeholder for field value '$value'.
28
- *
29
- * Used for validation settings.
30
- * Field value is not processed here, instead string '$value' is used
31
- * to be replaced with actual value when needed.
32
- *
33
- * For example:
34
- * validation['rangelength'] = array(
35
- * 'args' => array( '$value', 5, 12 ),
36
- * 'message' => 'Value length between %s and %s required'
37
- * );
38
- * validation['reqiuired'] = array(
39
- * 'args' => array( '$value', true ),
40
- * 'message' => 'This field is required'
41
- * );
42
- *
43
- * Types have default and custom messages defined on it's side.
44
- */
45
- $value = '$value';
46
- $validation = array();
47
- if ( isset( $config['data']['validate'] ) ) {
48
- foreach ( $config['data']['validate'] as $rule => $settings ) {
49
- if ( $settings['active'] ) {
50
- $validation[$rule] = array(
51
- 'args' => isset( $settings['args'] ) ? array_unshift( $value,
52
- $settings['args'] ) : array($value, true),
53
- 'message' => $settings['message']
54
- );
55
- }
56
- }
57
- }
58
- return $validation;
59
- }
60
-
61
- /**
62
- * Filters conditional.
63
- *
64
- * We'll just handle this as a custom conditional
65
- *
66
- * Custom conditional
67
- * Main properties:
68
- * [custom] - custom statement made by user, note that $xxxx should match
69
- * IDs of fields that passed this filter.
70
- * [values] - same as for regular conditional
71
- *
72
- * [conditional] => Array(
73
- [custom] => ($wpcf-my-date = DATE(01,02,2014)) OR ($wpcf-my-date > DATE(07,02,2014))
74
- [values] => Array(
75
- [wpcf-my-date] => 32508691200
76
- )
77
- )
78
- *
79
- * @param array|string $field settings array (as stored in DB) or field ID
80
- * @param int $post_id Post or user ID to fetch meta data to check against
81
- * @return array
82
- */
83
- public static function filterConditional( $if, $post_id ){
84
-
85
- $data = WPToolset_Types::getCustomConditional($if, '', WPToolset_Types::getConditionalValues($post_id));
86
- return $data;
87
- }
88
-
89
- }
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.credaudio.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
- require_once 'class.credfile.php';
3
- require_once 'class.audio.php';
4
-
5
- /**
6
- * Description of class
7
- *
8
- * @author Srdjan
9
- *
10
- *
11
- */
12
- class WPToolset_Field_Credaudio extends WPToolset_Field_Credfile
13
- {
14
- protected $_settings = array('min_wp_version' => '3.6');
15
-
16
- public function metaform()
17
- {
18
- //TODO: check if this getValidationData does not break PHP Validation _cakePHP required file.
19
- $validation = $this->getValidationData();
20
- $validation = WPToolset_Field_Audio::addTypeValidation($validation);
21
- $this->setValidationData($validation);
22
- return parent::metaform();
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.credfile.php DELETED
@@ -1,186 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
- require_once 'class.textfield.php';
8
-
9
- /**
10
- * Description of class
11
- *
12
- * @author Francesco / Srdjan
13
- */
14
- class WPToolset_Field_Credfile extends WPToolset_Field_Textfield {
15
-
16
- public $enable_progress_bar;
17
-
18
- public function init() {
19
- wp_register_script('wpt-field-credfile', WPTOOLSET_FORMS_RELPATH . '/js/credfile.js', array('wptoolset-forms'), WPTOOLSET_FORMS_VERSION, true);
20
- wp_enqueue_script('wpt-field-credfile');
21
-
22
- $this->enable_progress_bar = true;
23
- if ($this->enable_progress_bar) {
24
- //Add settings switch in order to use AJAX JQUERY UPLOAD or not
25
- $scriptpath = WPTOOLSET_FORMS_RELPATH . '/js/jquery_upload/';
26
- $stylepath = WPTOOLSET_FORMS_RELPATH . '/js/jquery_upload/';
27
-
28
- wp_enqueue_style('progress_bar-style', $stylepath . 'progress_bar.css');
29
-
30
- if (!wp_script_is('jquery')) {
31
- wp_enqueue_script('jquery', $scriptpath . 'jquery.min.js', array(), '', false);
32
- }
33
- wp_enqueue_script('jquery-ui-script', $scriptpath . 'jquery-ui.min.js', array('jquery'), '', true);
34
- wp_enqueue_script('jquery-ui-widget-script', $scriptpath . 'jquery.ui.widget.js', array('jquery'), '', true);
35
- //wp_enqueue_script('jtmpl-script', $scriptpath . 'tmpl.min.js', array('jquery'), '', true);
36
- wp_enqueue_script('load-image-all-script', $scriptpath . 'load-image.all.min.js', array('jquery'), '', true);
37
- //wp_enqueue_script('canvas-to-blob-script', $scriptpath . 'canvas-to-blob.min.js', array('jquery'), '', true);
38
- //wp_enqueue_script('jquery-blueimp-gallery-script', $scriptpath . 'jquery.blueimp-gallery.min.js', array('jquery'), '', true);
39
- wp_enqueue_script('jquery-iframe-transport-script', $scriptpath . 'jquery.iframe-transport.js', array('jquery'), '', true);
40
- wp_enqueue_script('jquery-fileupload-script', $scriptpath . 'jquery.fileupload.js', array('jquery'), '', true);
41
- wp_enqueue_script('jquery-fileupload-process-script', $scriptpath . 'jquery.fileupload-process.js', array('jquery'), '', true);
42
- wp_enqueue_script('jquery-fileupload-image-script', $scriptpath . 'jquery.fileupload-image.js', array('jquery'), '', true);
43
- wp_enqueue_script('jquery-fileupload-audio-script', $scriptpath . 'jquery.fileupload-audio.js', array('jquery'), '', true);
44
- wp_enqueue_script('jquery-fileupload-video-script', $scriptpath . 'jquery.fileupload-video.js', array('jquery'), '', true);
45
- wp_enqueue_script('jquery-fileupload-validate-script', $scriptpath . 'jquery.fileupload-validate.js', array('jquery'), '', true);
46
- wp_enqueue_script('jquery-fileupload-ui-script', $scriptpath . 'jquery.fileupload-ui.js', array('jquery'), '', true);
47
- wp_enqueue_script('jquery-fileupload-jquery-ui-script', $scriptpath . 'jquery.fileupload-jquery-ui.js', array('jquery'), '', true);
48
- wp_enqueue_script('my_ajax_file_uploader', $scriptpath . 'file_upload.js', array('jquery'));
49
-
50
- //wp_localize_script('my_ajax_file_uploader_thing', 'settings', array('ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('uploader_nonce')));
51
- wp_localize_script('my_ajax_file_uploader', 'settings', array('ajaxurl' => plugins_url("submit.php", __FILE__), 'nonce' => wp_create_nonce('ajax_nonce')));
52
- }
53
- }
54
-
55
- public static function registerScripts() {
56
-
57
- }
58
-
59
- public static function registerStyles() {
60
-
61
- }
62
-
63
- public function enqueueScripts() {
64
-
65
- }
66
-
67
- public function enqueueStyles() {
68
-
69
- }
70
-
71
- public function metaform() {
72
- $value = $this->getValue();
73
- $name = $this->getName();
74
- if (isset($this->_data['title'])) {
75
- $title = $this->_data['title'];
76
- } else {
77
- $title = $name;
78
- }
79
-
80
- $id = str_replace(array("[", "]"), "", $name);
81
- $delete_input_showhide = '';
82
- $button_extra_classnames = '';
83
-
84
- $has_image = false;
85
- $is_empty = false;
86
-
87
- if (empty($value)) {
88
- $value = ''; // NOTE we need to set it to an empty string because sometimes it is NULL on repeating fields
89
- $is_empty = true;
90
- $delete_input_showhide = ' style="display:none"';
91
- }
92
-
93
- if ($name == '_featured_image') {
94
- $title = __('Featured Image', 'wpv-views');
95
- if (!$is_empty) {
96
- if (preg_match('/src="([\w\d\:\/\._-]*)"/', $value, $_v)) {
97
- $value = $_v[1];
98
- }
99
- }
100
- }
101
-
102
- if (!$is_empty) {
103
- $pathinfo = pathinfo($value);
104
- // TODO we should check against the allowed mime types, not file extensions
105
- if (isset($pathinfo['extension']) && in_array(strtolower($pathinfo['extension']), array('png', 'gif', 'jpg', 'jpeg', 'bmp', 'tif'))) {
106
- $has_image = true;
107
- }
108
- }
109
-
110
- if (array_key_exists('use_bootstrap', $this->_data) && $this->_data['use_bootstrap']) {
111
- $button_extra_classnames = ' btn btn-default btn-sm';
112
- }
113
-
114
- $preview_file = ''; //WPTOOLSET_FORMS_RELPATH . '/images/icon-attachment32.png';
115
- $attr_hidden = array(
116
- 'id' => $id . "_hidden",
117
- 'class' => 'js-wpv-credfile-hidden',
118
- 'data-wpt-type' => 'file'
119
- );
120
- $attr_file = array(
121
- 'id' => $id . "_file",
122
- 'class' => 'js-wpt-credfile-upload-file wpt-credfile-upload-file',
123
- 'alt' => $value,
124
- );
125
-
126
- if (!$is_empty) {
127
- $preview_file = $value;
128
- // Set attributes
129
- $attr_file['disabled'] = 'disabled';
130
- $attr_file['style'] = 'display:none';
131
- } else {
132
- $attr_hidden['disabled'] = 'disabled';
133
- }
134
-
135
- $form = array();
136
-
137
- $form[] = array(
138
- '#type' => 'markup',
139
- '#markup' => '<input type="button" style="display:none" data-action="undo" class="js-wpt-credfile-undo wpt-credfile-undo' . $button_extra_classnames . '" value="' . esc_attr(__('Restore original', 'wpv-views')) . '" />',
140
- );
141
- $form[] = array(
142
- '#type' => 'markup',
143
- '#markup' => '<input type="button"' . $delete_input_showhide . ' data-action="delete" class="js-wpt-credfile-delete wpt-credfile-delete' . $button_extra_classnames . '" value="' . esc_attr(__('Clear', 'wpv-views')) . '" />',
144
- );
145
- $form[] = array(
146
- '#type' => 'hidden',
147
- '#name' => $name,
148
- '#value' => $value,
149
- '#attributes' => $attr_hidden,
150
- );
151
- $form[] = array(
152
- '#type' => 'file',
153
- '#name' => $name,
154
- '#value' => $value,
155
- '#title' => $title,
156
- '#before' => '',
157
- '#after' => '',
158
- '#attributes' => $attr_file,
159
- '#validate' => $this->getValidationData(),
160
- '#repetitive' => $this->isRepetitive(),
161
- );
162
-
163
- if ($this->enable_progress_bar) {
164
- //Progress Bar
165
- $form[] = array(
166
- '#type' => 'markup',
167
- '#markup' => '<div id="progress_' . $id . '" class="meter" style="display:none;"><span class = "progress-bar" style="width:0;"></span></div>',
168
- );
169
- }
170
-
171
- if ($has_image) {
172
- $form[] = array(
173
- '#type' => 'markup',
174
- '#markup' => '<span class="js-wpt-credfile-preview wpt-credfile-preview"><img id="' . $id . '_image" src="' . $preview_file . '" title="' . $preview_file . '" alt="' . $preview_file . '" class="js-wpt-credfile-preview-item wpt-credfile-preview-item" /></span>',
175
- );
176
- } else {
177
- //if ( !$is_empty )
178
- $form[] = array(
179
- '#type' => 'markup',
180
- '#markup' => '<span class="js-wpt-credfile-preview wpt-credfile-preview">' . $preview_file . '</span>',
181
- );
182
- }
183
- return $form;
184
- }
185
-
186
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.credimage.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
- require_once 'class.credfile.php';
3
- require_once 'class.image.php';
4
-
5
- /**
6
- * Description of class
7
- *
8
- * @author Srdjan
9
- *
10
- *
11
- */
12
- class WPToolset_Field_Credimage extends WPToolset_Field_Credfile
13
- {
14
- public function metaform()
15
- {
16
- //TODO: check if this getValidationData does not break PHP Validation _cakePHP required file.
17
- $validation = $this->getValidationData();
18
- $validation = WPToolset_Field_Image::addTypeValidation($validation);
19
- $this->setValidationData($validation);
20
- return parent::metaform();
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.credvideo.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
- require_once 'class.credfile.php';
3
- require_once 'class.video.php';
4
-
5
- /**
6
- * Description of class
7
- *
8
- * @author Srdjan
9
- *
10
- *
11
- */
12
- class WPToolset_Field_Credvideo extends WPToolset_Field_Credfile
13
- {
14
- protected $_settings = array('min_wp_version' => '3.6');
15
-
16
- public function metaform()
17
- {
18
- //TODO: check if this getValidationData does not break PHP Validation _cakePHP required file.
19
- $validation = $this->getValidationData();
20
- $validation = WPToolset_Field_Video::addTypeValidation($validation);
21
- $this->setValidationData($validation);
22
- return parent::metaform();
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.date.php DELETED
@@ -1,434 +0,0 @@
1
- <?php
2
-
3
- require_once 'class.field_factory.php';
4
- if (!function_exists('adodb_mktime')) {
5
- require_once WPTOOLSET_FORMS_ABSPATH . '/lib/adodb-time.inc.php';
6
- }
7
-
8
- /**
9
- * Description of class
10
- *
11
- * @author Srdjan
12
- */
13
- class WPToolset_Field_Date extends FieldFactory
14
- {
15
- // 15/10/1582 00:00 - 31/12/3000 23:59
16
- protected static $_mintimestamp = -12219292800, $_maxtimestamp = 32535215940;
17
-
18
- public function init()
19
- {
20
- $this->set_placeholder_as_attribute();
21
- }
22
-
23
- public static function registerScripts()
24
- {
25
- }
26
-
27
- public static function registerStyles()
28
- {
29
- }
30
-
31
- public static function addFilters()
32
- {
33
- if (has_filter('wptoolset_validation_value_date', array('WPToolset_Field_Date', 'filterValidationValue'))) {
34
- return;
35
- }
36
- // Filter validation
37
- add_filter('wptoolset_validation_value_date', array('WPToolset_Field_Date', 'filterValidationValue'));
38
- add_filter('wptoolset_validation_rule_js', array('WPToolset_Field_Date', 'filterValidationRuleJs'));
39
- add_filter('wptoolset_validation_args_php', array('WPToolset_Field_Date', 'filterValidationArgsPhp'), 10, 2);
40
- // Filter conditional
41
- add_filter('wptoolset_conditional_args_php', array('WPToolset_Field_Date', 'filterConditionalArgsPhp'), 10, 2);
42
- add_filter('wptoolset_conditional_value_php', array('WPToolset_Field_Date', 'filterConditionalValuePhp'), 10, 2);
43
- add_filter('wptoolset_conditional_args_js', array('WPToolset_Field_Date', 'filterConditionalArgsJs'), 10, 2);
44
- }
45
-
46
- public function enqueueScripts()
47
- {
48
- }
49
-
50
- public function enqueueStyles()
51
- {
52
- }
53
-
54
- public function metaform()
55
- {
56
- $time_value = $this->getValue();
57
- $datepicker = $hour = $minute = null;
58
- $timestamp = null;
59
- $readonly = false;
60
- if (is_admin()) {
61
- if (is_array($time_value) && array_key_exists('timestamp', $time_value) && $time_value ) {
62
- $timestamp = $time_value['timestamp'];
63
- }
64
- $datepicker = self::timetodate($timestamp);
65
- $hour = self::timetodate($timestamp, 'H');
66
- $minute = self::timetodate($timestamp, 'i');
67
- } else {
68
- // We are on a CRED form, on frontend, so getVAlue returns nothing or a string or an array of the kind array( 'datepicker' =>, 'hour' =>, 'minute' => )
69
- // Note that even if the array is passed, 'hour' and 'minute' will only be passed if there are any
70
- if (!empty($time_value)) {
71
- if (is_array($time_value)) {
72
- if (isset($time_value['timestamp']) && is_numeric($time_value['timestamp']) && self::_isTimestampInRange($time_value['timestamp'])) {
73
- $timestamp = $time_value['timestamp'];
74
- $datepicker = self::timetodate($timestamp);
75
- } elseif (isset($time_value['datepicker']) && $time_value['datepicker'] !== false && is_numeric($time_value['datepicker']) && self::_isTimestampInRange($time_value['datepicker'])) {
76
- $timestamp = $time_value['datepicker'];
77
- $datepicker = self::timetodate($timestamp);
78
- }
79
- if (isset($time_value['hour']) && is_numeric($time_value['hour'])) {
80
- $hour = $time_value['hour'];
81
- }
82
- if (isset($time_value['minute']) && is_numeric($time_value['minute'])) {
83
- $minute = $time_value['minute'];
84
- }
85
- } else {
86
- if (is_numeric($time_value) && self::_isTimestampInRange($time_value)) {
87
- $timestamp = $time_value;
88
- $datepicker = self::timetodate($timestamp);
89
- } else {
90
- $timestamp = self::strtotime($time_value);
91
- $datepicker = $time_value;
92
- }
93
- }
94
- }
95
- }
96
- $data = $this->getData();
97
-
98
- if (!$timestamp) {
99
- // If there is no timestamp, we need to make it an empty string
100
- // A false value would render the hidden field with a value of 1
101
- $timestamp = '';
102
- $datepicker = null;
103
- }
104
-
105
- $def_class = 'js-wpt-date';
106
-
107
- $def_class_aux = 'js-wpt-date-auxiliar';
108
-
109
- if (isset($data['attribute']) && isset($data['attribute']['readonly']) && $data['attribute']['readonly'] == 'readonly') {
110
- $def_class .= ' js-wpv-date-readonly';
111
- $def_class_aux .= ' js-wpt-date-readonly';
112
- $readonly = true;
113
- }
114
-
115
- $form = array();
116
-
117
- $validate = $this->getValidationData();
118
- $title = $this->getTitle();
119
-
120
- if (isset($validate['required']) && !empty($title)) {
121
- // Asterisk
122
- $title .= '&#42;';
123
- }
124
-
125
- $attr_visible = array(
126
- 'class' => $def_class,
127
- 'style' => 'display:inline;width:150px;position:relative;',
128
- 'readonly' => 'readonly',
129
- 'title' => esc_attr(__('Select', 'wpv-views'))." Date"
130
- );
131
- $attr_hidden = array('class' => $def_class_aux, 'data-ts' => $timestamp, 'data-wpt-type' => 'date');
132
-
133
- if (isset($data['attribute']) && isset($data['attribute']['placeholder'])) {
134
- $attr_visible['placeholder'] = $data['attribute']['placeholder'];
135
- }
136
-
137
- $form[] = array(
138
- '#type' => 'textfield',
139
- '#title' => $title,
140
- '#description' => $this->getDescription(),
141
- '#attributes' => $attr_visible,
142
- '#name' => $this->getName() . '[display-only]',
143
- '#value' => $datepicker,
144
- '#inline' => true,
145
- );
146
- $form[] = array(
147
- '#type' => 'hidden',
148
- '#title' => $title,
149
- '#attributes' => $attr_hidden,
150
- '#name' => $this->getName() . '[datepicker]',
151
- '#value' => $timestamp,
152
- '#validate' => $validate,
153
- '#repetitive' => $this->isRepetitive(),
154
- );
155
-
156
- /*
157
- // This was the old implementaton
158
- // We have implemented the above one because we need a hidden field to hold the timestamp
159
- // And the visible text input field to display the date string to the user
160
- $form[] = array(
161
- '#type' => 'textfield',
162
- '#title' => $this->getTitle(),
163
- '#attributes' => array('class' => $def_class, 'style' => 'width:150px;'),
164
- '#name' => $this->getName() . '[datepicker]',
165
- '#value' => $timestamp,
166
- '#validate' => $this->getValidationData(),
167
- '#repetitive' => $this->isRepetitive(),
168
- );
169
- */
170
- if (!empty($data['add_time'])) {
171
- // Shared attributes
172
- $attributes_hour_minute = array();
173
- if ($readonly) {
174
- $attributes_hour_minute['disabled'] = 'disabled';
175
- }
176
- if (array_key_exists('use_bootstrap', $this->_data) && $this->_data['use_bootstrap']) {
177
- $attributes_hour_minute['style'] = 'display:inline;width:auto;';
178
- }
179
-
180
- // Hour
181
- $hours = 24;
182
- $options = array();
183
- for ($index = 0; $index < $hours; $index++) {
184
- $prefix = $index < 10 ? '0' : '';
185
- $options[$index] = array(
186
- '#title' => $prefix . strval($index),
187
- '#value' => $index,
188
- );
189
- }
190
- $hour_element = array(
191
- '#type' => 'select',
192
- '#before' => '<span class="wpt-form-label">' . __('Hour', 'wpv-views') . '</span>',
193
- '#options' => $options,
194
- '#default_value' => $hour,
195
- '#name' => $this->getName() . '[hour]',
196
- '#inline' => true,
197
- '#attributes' => array('title' => esc_attr(__('Select', 'wpv-views'))." Date"),
198
- );
199
- if (!empty($attributes_hour_minute)) {
200
- $hour_element['#attributes'] = $attributes_hour_minute;
201
- }
202
- $form[] = $hour_element;
203
- // Minutes
204
- $minutes = 60;
205
- $options = array();
206
- for ($index = 0; $index < $minutes; $index++) {
207
- $prefix = $index < 10 ? '0' : '';
208
- $options[$index] = array(
209
- '#title' => $prefix . strval($index),
210
- '#value' => $index,
211
- );
212
- }
213
- $minute_element = array(
214
- '#type' => 'select',
215
- '#before' => '<span class="wpt-form-label">' . __('Minute', 'wpv-views') . '</span>',
216
- '#options' => $options,
217
- '#default_value' => $minute,
218
- '#name' => $this->getName() . '[minute]',
219
- '#inline' => true,
220
- '#attributes' => array('title' => esc_attr(__('Select minute', 'wpv-views'))),
221
- );
222
- if (!empty($attributes_hour_minute)) {
223
- $minute_element['#attributes'] = $attributes_hour_minute;
224
- }
225
- $form[] = $minute_element;
226
- }
227
-
228
- $form[] = array(
229
- '#type' => 'markup',
230
- '#inline' => true,
231
- '#markup' => sprintf(
232
- '<input type="button" class="button button-secondary js-wpt-date-clear wpt-date-clear" value="%s" %s/>',
233
- esc_attr(__('Clear', 'wpv-views'))." Date",
234
- /**
235
- * show button if array is empty or timestamp in array is
236
- * empty
237
- */
238
- (
239
- empty($time_value)
240
- || !isset($time_value['timestamp'])
241
- || (isset($time_value['timestamp']) && empty($time_value['timestamp']))
242
- )? 'style="display:none" ':''
243
- ),
244
- );
245
- return $form;
246
- }
247
-
248
- public static function getDateFormat()
249
- {
250
- return WPToolset_Field_Date_Scripts::getDateFormat();
251
- }
252
-
253
- protected function _dateToStrftime($format)
254
- {
255
- $format = str_replace('d', '%d', $format);
256
- $format = str_replace('D', '%a', $format);
257
- $format = str_replace('j', '%e', $format);
258
- $format = str_replace('l', '%A', $format);
259
- $format = str_replace('N', '%u', $format);
260
- $format = str_replace('w', '%w', $format);
261
-
262
- $format = str_replace('W', '%W', $format);
263
-
264
- $format = str_replace('F', '%B', $format);
265
- $format = str_replace('m', '%m', $format);
266
- $format = str_replace('M', '%b', $format);
267
- $format = str_replace('n', '%m', $format);
268
-
269
- $format = str_replace('o', '%g', $format);
270
- $format = str_replace('Y', '%Y', $format);
271
- $format = str_replace('y', '%y', $format);
272
-
273
- return $format;
274
- }
275
-
276
- public static function filterValidationValue($value)
277
- {
278
- /**
279
- * validate fimestamp range is possible
280
- */
281
- if (isset($value['timestamp'])) {
282
- return $value['timestamp'];
283
- }
284
- if (isset($value['datepicker'])) {
285
- return $value['datepicker'];
286
- }
287
- return $value;
288
- }
289
-
290
- public static function filterValidationRuleJs($rule)
291
- {
292
- if ($rule == 'date') {
293
- return 'dateADODB_STAMP';
294
- } else {
295
- return $rule;
296
- }
297
- }
298
-
299
- public static function filterValidationArgsPhp($args, $rule)
300
- {
301
- if ($rule == 'date') {
302
- return array('$value', self::getDateFormat());
303
- }
304
- return $args;
305
- }
306
-
307
- public static function filterConditionalArgsJs($args, $type)
308
- {
309
- if ($type == 'date') {
310
- foreach ($args as &$arg) {
311
- if (!is_numeric($arg)) {
312
- // Well it should be a numeric timestamp indeed
313
- $arg = self::strtotime($arg);
314
- }
315
- }
316
- }
317
- return $args;
318
- }
319
-
320
- public static function filterConditionalArgsPhp($args, $type)
321
- {
322
- if ($type == 'date') {
323
- foreach ($args as &$arg) {
324
- $arg = self::filterConditionalValuePhp($arg, $type);
325
- }
326
- }
327
- return $args;
328
- }
329
-
330
- public static function filterConditionalValuePhp($value, $type)
331
- {
332
- if ($type == 'date') {
333
- if (!is_numeric($value)) {
334
- // Well it should be a numeric timestamp indeed
335
- $value = self::strtotime($value);
336
- }
337
- // Use timestamp with PHP
338
- // Convert back/forward to have rounded timestamp (no H and i)
339
- // TODO review this because we should not play with timestamps generated on adodb_xxx functions
340
- //$value = self::strtotime( self::timetodate( $value ) );
341
- }
342
- return $value;
343
- }
344
-
345
- // We need to keep this for backwards compatibility
346
- // Note that this function will only convert dates coming on a string:
347
- // - in english
348
- // - inside the valid PHP date range
349
- // We are only using this when the value being checked is not a timestamp
350
- // And we have tried to avoid that situation from happening
351
- // But for old implementation, this happens for date conditions on conditional fields
352
- public static function strtotime($value, $format = null)
353
- {
354
- if (is_null($format)) {
355
- $format = self::getDateFormat();
356
- }
357
- /**
358
- * add exception to handle short year
359
- */
360
- if ('d/m/y' == $format) {
361
- preg_match_all('/(\d{2})/', $value, $value);
362
- $value[0][2] += $value[0][2] < 70 ? 2000 : 1900;
363
- $value = implode('-', $value[0]);
364
- }
365
- if (strpos($format, 'd/m/Y') !== false) {
366
- // strtotime requires a dash or dot separator to determine dd/mm/yyyy format
367
- preg_match('/\d{2}\/\d{2}\/\d{4}/', $value, $matches);
368
- if (!empty($matches)) {
369
- foreach ($matches as $match) {
370
- $value = str_replace($match, str_replace('/', '-', $match), $value);
371
- }
372
- }
373
- }
374
- try {
375
- $date = new DateTime($value);
376
- } catch (Exception $e) {
377
- return false;
378
- }
379
- $timestamp = $date->format("U");
380
- return self::_isTimestampInRange($timestamp) ? $timestamp : false;
381
- }
382
-
383
- // TODO review this because we should not play with timestamps generated on adodb_xxx functions
384
- public static function timetodate($timestamp, $format = null)
385
- {
386
- return WPToolset_Field_Date_Scripts::timetodate($timestamp, $format);
387
- }
388
-
389
- protected static function _isTimestampInRange($timestamp)
390
- {
391
- return WPToolset_Field_Date_Scripts::_isTimestampInRange($timestamp);
392
- }
393
-
394
- /**
395
- * DEPRECATED
396
- *
397
- * This is not used anymore
398
- */
399
- public static function timeIsValid($time)
400
- {
401
- /*
402
- * http://php.net/manual/en/function.strtotime.php
403
- * The valid range of a timestamp is typically
404
- * from Fri, 13 Dec 1901 20:45:54 UTC
405
- * to Tue, 19 Jan 2038 03:14:07 UTC.
406
- * (These are the dates that correspond to the minimum
407
- * and maximum values for a 32-bit signed integer.)
408
- * Additionally, not all platforms support negative timestamps,
409
- * therefore your date range may be limited to no earlier than
410
- * the Unix epoch.
411
- * This means that e.g. dates prior to Jan 1, 1970 will not
412
- * work on Windows, some Linux distributions,
413
- * and a few other operating systems.
414
- * PHP 5.1.0 and newer versions overcome this limitation though.
415
- */
416
- // MIN 'Jan 1, 1970' - 0 | Fri, 13 Dec 1901 20:45:54 UTC
417
- $_min_time = self::timeNegativeSupported() ? -2147483646 : 0;
418
- // MAX 'Tue, 19 Jan 2038 03:14:07 UTC' - 2147483647
419
- $_max_time = 2147483647;
420
-
421
- return is_numeric($time) && $_min_time <= intval($time) && intval($time) <= $_max_time;
422
- }
423
-
424
- /**
425
- * DEPRECATED
426
- *
427
- * This is not used anymore
428
- */
429
- public static function timeNegativeSupported()
430
- {
431
- return strtotime('Fri, 13 Dec 1950 20:45:54 UTC') === -601010046;
432
- }
433
-
434
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.date.scripts.php DELETED
@@ -1,190 +0,0 @@
1
- <?php
2
- if (!function_exists('adodb_mktime')) {
3
- require_once WPTOOLSET_FORMS_ABSPATH . '/lib/adodb-time.inc.php';
4
- }
5
-
6
- class WPToolset_Field_Date_Scripts
7
- {
8
-
9
- public static $_supported_date_formats = array(
10
- 'F j, Y', //December 23, 2011
11
- 'Y/m/d', // 2011/12/23
12
- 'm/d/Y', // 12/23/2011
13
- 'd/m/Y', // 23/22/2011
14
- 'd/m/y', // 23/22/11
15
- );
16
-
17
- public $_supported_date_formats_text = array(
18
- 'F j, Y' => 'Month dd, yyyy',
19
- 'Y/m/d' => 'yyyy/mm/dd',
20
- 'm/d/Y' => 'mm/dd/yyyy',
21
- 'd/m/Y' => 'dd/mm/yyyy',
22
- 'd/m/y' => 'dd/mm/yy',
23
- );
24
-
25
- // 15/10/1582 00:00 - 31/12/3000 23:59
26
- protected static $_mintimestamp = -12219292800;
27
- protected static $_maxtimestamp = 32535215940;
28
-
29
- public function __construct()
30
- {
31
- global $pagenow;
32
- if (
33
- //for front-end
34
- !is_admin() ||
35
- //for edit group pages
36
- ( ( isset($_GET['page']) && ($_GET['page'] == 'wpcf-edit-usermeta' || $_GET['page'] == 'wpcf-edit') ) ||
37
- //for edit pages including profile pages
38
- ($pagenow == 'profile.php' || $pagenow == 'post-new.php' || $pagenow == 'user-edit.php' || $pagenow == 'user-new.php' || $pagenow == 'post.php' || $pagenow == 'admin-ajax.php') && is_admin() ) ){
39
- add_action( 'admin_enqueue_scripts', array( $this,'date_enqueue_scripts' ) );
40
- if ( defined('CRED_FE_VERSION')) {
41
- add_action( 'wp_enqueue_scripts', array( $this, 'date_enqueue_scripts' ) );
42
- }
43
- }
44
- $this->localization_slug = false;
45
- }
46
-
47
- public function date_enqueue_scripts()
48
- {
49
- /**
50
- * prevent load scripts on custom field group edit screen
51
- */
52
- if ( is_admin() ) {
53
- $screen = get_current_screen();
54
- if ( 'types_page_wpcf-edit' == $screen->id ) {
55
- return;
56
- }
57
- }
58
- /**
59
- * styles
60
- */
61
- wp_register_style(
62
- 'wptoolset-field-datepicker',
63
- WPTOOLSET_FORMS_RELPATH . '/css/wpt-jquery-ui/datepicker.css',
64
- array(),
65
- WPTOOLSET_FORMS_VERSION
66
- );
67
-
68
- /**
69
- * check first is wptoolset-forms registered?
70
- */
71
- if (!wp_script_is('wptoolset-forms', 'registered')) {
72
- wp_register_script(
73
- 'wptoolset-forms',
74
- WPTOOLSET_FORMS_RELPATH . '/js/main.js',
75
- array('jquery', 'underscore', 'suggest'),
76
- WPTOOLSET_FORMS_VERSION,
77
- true
78
- );
79
- }
80
-
81
- /**
82
- * scripts
83
- */
84
- wp_register_script(
85
- 'wptoolset-field-date',
86
- WPTOOLSET_FORMS_RELPATH . '/js/date.js',
87
- array('jquery-ui-datepicker', 'wptoolset-forms'),
88
- WPTOOLSET_FORMS_VERSION,
89
- true
90
- );
91
- // Localize datepicker
92
- if ( in_array( self::getDateFormat(), self::$_supported_date_formats ) ) {
93
- /*
94
- $locale = str_replace( '_', '-', strtolower( get_locale() ) );
95
- $file = WPTOOLSET_FORMS_ABSPATH . '/js/i18n/jquery.ui.datepicker-' . $locale . '.js';
96
- if ( file_exists( $file ) ) {
97
- wp_register_script(
98
- 'wptoolset-field-date-localized',
99
- WPTOOLSET_FORMS_RELPATH . '/js/i18n/jquery.ui.datepicker-' . $locale . '.js',
100
- array('jquery-ui-datepicker'),
101
- WPTOOLSET_FORMS_VERSION,
102
- true
103
- );
104
- }
105
- */
106
- $lang = get_locale();
107
- $lang = str_replace('_', '-', $lang);
108
- // TODO integrate this with WPML lang
109
- if ( file_exists( WPTOOLSET_FORMS_ABSPATH . '/js/i18n/jquery.ui.datepicker-' . $lang . '.js' ) ) {
110
- if ( !wp_script_is( 'jquery-ui-datepicker-local-' . $lang, 'registered' ) ) {
111
- wp_register_script( 'jquery-ui-datepicker-local-' . $lang, WPTOOLSET_FORMS_RELPATH . '/js/i18n/jquery.ui.datepicker-' . $lang . '.js', array('jquery-ui-core', 'jquery', 'jquery-ui-datepicker'), WPTOOLSET_FORMS_VERSION, true );
112
- $this->localization_slug = $lang;
113
- }
114
- } else {
115
- $lang = substr($lang, 0, 2);
116
- if ( file_exists( WPTOOLSET_FORMS_ABSPATH . '/js/i18n/jquery.ui.datepicker-' . $lang . '.js' ) ) {
117
- if ( !wp_script_is( 'jquery-ui-datepicker-local-' . $lang, 'registered' ) ) {
118
- wp_register_script( 'jquery-ui-datepicker-local-' . $lang, WPTOOLSET_FORMS_RELPATH . '/js/i18n/jquery.ui.datepicker-' . $lang . '.js', array('jquery-ui-core', 'jquery', 'jquery-ui-datepicker'), WPTOOLSET_FORMS_VERSION, true );
119
- $this->localization_slug = $lang;
120
- }
121
- }
122
- }
123
- }
124
- /**
125
- * styles
126
- */
127
- wp_enqueue_style( 'wptoolset-field-datepicker' );
128
- /**
129
- * scripts
130
- */
131
- wp_enqueue_script( 'wptoolset-field-date' );
132
- $date_format = self::getDateFormat();
133
- $js_date_format = $this->_convertPhpToJs( $date_format );
134
- $calendar_image = WPTOOLSET_FORMS_RELPATH . '/images/calendar.gif';
135
- $calendar_image = apply_filters( 'wptoolset_filter_wptoolset_calendar_image', $calendar_image );
136
- $calendar_image_readonly = WPTOOLSET_FORMS_RELPATH . '/images/calendar-readonly.gif';
137
- $calendar_image_readonly = apply_filters( 'wptoolset_filter_wptoolset_calendar_image_readonly', $calendar_image_readonly );
138
- $js_data = array(
139
- 'buttonImage' => $calendar_image,
140
- 'buttonText' => __( 'Select date', 'wpv-views' ),
141
- 'dateFormat' => $js_date_format,
142
- 'dateFormatPhp' => $date_format,
143
- 'dateFormatNote' => esc_js( sprintf( __( 'Input format: %s', 'wpv-views' ), $date_format ) ),
144
- 'yearMin' => intval( self::timetodate( self::$_mintimestamp, 'Y' ) ) + 1,
145
- 'yearMax' => self::timetodate( self::$_maxtimestamp, 'Y' ),
146
- 'ajaxurl' => admin_url('admin-ajax.php', null),
147
- 'readonly' => esc_js( __( 'This is a read-only date input', 'wpv-views' ) ),
148
- 'readonly_image' => $calendar_image_readonly,
149
- );
150
- wp_localize_script( 'wptoolset-field-date', 'wptDateData', $js_data );
151
- if ( $this->localization_slug && !wp_script_is( 'jquery-ui-datepicker-local-' . $this->localization_slug ) ) {
152
- wp_enqueue_script( 'jquery-ui-datepicker-local-' . $this->localization_slug );
153
- }
154
- }
155
-
156
- protected function _convertPhpToJs( $date_format )
157
- {
158
- $date_format = str_replace( 'd', 'dd', $date_format );
159
- $date_format = str_replace( 'j', 'd', $date_format );
160
- $date_format = str_replace( 'l', 'DD', $date_format );
161
- $date_format = str_replace( 'm', 'mm', $date_format );
162
- $date_format = str_replace( 'n', 'm', $date_format );
163
- $date_format = str_replace( 'F', 'MM', $date_format );
164
- $date_format = str_replace( 'y', 'y', $date_format );
165
- $date_format = str_replace( 'Y', 'yy', $date_format );
166
-
167
- return $date_format;
168
- }
169
-
170
- public static function getDateFormat() {
171
- $date_format = get_option( 'date_format' );
172
- if ( !in_array( $date_format, self::$_supported_date_formats ) ) {
173
- $date_format = 'F j, Y';
174
- }
175
- return $date_format;
176
- }
177
-
178
- public static function timetodate( $timestamp, $format = null )
179
- {
180
- if ( is_null( $format ) ) {
181
- $format = self::getDateFormat();
182
- }
183
- return self::_isTimestampInRange( $timestamp ) ? @adodb_date( $format, $timestamp ) : false;
184
- }
185
-
186
- public static function _isTimestampInRange( $timestamp )
187
- {
188
- return self::$_mintimestamp <= $timestamp && $timestamp <= self::$_maxtimestamp;
189
- }
190
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.eforms.php DELETED
@@ -1,1226 +0,0 @@
1
- <?php
2
-
3
- /* Copyright 2011 enlimbo lancers (email : lancers@enlimbo.net)
4
-
5
- This program is free software; you can redistribute it and/or
6
- modify it under the terms of the GNU General Public License
7
- as published by the Free Software Foundation; either version 2
8
- of the License, or (at your option) any later version.
9
-
10
- This program is distributed in the hope that it will be useful,
11
- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- GNU General Public License for more details.
14
-
15
- You should have received a copy of the GNU General Public License
16
- along with this program; if not, write to the Free Software
17
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
- */
19
-
20
- /**
21
- * Enlimbo Forms class for form creation
22
- *
23
- * @package Enlimbo
24
- * @subpackage Forms
25
- * @copyright enlimbo lancers 2012
26
- * @license GPLv2 or later
27
- * @version 1.1
28
- * @link http://enlimbo.net/forms
29
- * @author srdjan <srdjan@enlimbo.net>
30
- *
31
- *
32
- */
33
- /*
34
- Element attributes
35
-
36
- General rules when adding attributes to an element using strings in chunks
37
- * always start the chunk with a space and do not end the chunk with another space
38
- * mind the closing tags and add a space when needed
39
- */
40
- class Enlimbo_Forms {
41
-
42
- /**
43
- * @var string
44
- */
45
- private $_id;
46
-
47
- /**
48
- * @var array
49
- */
50
- private $_errors = array();
51
-
52
- /**
53
- * @var array
54
- */
55
- private $_elements = array();
56
-
57
- /**
58
- * @var array
59
- */
60
- private $_count = array();
61
-
62
- /**
63
- * @var string
64
- */
65
- public $css_class = 'wpt-form';
66
-
67
- /**
68
- * @var string
69
- */
70
- private $_validationFunc = '';
71
-
72
- /**
73
- * @var array
74
- */
75
- public $form_settings = array();
76
-
77
- public function __construct($id) {
78
- /**
79
- * default settings
80
- */
81
- $this->form_settings = array(
82
- 'has_media_button' => true,
83
- 'use_bootstrap' => false,
84
- );
85
- $this->_id = $id;
86
- if (!is_admin()|| (defined( 'DOING_AJAX' ) && DOING_AJAX)) {
87
- // TODO check also doing_ajax as this gives false positives
88
- $cred_form_id = preg_replace('/^cred_form_(\d+)_\d+$/', "$1", $this->_id);
89
- $form_settings = get_post_meta($cred_form_id, '_cred_form_settings', true);
90
- if (isset($form_settings->form)) {
91
- $this->form_settings = $form_settings->form;
92
- }
93
- unset($form_settings);
94
- /**
95
- * check CRED setting for bootstrap: only on frontend
96
- */
97
- $cred_cred_settings = get_option('cred_cred_settings');
98
- if (is_array($cred_cred_settings)) {
99
- $this->form_settings['use_bootstrap'] = array_key_exists('use_bootstrap', $cred_cred_settings) && $cred_cred_settings['use_bootstrap'];
100
- }
101
- }
102
- }
103
-
104
- /**
105
- * Auto handler
106
- *
107
- * Renders.
108
- *
109
- * @param array $element
110
- * @return HTML formatted output
111
- */
112
- public function autoHandle($id, $form) {
113
- // Auto-add nonce field
114
- $form['nonce'] = array(
115
- '#type' => 'hidden',
116
- '#name' => '_nonce',
117
- '#value' => md5($id),
118
- );
119
-
120
- $this->_id = $id;
121
- $this->_elements = $form;
122
-
123
- // get submitted data
124
- if ($this->isSubmitted()) {
125
-
126
- // check if errors (validation)
127
- $this->validate($this->_elements);
128
-
129
- // callback
130
- if (empty($this->_errors)) {
131
-
132
- if (isset($form['#form']['callback'])) {
133
- if (is_array($form['#form']['callback'])) {
134
- foreach ($form['#form']['callback'] as $callback) {
135
- if (is_callable($callback)) {
136
- call_user_func($callback, $this);
137
- }
138
- }
139
- } else {
140
- if (is_callable($form['#form']['callback'])) {
141
- call_user_func($form['#form']['callback'], $this);
142
- }
143
- }
144
- }
145
- // Maybe triggered by callback function
146
- if (empty($this->_errors)) {
147
- // redirect
148
- if (!isset($form['#form']['redirection'])) {
149
- header('Location: ' . $_SERVER['REQUEST_URI']);
150
- } else if ($form['#form']['redirection'] != false) {
151
- header('Location: ' . $form['#form']['redirection']);
152
- }
153
- }
154
- }
155
- }
156
- }
157
-
158
- /**
159
- * Checks if form is submitted.
160
- *
161
- * @param type $id
162
- * @return type
163
- */
164
- public function isSubmitted($id = '') {
165
- if (empty($id)) {
166
- $id = $this->_id;
167
- }
168
- return (isset($_REQUEST['_nonce']) && md5($_REQUEST['_nonce']) == $id);
169
- }
170
-
171
- /**
172
- * Sets validation function.
173
- *
174
- * @param type $class
175
- */
176
- // public function setValidationFunc($func)
177
- // {
178
- // $this->_validationFunc = $func;
179
- // }
180
-
181
- /**
182
- * Loops over elements and validates them.
183
- *
184
- * @param type $elements
185
- */
186
- public function validate(&$elements) {
187
- foreach ($elements as $key => &$element) {
188
- if (!isset($element['#type']) || !$this->_isValidType($element['#type'])) {
189
- continue;
190
- }
191
- if ($element['#type'] != 'fieldset') {
192
- if (isset($element['#name']) && !in_array($element['#type'], array('submit', 'reset'))) {
193
- if ($this->isSubmitted()) {
194
- // Set submitted data
195
- if (!in_array($element['#type'], array('checkboxes')) && empty($element['#forced_value'])) {
196
- $element['#value'] = $this->getSubmittedData($element);
197
- } else if (!empty($element['#options']) && empty($element['#forced_value'])) {
198
- foreach ($element['#options'] as $option_key => $option) {
199
- $option['#type'] = 'checkbox';
200
- $element['#options'][$option_key]['#value'] = $this->getSubmittedData($option);
201
- }
202
- }
203
- }
204
- }
205
- // Validate
206
- if (isset($element['#validate'])) {
207
- $this->validateElement($element);
208
- }
209
- } else if (isset($element['#type']) && $element['#type'] == 'fieldset') {
210
- $this->validate($element);
211
- } else if (is_array($element)) {
212
- $this->validate($element);
213
- }
214
- }
215
- }
216
-
217
- /**
218
- * Validates element.
219
- *
220
- * @param type $element
221
- */
222
- public function validateElement(&$element) {
223
- $value = isset($element['#value']) ? $element['#value'] : null;
224
- if (is_null($value) && isset($element['#default_value'])) {
225
- $value = $element['#default_value'];
226
- }
227
- $element = apply_filters('wptoolset_form_' . $this->_id . '_validate_field', $element, $value);
228
- if (isset($element['error'])) {
229
- $this->_errors = true;
230
- $_errors = $element['error']->get_error_data();
231
- $element['#error'] = $_errors[0];
232
- }
233
- }
234
-
235
- /**
236
- * Checks if there are errors.
237
- *
238
- * @return type
239
- */
240
- public function isError() {
241
- return $this->_errors;
242
- }
243
-
244
- /**
245
- * Sets errors to true.
246
- */
247
- public function triggerError() {
248
- $this->_errors = true;
249
- }
250
-
251
- /**
252
- * Renders form.
253
- *
254
- * @return type
255
- */
256
- public function renderForm() {
257
- // loop over elements and render them
258
- return $this->renderElements($this->_elements);
259
- }
260
-
261
- /**
262
- * Counts element types.
263
- *
264
- * @param type $type
265
- * @return type
266
- */
267
- private function _count($type) {
268
- if (!isset($this->_count[$type])) {
269
- $this->_count[$type] = 0;
270
- }
271
- $this->_count[$type] += 1;
272
- return $this->_count[$type];
273
- }
274
-
275
- /**
276
- * Check if element is of valid type
277
- *
278
- * @param string $type
279
- * @return boolean
280
- */
281
- private function _isValidType($type) {
282
- return in_array($type, array('select', 'checkboxes', 'checkbox', 'radios',
283
- 'radio', 'textfield', 'textarea', 'file', 'submit', 'reset',
284
- 'hidden', 'fieldset', 'markup', 'button', 'password'));
285
- }
286
-
287
- /**
288
- * Renders elements.
289
- *
290
- * @param type $elements
291
- * @return type
292
- */
293
- public function renderElements($elements) {
294
- $output = '';
295
- if (!isset($elements))
296
- return $output;
297
- foreach ($elements as $key => $element) {
298
- if (!isset($element['#type']) || !$this->_isValidType($element['#type'])) {
299
- continue;
300
- }
301
- if ($element['#type'] != 'fieldset') {
302
-
303
- /**
304
- * Temporary fixing validation for checkbox/radios/skype because _cakeValidation is not working for thats
305
- * https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/186243370/comments
306
- */
307
- if (!is_admin()) {
308
- if ($element['#type'] == 'radios') {
309
- if (isset($element['#error'])) {
310
- if (isset($element['#options']) && count($element['#options']) > 0 && !isset($element['#options'][0]['#error']))
311
- $element['#options'][0]['#error'] = $element['#error'];
312
- }
313
- }
314
- }
315
- //##################################################################################################
316
-
317
- $output .= $this->renderElement($element);
318
- } else if (isset($element['#type']) && $element['#type'] == 'fieldset') {
319
- $buffer = $this->renderElements($element);
320
- $output .= $this->fieldset($element, 'wrap', $buffer);
321
- } else if (is_array($element)) {
322
- $output .= $this->renderElements($element);
323
- }
324
- }
325
- return $output;
326
- }
327
-
328
- /**
329
- * Renders element.
330
- *
331
- * Depending on element type, it calls class methods.
332
- *
333
- * @param array $element
334
- * @return HTML formatted output
335
- */
336
- public function renderElement($element) {
337
- $method = $element['#type'];
338
- if (!isset($element['#name']) && !in_array($element['#type'], array('markup', 'checkboxes'))) {
339
- if (!isset($element['#attributes']['name'])) {
340
- return '#name or #attributes[\'name\'] required!';
341
- } else {
342
- $element['#name'] = $element['#attributes']['name'];
343
- }
344
- }
345
- if (is_callable(array($this, $method))) {
346
- $custom_field_title = '';
347
- if (isset($element['#title']) && !empty($element['#title'])) {
348
- $custom_field_title = $element['#title'];
349
- }
350
-
351
- if (empty($custom_field_title) && isset($element['#name']) && !empty($element['#name'])) {
352
- $custom_field_title = $element['#name'];
353
- }
354
- if (!isset($element['#id'])) {
355
- if (isset($element['#attributes']['id'])) {
356
- $element['#id'] = $element['#attributes']['id'];
357
- } else {
358
- $_id = isset($this->_id) ? $this->_id . '-' : '';
359
- $element['#id'] = "{$_id}{$element['#type']}-"
360
- . $this->_count($element['#type']) . '-' . time();
361
- }
362
- }
363
-
364
- if (isset($this->_errors[$element['#id']])) {
365
- $element['#error'] = $this->_errors[$element['#id']];
366
- }
367
- // Add JS validation
368
- if (!empty($element['#validate'])) {
369
- if (isset($element['#validate']['required']) && !empty($element['#title'])) {
370
- // Asterisk
371
- $element['#title'] .= '&#42;';
372
- }
373
- $element['#attributes']['data-wpt-validate'] = esc_html(self::json_encode(apply_filters('wptoolset_forms_field_js_validation_data_' . $this->_id, $element['#validate'])));
374
- $element['#attributes']['data-wpt-field-title'] = esc_js($custom_field_title);
375
- }
376
- if ($element['#type'] == 'radios' && !empty($element['#options'])) {
377
- foreach ($element['#options'] as &$option) {
378
- if (!empty($option['#validate'])) {
379
- $option['#attributes']['data-wpt-validate'] = esc_html(self::json_encode(apply_filters('wptoolset_forms_field_js_validation_data_' . $this->_id, $option['#validate'])));
380
- $option['#attributes']['data-wpt-field-title'] = esc_js($custom_field_title);
381
- }
382
- }
383
- }
384
- /**
385
- * WPML - lock CF is has option "copy from original".
386
- */
387
- if (is_admin() && function_exists('wpcf_wpml_field_is_copied') && wpcf_wpml_field_is_copied($element)) {
388
- $element['#title'] .= sprintf(
389
- '<img src="%s/images/locked.png" alt="%s" title="%s" style="position:relative;left:2px;top:2px;" />', WPCF_EMBEDDED_RES_RELPATH, __('This field is locked for editing because WPML will copy its value from the original language.', 'wpcf'), __('This field is locked for editing because WPML will copy its value from the original language.', 'wpcf')
390
- );
391
- $element['#attributes']['readonly'] = true;
392
- }
393
- return $this->{$method}($element);
394
- }
395
- }
396
-
397
- /**
398
- * Sets other element attributes.
399
- *
400
- * @param array $element
401
- * @return string
402
- */
403
- private function _setElementAttributes($element) {
404
- $attributes = '';
405
-
406
- $classes = array();
407
- $classes[] = $this->css_class . '-' . $element['#type'];
408
- $classes[] = 'form-' . $element['#type'];
409
-
410
- if ($this->form_settings['use_bootstrap']) {
411
- switch ($element['#type']) {
412
- case 'hidden':
413
- case 'button':
414
- case 'submit':
415
- case 'radio':
416
- case 'checkbox':
417
- case 'file':
418
- break;
419
- default:
420
- $classes[] = 'form-control';
421
- }
422
- } else {
423
- if ('hidden' != $element['#type']) {
424
- $classes[] = $element['#type'];
425
- }
426
- }
427
-
428
- if (isset($element['#attributes']) && !empty($element['#attributes'])
429
- ) {
430
- if (isset($element['#attributes']['class'])) {
431
- $element['#attributes']['class'] .= ' ' . implode(' ', $classes);
432
- } else {
433
- $element['#attributes']['class'] = implode(' ', $classes);
434
- }
435
- } else {
436
- $element['#attributes'] = array(
437
- 'class' => implode(' ', $classes)
438
- );
439
- }
440
-
441
-
442
- foreach ($element['#attributes'] as $attribute => $value) {
443
- // Prevent undesired elements
444
- if (in_array($attribute, array('id', 'name'))) {
445
- continue;
446
- }
447
- // Don't set disabled for checkbox
448
- if ($attribute == 'disabled' && $element['#type'] == 'checkbox') {
449
- continue;
450
- }
451
- // Set return string
452
- $attributes .= ' ' . $attribute . '="' . $value . '"';
453
- }
454
-
455
- return $attributes;
456
- }
457
-
458
- /**
459
- * Sets render elements.
460
- *
461
- * @param array $element
462
- */
463
- private function _setRender($element) {
464
- if (!isset($element['#id'])) {
465
- if (isset($element['#attributes']['id'])) {
466
- $element['#id'] = $element['#attributes']['id'];
467
- } else {
468
- $element['#id'] = 'form-' . mt_rand();
469
- }
470
- }
471
- $element['_attributes_string'] = $this->_setElementAttributes($element);
472
- $element['_render'] = array();
473
- $element['_render']['prefix'] = isset($element['#prefix']) ? $element['#prefix'] . "\r\n" : '';
474
- $element['_render']['suffix'] = isset($element['#suffix']) ? $element['#suffix'] . "\r\n" : '';
475
- $element['_render']['before'] = isset($element['#before']) ? $element['#before'] . "\r\n" : '';
476
- $element['_render']['after'] = isset($element['#after']) ? $element['#after'] . "\r\n" : '';
477
- $element['_render']['title'] = $this->_setElementTitle($element);
478
- $element['_render']['description'] = isset($element['#description']) ? $this->_setElementDescription($element) : '';
479
- $element['_render']['error'] = $this->renderError($element) . "\r\n";
480
- /**
481
- * label
482
- */
483
- $element['_render']['label'] = '';
484
- if (isset($element['#title'])) {
485
- $classes = array();
486
- $classes[] = sprintf('%s-label', $this->css_class);
487
- $classes[] = sprintf('%s-%s-label', $this->css_class, $element['#type']);
488
- if ($this->form_settings['use_bootstrap']) {
489
- switch ($element['#type']) {
490
- case 'checkbox':
491
- case 'radio':
492
- $classes[] = 'control-label';
493
- break;
494
- }
495
- }
496
- $element['_render']['label'] .= sprintf(
497
- '<label class="%s" for="%s">', implode(' ', $classes), $element['#id']
498
- );
499
- $element['_render']['label'] .= stripslashes($element['#title']);
500
- $element['_render']['label'] .= '</label>';
501
- }
502
- return $element;
503
- }
504
-
505
- /**
506
- * Applies pattern to output.
507
- *
508
- * Pass element property #pattern to get custom renedered element.
509
- *
510
- * @param array $pattern
511
- * Accepts: <prefix><suffix><label><title><desription><error>
512
- * @param array $element
513
- */
514
- private function _pattern($pattern, $element) {
515
- $pattern = strtolower($pattern);
516
- foreach ($element['_render'] as $key => $value) {
517
- $pattern = str_replace('<' . strtolower($key) . '>', $value, $pattern);
518
- }
519
- return $pattern;
520
- }
521
-
522
- /**
523
- * Wrapps element in <div></div>.
524
- *
525
- * @param arrat $element
526
- * @param string $output
527
- * @return string
528
- */
529
- private function _wrapElement($element, $output) {
530
- if (!empty($element['#inline'])) {
531
- return $output;
532
- }
533
- $classes = array();
534
- $classes[] = 'form-item';
535
- $classes[] = 'form-item-' . $element['#type'];
536
- $classes[] = $this->css_class . '-item';
537
- $classes[] = $this->css_class . '-item-' . $element['#type'];
538
- if ($this->form_settings['use_bootstrap']) {
539
- $classes[] = 'form-group';
540
- }
541
- if (preg_match('/_hidden$/', $element['#id']) && !is_admin()) {
542
- $classes[] = 'wpt-form-hide-container';
543
- }
544
- if (is_admin()) {
545
- return sprintf(
546
- '<div id="%s-wrapper" class="%s">%s</div>', $element['#id'], implode(' ', $classes), $output
547
- );
548
- }
549
- return $output;
550
- }
551
-
552
- /**
553
- * Returns HTML formatted output for element's title.
554
- *
555
- * @param string $element
556
- * @return string
557
- */
558
- private function _setElementTitle($element) {
559
- $output = '';
560
- if (isset($element['#title'])) {
561
- $output .= '<div class="title '
562
- . $this->css_class . '-title '
563
- . $this->css_class . '-title-' . $element['#type'] . ' '
564
- . 'title-' . $element['#type'] . '">'
565
- . stripslashes($element['#title'])
566
- . "</div>\r\n";
567
- }
568
- return $output;
569
- }
570
-
571
- /**
572
- * Returns HTML formatted output for element's description.
573
- *
574
- * @param array $element
575
- * @return string
576
- */
577
- private function _setElementDescription($element) {
578
- if (empty($element['#description']))
579
- return '';
580
- $element['#description'] = stripslashes($element['#description']);
581
- $output = "\r\n"
582
- . '<div class="description '
583
- . $this->css_class . '-description '
584
- . $this->css_class . '-description-' . $element['#type'] . ' '
585
- . 'description-' . $element['#type'] . '">'
586
- . $element['#description'] . "</div>\r\n";
587
- return $output;
588
- }
589
-
590
- /**
591
- * Returns HTML formatted element's error message.
592
- *
593
- * Pass #supress_errors in #form element to avoid error rendering.
594
- *
595
- * @param array $element
596
- * @return string
597
- */
598
- public function renderError($element) {
599
- if (!isset($element['#error'])) {
600
- return '';
601
- }
602
- $output = '<label class="' . $this->css_class . '-error" for="'
603
- . $element['#id'] . '" generated="true">'
604
- . $element['#error'] . '</label>' . "\r\n";
605
- // $output = '<div class="form-error '
606
- // . $this->css_class . '-error '
607
- // . $this->css_class . '-form-error '
608
- // . $this->css_class . '-' . $element['#type'] . '-error '
609
- // . $element['#type'] . '-error form-error-label'
610
- // . '">' . $element['#error'] . '</div>'
611
- // . "\r\n";
612
- return $output;
613
- }
614
-
615
- /**
616
- * Returns HTML formatted output for fieldset.
617
- *
618
- * @param array $element
619
- * @param string $action open|close|wrap
620
- * @param string $wrap_content HTML formatted output of child elements
621
- * @return string
622
- */
623
- public function fieldset($element, $action = 'open', $wrap_content = '') {
624
- $collapsible_open = '<div class="fieldset-wrapper">';
625
- $collapsible_close = '</div>';
626
- $legend_class = '';
627
- if (!isset($element['#id'])) {
628
- $element['#id'] = 'fieldset-' . $this->_count('fieldset');
629
- }
630
- if (!isset($element['_attributes_string'])) {
631
- $element['_attributes_string'] = $this->_setElementAttributes($element);
632
- }
633
- if ((isset($element['#collapsible']) && $element['#collapsible']) || (isset($element['#collapsed']) && $element['#collapsed'])) {
634
- $collapsible_open = '<div class="collapsible fieldset-wrapper">';
635
- $collapsible_close = '</div>';
636
- $legend_class = ' class="legend-expanded"';
637
- }
638
- if (isset($element['#collapsed']) && $element['#collapsed']) {
639
- $collapsible_open = str_replace('class="', 'class="collapsed ', $collapsible_open);
640
- $legend_class = ' class="legend-collapsed"';
641
- }
642
- $output = '';
643
- switch ($action) {
644
- case 'close':
645
- $output .= $collapsible_close . "</fieldset>\r\n";
646
- $output .= isset($element['#suffix']) ? $element['#suffix']
647
- . "\r\n" : '';
648
- $output .= "\n\r";
649
- break;
650
-
651
- case 'open':
652
- $output .= $collapsible_open;
653
- $output .= isset($element['#prefix']) ? $element['#prefix']
654
- . "\r\n" : '';
655
- $output .= '<fieldset' . $element['_attributes_string']
656
- . ' id="' . $element['#id'] . '">' . "\r\n";
657
- $output .= isset($element['#title']) ? '<legend'
658
- . $legend_class . '>'
659
- . stripslashes($element['#title'])
660
- . "</legend>\r\n" : '';
661
- $output .=
662
- isset($element['#description']) ? $this->_setElementDescription($element) : '';
663
- $output .= "\n\r";
664
- break;
665
-
666
- case 'wrap':
667
- if (!empty($wrap_content)) {
668
- $output .= isset($element['#prefix']) ? $element['#prefix'] : '';
669
- $output .= '<fieldset' . $element['_attributes_string']
670
- . ' id="' . $element['#id'] . '">' . "\r\n";
671
- $output .= '<legend' . $legend_class . '>'
672
- . stripslashes($element['#title'])
673
- . "</legend>\r\n"
674
- . $collapsible_open;
675
- $output .= isset($element['#description']) ? $this->_setElementDescription($element) : '';
676
- $output .= $wrap_content . $collapsible_close
677
- . "</fieldset>\r\n";
678
- $output .=
679
- isset($element['#suffix']) ? $element['#suffix'] : '';
680
- $output .= "\n\r";
681
- }
682
- break;
683
- }
684
- return $output;
685
- }
686
-
687
- /**
688
- * Returns HTML formatted output for checkbox element.
689
- *
690
- * @param array $element
691
- * @return string
692
- */
693
- public function checkbox($element) {
694
- $element['#type'] = 'checkbox';
695
- $element = $this->_setRender($element);
696
- $element['_render']['element'] = '<input type="checkbox"';
697
- foreach (array('id', 'name') as $key) {
698
- $element['_render']['element'] .= sprintf(' %s="%s"', $key, $element['#' . $key]);
699
- }
700
- /**
701
- * type and data_id
702
- */
703
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
704
- $element['_render']['element'] .= $this->_getDataWptId($element);
705
-
706
- $element['_render']['element'] .= ' value="';
707
- /**
708
- * Specific: if value is empty force 1 to be rendered
709
- * but if is defined default value, use default
710
- */
711
- $value = 1;
712
- if (array_key_exists('#default_value', $element)) {
713
- $value = $element['#default_value'];
714
- }
715
- $element['_render']['element'] .= ( empty($element['#value']) && !preg_match('/^0$/', $element['#value']) ) ? $value : esc_attr($element['#value']);
716
- $element['_render']['element'] .= '"' . $element['_attributes_string'];
717
- if (
718
- (
719
- !$this->isSubmitted() && (
720
- (!empty($element['#default_value']) && $element['#default_value'] == $element['#value'] ) || ( isset($element['#checked']) && $element['#checked'] )
721
- )
722
- ) || ($this->isSubmitted() && !empty($element['#value']))
723
- ) {
724
- $element['_render']['element'] .= ' checked="checked"';
725
- }
726
- if (!empty($element['#attributes']['disabled']) || !empty($element['#disable'])) {
727
- $element['_render']['element'] .= ' onclick="javascript:return false; if(this.checked == 1){this.checked=1; return true;}else{this.checked=0; return false;}"';
728
- }
729
- $element['_render']['element'] .= ' />';
730
-
731
- $pattern = $this->_getStatndardPatern($element, '<BEFORE><PREFIX><ELEMENT>&nbsp;<LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>');
732
- $output = $this->_pattern($pattern, $element);
733
- $output = $this->_wrapElement($element, $output);
734
- return $output . "\r\n";
735
- }
736
-
737
- /**
738
- * Returns HTML formatted output for checkboxes element.
739
- *
740
- * Renders more than one checkboxes provided as elements in '#options'
741
- * array element.
742
- *
743
- * @param array $element
744
- * @return string
745
- */
746
- public function checkboxes($element) {
747
- $element['#type'] = 'checkboxes';
748
- $element = $this->_setRender($element);
749
- $clone = $element;
750
- $clone['#type'] = 'checkbox';
751
- $element['_render']['element'] = '';
752
- foreach ($element['#options'] as $ID => $value) {
753
- if (!is_array($value)) {
754
- $value = array('#title' => $ID, '#value' => $value, '#name' => $element['#name'] . '[]');
755
- }
756
- $element['_render']['element'] .= $this->checkbox($value);
757
- }
758
- $pattern = $this->_getStatndardPatern($element, '<BEFORE><PREFIX><TITLE><DESCRIPTION><ELEMENT><SUFFIX><AFTER>');
759
- $output = $this->_pattern($pattern, $element);
760
- $output = $this->_wrapElement($element, $output);
761
- return $output;
762
- }
763
-
764
- /**
765
- * Returns HTML formatted output for radio element.
766
- *
767
- * @param array $element
768
- * @return string
769
- */
770
- public function radio($element) {
771
- $element['#type'] = 'radio';
772
- $element = $this->_setRender($element);
773
- $element['_render']['element'] = '<input type="radio" id="'
774
- . $element['#id'] . '" name="'
775
- . $element['#name'] . '" value="';
776
- $element['_render']['element'] .= isset($element['#value']) ? htmlspecialchars($element['#value']) : $this->_count['radio'];
777
- $element['_render']['element'] .= '"';
778
- $element['_render']['element'] .= $element['_attributes_string'];
779
- $element['_render']['element'] .= ( isset($element['#value']) && $element['#value'] === $element['#default_value']) ? ' checked="checked"' : '';
780
- if (isset($element['#disable']) && $element['#disable']) {
781
- $element['_render']['element'] .= ' disabled="disabled"';
782
- }
783
- if (array_key_exists('#types-value', $element)) {
784
- $element['_render']['element'] .= sprintf(' data-types-value="%s"', $element['#types-value']);
785
- }
786
- /**
787
- * type and data_id
788
- */
789
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
790
- $element['_render']['element'] .= $this->_getDataWptId($element);
791
-
792
- $element['_render']['element'] .= ' />';
793
-
794
- $pattern = isset($element['#pattern']) ? $element['#pattern'] : '<BEFORE><PREFIX><ELEMENT>&nbsp;<LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
795
- $output = $this->_pattern($pattern, $element);
796
- $output = $this->_wrapElement($element, $output);
797
- return $output . "\r\n";
798
- }
799
-
800
- /**
801
- * Returns HTML formatted output for radios elements.
802
- *
803
- * Radios are provided via #options array.
804
- * Requires #name value.
805
- *
806
- * @param array $element
807
- * @return string
808
- */
809
- public function radios($element) {
810
- if (!isset($element['#name']) || empty($element['#name'])) {
811
- return FALSE;
812
- }
813
- $element['#type'] = 'radios';
814
- $element = $this->_setRender($element);
815
- $element['_render']['element'] = '';
816
- foreach ($element['#options'] as $ID => $value) {
817
- $this->_count('radio');
818
- if (!is_array($value)) {
819
- $value = array('#title' => $ID, '#value' => $value);
820
- $value['#inline'] = true;
821
- $value['#after'] = '<br />';
822
- }
823
- $value['#name'] = $element['#name'];
824
- $value['#default_value'] = isset($element['#default_value']) ? $element['#default_value'] : $value['#value'];
825
- $value['#disable'] = isset($element['#disable']) ? $element['#disable'] : false;
826
- $element['_render']['element'] .= $this->radio($value);
827
- }
828
- if (is_admin()) {
829
- $pattern = '<BEFORE><PREFIX><TITLE><DESCRIPTION><ELEMENT><SUFFIX><AFTER>';
830
- } else {
831
- $pattern = '<BEFORE><PREFIX><DESCRIPTION><ELEMENT><SUFFIX><AFTER>';
832
- }
833
-
834
- $pattern = $this->_getStatndardPatern($element, $pattern);
835
- $output = $this->_pattern($pattern, $element);
836
- $output = $this->_wrapElement($element, $output);
837
- return $output;
838
- }
839
-
840
- /**
841
- * Returns HTML formatted output for select element.
842
- *
843
- * @param array $element
844
- * @return string
845
- */
846
- public function select($element) {
847
- $element = $this->_setRender($element);
848
-
849
- $element['_render']['element'] = '';
850
- $element['_render']['element'] .= '<select id="' . $element['#id'] . '" ';
851
- $element['_render']['element'] .= $element['_attributes_string'];
852
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
853
- /**
854
- * multiple
855
- */
856
- if (array_key_exists('#multiple', $element) && $element['#multiple']) {
857
- $element['_render']['element'] .= ' multiple="multiple"';
858
- $element['_render']['element'] .= ' name="' . $element['#name'] . '[]"';
859
- } else {
860
- $element['_render']['element'] .= ' name="' . $element['#name'] . '"';
861
- }
862
- $element['_render']['element'] .= ">\r\n";
863
- $count = 1;
864
- foreach ($element['#options'] as $id => $value) {
865
- if (!is_array($value)) {
866
- $value = array('#title' => $id, '#value' => $value, '#type' => 'option');
867
- }
868
- $value['#type'] = 'option';
869
- if (!isset($value['#value'])) {
870
- $value['#value'] = $this->_count['select'] . '-' . $count;
871
- $count += 1;
872
- }
873
- $element['_render']['element'] .= '<option value="' . htmlspecialchars($value['#value']) . '"';
874
- $element['_render']['element'] .= $this->_setElementAttributes($value);
875
- if (array_key_exists('#types-value', $value)) {
876
- $element['_render']['element'] .= sprintf(' data-types-value="%s"', $value['#types-value']);
877
- }
878
- /**
879
- * type and data_id
880
- */
881
- $element['_render']['element'] .= ' data-wpt-type="option"';
882
- $element['_render']['element'] .= $this->_getDataWptId($element);
883
- /**
884
- * selected
885
- */
886
- if (array_key_exists('#multiple', $element) && $element['#multiple']) {
887
- if (is_array($element['#default_value']) && in_array($value['#value'], $element['#default_value'])) {
888
- $element['_render']['element'] .= ' selected="selected"';
889
- }
890
- } elseif ($element['#default_value'] == $value['#value']) {
891
- $element['_render']['element'] .= ' selected="selected"';
892
- }
893
- $element['_render']['element'] .= '>';
894
- $element['_render']['element'] .= isset($value['#title']) ? $value['#title'] : $value['#value'];
895
- $element['_render']['element'] .= "</option>\r\n";
896
- }
897
- $element['_render']['element'] .= '</select>';
898
- $element['_render']['element'] .= PHP_EOL;
899
-
900
- $pattern = $this->_getStatndardPatern($element);
901
- $output = $this->_pattern($pattern, $element);
902
- $output = $this->_wrapElement($element, $output);
903
-
904
- return $output;
905
- }
906
-
907
- /**
908
- * Returns HTML formatted output for textfield element.
909
- *
910
- * @param array $element
911
- * @return string
912
- */
913
- public function textfield($element) {
914
- $element['#type'] = 'textfield';
915
- $element = $this->_setRender($element);
916
-
917
- $element['_render']['element'] = '<input type="text"';
918
- //$element['_render']['element'] .= sprintf( ' data-wpt-type="%s" ', __FUNCTION__ );
919
- $element['_render']['element'] .= sprintf(' id="%s"', $element['#id']);
920
- $element['_render']['element'] .= sprintf(' name="%s"', $element['#name']);
921
- $element['_render']['element'] .= sprintf(' value="%s"', isset($element['#value']) ? esc_attr($element['#value']) : '' );
922
- $element['_render']['element'] .= $element['_attributes_string'];
923
- if (isset($element['#disable']) && $element['#disable']) {
924
- $element['_render']['element'] .= ' disabled="disabled"';
925
- }
926
- /**
927
- * type and data_id
928
- */
929
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
930
- $element['_render']['element'] .= $this->_getDataWptId($element);
931
-
932
- $element['_render']['element'] .= ' />';
933
- $pattern = $this->_getStatndardPatern($element);
934
- $output = $this->_pattern($pattern, $element);
935
- $output = $this->_wrapElement($element, $output);
936
- return $output . "\r\n";
937
- }
938
-
939
- /**
940
- * Returns HTML formatted output for textfield element.
941
- *
942
- * @param array $element
943
- * @return string
944
- */
945
- public function password($element) {
946
- $element['#type'] = 'password';
947
- $element = $this->_setRender($element);
948
- $element['_render']['element'] = '<input type="password" id="'
949
- . $element['#id'] . '" name="' . $element['#name'] . '" value="';
950
- $element['_render']['element'] .= isset($element['#value']) ? $element['#value'] : '';
951
- $element['_render']['element'] .= '"' . $element['_attributes_string'];
952
- if (isset($element['#disable']) && $element['#disable']) {
953
- $element['_render']['element'] .= ' disabled="disabled"';
954
- }
955
- /**
956
- * type and data_id
957
- */
958
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
959
- $element['_render']['element'] .= $this->_getDataWptId($element);
960
-
961
- $element['_render']['element'] .= ' />';
962
- $pattern = $this->_getStatndardPatern($element);
963
- $output = $this->_pattern($pattern, $element);
964
- $output = $this->_wrapElement($element, $output);
965
- return $output . "\r\n";
966
- }
967
-
968
- /**
969
- * Returns HTML formatted output for textarea element.
970
- *
971
- * @param array $element
972
- * @return string
973
- */
974
- public function textarea($element) {
975
- $element['#type'] = 'textarea';
976
- if (!isset($element['#attributes']['rows'])) {
977
- $element['#attributes']['rows'] = 5;
978
- }
979
- if (!isset($element['#attributes']['cols'])) {
980
- $element['#attributes']['cols'] = 1;
981
- }
982
- $element = $this->_setRender($element);
983
- $element['_render']['element'] = '<textarea id="' . $element['#id']
984
- . '" name="' . $element['#name'] . '"'
985
- . $element['_attributes_string'];
986
- /**
987
- * type and data_id
988
- */
989
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
990
- $element['_render']['element'] .= $this->_getDataWptId($element);
991
-
992
- $element['_render']['element'] .= '>';
993
-
994
- $element['_render']['element'] .= isset($element['#value']) ? esc_attr($element['#value']) : '';
995
- $element['_render']['element'] .= '</textarea>' . "\r\n";
996
- $pattern = $this->_getStatndardPatern($element);
997
- $output = $this->_pattern($pattern, $element);
998
- $output = $this->_wrapElement($element, $output);
999
- return $output . "\r\n";
1000
- }
1001
-
1002
- /**
1003
- * Returns HTML formatted output for file upload element.
1004
- *
1005
- * @param array $element
1006
- * @return string
1007
- */
1008
- public function file($element) {
1009
- $element['#type'] = 'file';
1010
- $element = $this->_setRender($element);
1011
- $element['_render']['element'] = '<input type="file" id="'
1012
- . $element['#id'] . '" name="' . $element['#name'] . '"'
1013
- . $element['_attributes_string'];
1014
- if (isset($element['#disable']) && $element['#disable']) {
1015
- $element['_render']['element'] .= ' disabled="disabled"';
1016
- }
1017
- /**
1018
- * type and data_id
1019
- */
1020
- $element['_render']['element'] .= sprintf(' data-wpt-type="%s"', __FUNCTION__);
1021
- $element['_render']['element'] .= $this->_getDataWptId($element);
1022
-
1023
- $element['_render']['element'] .= ' />';
1024
- $pattern = $this->_getStatndardPatern($element);
1025
- $output = $this->_pattern($pattern, $element);
1026
- $output = $this->_wrapElement($element, $output);
1027
- return $output;
1028
- }
1029
-
1030
- /**
1031
- * Returns HTML formatted output for markup element.
1032
- *
1033
- * @param array $element
1034
- * @return string
1035
- */
1036
- public function markup($element) {
1037
- return $element['#markup'];
1038
- }
1039
-
1040
- /**
1041
- * Returns HTML formatted output for hidden element.
1042
- *
1043
- * @param array $element
1044
- * @return string
1045
- */
1046
- public function hidden($element) {
1047
- $element['#type'] = 'hidden';
1048
- $element = $this->_setRender($element);
1049
- $output = '<input type="hidden" id="' . $element['#id'] . '" name="'
1050
- . $element['#name'] . '" value="';
1051
- $output .= isset($element['#value']) ? $element['#value'] : 1;
1052
- $output .= '"' . $element['_attributes_string'] . $this->_getDataWptId($element) . ' />';
1053
- return $output;
1054
- }
1055
-
1056
- /**
1057
- * Returns HTML formatted output for reset button element.
1058
- *
1059
- * @param array $element
1060
- * @return string
1061
- */
1062
- public function reset($element) {
1063
- return $this->submit($element, 'reset', 'Reset');
1064
- }
1065
-
1066
- /**
1067
- * Returns HTML formatted output for button element.
1068
- *
1069
- * @param array $element
1070
- * @return string
1071
- */
1072
- public function button($element) {
1073
- return $this->submit($element, 'button', 'Button');
1074
- }
1075
-
1076
- /**
1077
- * Returns HTML formatted output for radio element.
1078
- *
1079
- * Used by reset and button.
1080
- *
1081
- * @param array $element
1082
- * @param string $type
1083
- * @param string $title
1084
- * @return string
1085
- */
1086
- public function submit($element, $type = 'submit', $title = 'Submit') {
1087
- $element['#type'] = $type;
1088
- $element = $this->_setRender($element);
1089
- $element['_render']['element'] = '<input type="' . $type . '" id="'
1090
- . $element['#id'] . '" name="' . $element['#name'] . '" value="';
1091
- $element['_render']['element'] .= isset($element['#value']) ? $element['#value'] : $title;
1092
- $element['_render']['element'] .= '"' . $element['_attributes_string']
1093
- . ' />';
1094
- $pattern = $this->_getStatndardPatern($element, '<BEFORE><PREFIX><ELEMENT><SUFFIX><AFTER>');
1095
- $output = $this->_pattern($pattern, $element);
1096
- return $output;
1097
- }
1098
-
1099
- /**
1100
- * Searches and returns submitted data for element.
1101
- *
1102
- * @param type $element
1103
- * @return type mixed
1104
- */
1105
- public function getSubmittedData($element) {
1106
- $name = $element['#name'];
1107
- if (strpos($name, '[') === false) {
1108
- if ($element['#type'] == 'file') {
1109
- return $_FILES[$name]['tmp_name'];
1110
- }
1111
- return isset($_REQUEST[$name]) ? $_REQUEST[$name] : in_array($element['#type'], array('textfield', 'textarea')) ? '' : 0;
1112
- }
1113
-
1114
- $parts = explode('[', $name);
1115
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/196173458/comments
1116
- //Security Fixing
1117
- //$parts = array_map(create function('&$a', 'return trim($a, \']\');'), $parts);
1118
- $parts = array_map("cred_mytrimfunction", $parts);
1119
- if (!isset($_REQUEST[$parts[0]])) {
1120
- return in_array($element['#type'], array('textfield', 'textarea')) ? '' : 0;
1121
- }
1122
- $search = $_REQUEST[$parts[0]];
1123
- for ($index = 0; $index < count($parts); $index++) {
1124
- $key = $parts[$index];
1125
- // We're at the end but no data retrieved
1126
- if (!isset($parts[$index + 1])) {
1127
- return in_array($element['#type'], array('textfield', 'textarea')) ? '' : 0;
1128
- }
1129
- $key_next = $parts[$index + 1];
1130
- if ($index > 0) {
1131
- if (!isset($search[$key])) {
1132
- return in_array($element['#type'], array('textfield', 'textarea')) ? '' : 0;
1133
- } else {
1134
- $search = $search[$key];
1135
- }
1136
- }
1137
- if (is_array($search) && array_key_exists($key_next, $search)) {
1138
- if (!is_array($search[$key_next])) {
1139
- return $search[$key_next];
1140
- }
1141
- }
1142
- }
1143
- return 0;
1144
- }
1145
-
1146
- private function _getDataWptId($element) {
1147
- $html = '';
1148
- if (array_key_exists('#id', $element)) {
1149
- if (is_admin()) {
1150
- $html .= sprintf(' data-wpt-id="%s"', preg_replace('/\[/', '-', preg_replace('/\]/', '', $element['#name'])));
1151
- } else {
1152
- $html .= sprintf(' data-wpt-id="%s_%s"', $this->_id, $element['#id']);
1153
- }
1154
- if (array_key_exists('#name', $element) && $element['#name']) {
1155
- if (!is_admin() && $this->_isRepetitive($element)) {
1156
- $html .= sprintf(' data-wpt-name="%s"', preg_replace('/\[.+$/', '', $element['#name']));
1157
- } else {
1158
- if (preg_match('/^wpcf_post_relationship\[\d+\]\[\d+\]\[[^\]]+\]/', $element['#name'])) {
1159
- $html .= sprintf(
1160
- ' data-wpt-name="%s"', preg_replace('/^wpcf_post_relationship\[\d+\]\[(\d+)\]\[wpcf-([^\]]+)\]/', "wpcf[$2-$1]", $element['#name']));
1161
- } else {
1162
- $html .= sprintf(' data-wpt-name="%s"', $element['#name']);
1163
- }
1164
- }
1165
- }
1166
- }
1167
- return $html;
1168
- }
1169
-
1170
- private function _getStatndardPatern($element, $default = false) {
1171
- if (isset($element['#pattern'])) {
1172
- return $element['#pattern'];
1173
- }
1174
- if ($default) {
1175
- return $default;
1176
- }
1177
- if (is_admin()) {
1178
- return '<BEFORE><LABEL><DESCRIPTION><ERROR><PREFIX><ELEMENT><SUFFIX><AFTER>';
1179
- }
1180
- return '<BEFORE><DESCRIPTION><ERROR><PREFIX><ELEMENT><SUFFIX><AFTER>';
1181
- }
1182
-
1183
- private function _isRepetitive($element) {
1184
- if (!is_array($element)) {
1185
- return false;
1186
- }
1187
- return array_key_exists('#repetitive', $element) && $element['#repetitive'];
1188
- }
1189
-
1190
- static function json_encode($array) {
1191
- // php > 5.3 do not escape utf-8 characters using native constant argument
1192
- if (defined('JSON_UNESCAPED_UNICODE')) {
1193
- return json_encode($array, JSON_UNESCAPED_UNICODE);
1194
- }
1195
- // fallback for php < 5.3 to support unicode characters in json string
1196
- else {
1197
- if (function_exists('mb_decode_numericentity')) {
1198
- return self::json_encode_unescaped_unicode($array);
1199
- } else {
1200
- return json_encode($array);
1201
- }
1202
- }
1203
- }
1204
-
1205
- /**
1206
- * @param $arr
1207
- * @return string
1208
- * courtesy from: http://www.php.net/manual/ru/function.json-encode.php#105789
1209
- */
1210
- public static function json_encode_unescaped_unicode($arr) {
1211
-
1212
- array_walk_recursive($arr, array(__CLASS__, 'json_unescaped_unicode_walk_callback'));
1213
-
1214
- return mb_decode_numericentity(json_encode($arr), array(0x80, 0xffff, 0, 0xffff), 'UTF-8');
1215
- }
1216
-
1217
- /*
1218
- * Helper function to json_encode with UTF-8 support for php < 5.3
1219
- */
1220
-
1221
- public static function json_unescaped_unicode_walk_callback(&$item, $key) {
1222
- if (is_string($item))
1223
- $item = mb_encode_numericentity($item, array(0x80, 0xffff, 0, 0xffff), 'UTF-8');
1224
- }
1225
-
1226
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.email.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- */
9
- class WPToolset_Field_Email extends WPToolset_Field_Textfield
10
- {
11
-
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.embed.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- */
9
- class WPToolset_Field_Embed extends WPToolset_Field_Textfield
10
- {
11
-
12
- protected $_settings = array('min_wp_version' => '3.6');
13
-
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.field_factory.php DELETED
@@ -1,166 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
-
8
- require 'abstract.field.php';
9
-
10
- abstract class FieldFactory extends FieldAbstract
11
- {
12
- protected $_nameField, $_data, $_value, $_use_bootstrap;
13
-
14
- function __construct($data, $global_name_field, $value)
15
- {
16
- $this->_nameField = $global_name_field;
17
- $this->_data = $data;
18
- $this->_value = $value;
19
-
20
- $this->init();
21
- }
22
-
23
- public function init()
24
- {
25
- $cred_cred_settings = get_option( 'cred_cred_settings' );
26
- $this->_use_bootstrap = is_array($cred_cred_settings) && array_key_exists( 'use_bootstrap', $cred_cred_settings ) && $cred_cred_settings['use_bootstrap'];
27
- $this->set_placeholder_as_attribute();
28
- }
29
-
30
- public function set_placeholder_as_attribute()
31
- {
32
- if ( !isset($this->_data['attribute']) ) {
33
- $this->_data['attribute'] = array();
34
- }
35
- if ( isset($this->_data['placeholder']) && !empty($this->_data['placeholder'])) {
36
- $this->_data['attribute']['placeholder'] = htmlentities(stripcslashes($this->_data['placeholder']));
37
- }
38
- }
39
-
40
- public function set_metaform($metaform)
41
- {
42
- $this->_metaform = $metaform;
43
- }
44
-
45
- public function get_metaform()
46
- {
47
- return $this->_metaform;
48
- }
49
-
50
- public function get_data()
51
- {
52
- return $this->data;
53
- }
54
-
55
- public function set_data($data)
56
- {
57
- $this->data = $data;
58
- }
59
-
60
- public function set_nameField($nameField)
61
- {
62
- $this->_nameField = $nameField;
63
- }
64
-
65
- public function get_nameField()
66
- {
67
- return $this->_nameField;
68
- }
69
-
70
- public function getId()
71
- {
72
- return $this->_data['id'];
73
- }
74
-
75
- public function getType()
76
- {
77
- return $this->_data['type'];
78
- }
79
-
80
- public function getValue()
81
- {
82
- global $post;
83
- $value = $this->_value;
84
- /**
85
- * default value
86
- */
87
- if ( empty( $value ) && array_key_exists('user_default_value', $this->_data)) {
88
- $value = stripcslashes($this->_data['user_default_value']);
89
- }
90
- $value = apply_filters( 'wpcf_fields_value_get', $value, $post );
91
- if ( array_key_exists('slug', $this->_data ) ) {
92
- $value = apply_filters( 'wpcf_fields_slug_' . $this->_data['slug'] . '_value_get', $value, $post );
93
- }
94
- $value = apply_filters( 'wpcf_fields_type_' . $this->_data['type'] . '_value_get', $value, $post );
95
- return $value;
96
- }
97
-
98
- public function getTitle($_title = false)
99
- {
100
- if ( $_title && empty($this->_data['title']) && isset($this->_data['_title']) ) {
101
- return $this->_data['_title'];
102
- }
103
- return $this->_data['title'];
104
- }
105
-
106
- public function getDescription()
107
- {
108
- return wpautop( $this->_data['description'] );
109
- }
110
-
111
- public function getName()
112
- {
113
- return $this->_data['name'];
114
- }
115
-
116
- public function getData()
117
- {
118
- return $this->_data;
119
- }
120
-
121
- public function getValidationData()
122
- {
123
- return !empty( $this->_data['validation'] ) ? $this->_data['validation'] : array();
124
- }
125
-
126
- public function setValidationData($validation)
127
- {
128
- $this->_data['validation'] = $validation;
129
- }
130
-
131
- public function getSettings()
132
- {
133
- return isset( $this->_settings ) ? $this->_settings : array();
134
- }
135
-
136
- public function isRepetitive()
137
- {
138
- return (bool)$this->_data['repetitive'];
139
- }
140
-
141
- public function getAttr() {
142
- if ( array_key_exists( 'attribute', $this->_data ) ) {
143
- return $this->_data['attribute'];
144
- }
145
- return array();
146
- }
147
-
148
- public function getWPMLAction()
149
- {
150
- if ( array_key_exists( 'wpml_action', $this->_data ) ) {
151
- return $this->_data['wpml_action'];
152
- }
153
- return 0;
154
- }
155
-
156
- public static function registerScripts() {}
157
- public static function registerStyles() {}
158
- public static function addFilters() {}
159
- public static function addActions() {}
160
-
161
- public function enqueueScripts() {}
162
- public function enqueueStyles() {}
163
- public function metaform() {}
164
- public function editform() {}
165
- public function mediaEditor() {}
166
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.fieldconfig.php DELETED
@@ -1,250 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
- if (!class_exists("FieldConfig")) {
8
-
9
- /**
10
- * Description of FieldConfig
11
- *
12
- * @author ontheGoSystem
13
- */
14
- class FieldConfig {
15
-
16
- private $id;
17
- private $name = "cred[post_title]";
18
- private $value;
19
- private $type = 'textfield';
20
- private $title = 'Post title';
21
- private $repetitive = false;
22
- private $display = '';
23
- private $description = '';
24
- private $config = array();
25
- private $options = array();
26
- private $default_value = '';
27
- private $validation = array();
28
- private $attr;
29
- private $add_time = false;
30
-
31
- public function __construct() {
32
-
33
- }
34
-
35
- public function setRepetitive($repetitive) {
36
- $this->repetitive = $repetitive;
37
- }
38
-
39
- public function isRepetitive() {
40
- return $this->repetitive;
41
- }
42
-
43
- public function set_add_time($addtime) {
44
- $this->add_time = $addtime;
45
- }
46
-
47
- public function setAttr($attr) {
48
- $this->attr = $attr;
49
- }
50
-
51
- public function getAttr() {
52
- return $this->attr;
53
- }
54
-
55
- public function setDefaultValue($type, $field_arr) {
56
- switch ($type) {
57
- case 'date':
58
- $this->add_time = false;
59
- if (isset($field_arr['data']['date_and_time']) && 'and_time' == $field_arr['data']['date_and_time']) {
60
- $this->add_time = true;
61
- }
62
- break;
63
- case 'checkboxes':
64
- if (is_array($field_arr['attr']['default']) && count($field_arr['attr']['default'])) {
65
- $this->default_value = $field_arr['attr']['default'][0];
66
- }
67
- break;
68
-
69
- case 'select':
70
- if (isset($field_arr['attr']['multiple'])) {
71
- //Multiselect
72
- if (isset($field_arr['value']))
73
- foreach ($field_arr['value'] as $value) {
74
- if (isset($value[0])) {
75
- $this->default_value = $value;
76
- break;
77
- }
78
- }
79
- } else
80
- $this->default_value = isset($field_arr['attr']['actual_value'][0]) ? $field_arr['attr']['actual_value'][0] : null;
81
- break;
82
-
83
- case 'radios':
84
- $this->default_value = $field_arr['attr']['default'];
85
- break;
86
-
87
- case 'checkbox':
88
- $this->default_value = isset($field_arr['data']['checked']) ? $field_arr['data']['checked'] : false;
89
- /*if (!$this->default_value)
90
- $this->default_value = isset($field_arr['data']['set_value']) && $field_arr['data']['set_value'] == 'y' ? true : false;*/
91
- break;
92
-
93
- default:
94
- $this->default_value = "";
95
- break;
96
- }
97
- }
98
-
99
- public function setOptions($name, $type, $values, $attrs) {
100
- $arr = array();
101
- switch ($type) {
102
- case 'checkbox':
103
- $arr = $attrs;
104
- break;
105
- case 'checkboxes':
106
- foreach ($attrs['actual_titles'] as $refvalue => $title) {
107
- $value = $attrs['actual_values'][$refvalue];
108
- $arr[$refvalue] = array('value' => $refvalue, 'title' => $title, 'name' => $name, 'data-value' => $value);
109
- if (in_array($refvalue, $attrs['default'])) {
110
- $arr[$refvalue]['checked'] = true;
111
- }
112
- }
113
- break;
114
- case 'select':
115
- $values = $attrs['options'];
116
- foreach ($values as $refvalue => $title) {
117
- $arr[$refvalue] = array(
118
- 'value' => $refvalue,
119
- 'title' => $title,
120
- 'types-value' => $attrs['actual_options'][$refvalue],
121
- );
122
- }
123
- break;
124
- case 'radios':
125
- foreach ($attrs['actual_titles'] as $refvalue => $title) {
126
- $arr[$refvalue] = array(
127
- 'value' => $refvalue,
128
- 'title' => $title,
129
- 'checked' => false,
130
- 'name' => $refvalue,
131
- 'types-value' => $attrs['actual_values'][$refvalue],
132
- );
133
- }
134
- break;
135
- default:
136
- return;
137
- break;
138
- }
139
- $this->options = $arr;
140
- }
141
-
142
- public function createConfig() {
143
- $base_name = "cred";
144
- $this->config = array(
145
- 'id' => $this->getId(),
146
- 'type' => $this->getType(),
147
- 'title' => $this->getTitle(),
148
- 'options' => $this->getOptions(),
149
- 'default_value' => $this->getDefaultValue(),
150
- 'description' => $this->getDescription(),
151
- 'repetitive' => $this->isRepetitive(),
152
- /* 'name' => $base_name."[".$this->getType()."]", */
153
- 'name' => $this->getName(),
154
- 'value' => $this->getValue(),
155
- 'add_time' => $this->getAddTime(),
156
- 'validation' => array(),
157
- 'display' => $this->getDisplay(),
158
- 'attribute' => $this->getAttr()
159
- );
160
- return $this->config;
161
- }
162
-
163
- public function getAddTime() {
164
- return $this->add_time;
165
- }
166
-
167
- public function getType() {
168
- return $this->type;
169
- }
170
-
171
- public function setType($type) {
172
- $this->type = $type;
173
- }
174
-
175
- public function getOptions() {
176
- return $this->options;
177
- }
178
-
179
- public function getDefaultValue() {
180
- return $this->default_value;
181
- }
182
-
183
- public function getTitle() {
184
- return $this->title;
185
- }
186
-
187
- public function getDisplay() {
188
- return $this->display;
189
- }
190
-
191
- public function setTitle($title) {
192
- $this->title = $title;
193
- }
194
-
195
- public function getDescription() {
196
- return $this->description;
197
- }
198
-
199
- public function setDescription($description) {
200
- $this->description = $description;
201
- }
202
-
203
- public function getName() {
204
- return $this->name;
205
- }
206
-
207
- public function setName($name) {
208
- $this->name = $name;
209
- }
210
-
211
- public function getValue() {
212
- return $this->value;
213
- }
214
-
215
- public function setValue($value) {
216
- $this->value = $value;
217
- }
218
-
219
- public function getValidation() {
220
- return !empty($this->validation) ? $this->validation : array();
221
- }
222
-
223
- public function setValidation($validation) {
224
- $this->validation = $validation;
225
- }
226
-
227
- public function getConfig() {
228
- return $this->config;
229
- }
230
-
231
- public function setConfig($config) {
232
- $this->config = $config;
233
- }
234
-
235
- public function getId() {
236
- return $this->id;
237
- }
238
-
239
- public function setId($id) {
240
- $this->id = $id;
241
- }
242
-
243
- public function setDisplay($display) {
244
- $this->display = $display;
245
- }
246
-
247
- }
248
-
249
- }
250
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.file.php DELETED
@@ -1,149 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.textfield.php';
7
-
8
- /**
9
- * Description of class
10
- *
11
- * @author Srdjan
12
- */
13
- class WPToolset_Field_File extends WPToolset_Field_Textfield
14
- {
15
-
16
- protected $_validation = array('required');
17
- //protected $_defaults = array('filename' => '', 'button_style' => 'btn2');
18
-
19
- public function init()
20
- {
21
- WPToolset_Field_File::file_enqueue_scripts();
22
- $this->set_placeholder_as_attribute();
23
- }
24
-
25
- public static function file_enqueue_scripts()
26
- {
27
- wp_register_script(
28
- 'wptoolset-field-file',
29
- WPTOOLSET_FORMS_RELPATH . '/js/file-wp35.js',
30
- array('jquery', 'jquery-masonry'),
31
- WPTOOLSET_FORMS_VERSION,
32
- true
33
- );
34
-
35
- if ( !wp_script_is( 'wptoolset-field-file', 'enqueued' ) ) {
36
- wp_enqueue_script( 'wptoolset-field-file' );
37
- }
38
-
39
- if ( is_admin() ) {
40
- $screen = get_current_screen();
41
- if (isset($screen->parent_base) && 'users' == $screen->parent_base) {
42
- wp_enqueue_media();
43
- }
44
-
45
- if (isset($screen->post_type) && isset($screen->base) && 'post' == $screen->base) {
46
- global $post;
47
- if ( is_object($post) ) {
48
- wp_enqueue_media(array('post' => $post->ID));
49
- }
50
- }
51
- }
52
-
53
- }
54
-
55
- public function enqueueStyles()
56
- {
57
- }
58
-
59
- /**
60
- *
61
- * @global object $wpdb
62
- *
63
- */
64
- public function metaform()
65
- {
66
- $value = $this->getValue();
67
- $type = $this->getType();
68
- $translated_type = '';
69
- $form = array();
70
- $preview = '';
71
-
72
- // Get attachment by guid
73
- if ( !empty( $value ) ) {
74
- global $wpdb;
75
- $attachment_id = $wpdb->get_var(
76
- $wpdb->prepare(
77
- "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND guid=%s",
78
- $value
79
- )
80
- );
81
- }
82
-
83
- // Set preview
84
- if ( !empty( $attachment_id ) ) {
85
- $attributes = array();
86
- $full = wp_get_attachment_image_src($attachment_id, 'full');
87
- if ( !empty($full) ) {
88
- $attributes['data-full-src'] = esc_attr($full[0]);
89
- }
90
- $preview = wp_get_attachment_image( $attachment_id, 'thumbnail', false, $attributes);
91
- } else {
92
- // If external image set preview
93
- $file_path = parse_url( $value );
94
- if ( $file_path && isset( $file_path['path'] ) ) {
95
- $file = pathinfo( $file_path['path'] );
96
- }
97
- else {
98
- $file = pathinfo( $value );
99
- }
100
- if (
101
- isset( $file['extension'] )
102
- && in_array( strtolower( $file['extension'] ), array('jpg', 'jpeg', 'gif', 'png') )
103
- ) {
104
- $preview = '<img alt="" src="' . $value . '" />';
105
- }
106
- }
107
-
108
- // Set button
109
- switch( $type ) {
110
- case 'audio':
111
- $translated_type = __( 'audio', 'wpv-views' );
112
- break;
113
- case 'image':
114
- $translated_type = __( 'image', 'wpv-views' );
115
- break;
116
- case 'video':
117
- $translated_type = __( 'video', 'wpv-views' );
118
- break;
119
- default:
120
- $translated_type = __( 'file', 'wpv-views' );
121
- break;
122
- }
123
- $button = sprintf(
124
- '<a href="#" class="js-wpt-file-upload button button-secondary" data-wpt-type="%s">%s</a>',
125
- $type,
126
- sprintf( __( 'Select %s', 'wpv-views' ), $translated_type )
127
- );
128
-
129
- // Set form
130
- $form[] = array(
131
- '#type' => 'textfield',
132
- '#name' => $this->getName(),
133
- '#title' => $this->getTitle(),
134
- '#description' => $this->getDescription(),
135
- '#value' => $value,
136
- '#suffix' => '&nbsp;' . $button,
137
- '#validate' => $this->getValidationData(),
138
- '#repetitive' => $this->isRepetitive(),
139
- '#attributes' => $this->getAttr(),
140
- );
141
-
142
- $form[] = array(
143
- '#type' => 'markup',
144
- '#markup' => '<div class="js-wpt-file-preview wpt-file-preview">' . $preview . '</div>',
145
- );
146
-
147
- return $form;
148
- }
149
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.form_factory.php DELETED
@@ -1,482 +0,0 @@
1
- <?php
2
- require_once 'abstract.form.php';
3
- require_once 'class.eforms.php';
4
- require_once 'class.field_factory.php';
5
-
6
- define( "CLASS_NAME_PREFIX", "WPToolset_Field_" );
7
-
8
- /**
9
- * FormFactory
10
- * Creation Form Class
11
- * @author onTheGo System
12
- *
13
- *
14
- *
15
- */
16
- class FormFactory extends FormAbstract
17
- {
18
-
19
- private $field_count = 0;
20
- private $form = array();
21
- private $nameForm;
22
- private $theForm;
23
- protected $_validation, $_conditional, $_repetitive, $_use_bootstrap;
24
-
25
- public function __construct( $nameForm = 'default' )
26
- {
27
- if ( !isset( $GLOBALS['formFactories'] ) )
28
- $GLOBALS['formFactories'] = array();
29
- $this->nameForm = $nameForm;
30
- $this->field_count = 0;
31
- $this->theForm = new Enlimbo_Forms( $nameForm );
32
- $this->_use_bootstrap = false;
33
-
34
- wp_register_script( 'wptoolset-forms',
35
- WPTOOLSET_FORMS_RELPATH . '/js/main.js',
36
- array('jquery', 'underscore', 'suggest'), WPTOOLSET_FORMS_VERSION, true );
37
- wp_enqueue_script( 'wptoolset-forms' );
38
- $wptoolset_forms_localization = array(
39
- 'ajaxurl' => admin_url( 'admin-ajax.php', null )
40
- );
41
- wp_localize_script( 'wptoolset-forms', 'wptoolset_forms_local', $wptoolset_forms_localization );
42
-
43
- if ( is_admin() ) {
44
- wp_register_style( 'wptoolset-forms-admin',
45
- WPTOOLSET_FORMS_RELPATH . '/css/wpt-toolset-backend.css', array(),
46
- WPTOOLSET_FORMS_VERSION );
47
- wp_enqueue_style( 'wptoolset-forms-admin' );
48
- } else {
49
- /**
50
- * get cred form settings
51
- */
52
- $cred_cred_settings = get_option( 'cred_cred_settings' );
53
- /**
54
- * load or not cred.css
55
- * and check use bootstrap
56
- */
57
- $load_cred_css = true;
58
- if ( is_array($cred_cred_settings) ) {
59
- if (
60
- array_key_exists('dont_load_cred_css', $cred_cred_settings )
61
- && $cred_cred_settings['dont_load_cred_css']
62
- ) {
63
- $load_cred_css = false;
64
- }
65
- if (
66
- array_key_exists( 'use_bootstrap', $cred_cred_settings )
67
- && $cred_cred_settings['use_bootstrap']
68
- ) {
69
- $this->_use_bootstrap = true;
70
- }
71
- }
72
- /**
73
- * register
74
- */
75
- if ( $load_cred_css ) {
76
- wp_register_style(
77
- 'wptoolset-forms-cred',
78
- WPTOOLSET_FORMS_RELPATH . '/css/wpt-toolset-frontend.css',
79
- array(),
80
- WPTOOLSET_FORMS_VERSION
81
- );
82
- wp_enqueue_style( 'wptoolset-forms-cred' );
83
- }
84
- }
85
- }
86
-
87
- /**
88
- * (non-PHPdoc)
89
- * @see classes/FormAbstract::formNameExists()
90
- */
91
- public function formNameExists( &$nameForm ) {
92
- if ( !in_array( $nameForm, $GLOBALS['formFactories'] ) ) {
93
- $GLOBALS['formFactories'][] = $nameForm;
94
- return false;
95
- } else {
96
- echo "Form name already exists!";
97
- return true;
98
- }
99
- }
100
-
101
- /**
102
- * getClassFromType
103
- * Return the class name from a type
104
- * @param unknown_type $type
105
- */
106
- protected function getClassFromType( $type ) {
107
- return CLASS_NAME_PREFIX . ucfirst( $type );
108
- }
109
-
110
- /**
111
- * (non-PHPdoc)
112
- * @see classes/FormAbstract::getFieldObject()
113
- */
114
- public function getFieldObject( $data, $global_name_field, $value )
115
- {
116
- if ( $class = $this->loadFieldClass( $data['type'] ) ) {
117
- return new $class( $data, $global_name_field, $value );
118
- }
119
- return null;
120
- }
121
-
122
- /**
123
- * (non-PHPdoc)
124
- * @see classes/FormAbstract::addFormField()
125
- */
126
- public function addFormField( $data ) {
127
- //check mandatory info in data like type and name field
128
- $global_name_field = $this->nameForm . '_field_' . $this->field_count;
129
- $obj = $this->getFieldObject( $data, $global_name_field );
130
- $this->form[$global_name_field] = $obj->metaform();
131
- $this->field_count++;
132
- }
133
-
134
- /**
135
- * (non-PHPdoc)
136
- * @see classes/FormAbstract::createForm()
137
- */
138
- public function createForm( $nameForm /*= 'default'*/ ) {
139
- if ( $this->formNameExists( $nameForm ) ) return;
140
- $this->theForm->autoHandle( $nameForm, $this->form );
141
-
142
- $out = "";
143
- $out .= '<form method="post" action="" id="' . $nameForm . '">';
144
- $out .= $this->theForm->renderElements( $this->form );
145
- //$out .= $this->theForm->renderForm();
146
- $out .= '</form>';
147
-
148
- return $out;
149
- }
150
-
151
- /**
152
- * (non-PHPdoc)
153
- * @see classes/FormAbstract::displayForm()
154
- */
155
- public function displayForm( $nameForm /*= 'default'*/ ) {
156
- if ( $this->formNameExists( $nameForm ) ) return;
157
- $myform = $this->theForm;
158
- $this->theForm->autoHandle( $nameForm, $this->form );
159
-
160
- echo '<form method="post" action="" id="' . $nameForm . '">';
161
- echo $this->theForm->renderForm();
162
- echo '</form>';
163
- }
164
-
165
- /**
166
- * metaform
167
- * @param type $name
168
- * @param type $type
169
- * @param type $config
170
- * @param type $global_name_field
171
- * @param type $value
172
- * @return type
173
- */
174
- public function metaform( $config, $global_name_field, $value )
175
- {
176
- /**
177
- * add bootstrap config to every field
178
- */
179
- $config['use_bootstrap'] = $this->theForm->form_settings['use_bootstrap'];
180
- $config['has_media_button'] = $this->theForm->form_settings['has_media_button'];
181
-
182
- /**
183
- * WMPL configuration
184
- */
185
- $config['wpml_action'] = $this->get_wpml_action($config['id']);
186
-
187
- /**
188
- * Change config options.
189
- *
190
- * This filter allow to chenge value of key 'options' for field config..
191
- *
192
- * @since 1.8.0
193
- *
194
- * @param array $options Array options for field.
195
- * @param string $slug Field slug.
196
- * @param string $type field type
197
- */
198
- if (
199
- isset($config['type'])
200
- && isset($config['slug'])
201
- && isset($config['options'])
202
- ) {
203
- $config['options'] = apply_filters(
204
- 'wpcf_config_options_'.$config['type'],
205
- $config['options'],
206
- $config['slug'],
207
- $config['type']
208
- );
209
- }
210
-
211
- $htmlArray = array();
212
- $_gnf = $global_name_field;
213
- $_cfg = $config;
214
- if ( empty( $value ) ) $value = array(null);
215
- elseif ( !is_array( $value ) ) $value = array($value);
216
- $count = 0;
217
-
218
- //Fix if i get skype i receive skype i have 2 elements array in $value !!
219
- if ($config['type']=='skype') {
220
- if (isset($value['style'])) unset($value['style']);
221
- if (isset($value['button_style'])) unset($value['button_style']);
222
- }
223
-
224
- foreach ( $value as $val ) {
225
- if ( !empty( $config['repetitive'] ) ) {
226
- $_gnf = $_cfg['name'] = "{$global_name_field}[{$count}]";
227
- }
228
- //CHECKGEN
229
- if ( isset($_cfg['validation']) &&
230
- is_array($_cfg['validation']) &&
231
- count($_cfg['validation']) > 0 &&
232
- !is_admin() && $_SERVER['REQUEST_METHOD'] == 'POST' &&
233
- isset( $_GET['_tt'] ) &&
234
- !isset( $_GET['_success'] ) &&
235
- !isset( $_GET['_success_message'] ) )
236
- {
237
- $_cfg['validate'] = 1;
238
- }
239
- if ( !is_wp_error( $field = $this->loadField( $_cfg, $_gnf, $val ) ) ) {
240
- $form = $field->metaform();
241
- // Set $config['validate'] to trigger PHP validation
242
- // when rendering metaform
243
- if ( !empty( $_cfg['validate'] ) &&
244
- is_wp_error( $valid = $this->validateField( $field, $val ) ) ) {
245
- $key = key( $form );
246
- $error = $valid->get_error_data();
247
- if ( is_array( $error ) ) {
248
- $error = array_shift( $error );
249
- }
250
- $form[$key]['#error'] = $error;
251
- }
252
-
253
- if ( isset( $_cfg['validation_error'] ) ) {
254
- $key = key( $form );
255
- $form[$key]['#error'] = $_cfg['validation_error'];
256
- }
257
- $this->form[$global_name_field] = $form;
258
- $this->field_count++;
259
- $htmlArray[] = $this->theForm->renderElements( $form );
260
- if ( empty( $config['repetitive'] ) ) break;
261
- $count++;
262
- } else {
263
- if ( current_user_can('manage_options') ) {
264
- $htmlArray[] = sprintf(
265
- '<div id="message" class="error"><p>%s</p><p>%s</p></div>',
266
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/196628627/comments#310360880
267
- //changed render to rendering
268
- sprintf(
269
- __('There is a problem rendering field <strong>%s (%s)</strong>.', 'wpv-views'),
270
- $_cfg['title'],
271
- $_cfg['type']
272
- ),
273
- $field->get_error_message()
274
- );
275
- }
276
- }
277
- }
278
- if ( !empty( $htmlArray ) && isset($config['repetitive']) && $config['repetitive'] ) {
279
- $_gnf = $_cfg['name'] = "{$global_name_field}[%%{$count}%%]";
280
- if ( !is_wp_error( $field = $this->loadField( $_cfg, $_gnf, null ) ) ) {
281
- $tpl = $this->_tplItem( $config,
282
- $this->theForm->renderElements( $field->metaform() ) );
283
- $this->_repetitive()->add( $config, $tpl );
284
- }
285
- }
286
-
287
- return !empty( $htmlArray ) ? $this->_tpl( $config, $htmlArray ) : '';
288
- }
289
-
290
- /**
291
- *
292
- * @staticvar array $loaded
293
- * @param type $config
294
- * @param string $global_name_field
295
- * @param type $value
296
- * @return \WP_Error|\class
297
- */
298
- public function loadField( $config, $global_name_field, $value ){
299
- global $wp_version;
300
- static $loaded = array();
301
- $type = $config['type'];
302
- $global_name_field = $this->nameForm . '_field_' . $this->field_count;
303
- $field = $this->getFieldObject( $config, $global_name_field, $value );
304
-
305
- if ( is_null( $field ) ) {
306
- return new WP_Error( 'wptoolset_forms', 'wrong field type' );
307
- }
308
-
309
- $settings = $field->getSettings();
310
- if ( isset( $settings['min_wp_version'] ) && version_compare( $wp_version,
311
- $settings['min_wp_version'], '<' ) ) {
312
- return new WP_Error( 'wptoolset_forms', 'Higher WP version required' );
313
- }
314
-
315
- $this->_setGlobalField( $field );
316
-
317
- // Load/enqueue scripts
318
- if ( !isset( $loaded[$type] ) ) {
319
- $loaded[$type] = 1;
320
- // These should be performed only once
321
- $field->registerScripts();
322
- $field->registerStyles();
323
- $field->enqueueScripts();
324
- $field->enqueueStyles();
325
- $field->addFilters();
326
- $field->addActions();
327
- }
328
- $this->_checkValidation( $config );
329
- $this->_checkConditional( $config );
330
-
331
- return $field;
332
- }
333
-
334
- protected function _checkValidation( $config ) {
335
- if ( isset( $config['validation'] ) && is_null( $this->_validation ) ) {
336
- require_once 'class.validation.php';
337
- $this->_validation = new WPToolset_Forms_Validation( $this->nameForm );
338
- }
339
- }
340
-
341
- protected function _checkConditional( $config ) {
342
- if ( !empty( $config['conditional'] ) ) {
343
- $this->getConditionalClass()->add( $config );
344
- }
345
- }
346
-
347
- public function addConditional( $config ) {
348
- $this->getConditionalClass()->add( $config );
349
- }
350
-
351
- public function getConditionalClass(){
352
- if ( is_null( $this->_conditional ) ) {
353
- require_once 'class.conditional.php';
354
- $this->_conditional = new WPToolset_Forms_Conditional( $this->nameForm );
355
- }
356
- return $this->_conditional;
357
- }
358
-
359
- protected function _repetitive() {
360
- if ( is_null( $this->_repetitive ) ) {
361
- require_once 'class.repetitive.php';
362
- $this->_repetitive = new WPToolset_Forms_Repetitive();
363
- }
364
- return $this->_repetitive;
365
- }
366
-
367
- protected function _tpl( $cfg, $html ) {
368
- ob_start();
369
- include WPTOOLSET_FORMS_ABSPATH . '/templates/metaform.php';
370
- $o = ob_get_contents();
371
- ob_get_clean();
372
- return $o;
373
- }
374
-
375
- protected function _tplItem( $cfg, $out ) {
376
- ob_start();
377
- include WPTOOLSET_FORMS_ABSPATH . '/templates/metaform-item.php';
378
- $o = ob_get_contents();
379
- ob_get_clean();
380
- return $o;
381
- }
382
-
383
- static $_validate_flag = array();
384
- public function validateField( $field, $value ) {
385
- if ( is_array( $field ) ) {
386
- $field = $this->loadField( $field, $field['name'], $value );
387
- }
388
-
389
- /**
390
- * Temporary fixing validation for checkbox/radios/skype because _cakeValidation is not working for thats
391
- * https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/186243370/comments
392
- */
393
- if (!is_admin()) {
394
- //I receive wpcf-id and wpcf[id] for the same type
395
- if ( $field->getId()==$field->getName() &&
396
- ($field->getType()=='checkbox' ||
397
- $field->getType()=='radios' ||
398
- $field->getType()=='skype' )
399
- )
400
- {
401
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/188604193/comments
402
- //added sanitize_text_field for sucuri warning php.backdoor.eval_POST.010
403
- $field_value = isset($_POST[$field->getName()])?sanitize_text_field($_POST[$field->getName()]):"";
404
- if ($field->getType()=='skype') {
405
- $field_value = isset($_POST[$field->getName()]['skypename'])?sanitize_text_field($_POST[$field->getName()]['skypename']):"";
406
- }
407
- //##########################################################################################
408
-
409
- $_tmp = $field->getValidationData();
410
- if (isset($_tmp['required']) &&
411
- !isset($field_value))
412
- {
413
- $mess = $field->getTitle().' Field is required';
414
- return new WP_Error( 'wptoolset_forms', $mess,
415
- array($field->getTitle().' Field is required') );
416
- }
417
- }
418
- }
419
- //****************************************************************
420
-
421
- if ( !is_wp_error( $field ) ) {
422
- if ( $field->getValidationData() ) {
423
- return $this->_validation->validateField( $field );
424
- }
425
- return true;
426
- }
427
- return new WP_Error( 'wptoolset_forms', 'Field do not exist',
428
- array('Field do not exist') );
429
- }
430
-
431
- protected function _setGlobalField( $field ) {
432
- global $wptoolset_field;
433
- $wptoolset_field = $field;
434
- }
435
-
436
- public function __toString() {
437
- return join( "\n", $this->elements );
438
- }
439
-
440
- public function loadFieldClass( $type ) {
441
- $type = strtolower( $type );
442
- $class = $this->getClassFromType( $type );
443
-
444
- /**
445
- * try to load custom class
446
- */
447
- $loader = $class.'_loader';
448
- if ( function_exists($loader) ) {
449
- $loader();
450
- }
451
-
452
- if ( !class_exists( $class ) ) {
453
- $file = WPTOOLSET_FORMS_ABSPATH . "/classes/class.{$type}.php";
454
- if ( file_exists( $file ) ) {
455
- require_once $file;
456
- return $class;
457
- } else {
458
- // third party fields array $type => __FILE__
459
- $third_party_fields = apply_filters( 'wptoolset_registered_fields',
460
- array() );
461
- if ( isset( $third_party_fields[$type] ) && file_exists( $third_party_fields[$type] ) ) {
462
- require_once $third_party_fields[$type];
463
- return $class;
464
- }
465
- }
466
- }
467
- return class_exists( $class ) ? $class : false;
468
- }
469
-
470
- private function get_wpml_action($id)
471
- {
472
- global $iclTranslationManagement;
473
- if (
474
- is_object($iclTranslationManagement)
475
- && 'TranslationManagement' == get_class($iclTranslationManagement)
476
- && isset($iclTranslationManagement->settings['custom_fields_translation'][$id])
477
- ) {
478
- return $iclTranslationManagement->settings['custom_fields_translation'][$id];
479
- }
480
- return 0;
481
- }
482
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.hidden.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- class WPToolset_Field_Hidden extends WPToolset_Field_Textfield
5
- {
6
- public function metaform() {
7
- $metaform = array();
8
- $metaform[] = array(
9
- '#type' => 'hidden',
10
- '#title' => $this->getTitle(),
11
- '#description' => $this->getDescription(),
12
- '#name' => $this->getName(),
13
- '#value' => $this->getValue(),
14
- '#validate' => $this->getValidationData()
15
- );
16
- $this->set_metaform($metaform);
17
- return $metaform;
18
- }
19
-
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.image.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
- require_once 'class.file.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- *
9
- *
10
- */
11
- class WPToolset_Field_Image extends WPToolset_Field_File
12
- {
13
- public function metaform()
14
- {
15
- $validation = $this->getValidationData();
16
- $validation = self::addTypeValidation($validation);
17
- $this->setValidationData($validation);
18
- return parent::metaform();
19
- }
20
-
21
- public static function addTypeValidation($validation)
22
- {
23
- $valid_extensions = array(
24
- 'bmp',
25
- 'gif',
26
- 'ico',
27
- 'jpeg',
28
- 'jpg',
29
- 'png',
30
- 'svg',
31
- 'webp',
32
- );
33
- $valid_extensions = apply_filters( 'toolset_valid_image_extentions', $valid_extensions);
34
- $validation['extension'] = array(
35
- 'args' => array(
36
- 'extension',
37
- implode('|', $valid_extensions),
38
- ),
39
- 'message' => __( 'You can add only images.', 'wpv-views' ),
40
- );
41
- return $validation;
42
- }
43
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.integer.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- */
9
- class WPToolset_Field_Integer extends WPToolset_Field_Textfield
10
- {
11
-
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.numeric.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- */
9
- class WPToolset_Field_Numeric extends WPToolset_Field_Textfield
10
- {
11
-
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.password.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.field_factory.php';
7
-
8
- /**
9
- * Generic Cred field: password
10
- *
11
- * @author Gen
12
- */
13
- class WPToolset_Field_Password extends FieldFactory
14
- {
15
-
16
- public function metaform() {
17
- $attributes = $this->getAttr();
18
-
19
- $metaform = array();
20
- $metaform[] = array(
21
- '#type' => 'password',
22
- '#title' => $this->getTitle(),
23
- '#description' => $this->getDescription(),
24
- '#name' => $this->getName(),
25
- '#value' => $this->getValue(),
26
- '#validate' => $this->getValidationData(),
27
- '#repetitive' => $this->isRepetitive(),
28
- '#attributes' => $attributes
29
- );
30
- return $metaform;
31
- }
32
-
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.phone.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- */
9
- class WPToolset_Field_Phone extends WPToolset_Field_Textfield
10
- {
11
-
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.radios.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.field_factory.php';
7
-
8
- /**
9
- * Description of class
10
- *
11
- * @author Srdjan
12
- */
13
- class WPToolset_Field_Radios extends FieldFactory
14
- {
15
-
16
- public function metaform()
17
- {
18
- $value = $this->getValue();
19
- $data = $this->getData();
20
- $name = $this->getName();
21
- $form = array();
22
- $options = array();
23
- foreach ( $data['options'] as $option ) {
24
- $one_option_data = array(
25
- '#value' => $option['value'],
26
- '#title' => $option['title'],
27
- '#validate' => $this->getValidationData()
28
- );
29
- if ( !is_admin() ) {// TODO maybe add a doing_ajax() check too, what if we want to load a form using AJAX?
30
- $clases = array(
31
- 'wpt-form-item',
32
- 'wpt-form-item-radio',
33
- 'radio-'.sanitize_title($option['title'])
34
- );
35
- /**
36
- * filter: cred_checkboxes_class
37
- * @param array $clases current array of classes
38
- * @parem array $option current option
39
- * @param string field type
40
- *
41
- * @return array
42
- */
43
- $clases = apply_filters( 'cred_item_li_class', $clases, $option, 'radio' );
44
- $one_option_data['#before'] = sprintf(
45
- '<li class="%s">',
46
- implode(' ', $clases)
47
- );
48
- $one_option_data['#after'] = '</li>';
49
- $one_option_data['#pattern'] = '<BEFORE><PREFIX><ELEMENT><LABEL><ERROR><SUFFIX><DESCRIPTION><AFTER>';
50
- }
51
- /**
52
- * add default value if needed
53
- * issue: frontend, multiforms CRED
54
- */
55
- if ( array_key_exists( 'types-value', $option ) ) {
56
- $one_option_data['#types-value'] = $option['types-value'];
57
- }
58
- /**
59
- * add to options array
60
- */
61
- $options[] = $one_option_data;
62
- }
63
- /**
64
- * for user fields we reset title and description to avoid double
65
- * display
66
- */
67
- $title = $this->getTitle();
68
- if ( empty($title) ) {
69
- $title = $this->getTitle(true);
70
- }
71
- $options = apply_filters( 'wpt_field_options', $options, $title, 'select' );
72
- /**
73
- * default_value
74
- */
75
- if ( !empty( $value ) || $value == '0' ) {
76
- $data['default_value'] = $value;
77
- }
78
- /**
79
- * metaform
80
- */
81
- $form_attr = array(
82
- '#type' => 'radios',
83
- '#title' => $this->getTitle(),
84
- '#description' => $this->getDescription(),
85
- '#name' => $name,
86
- '#options' => $options,
87
- '#default_value' => isset( $data['default_value'] ) ? $data['default_value'] : false,
88
- '#repetitive' => $this->isRepetitive(),
89
- '#validate' => $this->getValidationData(),
90
- );
91
-
92
- if ( !is_admin() ) {// TODO maybe add a doing_ajax() check too, what if we want to load a form using AJAX?
93
- $form_attr['#before'] = '<ul class="wpt-form-set wpt-form-set-radios wpt-form-set-radios-' . $name . '">';
94
- $form_attr['#after'] = '</ul>';
95
- }
96
-
97
- $form[] = $form_attr;
98
-
99
- return $form;
100
- }
101
-
102
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.recaptcha.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
- require_once 'class.textfield.php';
3
-
4
- /**
5
- * Description of class
6
- *
7
- * @author Srdjan
8
- */
9
- class WPToolset_Field_Recaptcha extends WPToolset_Field_Textfield
10
- {
11
- private $pubkey = '';
12
- private $privkey = '';
13
- private $settings;
14
-
15
- public function init() {
16
- require_once ( WPTOOLSET_FORMS_ABSPATH."/js/recaptcha-php-1.11/recaptchalib.php");
17
-
18
- //$settings_model = CRED_Loader::get('MODEL/Settings');
19
- //$this->settings = $settings_model->getSettings();
20
- $attr = $this->getAttr();
21
- $this->pubkey = isset($attr['public_key']) ? $attr['public_key'] : '';
22
- $this->privkey = isset($attr['private_key']) ? $attr['private_key'] : '';
23
-
24
- wp_register_script( 'wpt-cred-recaptcha',
25
- WPTOOLSET_FORMS_RELPATH . '/js/recaptcha-php-1.11/recaptcha_ajax.js',
26
- array('wptoolset-forms'), WPTOOLSET_FORMS_VERSION, true );
27
- wp_enqueue_script( 'wpt-cred-recaptcha' );
28
- }
29
-
30
- public static function registerStyles() {
31
- }
32
-
33
- public function enqueueScripts() {
34
-
35
- }
36
-
37
- public function enqueueStyles() {
38
- }
39
-
40
- public function metaform() {
41
- $form = array();
42
-
43
- $capture = '';
44
- if ($this->pubkey || !is_admin()) {
45
- try {
46
- $capture = recaptcha_get_html($this->pubkey,null,is_ssl());
47
- } catch(Exception $e ) {
48
- //https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/188424989/comments
49
- if ( current_user_can( 'manage_options' ) ) {
50
- $id_field = $this->getId();
51
- $text = 'Caught exception: '. $e->getMessage();
52
- $capture = "<label id=\"lbl_$id_field\" class=\"wpt-form-error\">$text</label><div style=\"clear:both;\"></div>";
53
- }
54
- //###########################################################################################
55
- }
56
- }
57
-
58
- $form[] = array(
59
- '#type' => 'textfield',
60
- '#title' => '',
61
- '#name' => '_recaptcha',
62
- '#value' => '',
63
- '#attributes' => array( 'style' => 'display:none;'),
64
- '#before' => $capture
65
- );
66
-
67
- return $form;
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.repetitive.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
- /*
3
- * Repetitive controller
4
- *
5
- *
6
- * If field is repetitive
7
- * - queues repetitive CSS and JS
8
- * - renders JS templates in admin footer
9
- */
10
- class WPToolset_Forms_Repetitive
11
- {
12
- private $__templates = array();
13
-
14
- function __construct(){
15
- // Register
16
- wp_register_script( 'wptoolset-forms-repetitive',
17
- WPTOOLSET_FORMS_RELPATH . '/js/repetitive.js',
18
- array('jquery', 'jquery-ui-sortable', 'underscore'), WPTOOLSET_FORMS_VERSION,
19
- true );
20
- // wp_register_style( 'wptoolset-forms-repetitive', '' );
21
- // Render settings
22
- add_action( 'admin_footer', array($this, 'renderTemplates') );
23
- add_action( 'wp_footer', array($this, 'renderTemplates') );
24
-
25
- wp_enqueue_script( 'wptoolset-forms-repetitive' );
26
-
27
- }
28
-
29
- function add( $config, $html ) {
30
- if ( !empty( $config['repetitive'] ) ) {
31
- $this->__templates[$config['id']] = $html;
32
- }
33
- }
34
-
35
- function renderTemplates() {
36
- foreach ( $this->__templates as $id => $template ) {
37
- echo '<script type="text/html" id="tpl-wpt-field-' . $id . '">'
38
- . $template . '</script>';
39
- }
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.select.php DELETED
@@ -1,87 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.field_factory.php';
7
-
8
- /**
9
- * Description of class
10
- *
11
- * @author Srdjan
12
- */
13
- class WPToolset_Field_Select extends FieldFactory
14
- {
15
-
16
- public function metaform() {
17
- $value = $this->getValue();
18
- $data = $this->getData();
19
- $attributes = $this->getAttr();
20
-
21
- $form = array();
22
- $options = array();
23
- if (isset($data['options'])) {
24
- foreach ( $data['options'] as $option ) {
25
- $one_option_data = array(
26
- '#value' => $option['value'],
27
- '#title' => stripslashes($option['title']),
28
- );
29
- /**
30
- * add default value if needed
31
- * issue: frontend, multiforms CRED
32
- */
33
- if ( array_key_exists( 'types-value', $option ) ) {
34
- $one_option_data['#types-value'] = $option['types-value'];
35
- }
36
- /**
37
- * add to options array
38
- */
39
- $options[] = $one_option_data;
40
- }
41
- }
42
-
43
- /**
44
- * for user fields we reset title and description to avoid double
45
- * display
46
- */
47
- $title = $this->getTitle();
48
- if ( empty($title) ) {
49
- $title = $this->getTitle(true);
50
- }
51
- $options = apply_filters( 'wpt_field_options', $options, $title, 'select' );
52
- /**
53
- * default_value
54
- */
55
- if ( !empty( $value ) || $value == '0' ) {
56
- $data['default_value'] = $value;
57
- }
58
-
59
- $is_multiselect = array_key_exists('multiple', $attributes) && 'multiple' == $attributes['multiple'];
60
- $default_value = isset( $data['default_value'] ) ? $data['default_value'] : null;
61
- //Fix https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/189219391/comments
62
- if ($is_multiselect) {
63
- $default_value = new RecursiveIteratorIterator(new RecursiveArrayIterator($default_value));
64
- $default_value = iterator_to_array($default_value,false);
65
- }
66
- //##############################################################################################
67
-
68
- /**
69
- * metaform
70
- */
71
- $form[] = array(
72
- '#type' => 'select',
73
- '#title' => $this->getTitle(),
74
- '#description' => $this->getDescription(),
75
- '#name' => $this->getName(),
76
- '#options' => $options,
77
- '#default_value' => $default_value,
78
- '#multiple' => $is_multiselect,
79
- '#validate' => $this->getValidationData(),
80
- '#class' => 'form-inline',
81
- '#repetitive' => $this->isRepetitive(),
82
- );
83
-
84
- return $form;
85
- }
86
-
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.skype.php DELETED
@@ -1,267 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.textfield.php';
7
-
8
- class WPToolset_Field_Skype extends WPToolset_Field_Textfield
9
- {
10
- protected $_defaults = array(
11
- 'skypename' => '',
12
- 'action' => 'chat',
13
- 'color' => 'blue',
14
- 'size' => 32,
15
- );
16
-
17
- public function init()
18
- {
19
- add_action( 'admin_footer', array($this, 'editButtonTemplate') );
20
- add_action( 'wp_footer', array($this, 'editButtonTemplate') );
21
-
22
- wp_register_script(
23
- 'skype-uri-buttom',
24
- '//www.skypeassets.com/i/scom/js/skype-uri.js'
25
- );
26
-
27
- wp_register_script(
28
- 'wptoolset-field-skype',
29
- WPTOOLSET_FORMS_RELPATH . '/js/skype.js',
30
- array('jquery', 'skype-uri-buttom'),
31
- WPTOOLSET_FORMS_VERSION,
32
- true
33
- );
34
- wp_enqueue_script( 'wptoolset-field-skype' );
35
- add_thickbox();
36
- $translation = array('title' => esc_js( __( 'Edit Skype button', 'wpv-views' ) ) );
37
- wp_localize_script( 'wptoolset-field-skype', 'wptSkypeData', $translation );
38
- $this->set_placeholder_as_attribute();
39
- }
40
-
41
- public function enqueueStyles() {
42
-
43
- }
44
-
45
- public function metaform() {
46
- $value = wp_parse_args( $this->getValue(), $this->_defaults );
47
- $attributes = $this->getAttr();
48
- if ( isset($attributes['class'] ) ) {
49
- $attributes['class'] .= ' ';
50
- } else {
51
- $attributes['class'] = '';
52
- }
53
- $attributes['class'] = 'js-wpt-skypename js-wpt-cond-trigger regular-text';// What is this js-wpt-cond-trigger classname for?
54
- $form = array();
55
- $form[] = array(
56
- '#type' => 'textfield',
57
- '#title' => $this->getTitle(),
58
- '#description' => $this->getDescription(),
59
- '#name' => $this->getName() . "[skypename]",
60
- '#attributes' => array(),
61
- '#value' => $value['skypename'],
62
- '#validate' => $this->getValidationData(),
63
- '#attributes' => $attributes,
64
- '#repetitive' => $this->isRepetitive(),
65
- );
66
-
67
- /**
68
- * action
69
- */
70
- $form[] = array(
71
- '#type' => 'hidden',
72
- '#value' => $value['action'],
73
- '#name' => $this->getName() . '[action]',
74
- '#attributes' => array('class' => 'js-wpt-skype-action'),
75
- );
76
-
77
- /**
78
- * color
79
- */
80
- $form[] = array(
81
- '#type' => 'hidden',
82
- '#value' => $value['color'],
83
- '#name' => $this->getName() . '[color]',
84
- '#attributes' => array('class' => 'js-wpt-skype-color'),
85
- );
86
-
87
- /**
88
- * size
89
- */
90
- $form[] = array(
91
- '#type' => 'hidden',
92
- '#value' => $value['size'],
93
- '#name' => $this->getName() . '[size]',
94
- '#attributes' => array('class' => 'js-wpt-skype-size'),
95
- );
96
-
97
- if (!is_admin()) {
98
- return $form;
99
- }
100
- $button_element = array(
101
- '#name' => '',
102
- '#type' => 'button',
103
- '#value' => esc_attr( __( 'Edit Skype', 'wpv-views' ) ),
104
- '#attributes' => array(
105
- 'class' => 'js-wpt-skype-edit-button button button-small button-secondary',
106
- ),
107
- );
108
- foreach( $value as $key => $val ) {
109
- $button_element['#attributes']['data-'.esc_attr($key)] = $val;
110
- }
111
- $form[] = $button_element;
112
- return $form;
113
- }
114
-
115
- public function editButtonTemplate()
116
- {
117
-
118
- static $edit_button_template_template_already_loaded;
119
-
120
- if ( $edit_button_template_template_already_loaded ) {
121
- return;
122
- }
123
-
124
- $edit_button_template_template_already_loaded = true;
125
-
126
- $form = array();
127
- $form['full-open'] = array(
128
- '#type' => 'markup',
129
- '#markup' => '<div id="tpl-wpt-skype-edit-button" style="display:none;"><div id="wpt-skype-edit-button-popup">',
130
- );
131
- $form['preview'] = array(
132
- '#type' => 'markup',
133
- '#markup' => sprintf(
134
- '<div id="wpt-skype-edit-button-popup-preview"><p class="bold">%s</p><div id="wpt-skype-edit-button-popup-preview-button"><div id="wpt-skype-preview"></div><small style="display:none">%s</small></div><p class="description"><strong>%s</strong>: %s</p></div>',
135
- __('Preview of your Skype button', 'wpv-views'),
136
- __('*Hover over to see the menu', 'wpv-views'),
137
- __('Note', 'wpv-views'),
138
- __('Skype button background is transparent and will work on any colour backgrounds.', 'wpv-views')
139
- ),
140
- );
141
- $form['options-open'] = array(
142
- '#type' => 'markup',
143
- '#markup' => '<div class="main">',
144
- );
145
- $form['skypename'] = array(
146
- '#type' => 'textfield',
147
- '#name' => 'skype[name]',
148
- '#attributes' => array(
149
- 'class' => 'js-wpt-skypename-popup js-wpt-skype',
150
- 'data-skype-field-name' => 'skypename',
151
- ),
152
- '#before' => sprintf('<h3>%s</h2>', __( 'Enter your Skype Name', 'wpv-views' )),
153
- );
154
- $form['skype-action'] = array(
155
- '#type' => 'checkboxes',
156
- '#name' => 'skype[action]',
157
- '#options' => array(
158
- 'call' => array(
159
- '#name' => 'skype[action][call]',
160
- '#value' => 'call',
161
- '#title' => __('Call', 'wpv-views'),
162
- '#description' => __('Start a call with just a click.', 'wpv-views'),
163
- '#default_value' => 'call',
164
- '#attributes' => array(
165
- 'class' => 'js-wpt-skype js-wpt-skype-action js-wpt-skype-action-call',
166
- 'data-skype-field-name' => 'action',
167
- ),
168
- ),
169
- 'chat' => array(
170
- '#name' => 'skype[action][chat]',
171
- '#title' => __('Chat', 'wpv-views'),
172
- '#value' => 'chat',
173
- '#description' => __('Start the conversation with an instant message.', 'wpv-views'),
174
- '#attributes' => array(
175
- 'class' => 'js-wpt-skype js-wpt-skype-action js-wpt-skype-action-chat',
176
- 'data-skype-field-name' => 'action',
177
- ),
178
- ),
179
- ),
180
- '#before' => sprintf('<h3>%s</h3>', __( "Choose what you'd like your button to do", 'wpv-views' )),
181
- );
182
-
183
- $form['skype-color-header'] = array(
184
- '#type' => 'markup',
185
- '#markup' => sprintf('<h3>%s</h3>', __( 'Choose how you want your button to look', 'wpv-views' )),
186
- );
187
-
188
- $form['skype-color'] = array(
189
- '#type' => 'select',
190
- '#name' => 'skype[color]',
191
- '#options' => array(
192
- array(
193
- '#value' => 'blue',
194
- '#title' => __('Blue', 'wpv-views'),
195
- '#attributes' => array(
196
- 'data-skype-field-name' => 'color',
197
- 'class' => 'js-wpt-skype',
198
- ),
199
- ),
200
- array(
201
- '#value' => 'white',
202
- '#title' => __('White', 'wpv-views'),
203
- '#attributes' => array(
204
- 'data-skype-field-name' => 'color',
205
- 'class' => 'js-wpt-skype',
206
- ),
207
- ),
208
- ),
209
- '#default_value' => 'blue',
210
- '#attributes' => array(
211
- 'class' => 'js-wpt-skype js-wpt-skype-color'
212
- ),
213
- '#inline' => true,
214
- );
215
- $form['skype-size'] = array(
216
- '#type' => 'select',
217
- '#name' => 'skype[size]',
218
- '#options' => array(),
219
- '#default_value' => 32,
220
- '#attributes' => array(
221
- 'class' => 'js-wpt-skype js-wpt-skype-size'
222
- ),
223
- '#inline' => true,
224
- );
225
- foreach( array(10,12,14,16,24,32) as $size ) {
226
- $form['skype-size']['#options'][] = array(
227
- '#value' => $size,
228
- '#title' => sprintf('%dpx', $size),
229
- '#attributes' => array(
230
- 'data-skype-field-name' => 'size',
231
- 'class' => 'js-wpt-skype',
232
- ),
233
- );
234
- }
235
- $form['options-close'] = array(
236
- '#type' => 'markup',
237
- '#markup' => '</div>',
238
- );
239
-
240
- $form['submit'] = array(
241
- '#type' => 'button',
242
- '#name' => 'skype[submit]',
243
- '#attributes' => array(
244
- 'class' => 'button-secondary js-wpt-close-thickbox',
245
- ),
246
- '#value' => __( 'Save', 'wpv-views' ),
247
- );
248
-
249
- $form['full-close'] = array(
250
- '#type' => 'markup',
251
- '#markup' => '</div></div>',
252
- );
253
-
254
- $theForm = new Enlimbo_Forms( __FUNCTION__ );
255
- $theForm->autoHandle( __FUNCTION__, $form);
256
- echo $theForm->renderElements($form);
257
- }
258
-
259
- public function editform( $config = null ) {
260
-
261
- }
262
-
263
- public function mediaEditor(){
264
- return array();
265
- }
266
-
267
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.submit.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- *
5
- */
6
- require_once 'class.textfield.php';
7
-
8
- class WPToolset_Field_Submit extends WPToolset_Field_Textfield
9
- {
10
-
11
- public function metaform()
12
- {
13
- $attributes = $this->getAttr();
14
-
15
- $metaform = array();
16
- $metaform[] = array(
17
- '#type' => 'submit',
18
- '#title' => $this->getTitle(),
19
- '#description' => $this->getDescription(),
20
- '#name' => $this->getName(),
21
- '#value' => esc_attr(__($this->getValue(), 'wpv-views')),
22
- '#validate' => $this->getValidationData(),
23
- '#attributes' => array(
24
- 'class' => '',
25
- ),
26
- );
27
- if (array_key_exists( 'class', $attributes )) {
28
- $metaform[0]['#attributes']['class'] = $attributes['class'];
29
- }
30
- if ( array_key_exists( 'use_bootstrap', $this->_data ) && $this->_data['use_bootstrap'] ) {
31
- $metaform[0]['#attributes']['class'] .= ' btn btn-primary';
32
- }
33
- $this->set_metaform($metaform);
34
- return $metaform;
35
- }
36
-
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.taxonomy.php DELETED
@@ -1,219 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
-
8
- require_once 'class.textfield.php';
9
-
10
- class WPToolset_Field_Taxonomy extends WPToolset_Field_Textfield
11
- {
12
- public $values = "";
13
- public $objValues;
14
-
15
- public function init() {
16
- $this->objValues = array();
17
-
18
- $terms = wp_get_post_terms(CredForm::$current_postid, $this->getName(), array("fields" => "all"));
19
- $i = 0;
20
- foreach ($terms as $n => $term) {
21
- $this->values .= ($i==0) ? $term->slug : ",".$term->slug;
22
- $this->objValues[$term->slug] = $term;
23
- $i++;
24
- }
25
-
26
- add_action( 'wp_footer', array($this, 'javascript_autocompleter') );
27
- }
28
-
29
- public function javascript_autocompleter() {
30
- echo '<script type="text/javascript">
31
- jQuery(document).ready(function() {
32
- initTaxonomies("'. $this->values .'", "'.$this->getName().'", "'.WPTOOLSET_FORMS_RELPATH.'", "'.$this->_nameField.'");
33
- });
34
- </script>';
35
- }
36
-
37
- public function metaform()
38
- {
39
- $use_bootstrap = array_key_exists( 'use_bootstrap', $this->_data ) && $this->_data['use_bootstrap'];
40
- $attributes = $this->getAttr();
41
- $taxonomy = $this->getName();
42
-
43
- $metaform = array();
44
- $metaform[] = array(
45
- '#type' => 'hidden',
46
- '#title' => '',
47
- '#description' => '',
48
- '#name' => $taxonomy,
49
- '#value' => $this->values,
50
- '#attributes' => array(
51
-
52
- ),
53
- '#validate' => $this->getValidationData(),
54
- );
55
- $metaform[] = array(
56
- '#type' => 'textfield',
57
- '#title' => '',
58
- '#description' => '',
59
- '#name' => "tmp_".$taxonomy,
60
- '#value' => $this->getValue(),
61
- '#attributes' => array(
62
- 'data-taxonomy' => $taxonomy,
63
- 'data-taxtype' => 'flat',
64
- 'class' => $use_bootstrap ? 'inline wpt-new-taxonomy-title js-wpt-new-taxonomy-title' : 'wpt-new-taxonomy-title js-wpt-new-taxonomy-title',
65
- ),
66
- '#validate' => $this->getValidationData(),
67
- '#before' => $use_bootstrap ? '<div class="form-group">' : '',
68
- );
69
-
70
- /**
71
- * add button
72
- */
73
- $metaform[] = array(
74
- '#type' => 'button',
75
- '#title' => '',
76
- '#description' => '',
77
- '#name' => "new_tax_button_".$taxonomy,
78
- '#value' => apply_filters('toolset_button_add_text', esc_attr( $attributes['add_text'] )),
79
- '#attributes' => array(
80
- 'class' => $use_bootstrap ? 'btn btn-default wpt-taxonomy-add-new js-wpt-taxonomy-add-new' : 'wpt-taxonomy-add-new js-wpt-taxonomy-add-new',
81
- 'data-taxonomy' => $taxonomy,
82
- ),
83
-
84
- '#validate' => $this->getValidationData(),
85
- '#after' => $use_bootstrap ? '</div>' : '',
86
- );
87
-
88
- $before = sprintf(
89
- '<div class="tagchecklist tagchecklist-%s"></div>',
90
- $this->getName()
91
- );
92
- $after = $this->getMostPopularTerms();
93
- if ( $use_bootstrap ) {
94
- $before = '<div class="form-group">'.$before;
95
- $after .= '</div>';
96
- }
97
- $show = isset($attributes['show_popular']) && $attributes['show_popular'] == 'true';
98
- /**
99
- * show popular button
100
- */
101
- $metaform[] = array(
102
- '#type' => 'button',
103
- '#title' => '',
104
- '#description' => '',
105
- '#name' => "sh_".$taxonomy,
106
- '#value' => apply_filters('toolset_button_show_popular_text', esc_attr( $attributes['show_popular_text'] )),
107
- '#attributes' => array(
108
- 'class' => $use_bootstrap ? 'btn btn-default popular wpt-taxonomy-popular-show-hide js-wpt-taxonomy-popular-show-hide' : 'popular wpt-taxonomy-popular-show-hide js-wpt-taxonomy-popular-show-hide',
109
- 'data-taxonomy' => $this->getName(),
110
- 'data-show-popular-text' => apply_filters('toolset_button_show_popular_text', esc_attr( $attributes['show_popular_text'] )),
111
- 'data-hide-popular-text' => apply_filters('toolset_button_hide_popular_text', esc_attr( $attributes['hide_popular_text'] )),
112
- 'data-after-selector' => 'js-show-popular-after',
113
- 'style' => $show ? '' : 'display:none;'
114
- ),
115
- '#before' => $before,
116
- '#after' => $after,
117
- );
118
-
119
- $this->set_metaform($metaform);
120
- return $metaform;
121
- }
122
-
123
- private function buildTerms($obj_terms) {
124
- $tax_terms=array();
125
- foreach ($obj_terms as $term)
126
- {
127
- $tax_terms[]=array(
128
- 'name'=>$term->name,
129
- 'count'=>$term->count,
130
- 'parent'=>$term->parent,
131
- 'term_taxonomy_id'=>$term->term_taxonomy_id,
132
- 'term_id'=>$term->term_id
133
- );
134
- }
135
- return $tax_terms;
136
- }
137
-
138
- private function buildCheckboxes($index, &$childs, &$names)
139
- {
140
- if (isset($childs[$index]))
141
- {
142
- foreach ($childs[$index] as $tid)
143
- {
144
- $name = $names[$tid];
145
- ?>
146
- <div style='position:relative;line-height:0.9em;margin:2px 0;<?php if ($tid!=0) echo 'margin-left:15px'; ?>' class='myzebra-taxonomy-hierarchical-checkbox'>
147
- <label class='myzebra-style-label'><input type='checkbox' name='<?php echo $name; ?>' value='<?php echo $tid; ?>' <?php if (isset($values[$tid])) echo 'checked="checked"'; ?> /><span class="myzebra-checkbox-replace"></span>
148
- <span class='myzebra-checkbox-label-span' style='position:relative;font-size:12px;display:inline-block;margin:0;padding:0;margin-left:15px'><?php echo $names[$tid]; ?></span></label>
149
- <?php
150
- if (isset($childs[$tid]))
151
- echo $this->buildCheckboxes($tid,$childs,$names);
152
- ?>
153
- </div>
154
- <?php
155
- }
156
- }
157
- }
158
-
159
- public function getMostPopularTerms()
160
- {
161
- $use_bootstrap = array_key_exists( 'use_bootstrap', $this->_data ) && $this->_data['use_bootstrap'];
162
-
163
- $term_args = array(
164
- 'number' => 10,
165
- 'orderby' => 'count',
166
- 'order' => 'DESC'
167
- );
168
- $terms = get_terms(array($this->getName()), $term_args);
169
- if ( empty( $terms ) ) {
170
- return '';
171
- }
172
- $max = -1;
173
- $min = PHP_INT_MAX;
174
- foreach($terms as $term) {
175
- if ( $term->count < $min ) {
176
- $min = $term->count;
177
- }
178
- if ( $term->count > $max ) {
179
- $max = $term->count;
180
- }
181
- }
182
- $add_sizes = $max > $min;
183
-
184
- if ( $use_bootstrap ) {
185
- $content = sprintf(
186
- '<div class="shmpt-%s form-group wpt-taxonomy-show-popular-list js-show-popular-after" style="display:none">',
187
- $this->getName()
188
- );
189
- } else {
190
- $content = sprintf(
191
- '<div class="shmpt-%s wpt-taxonomy-show-popular-list js-show-popular-after" style="display:none">',
192
- $this->getName()
193
- );
194
- }
195
-
196
- foreach($terms as $term) {
197
- $style = '';
198
- if ( $add_sizes ) {
199
- $font_size = ( ( $term->count - $min ) * 10 ) / ( $max - $min ) + 8;
200
- $style = sprintf( ' style="font-size:%fem;"', $font_size/10 );
201
- }
202
- $clases = array('wpt-taxonomy-popular-add', 'js-wpt-taxonomy-popular-add');
203
- $clases[] = 'tax-'.$term->slug;
204
- $clases[] = 'taxonomy-'.$this->getName().'-'.$term->term_id;
205
- $content .= sprintf(
206
- '<a href="#" class="%s" data-slug="%s" data-name="%s" data-taxonomy="%s"%s>%s</a> ',
207
- implode(' ', $clases ),
208
- $term->slug,
209
- $term->name,
210
- $this->getName(),
211
- $style,
212
- $term->name
213
- );
214
- }
215
- $content .= "</div>";
216
- return $content;
217
- }
218
-
219
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
embedded/common/toolset-forms/classes/class.taxonomyhierarchical.php DELETED
@@ -1,338 +0,0 @@
1
- <?php
2
-
3
- /**
4
- *
5
- *
6
- */
7
- include_once 'class.textfield.php';
8
-
9
- class WPToolset_Field_Taxonomyhierarchical extends WPToolset_Field_Textfield {
10
-
11
- protected $child;
12
- protected $names;
13
- protected $values = array();
14
- protected $valuesId = array();
15
- protected $objValues;
16
-
17
- public function init() {
18
- global $post;
19
-
20
- $this->objValues = array();
21
- if (isset($post)) {
22
- $terms = wp_get_post_terms($post->ID, $this->getName(), array("fields" => "all"));
23
- foreach ($terms as $n => $term) {
24
- $this->values[] = $term->slug;
25
- $this->valuesId[] = $term->term_id;
26
- $this->objValues[$term->slug] = $term;
27
- }
28
- }
29
-
30
- $all = $this->buildTerms(get_terms($this->getName(), array('hide_empty' => 0, 'fields' => 'all')));
31
-
32
-
33
-
34
- $childs = array();
35
- $names = array();
36
- foreach ($all as $term) {
37
- $names[$term['term_id']] = $term['name'];
38
- if (!isset($childs[$term['parent']]) || !is_array($childs[$term['parent']]))
39
- $childs[$term['parent']] = array();
40
- $childs[$term['parent']][] = $term['term_id'];
41
- }
42
-
43
- // ksort($childs);
44
-
45
- $this->childs = $childs;
46
- $this->names = $names;
47
- }
48
-
49
- public function enqueueScripts() {
50
-
51
- }
52
-
53
- public function enqueueStyles() {
54
-
55
- }
56
-
57
- public function metaform() {
58
- $use_bootstrap = array_key_exists('use_bootstrap', $this->_data) && $this->_data['use_bootstrap'];
59
- $attributes = $this->getAttr();
60
- $taxname = $this->getName();
61
- $res = '';
62
- $metaform = array();
63
- $build_what = '';
64
-
65
- if (array_key_exists('display', $this->_data) && 'select' == $this->_data['display']) {
66
- $metaform = $this->buildSelect();
67
- $build_what = 'select';
68
- } else {
69
- $res = $this->buildCheckboxes(0, $this->childs, $this->names, $metaform);
70
- $this->set_metaform($res);
71
- $build_what = 'checkboxes';
72
- }
73
-
74
- /**
75
- * TODO
76
- *
77
- * Use this to get the taxonomy labels for the "Add new" event
78
- *
79
- * $taxobject = get_taxonomy( $taxname );
80
- */
81
- /**
82
- * "Add new" button
83
- */
84
- $metaform[] = array(
85
- '#type' => 'button',
86
- '#title' => '',
87
- '#description' => '',
88
- '#name' => "btn_" . $taxname,
89
- '#value' => apply_filters('toolset_button_add_new_text', esc_attr($attributes['add_new_text'])),
90
- '#attributes' => array(
91
- 'style' => 'display:none;',
92
- 'data-taxonomy' => $taxname,
93
- 'data-build_what' => $build_what,
94
- 'data-after-selector' => 'js-wpt-hierarchical-taxonomy-add-new-' . $taxname,
95
- 'data-open' => apply_filters('toolset_button_add_new_text', esc_attr($attributes['add_new_text'])),
96
- 'data-close' => apply_filters('toolset_button_cancel_text', esc_attr(__('Cancel', 'wpv-views'))), // TODO adjust the button value depending on open/close action
97
- 'class' => $use_bootstrap ? 'btn btn-default wpt-hierarchical-taxonomy-add-new-show-hide js-wpt-hierarchical-taxonomy-add-new-show-hide' : 'wpt-hierarchical-taxonomy-add-new-show-hide js-wpt-hierarchical-taxonomy-add-new-show-hide',
98
- ),
99
- '#validate' => $this->getValidationData(),
100
- );
101
-
102
- // Input for new taxonomy
103
-
104
- if ($use_bootstrap) {
105
- $container = '<div style="display:none" class="form-group wpt-hierarchical-taxonomy-add-new js-wpt-hierarchical-taxonomy-add-new-' . $taxname . '" data-taxonomy="' . $taxname . '">';
106
- } else {
107
- $container = '<div style="display:none" class="wpt-hierarchical-taxonomy-add-new js-wpt-hierarchical-taxonomy-add-new-' . $taxname . '" data-taxonomy="' . $taxname . '">';
108
- }
109
-
110
- /**
111
- * The textfield input
112
- */
113
- $metaform[] = array(
114
- '#type' => 'textfield',
115
- '#title' => '',
116
- '#description' => '',
117
- '#name' => "new_tax_text_" . $taxname,
118
- '#value' => '',
119
- '#attributes' => array(
120
- 'data-taxonomy' => $taxname,
121
- 'data-taxtype' => 'hierarchical',
122
- 'class' => $use_bootstrap ? 'inline wpt-new-taxonomy-title js-wpt-new-taxonomy-title' : 'wpt-new-taxonomy-title js-wpt-new-taxonomy-title',
123
- ),
124
- '#validate' => $this->getValidationData(),
125
- '#before' => $container,
126
- );
127
-
128
- /**
129
- * The select for parent
130
- */
131
- $metaform[] = array(
132
- '#type' => 'select',
133
- '#title' => '',
134
- '#options' => array(array(
135
- '#title' => $attributes['parent_text'],
136
- '#value' => -1,
137
- )),
138
- '#default_value' => 0,
139
- '#description' => '',
140
- '#name' => "new_tax_select_" . $taxname,
141
- '#attributes' => array(
142
- 'data-parent-text' => $attributes['parent_text'],
143
- 'data-taxonomy' => $taxname,
144
- 'class' => 'js-taxonomy-parent wpt-taxonomy-parent'
145
- ),
146
- '#validate' => $this->getValidationData(),
147
- );
148
-
149
- /**
150
- * The add button
151
- */
152
- $metaform[] = array(
153
- '#type' => 'button',
154
- '#title' => '',
155
- '#description' => '',
156
- '#name' => "new_tax_button_" . $taxname,
157
- '#value' => apply_filters('toolset_button_add_text', esc_attr($attributes['add_text'])),
158
- '#attributes' => array(
159
- 'data-taxonomy' => $taxname,
160
- 'data-build_what' => $build_what,
161
- 'class' => $use_bootstrap ? 'btn btn-default wpt-hierarchical-taxonomy-add-new js-wpt-hierarchical-taxonomy-add-new' : 'wpt-hierarchical-taxonomy-add-new js-wpt-hierarchical-taxonomy-add-new',
162
- ),
163
- '#validate' => $this->getValidationData(),
164
- '#after' => '</div>',
165
- );
166
-
167
- return $metaform;
168
- }
169
-
170
- private function buildTerms($obj_terms) {
171
- $tax_terms = array();
172
- foreach ($obj_terms as $term) {
173
- $tax_terms[] = array(
174
- 'name' => $term->name,
175
- 'count' => $term->count,
176
- 'parent' => $term->parent,
177
- 'term_taxonomy_id' => $term->term_taxonomy_id,
178
- 'term_id' => $term->term_id
179
- );
180
- }
181
- return $tax_terms;
182
- }
183
-
184
- private function buildSelect() {
185
- $attributes = $this->getAttr();
186
-
187
- $multiple = !isset($attributes['single_select']) || !$attributes['single_select'];
188
-
189
- $curr_options = $this->getOptions();
190
- $values = $this->valuesId;
191
- $options = array();
192
- if ($curr_options) {
193
- foreach ($curr_options as $name => $data) {
194
- $option = array(
195
- '#value' => $name,
196
- '#title' => $data['value'],
197
- '#attributes' => array('data-parent' => $data['parent'])
198
- );
199
- if ($multiple && in_array($name, $values)) {
200
- $option['#attributes']['selected'] = '';
201
- }
202
-
203
- $options[] = $option;
204
- }
205
- }
206
-
207
- /**
208
- * default_value
209
- */
210
- $default_value = null;
211
- if (count($this->valuesId)) {
212
- $default_value = $this->valuesId[0];
213
- }
214
- /**
215
- * form settings
216
- */
217
- $form = array();
218
- $select = array(
219
- '#type' => 'select',
220
- '#title' => $this->getTitle(),
221
- '#description' => $this->getDescription(),
222
- '#name' => $this->getName() . '[]',
223
- '#options' => $options,
224
- '#default_value' => isset($data['default_value']) && !empty($data['default_value']) ? $data['default_value'] : $default_value,
225
- '#validate' => $this->getValidationData(),
226
- '#class' => 'form-inline',
227
- '#repetitive' => $this->isRepetitive(),
228
- );
229
-
230
- if ($multiple) {
231
- $select['#attributes'] = array('multiple' => 'multiple');
232
- }
233
-
234
- if (count($options) == 0) {
235
- if (isset($select['#attributes'])) {
236
- $select['#attributes']['style'] = 'display:none';
237
- } else {
238
- $select['#attributes'] = array('style' => '