Business Directory Plugin - Version 5.0

Version Description

Download this release

Release Info

Developer businessdirectoryplugin
Plugin Icon 128x128 Business Directory Plugin
Version 5.0
Comparing to
See all releases

Code changes from version 4.1.15 to 5.0

Files changed (117) hide show
  1. README.TXT +35 -3
  2. assets/css/admin-csv-import.min.css +1 -1
  3. assets/css/admin-listing-metabox.min.css +1 -1
  4. assets/css/admin-listing-timeline.min.css +1 -0
  5. assets/css/admin-manual-upgrade.min.css +1 -0
  6. assets/css/admin.min.css +1 -1
  7. assets/css/less/admin-csv-import.less +53 -0
  8. assets/css/less/admin-fees.less +185 -0
  9. assets/css/less/admin-listing-metabox.less +122 -44
  10. assets/css/less/admin-listing-timeline.less +80 -0
  11. assets/css/less/admin-manual-upgrade.less +49 -0
  12. assets/css/less/admin-payments.less +129 -0
  13. assets/css/less/admin-settings.less +338 -0
  14. assets/css/less/admin.less +93 -379
  15. assets/css/less/checkout.less +112 -0
  16. assets/css/less/common.less +14 -0
  17. assets/css/less/form-fields.less +147 -0
  18. assets/css/less/login.less +25 -0
  19. assets/css/less/plan-selection.less +144 -0
  20. assets/css/less/submit-listing.less +278 -0
  21. assets/css/less/wpbdp-legacy.less +2 -1
  22. assets/css/less/wpbdp.less +110 -270
  23. assets/css/wpbdp.min.css +1 -1
  24. assets/images/default.png +0 -0
  25. assets/js/admin-export.js +1 -1
  26. assets/js/admin-fees.js +135 -0
  27. assets/js/admin-fees.min.js +1 -0
  28. assets/js/admin-listing-metabox.js +106 -0
  29. assets/js/admin-listing-metabox.min.js +1 -0
  30. assets/js/admin-manual-upgrade.js +55 -3
  31. assets/js/admin-manual-upgrade.min.js +1 -1
  32. assets/js/admin-payments.js +64 -0
  33. assets/js/admin-payments.min.js +1 -0
  34. assets/js/admin-settings.js +268 -0
  35. assets/js/admin-settings.min.js +1 -0
  36. assets/js/admin.js +128 -454
  37. assets/js/admin.min.js +1 -1
  38. assets/js/checkout.js +59 -0
  39. assets/js/checkout.min.js +1 -0
  40. assets/js/submit-listing.js +454 -8
  41. assets/js/submit-listing.min.js +1 -1
  42. assets/js/wpbdp.js +62 -20
  43. assets/js/wpbdp.min.js +1 -1
  44. business-directory-plugin.php +38 -1646
  45. includes/admin/admin-pages.php +67 -9
  46. includes/admin/class-admin-controller.php +88 -0
  47. includes/admin/class-admin-csv.php +54 -0
  48. includes/admin/class-admin-listings.php +256 -175
  49. includes/admin/class-admin.php +300 -396
  50. includes/admin/class-csv-exporter.php +57 -86
  51. includes/admin/class-csv-import.php +27 -102
  52. includes/admin/class-listing-fields-metabox.php +19 -6
  53. includes/admin/class-themes-admin.php +31 -171
  54. includes/admin/csv-export.php +2 -7
  55. includes/admin/csv-import.php +4 -28
  56. includes/admin/fees.php +94 -82
  57. includes/admin/form-fields.php +45 -7
  58. includes/admin/helpers/class-fees-table.php +69 -47
  59. includes/admin/helpers/class-listing-information-metabox.php +55 -0
  60. includes/admin/helpers/class-listing-timeline.php +117 -0
  61. includes/admin/helpers/class-payments-table.php +167 -0
  62. includes/admin/helpers/class-variable-pricing-configurator.php +49 -0
  63. includes/admin/helpers/listing-metabox.php +0 -119
  64. includes/admin/index.php +2 -1
  65. includes/admin/page-debug.php +15 -7
  66. includes/admin/payments.php +91 -18
  67. includes/admin/settings/class-settings-admin.php +532 -0
  68. includes/admin/settings/class-settings-bootstrap.php +1106 -0
  69. includes/admin/settings/class-settings.php +399 -1400
  70. includes/admin/upgrades/class-installer-installation-error.php +28 -0
  71. includes/admin/upgrades/class-manual-upgrade-helper.php +180 -0
  72. includes/admin/upgrades/class-migration.php +41 -0
  73. includes/admin/upgrades/migrations/manual-upgrade-18_0-featured-levels.php +309 -0
  74. includes/admin/upgrades/migrations/migration-11_0.php +9 -0
  75. includes/admin/upgrades/migrations/migration-12_0.php +9 -0
  76. includes/admin/upgrades/migrations/migration-13_0.php +13 -0
  77. includes/admin/upgrades/migrations/migration-17_0.php +99 -0
  78. includes/admin/upgrades/migrations/migration-18_0.php +545 -0
  79. includes/admin/upgrades/migrations/migration-18_1.php +12 -0
  80. includes/admin/upgrades/migrations/migration-2_0.php +27 -0
  81. includes/admin/upgrades/migrations/migration-2_1.php +72 -0
  82. includes/admin/upgrades/migrations/migration-2_2.php +12 -0
  83. includes/admin/upgrades/migrations/migration-2_3.php +51 -0
  84. includes/admin/upgrades/migrations/migration-2_4.php +18 -0
  85. includes/admin/upgrades/migrations/migration-2_5.php +45 -0
  86. includes/admin/upgrades/migrations/migration-3_1.php +13 -0
  87. includes/admin/upgrades/migrations/migration-3_2.php +81 -0
  88. includes/admin/upgrades/migrations/migration-3_4.php +12 -0
  89. includes/admin/upgrades/migrations/migration-3_5.php +11 -0
  90. includes/admin/upgrades/migrations/migration-3_6.php +16 -0
  91. includes/admin/upgrades/migrations/migration-3_7.php +194 -0
  92. includes/admin/upgrades/migrations/migration-3_9.php +18 -0
  93. includes/admin/upgrades/migrations/migration-4_0.php +14 -0
  94. includes/admin/upgrades/migrations/migration-5_0.php +132 -0
  95. includes/admin/upgrades/migrations/migration-6_0.php +12 -0
  96. includes/admin/upgrades/migrations/migration-7_0.php +30 -0
  97. includes/admin/upgrades/migrations/migration-8_0.php +10 -0
  98. includes/class-assets.php +153 -0
  99. includes/class-cpt-integration.php +242 -0
  100. includes/class-cron.php +19 -0
  101. includes/class-dispatcher.php +52 -3
  102. includes/class-fee-plan.php +250 -89
  103. includes/class-fees-api.php +47 -8
  104. includes/class-gateway.php +0 -163
  105. includes/class-listing-email-notification.php +161 -0
  106. includes/class-listing-expiration.php +67 -0
  107. includes/class-listing-subscription.php +173 -0
  108. includes/class-listing-upgrade-api.php +0 -224
  109. includes/class-listing.php +506 -457
  110. includes/class-listings-api.php +19 -721
  111. includes/class-meta.php +405 -0
  112. includes/class-module.php +53 -0
  113. includes/class-modules.php +65 -0
  114. includes/class-payment-gateway.php +137 -0
  115. includes/class-payment-gateways.php +134 -0
  116. includes/class-payment.php +183 -406
  117. includes/class-query-integration.php +112 -13
README.TXT CHANGED
@@ -4,9 +4,9 @@ Donate link: http://businessdirectoryplugin.com/premium-modules/
4
  Tags: business directory, directory plugin, company business directory, chamber of commerce business directory, church directory, address book, contact directory, custom business directory, local business directory, listings directory, link directory, member directory, staff directory
5
  Requires at least: 4.3
6
  Requires PHP: 5.6
7
- Tested up to: 4.8.1
8
- Last Updated: 2017-Sep-19
9
- Stable tag: 4.1.15
10
  License: GPLv2 or later
11
 
12
  Build any kind of local directory, directory of business providers, a Yellow-Pages business directory, Yelp-like review directory and much more!
@@ -144,6 +144,38 @@ If you are having problems please visit [support forum](http://www.businessdirec
144
 
145
  == Changelog ==
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  = Version 4.1.15 =
148
  * Fix 404 Not Found error for categories URLs that occurred when WPML was installed and configured to use a query parameter to define the language of the website.
149
  * Empty strings are not allowed as categories and tags slugs.
4
  Tags: business directory, directory plugin, company business directory, chamber of commerce business directory, church directory, address book, contact directory, custom business directory, local business directory, listings directory, link directory, member directory, staff directory
5
  Requires at least: 4.3
6
  Requires PHP: 5.6
7
+ Tested up to: 4.8.2
8
+ Last Updated: 2017-Oct-24
9
+ Stable tag: 5.0
10
  License: GPLv2 or later
11
 
12
  Build any kind of local directory, directory of business providers, a Yellow-Pages business directory, Yelp-like review directory and much more!
144
 
145
  == Changelog ==
146
 
147
+ = Version 5.0 =
148
+ * Added support for new fee plan pricing models: flat price, category-based, base + extra amount per category
149
+ * Added a new Payments screen to manage all payments.
150
+ * When sorting listings using the paid/free option, the paid amount is now taken into consideration.
151
+ * Completely redesigned category and fee plan selection.
152
+ * Listing statuses and attributes have been redesigned for improved UX on the backend.
153
+ * Listing expiration date is now shown as a column on the backend.
154
+ * Listings submitted by anonymous users can now be edited/renewed using Access Keys.
155
+ * Added support for creating an account during listing submit.
156
+ * Listing now have just one fee plan associated to them instead of one per category
157
+ * Listing renewal now keeps the featured flag. (#634)
158
+ * Listings can now have different background colors depending on their fee plan.
159
+ * Added normalized CSS classes and IDs for listing views.
160
+ * Redesigned listing information metabox.
161
+ * Completely redesigned listing submit workflow using AJAX.
162
+ * Added a "Timeline" metabox on the backend to clearly see a listing's history.
163
+ * Admins can now create any number of listing expiration/reminder notices.
164
+ * Simplify how premium modules integrate into BD.
165
+ * Added businessdirectory-quick-search shortcode to display the Quick Search form.
166
+ * Added warning when reaching the image limit during listing submit/edit.
167
+ * Allow users to edit categories for their listing if the plan allows it.
168
+ * Added option to sort listings using the configured sort for their fee plans.
169
+ * Added several hooks to allow adding content during the submit process and in other templates.
170
+ * Allow admins to mark some fields as required for searching.
171
+ * Added a more reliable cron implementation for scheduled events.
172
+ * Refreshed the Settings API implementation to increase speed, reduce queries and add validation support.
173
+ * Redesigned the settings screen for better UX.
174
+ * Increased reliability of upgrades.
175
+ * Added a new log mechanism for better debugging.
176
+ * Updated the premium module initialization API.
177
+ * License and update checking has been merged to cover both themes and premium modules, reducing external requests.
178
+
179
  = Version 4.1.15 =
180
  * Fix 404 Not Found error for categories URLs that occurred when WPML was installed and configured to use a query parameter to define the language of the website.
181
  * Empty strings are not allowed as categories and tags slugs.
assets/css/admin-csv-import.min.css CHANGED
@@ -1 +1 @@
1
- #wpbdp-csv-import-fatal-error{display:none}#wpbdp-csv-import-fatal-error .last-imported-line .placeholder{font-weight:bold}.wpbdp-page-csv-import .canceled-import{display:none}.wpbdp-page-csv-import a.cancel-import{margin-left:35px;color:red}.wpbdp-page-csv-import dl{margin-left:10px}.wpbdp-page-csv-import .status-msg{margin:5px 0 0 0;font-style:italic}.wpbdp-page-csv-import #wpbdp-csv-import-summary,.wpbdp-page-csv-import #wpbdp-csv-import-summary .no-warnings,.wpbdp-page-csv-import #wpbdp-csv-import-summary .with-warnings,.wpbdp-page-csv-import #wpbdp-csv-import-summary .wpbdp-csv-import-warnings{display:none}.wpbdp-page-csv-import .wpbdp-csv-import-warnings .col-line-no{width:40px}.wpbdp-page-csv-import .wpbdp-csv-import-warnings tbody .col-line-content{font-family:monospace;font-size:90%;width:350px;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-local-selection{margin:10px 0 0 0}.file-local-selection ul{margin-left:5px;border-left:solid 3px #ddd;padding-left:10px;display:none}.file-local-selection ul li{margin:0;padding:0}
1
+ #wpbdp-csv-import-fatal-error{display:none}#wpbdp-csv-import-fatal-error .last-imported-line .placeholder{font-weight:bold}.wpbdp-page-csv-import .canceled-import{display:none}.wpbdp-page-csv-import a.cancel-import{margin-left:35px;color:red}.wpbdp-page-csv-import dl{margin-left:10px}.wpbdp-page-csv-import .status-msg{margin:5px 0 0 0;font-style:italic}.wpbdp-page-csv-import #wpbdp-csv-import-summary,.wpbdp-page-csv-import #wpbdp-csv-import-summary .no-warnings,.wpbdp-page-csv-import #wpbdp-csv-import-summary .with-warnings,.wpbdp-page-csv-import #wpbdp-csv-import-summary .wpbdp-csv-import-warnings{display:none}.wpbdp-page-csv-import .wpbdp-csv-import-warnings .col-line-no{width:40px}.wpbdp-page-csv-import .wpbdp-csv-import-warnings tbody .col-line-content{font-family:monospace;font-size:90%;width:350px;display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-local-selection{margin:10px 0 0 0}.file-local-selection ul{margin-left:5px;border-left:solid 3px #ddd;padding-left:10px;display:none}.file-local-selection ul li{margin:0;padding:0}.wpbdp-csv-import-example{width:100%;padding:10px;display:block;background:#fff;border:solid 1px #ddd;font-size:90%;font-family:monospace;height:100%;white-space:pre}#wpbdp-csv-import-form input[type="file"]{border:none}table.wpbdp-csv-import-results,table.wpbdp-csv-import-warnings{width:100%}table.wpbdp-csv-import-results .line-no,table.wpbdp-csv-import-warnings .line-no{width:50px}table.wpbdp-csv-import-results td.line,table.wpbdp-csv-import-warnings td.line{font-family:monospace;font-size:90%}table.wpbdp-csv-import-results .error,table.wpbdp-csv-import-warnings .error{width:200px}table.wpbdp-csv-import-headers{width:100%}table.wpbdp-csv-import-headers td.field-is-required,table.wpbdp-csv-import-headers td.field-is-multivalued{text-align:center}table.wpbdp-csv-import-headers tbody tr{background:#f9f9f9}table.wpbdp-csv-import-headers tbody tr.alt{background:inherit}.wpbdp-csv-import-top-buttons{float:right}
assets/css/admin-listing-metabox.min.css CHANGED
@@ -1 +1 @@
1
- #BusinessDirectory_listinginfo .inside{margin:0;padding:0}.listing-metabox-tabs{display:block;border-bottom:solid 1px #ddd !important}.listing-metabox-tabs li{display:inline;padding:1px 8px;margin:0}.listing-metabox-tabs li a{text-decoration:none}.listing-metabox-tabs li.selected{background:#ddd}.listing-metabox-tabs li.selected a{color:#333}#listing-metabox-generalinfo,#listing-metabox-fees,#listing-metabox-transactions{display:none}#listing-metabox-generalinfo>strong,#listing-metabox-fees>strong,#listing-metabox-transactions>strong{display:block;margin-bottom:10px}.listing-metabox-tab .listing-categories{margin:20px 0}.listing-category{border-bottom:dotted 1px #bbb}.listing-category .header{margin-top:8px;min-height:25px}.listing-category .header .spinner{float:right;background-size:15px 15px}.listing-category .category-name{text-decoration:underline;font-weight:bold}.listing-category.expired .category-name{text-decoration:line-through underline}.listing-category .category-status{float:right}.listing-category .category-status.ok{background:green}.listing-category .category-status.pending{background:red}.listing-category .category-details{margin-left:25px}.listing-category dl{margin:0;clear:both}.listing-category dt{float:left;color:#595959;width:80px}.listing-category dd{margin-bottom:0}.listing-category .expiration-date-info .spinner{float:left}.listing-category a.expiration-change-link{float:right}.listing-category .datepicker{position:absolute;z-index:100;right:10px;font-size:80%}.listing-category .admin-actions{margin-top:10px;margin-left:25px;clear:both}.listing-category .admin-actions li{margin:0;padding:0}.listing-category .admin-actions li.delete{margin-top:10px}.listing-category .admin-actions a.category-delete{color:#ff0000}
1
+ #BusinessDirectory_listinginfo .inside{margin:0;padding:0}.listing-metabox-tabs{display:block;border-bottom:solid 1px #ddd !important}.listing-metabox-tabs li{display:inline;padding:1px 8px;margin:0}.listing-metabox-tabs li a{text-decoration:none}.listing-metabox-tabs li.selected{background:#ddd}.listing-metabox-tabs li.selected a{color:#333}#listing-metabox-generalinfo,#listing-metabox-fees,#listing-metabox-transactions{display:none}#listing-metabox-generalinfo>strong,#listing-metabox-fees>strong,#listing-metabox-transactions>strong{display:block;margin-bottom:10px}#listing-metabox-fees .listing-plan{border-bottom:dotted 1px #bbb}#listing-metabox-fees .listing-plan .plan-label{text-decoration:underline;font-weight:bold}#listing-metabox-fees .listing-plan .plan-status.ok{background:green}#listing-metabox-fees .listing-plan .plan-status.pending{background:red}#listing-metabox-fees .listing-plan .plan-details{margin-left:25px}a dl{margin:0;clear:both}#listing-metabox-fees .listing-plan dt{float:left;color:#595959;width:80px}#listing-metabox-fees .listing-plan .listing-category dd{margin-bottom:0}#listing-metabox-fees .listing-plan .spinner{text-align:center;display:block;float:none;margin:10px auto}#listing-metabox-fees .listing-plan .datepicker{position:absolute;z-index:100;right:10px;font-size:80%}#listing-metabox-fees .listing-plan .admin-actions{margin-top:10px;margin-left:25px;clear:both}#listing-metabox-fees .listing-plan .admin-actions li{margin:0;padding:0}#wpbdp-listing-metabox-payments .wpbdp-payment-item{padding:2px;border-bottom:solid 1px #efefef;clear:both;font-size:95%}#wpbdp-listing-metabox-payments .wpbdp-payment-item:first-child{margin-top:12px}#wpbdp-listing-metabox-payments .wpbdp-payment-item.wpbdp-payment-status-completed{color:green}#wpbdp-listing-metabox-payments .wpbdp-payment-item.wpbdp-payment-status-pending{color:red}#wpbdp-listing-metabox-payments .wpbdp-payment-item.wpbdp-payment-status-rejected{color:#bbb}#wpbdp-listing-metabox-payments .wpbdp-payment-item a{color:inherit}#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-item-row{clear:both}#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-date,#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-summary{float:left}#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-summary{width:150px}#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-summary a{font-size:95%}#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-status,#wpbdp-listing-metabox-payments .wpbdp-payment-item .wpbdp-payment-total{text-align:right}#wpbdp-listing-metabox-plan-info h4{margin:0 0 5px 0;font-size:85%;text-transform:uppercase}#wpbdp-listing-metabox-plan-info dl{margin:0 0 20px 10px}#wpbdp-listing-metabox-plan-info dl dd{margin-left:30px}#wpbdp-listing-metabox-plan-info .value-editor{display:none}#wpbdp-listing-metabox-plan-info .value-editor .update-value,#wpbdp-listing-metabox-plan-info .value-editor .cancel-edit{font-size:85%}#wpbdp-listing-metabox-plan-info a.edit-value-toggle{margin:0 0 0 10px;font-size:85%}
assets/css/admin-listing-timeline.min.css ADDED
@@ -0,0 +1 @@
 
1
+ #wpbdp-listing-metabox-timeline:before{position:absolute;top:0;bottom:0;left:10px;width:2px;content:"";display:block;background:#f3f3f3;height:100%;z-index:0}#wpbdp-listing-metabox-timeline:after{content:'';display:table;clear:both}#wpbdp-listing-metabox-timeline .timeline-item{display:block;padding:5px 0 5px 20px;border-bottom:1px solid #f5f5f5;margin:10px 0;position:relative}#wpbdp-listing-metabox-timeline .timeline-item .timeline-item-icon{z-index:1;float:left;width:12px;height:12px;background:#f3f3f3;border:2px solid #fff;border-radius:50%;margin-left:-28px;margin-top:1px}#wpbdp-listing-metabox-timeline .timeline-item .timeline-item-header{padding:5px 0;color:#000}#wpbdp-listing-metabox-timeline .timeline-item .timeline-item-datetime{font-size:90%;color:#767676;display:block}#wpbdp-listing-metabox-timeline .timeline-item .timeline-item-extra{font-size:90%}#wpbdp-listing-metabox-timeline .timeline-item .timeline-item-actions{font-size:80%}#wpbdp-listing-metabox-timeline .timeline-item-listing_payment .timeline-item-extra .payment-amount{float:right}#wpbdp-listing-metabox-timeline .timeline-item-listing_payment .payment-status{float:right}#wpbdp-listing-metabox-timeline .timeline-item-listing_payment .payment-status.pending{background:#ff0000}
assets/css/admin-manual-upgrade.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .wpbdp-admin-page-manual-upgrade .wpbdp-admin-content{margin:20px 0 0 0;padding:16px;background:#fff;border-radius:4px}#wpbdp-manual-upgrade-18_0-config #add-fee-form{display:none}#wpbdp-manual-upgrade-18_0-config table#fee-decisions{width:90%;border:1px solid #ccc;border-radius:3px;margin:24px auto;padding:12px}#wpbdp-manual-upgrade-18_0-config table#fee-decisions th{text-align:left;background:#efefef}#wpbdp-manual-upgrade-18_0-config table#fee-decisions th,#wpbdp-manual-upgrade-18_0-config table#fee-decisions td{padding:8px;vertical-align:top}#wpbdp-manual-upgrade-18_0-config table#fee-decisions th.level-name,#wpbdp-manual-upgrade-18_0-config table#fee-decisions td.level-name{width:200px}#wpbdp-manual-upgrade-18_0-config .option-description{color:#666;font-size:90%;margin:6px 0;display:none}#wpbdp-manual-upgrade-18_0-config .option-configuration{display:none}
assets/css/admin.min.css CHANGED
@@ -1 +1 @@
1
- .cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}span.tag{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:9px !important;margin-right:2px;text-transform:uppercase;text-decoration:none !important;line-height:1.5 !important}.button-primary.next-to-secondary{margin-left:30px}.wpbdp-admin-content.with-sidebar{margin-top:20px;clear:left;float:left;width:78%}.wpbdp-admin .sidebar{margin-top:20px;float:right;clear:right;width:20%}.wpbdp-admin .sidebar .postbox{min-width:0 !important}.wpbdp-admin .sidebar .premium-modules h3 span{color:#145200;font-weight:bold}.wpbdp-admin .sidebar .premium-modules{border-color:#0EAD00;border-width:3px;background:#FFFFCF}.wpbdp-admin .premium-modules .tag{font-size:8px !important}.wpbdp-admin .premium-modules .tag.new{background:#00A000;color: #fff}.wp-list-table tr.wpbdp-item-message-tr td{padding-top:0}.wp-list-table tr.wpbdp-item-message-tr td div{margin:0 15px;padding:6px 12px 8px 12px;background-color:#fef7f1;font-size:12px}.wpbdp-page-admin-fees .tablenav{display:none}.wpbdp-page-admin-fees .wp-list-table .wpbdp-drag-handle{margin-right:15px;display:none}.wpbdp-page-admin-fees .purchase-gateways{margin-left:20px}.wpbdp-page-admin-fees .purchase-gateways .gateway{float:left;width:35%;margin:30px 20px 0 0}.wpbdp-page-admin-fees .purchase-gateways .gateway.installed{opacity:.5}.wpbdp-page-admin-fees .purchase-gateways .gateway a img.gateway-logo{height:40px;margin:0;padding:0;border:none}.wpbdp-page-admin-fees .purchase-gateways .gateway a.price{margin-top:10px;display:block;color:green;font-size:22px;font-weight:bold}.wpbdp-page-admin-fees .purchase-gateways .gateway .check-mark{font-size:150%;font-weight:bold;color:green}td.column-payment_status .status,td.column-sticky_status .status{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:90%}td.column-payment_status .status.ok{background:green}td.column-payment_status .paymentdata{font-size:85%}td.column-payment_status .paymentdata b{font-weight:normal}td.column-payment_status .paymentdata span{font-style:italic}td.column-sticky_status .status.notpaid{background:orange}td.column-sticky_status .status.pending{background:red;font-weight:bold}td.column-sticky_status .status.sticky{background:green}table.wp-list-table td .tag{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:90%;margin-right:2px}table.wp-list-table.formfields th.column-label{width:40%}table.wp-list-table.formfields th.column-tags,table.wp-list-table.formfields td.column-tags{width:200px}table.wp-list-table.formfields th.column-order,table.wp-list-table.formfields td.column-order{width:55px}table.wp-list-table.formfields td.column-order .wpbdp-drag-handle{visibility:hidden}table.wp-list-table.formfields tr:hover .wpbdp-drag-handle{visibility:visible}table.wp-list-table.formfields .tag.required{background:orange}table.wp-list-table.formfields .tag.in-excerpt{background:green}table.wp-list-table.formfields .tag.in-listing{background:green}table.wp-list-table.formfields tr.wpbdp-draggable-highlight{height:54px}table.wp-list-table.formfields tr.ui-sortable-helper{background:#fff;border:1px dashed #c1c1c1}#wpbdp-admin-page-field-form .iframe-confirm{display:none}#wpbdp-admin-page-field-form .iframe-confirm p{font-size:90%}#wpbdp-listing-fields input[type="text"]{width:70%}#wpbdp-listing-fields .wpbdp-form-field.url .wpbdp-form-field-html{padding-left:10px}#wpbdp-listing-fields .wpbdp-form-field.url input[type="text"]{display:block}#wpbdp-listing-fields #wpbdp-uploaded-images .wpbdp-image{padding:5px;width:150px;vertical-align:top;display:inline-block;zoom:1;*display:inline;min-height:210px;_height:210px}#wpbdp-listing-fields div.listing-images .image img{max-width:150px}ul#wpbusdirmanerrors{margin-left:20px}.wpbdp-csv-import-example{width:100%;padding:10px;display:block;background:#fff;border:solid 1px #ddd;font-size:90%;font-family:monospace;height:100%;white-space:pre}#wpbdp-csv-import-form input[type="file"]{border:none}table.wpbdp-csv-import-results,table.wpbdp-csv-import-warnings{width:100%}table.wpbdp-csv-import-results .line-no,table.wpbdp-csv-import-warnings .line-no{width:50px}table.wpbdp-csv-import-results td.line,table.wpbdp-csv-import-warnings td.line{font-family:monospace;font-size:90%}table.wpbdp-csv-import-results .error,table.wpbdp-csv-import-warnings .error{width:200px}table.wpbdp-csv-import-headers{width:100%}table.wpbdp-csv-import-headers td.field-is-required,table.wpbdp-csv-import-headers td.field-is-multivalued{text-align:center}table.wpbdp-csv-import-headers tbody tr{background:#f9f9f9}table.wpbdp-csv-import-headers tbody tr.alt{background:inherit}.wpbdp-form-field.image .preview{float:none}table.wpbdp-debug-section{width:90%}table.wpbdp-debug-section tbody tr{background:#efefef}table.wpbdp-debug-section tbody tr td{padding:3px 8px}table.wpbdp-debug-section tbody tr:nth-child(2n){background:#f5f5f5}#wpbdp-admin-debug-info-page textarea.test-ssl-results{display:block;width:90%;font-family:monospace;font-size:11px;height:100px}.wpbdp-page-admin-transactions .tag{font-size:95%}.wpbdp-page-admin-transactions .tag.approved{background:green}.wpbdp-page-admin-transactions .tag.pending{background:red}.wpbdp-page-admin-transactions .column-actions a.delete{color:#bc0b0b}.wpbdp-page-admin-transactions tr.more-details-row{background:#fff}.wpbdp-page-admin-transactions tr.more-details-row td{padding-left:40px;font-size:95%}.wpbdp-page-admin-transactions tr.more-details-row td dl dt{font-weight:bold}body.taxonomy-wpbdp_category .column-id{width:35px}.transaction-status-container{text-align:right;padding:5px}.wpbdp-progress-bar .progress-bar{margin-left:10px;display:inline-block;vertical-align:middle}.wpbdp-progress-bar .progress-bar-outer{min-width:200px;height:12px;border:solid 1px #3366CC;padding:0}.wpbdp-progress-bar .progress-bar-inner{height:100%;background:#99CCFF}.wpbdp-note{padding:5px 10px;background:#d7f5ff;margin:5px 0 20px 0;border:solid 1px #bad5df;border-radius:4px}.wpbdp-note p{margin:0}.wpbdp-note h1,.wpbdp-note h2,.wpbdp-note h3,.wpbdp-note h4{margin:0 0 8px 0}.wpbdp-note.error,.wpbdp-note.warning{background-color:#FFEBE8;border-color:#C00}.directory-admin_page_wpbdp_admin_settings table.form-table th,.directory-admin_page_wpbdp_admin_settings table.form-table td{font-size:13px;line-height:1;padding:8px 20px}.directory-admin_page_wpbdp_admin_settings table.form-table th{min-width:150px}.directory-admin_page_wpbdp_admin_settings input,.directory-admin_page_wpbdp_admin_settings select{font-size:13px;line-height:1}.directory-admin_page_wpbdp_admin_settings textarea{font-size:13px;width:95%}.directory-admin_page_wpbdp_admin_settings select{display:block}.wpbdp-choices-list{margin-top:0;padding:0}.directory-admin_page_wpbdp_admin_settings .license-activation .status-message{background:none;box-shadow:none;border:none;font-size:85%;color:#595959;font-style:italic;margin:0;padding:0;-webkit-box-shadow:none}.directory-admin_page_wpbdp_admin_settings .license-activation .status-message.ok{color:green}.directory-admin_page_wpbdp_admin_settings .license-activation .status-message.error{color:red}.directory-admin_page_wpbdp_admin_settings table.form-table .license-activation-error td{padding-top:0;padding-right:0}.directory-admin_page_wpbdp_admin_settings .group-error{border-top:solid 1px red}.directory-admin_page_wpbdp_admin_settings .group-warning{border-top:solid 1px yellow}.wpbdp-notice.dismissible{position:relative}.tag.paymentstatus.ok{background:green}.tag.paymentstatus.completed{background:green}.tag.paymentstatus.pending,.tag.paymentstatus.pending-abandonment{background:red}#wpbdp-admin-settings tr.disabled{opacity:.7}#wpbdp-admin-settings .text-fields-warning{font-size:90%;display:block;margin-bottom:2px}#wpbdp-admin-settings .wpbdp-settings-email{margin:5px 0 0 0;border:solid 1px #ccc;padding:5px;background:#fff}#wpbdp-admin-settings .wpbdp-settings-email .short-preview{color:#999;font-size:90%;height:45px;cursor:pointer;overflow:hidden}#wpbdp-admin-settings .wpbdp-settings-email .short-preview h4{margin:0 0 10px 0}#wpbdp-admin-settings .wpbdp-settings-email .short-preview .edit-toggle{float:right}#wpbdp-admin-settings .wpbdp-settings-email .short-preview:hover .edit-toggle{visibility:visible}#wpbdp-admin-settings .wpbdp-settings-email .short-preview dl{margin:0;padding:0}#wpbdp-admin-settings .wpbdp-settings-email .short-preview dt{font-weight:bold;margin:0;padding:0}#wpbdp-admin-settings .wpbdp-settings-email .short-preview dd{margin:0;padding:0 0 0 10px}#wpbdp-admin-settings .wpbdp-settings-email .editor{margin-left:10px;font-size:90%}#wpbdp-admin-settings .wpbdp-settings-email .editor table.form-table{margin:0;padding:0}#wpbdp-admin-settings .wpbdp-settings-email table.form-table th{padding-left:4px;padding-right:0;min-width:0;width:20%}#wpbdp-admin-settings .wpbdp-settings-email .editor input[type="text"]{width:70%}#wpbdp-admin-settings .wpbdp-settings-email .editor textarea{width:100%;min-height:150px}#wpbdp-admin-settings .wpbdp-settings-email .editor .placeholders{margin:10px 0 0 0}#wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder{font-size:90%}#wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder-separator{margin-top:10px}#wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder .placeholder-code{font-family:monospace;font-weight:bold}#wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder .placeholder-description{font-style:italic}#wpbdp-admin-settings .wpbdp-settings-email .editor .buttons{margin:30px 0 0 0;text-align:right}#wpbdp-admin-settings .wpbdp-settings-email .editor .buttons .preview-email{float:left}#wpbdp-admin-settings .wpbdp-settings-email .editor .buttons .cancel{margin-right:10px}#quick-search-fields li{width:50%;display:inline-block}#listing-metabox-transactions table.payments-list{width:100%;border-spacing:0}#listing-metabox-transactions table.payments-list tr.payment td{border-bottom:solid 1px #efefef;padding:2px 0}#listing-metabox-transactions table.payments-list tr.payment td.status{text-align:right}#listing-metabox-transactions table.payments-list tr.payment.completed td{color:green}#listing-metabox-transactions table.payments-list tr.payment.pending td{color:red}#listing-metabox-transactions table.payments-list tr.payment.rejected td{color:#bbb}#listing-metabox-transactions table.payments-list tr.payment.canceled td{text-decoration:line-through}#listing-metabox-transactions table.payments-list tr.payment a{text-decoration:none;color:inherit}#listing-metabox-transactions table.payments-list tr.payment a:hover{text-decoration:underline}.wpbdp-payment-details .tag{float:right}.wpbdp-payment-details .details,.wpbdp-payment-details .invoice,.wpbdp-payment-details .actions{clear:both;margin:20px 0}.wpbdp-payment-details .details dl dt{font-weight:bold}.wpbdp-payment-details table.wpbdp-payment-items-table{width:100%}.wpbdp-payment-details table.wpbdp-payment-items-table th{text-transform:uppercase}.wpbdp-payment-details table.wpbdp-payment-items-table td{border-top:1px solid #bbb;padding:6px 10px 6px 0}.wpbdp-payment-details .actions a.button-primary{color:#fff !important}.listing-fee-change .fee-selection .fee{padding-bottom:5px;margin-bottom:10px;border-bottom:dotted 1px #ccc;opacity:.85}.listing-fee-change .fee-selection .fee:hover{opacity:1}.listing-fee-change .fee-selection .fee .details{margin-left:10px}.listing-fee-change .fee-selection .fee .tag{float:right}.listing-fee-change .fee-selection .fee .choose-this{float:right}.wpbdp-drag-handle{background:red;width:6px;height:10px;display:inline-block;background:url('../images/drag-handle.png') 0 0;cursor:move;float:left;margin:5px 5px 0 0;vertical-align:middle}.wpbdp-draggable-highlight{background:#bbb}.wpbdp-module-compat-check .module-info{margin-bottom:3px}.wpbdp-module-compat-check .module-info .module-version,.wpbdp-module-compat-check .module-info .module-required{color:#666}.wpbdp-module-compat-check .module-info .module-version{margin-left:15px}.wpbdp-module-compat-check .module-info .module-version b{color:#333}.wpbdp-module-compat-check .module-info .module-required b{color:#900000}.toplevel_page_wpbdp_admin .welcome-message{padding:10px;font-size:105%}.toplevel_page_wpbdp_admin .welcome-message p{font-size:inherit}.toplevel_page_wpbdp_admin .welcome-message h4{font-size:120%}.toplevel_page_wpbdp_admin .welcome-message ul{list-style-position:inside;list-style-type:disc}.toplevel_page_wpbdp_admin ul.shortcuts{margin:auto}.toplevel_page_wpbdp_admin ul.shortcuts li{float:left;margin-right:10px}.toplevel_page_wpbdp_admin ul.shortcuts li.clear{margin:0}#wpbdp-uninstall-capture-form .reasons{margin-left:15px}#wpbdp-uninstall-capture-form .reasons .reason{margin-bottom:5px}#wpbdp-uninstall-capture-form textarea{margin:10px 0 0 0;width:50%;min-height:100px;display:none}.wpbdp-license-expired-warning .module-name{background:#fff9aa;padding:0 5px;color:#000}.wpbdp-license-expired-warning .dismiss{margin-right:10px}.wp-admin.widgets-php .widget-content span.help{color:#666}
1
+ .wpbdp-tag{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:10px !important;margin-right:2px;text-decoration:none !important;line-height:1.5 !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.button-primary.next-to-secondary{margin-left:30px}.wpbdp-admin-content.with-sidebar{margin-top:20px;clear:left;float:left;width:78%}.wpbdp-admin .sidebar{margin-top:20px;float:right;clear:right;width:20%}.wpbdp-admin .sidebar .postbox{min-width:0 !important}.wpbdp-admin .sidebar .premium-modules h3 span{color:#145200;font-weight:bold}.wpbdp-admin .sidebar .premium-modules{border-color:#0EAD00;border-width:3px;background:#FFFFCF}.wpbdp-admin .premium-modules .tag{font-size:8px !important}.wpbdp-admin .premium-modules .tag.new{background:#00A000;color: #fff}.wp-list-table tr.wpbdp-item-message-tr td{padding-top:0}.wp-list-table tr.wpbdp-item-message-tr td div{margin:0 15px;padding:6px 12px 8px 12px;background-color:#fef7f1;font-size:12px}.wpbdp-admin-page-fees .tablenav{display:none}#wpbdp-admin-admin-page-fees .column-attributes .wpbdp-tag{background:green;color:#fff}.wpbdp-admin-page-fees .wp-list-table .wpbdp-drag-handle{margin-right:15px;display:none}.wpbdp-admin-page-fees .purchase-gateways{margin-left:20px}.wpbdp-admin-page-fees .purchase-gateways .gateway{float:left;width:35%;margin:30px 20px 0 0}.wpbdp-admin-page-fees .purchase-gateways .gateway.installed{opacity:.5}.wpbdp-admin-page-fees .purchase-gateways .gateway a img.gateway-logo{height:40px;margin:0;padding:0;border:none}.wpbdp-admin-page-fees .purchase-gateways .gateway a.price{margin-top:10px;display:block;color:green;font-size:22px;font-weight:bold}.wpbdp-admin-page-fees .purchase-gateways .gateway .check-mark{font-size:150%;font-weight:bold;color:green}#wpbdp-fee-form #limit-categories-list{font-size:90%}#wpbdp-fee-form #limit-categories-list p{margin:10px 0}#wpbdp-fee-form #limit-categories-list select{width:100%}#wpbdp-fee-form #limit-categories-list .select2-selection{padding:0 0 2px 0;margin:0;border-radius:5px;border-color:#ddd;min-height:26px}#wpbdp-fee-form #limit-categories-list .select2-selection__choice{border:none;padding:0;margin:2px 4px 0 0;background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:10px !important;margin-right:2px;text-decoration:none !important;line-height:1.5 !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#wpbdp-fee-form #limit-categories-list .select2-selection__choice.wpbdp-listing-attr-paid{background:green}#wpbdp-fee-form #limit-categories-list .select2-selection__choice.wpbdp-listing-attr-admin-posted{background:orange}#wpbdp-fee-form #limit-categories-list .select2-selection__choice.wpbdp-listing-attr-post-status-pending{background:blue;color:#fff}#wpbdp-fee-form #limit-categories-list .select2-selection__choice .select2-selection__choice__remove{color:#fff}#wpbdp-fee-form #limit-categories-list .select2-search{margin-bottom:0}#wpbdp-fee-form #limit-categories-list .wpbdp-category-item{width:33.33%;float:left;padding:2px 0}#wpbdp-fee-form .pricing-details-variable>td{padding-top:0}#wpbdp-fee-form .pricing-details-variable table th{font-weight:normal}#wpbdp-fee-form .pricing-details-variable table td:last-child{width:100%}#wpbdp-fee-form .pricing-details-variable table td{font-size:90%;padding:0}#wpbdp-fee-form .pricing-details-variable table td.category-name-col{padding-right:20px;text-align:right}#wpbdp-fee-form .pricing-details-variable .wpbdp-variable-pricing-configurator-row input{width:100px}#wpbdp-fee-form .pricing-options label{display:block}#wpbdp-fee-form .fee-pricing-details input[type="text"]{width:100px}#wpbdp-fee-form #fee-bgcolor-picker{position:relative}#wpbdp-fee-form #fee-bgcolor-picker input#fee-bgcolor-value{border:none;cursor:pointer}#wpbdp-fee-form #fee-bgcolor-picker .color-selection{left:5px;display:none;position:absolute;background:#fff;padding:10px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2)}#wpbdp-fee-form #fee-bgcolor-picker .color-selection-btns{margin:0 0 10px 0;font-size:12px}#wpbdp-fee-form #fee-bgcolor-picker .color-selection-btns a{text-decoration:none}#wpbdp-fee-form #fee-bgcolor-picker .color-selection-btns a.close-btn{float:right;color:#999}#wpbdp-fee-form #fee-bgcolor-picker .color-selection-btns a.reset-btn .no-color-img{background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 99 L99 0 L100 1 L1 100' fill='#ff0000' /></svg>");background-repeat:no-repeat;background-position:center center;background-size:100% 100%,auto;background-color:#fff;width:10px;height:10px;display:inline-block;border:solid 1px #000}#wpbdp-admin-page-settings .nav-tab.tab-error{border-top:solid 1px red}#wpbdp-admin-page-settings .nav-tab.tab-warning{border-top:solid 1px yellow}#wpbdp-admin-page-settings .form-table tr>th{min-width:250px}#wpbdp-admin-page-settings .form-table tr>th>h3{font-size:1.2em;margin:0 auto}#wpbdp-admin-page-settings .wpbdp-setting-description{color:#666;font-style:italic;display:block}#wpbdp-admin-page-settings .wpbdp-setting-tooltip{height:18px;width:18px;font-size:18px;line-height:18px;vertical-align:middle;margin-right:5px;color:#666;cursor:help}#wpbdp-admin-page-settings input[type="text"],#wpbdp-admin-page-settings textarea{padding:6px;width:85%}#wpbdp-admin-page-settings textarea{min-height:150px}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activate-btn,#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-deactivate-btn{margin-left:10px;margin-top:2px;display:none}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activate-btn{display:inline-block}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-warning-icon,#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-ok-icon{display:none;vertical-align:middle;margin:0 8px 2px 0}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-warning-icon{display:inline-block}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui.wpbdp-license-status-valid .wpbdp-license-warning-icon{display:none}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui.wpbdp-license-status-valid .wpbdp-license-ok-icon{display:inline-block}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui.wpbdp-license-status-valid .wpbdp-license-key-activate-btn{display:none}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui.wpbdp-license-status-valid .wpbdp-license-key-deactivate-btn{display:inline-block}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-input{width:70%}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg{font-size:90%;position:relative;border-radius:4px;padding:8px;margin:10px 12px 3px 30px;background:#fff;color:#000;box-sizing:border-box;width:calc(100% - 30px)}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg:after,#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg:before{bottom:100%;left:20px;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none;border-width:8px;margin-left:-8px}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg:before{border-color:rgba(214,66,38,0);border-bottom-color:#fff}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg.status-success{background-color:#27a533;color:#fff}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg.status-success:after{border-bottom-color:#27a533}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg.status-error{background-color:#d84747;color:#fff}#wpbdp-admin-page-settings .wpbdp-license-key-activation-ui .wpbdp-license-key-activation-status-msg.status-error:after{border-bottom-color:#d84747}#wpbdp-admin-page-settings tr.wpbdp-setting-disabled{opacity:.7}.wpbdp-tooltip-msg{background:#333 !important;border-width:1px !important;border-radius:3px !important;box-shadow:1px 1px 2px 1px rgba(214,214,214,0.5) !important;color:#dedede !important;max-width:300px !important;padding:7px !important;text-rendering:optimizeLegibility;text-shadow:none !important;z-index:9999 !important}.directory-admin_page_wpbdp_settings select{display:block}#wpbdp-admin-page-settings .wpbdp-settings-choice-radio{margin:0 0 5px 0}#wpbdp-admin-page-settings tr.disabled{opacity:.7}#wpbdp-admin-page-settings .text-fields-warning{font-size:90%;display:block;margin-bottom:2px}#wpbdp-admin-page-settings .wpbdp-expiration-notice-email-schedule-summary{background:#ccc;font-size:85%;padding:5px}#wpbdp-admin-page-settings .wpbdp-settings-email{margin:10px 0 0 0;border:solid 1px #ccc;padding:5px;background:#fff}#wpbdp-admin-page-settings .wpbdp-settings-email.wpbdp-expiration-notice-email{border-bottom:none}#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview{color:#999;font-size:90%;height:45px;cursor:pointer;overflow:hidden}#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview h4,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview h4{margin:0 0 10px 0}#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview a.wpbdp-settings-email-edit-btn,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview a.wpbdp-settings-email-edit-btn,#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview .edit-toggle,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview .edit-toggle{float:right;color:#fff}#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview dl,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview dl{margin:0;padding:0}#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview dl dt,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview dl dt{font-weight:bold;margin:0;padding:0}#wpbdp-admin-page-settings .wpbdp-settings-email .short-preview dl dd,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-preview dl dd{margin:0;padding:0 0 0 10px}#wpbdp-admin-page-settings .wpbdp-settings-email .editor,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor{display:none;margin-left:10px;font-size:90%}#wpbdp-admin-page-settings .wpbdp-settings-email .editor table.form-table,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor table.form-table{margin:0;padding:0}#wpbdp-admin-page-settings .wpbdp-settings-email .editor table.form-table th,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor table.form-table th{padding-left:4px;padding-right:0;min-width:0;width:20%}#wpbdp-admin-page-settings .wpbdp-settings-email .editor input[type="text"],#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor input[type="text"]{width:100%}#wpbdp-admin-page-settings .wpbdp-settings-email .editor textarea,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor textarea{width:100%;min-height:150px}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .placeholders,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .placeholders{margin:10px 0 0 0}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .placeholder,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .placeholder{font-size:90%}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .placeholder .placeholder-code,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .placeholder .placeholder-code{font-family:monospace;font-weight:bold}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .placeholder .placeholder-description,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .placeholder .placeholder-description{font-style:italic}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .placeholder-separator,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .placeholder-separator{margin-top:10px}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .buttons,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .buttons{margin:30px 0 0 0;text-align:right}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .buttons .preview-email,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .buttons .preview-email{float:left}#wpbdp-admin-page-settings .wpbdp-settings-email .editor .buttons .cancel,#wpbdp-admin-page-settings .wpbdp-settings-email .wpbdp-settings-email-editor .buttons .cancel{margin-right:10px}#wpbdp-admin-page-settings .wpbdp-settings-expiration-notices #wpbdp-settings-expiration-notices-add-btn{margin:0 0 5px 0}#wpbdp-admin-page-settings .wpbdp-settings-expiration-notices #wpbdp-settings-expiration-notices-add .wpbdp-expiration-notice-email{display:none;border-bottom:1px solid #ccc}#wpbdp-admin-page-settings .wpbdp-settings-expiration-notices .buttons .delete{color:#a00;float:left;font-size:13px}#wpbdp-admin-page-settings .wpbdp-settings-expiration-notices .buttons .delete:hover{color:red}#wpbdp-admin-page-settings .wpbdp-settings-type-checkbox input[type="checkbox"]{vertical-align:bottom}#wpbdp-admin-page-settings .wpbdp-settings-radio-options .wpbdp-settings-radio-option,#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options .wpbdp-settings-radio-option,#wpbdp-admin-page-settings .wpbdp-settings-radio-options .wpbdp-settings-multicheck-option,#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options .wpbdp-settings-multicheck-option{margin:0 0 5px 0}#wpbdp-admin-page-settings .wpbdp-settings-radio-options .wpbdp-settings-radio-option input[type="radio"],#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options .wpbdp-settings-radio-option input[type="radio"],#wpbdp-admin-page-settings .wpbdp-settings-radio-options .wpbdp-settings-multicheck-option input[type="radio"],#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options .wpbdp-settings-multicheck-option input[type="radio"],#wpbdp-admin-page-settings .wpbdp-settings-radio-options .wpbdp-settings-radio-option input[type="checkbox"],#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options .wpbdp-settings-radio-option input[type="checkbox"],#wpbdp-admin-page-settings .wpbdp-settings-radio-options .wpbdp-settings-multicheck-option input[type="checkbox"],#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options .wpbdp-settings-multicheck-option input[type="checkbox"]{vertical-align:bottom}#wpbdp-admin-page-settings .wpbdp-settings-radio-options+.wpbdp-setting-description,#wpbdp-admin-page-settings .wpbdp-settings-multicheck-options+.wpbdp-setting-description{margin:10px 0 0 0}#wpbdp-admin-page-settings #wpbdp-settings-quick-search-fields .wpbdp-settings-multicheck-option{width:50%;display:inline-block}td.column-payment_status .status,td.column-sticky_status .status{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:90%}td.column-payment_status .status.ok{background:green}td.column-payment_status .paymentdata{font-size:85%}td.column-payment_status .paymentdata b{font-weight:normal}td.column-payment_status .paymentdata span{font-style:italic}td.column-sticky_status .status.notpaid{background:orange}td.column-sticky_status .status.pending{background:red;font-weight:bold}td.column-sticky_status .status.sticky{background:green}table.wp-list-table td .tag{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:90%;margin-right:2px;display:inline-block}table.wp-list-table.formfields th.column-label{width:40%}table.wp-list-table.formfields th.column-tags,table.wp-list-table.formfields td.column-tags{width:200px}table.wp-list-table.formfields th.column-order,table.wp-list-table.formfields td.column-order{width:55px}table.wp-list-table.formfields td.column-order .wpbdp-drag-handle{visibility:hidden}table.wp-list-table.formfields tr:hover .wpbdp-drag-handle{visibility:visible}table.wp-list-table.formfields .tag.required{background:orange}table.wp-list-table.formfields .tag.in-excerpt{background:green}table.wp-list-table.formfields .tag.in-listing{background:green}table.wp-list-table.formfields tr.wpbdp-draggable-highlight{height:54px}table.wp-list-table.formfields tr.ui-sortable-helper{background:#fff;border:1px dashed #c1c1c1}#wpbdp-admin-page-field-form .iframe-confirm{display:none}#wpbdp-admin-page-field-form .iframe-confirm p{font-size:90%}.wpbdp-form-field.image .preview{float:none}table.wpbdp-debug-section{width:90%}table.wpbdp-debug-section tbody tr{background:#efefef}table.wpbdp-debug-section tbody tr td{padding:3px 8px}table.wpbdp-debug-section tbody tr:nth-child(2n){background:#f5f5f5}#wpbdp-admin-debug-info-page textarea.test-ssl-results{display:block;width:90%;font-family:monospace;font-size:11px;height:100px}.wpbdp-page-admin-transactions .tag{font-size:95%}.wpbdp-page-admin-transactions .tag.approved{background:green}.wpbdp-page-admin-transactions .tag.pending{background:red}.wpbdp-page-admin-transactions .column-actions a.delete{color:#bc0b0b}.wpbdp-page-admin-transactions tr.more-details-row{background:#fff}.wpbdp-page-admin-transactions tr.more-details-row td{padding-left:40px;font-size:95%}.wpbdp-page-admin-transactions tr.more-details-row td dl dt{font-weight:bold}body.taxonomy-wpbdp_category .column-id{width:35px}.transaction-status-container{text-align:right;padding:5px}.wpbdp-progress-bar .progress-bar{margin-left:10px;display:inline-block;vertical-align:middle}.wpbdp-progress-bar .progress-bar-outer{min-width:200px;height:12px;border:solid 1px #3366CC;padding:0}.wpbdp-progress-bar .progress-bar-inner{height:100%;background:#99CCFF}.wpbdp-note{padding:5px 10px;background:#d7f5ff;margin:5px 0 20px 0;border:solid 1px #bad5df;border-radius:4px}.wpbdp-note p{margin:0}.wpbdp-note h1,.wpbdp-note h2,.wpbdp-note h3,.wpbdp-note h4{margin:0 0 8px 0}.wpbdp-note.error,.wpbdp-note.warning{background-color:#FFEBE8;border-color:#C00}.wpbdp-notice.dismissible{position:relative}.tag.paymentstatus{text-transform:capitalize}.tag.paymentstatus.ok{background:green}.tag.paymentstatus.completed{background:green}.tag.paymentstatus.pending,.tag.paymentstatus.pending-abandonment{background:red}.wpbdp-listing-metabox-tab dl{margin:0}.wpbdp-payment-details .tag{float:right}.wpbdp-payment-details .details,.wpbdp-payment-details .invoice,.wpbdp-payment-details .actions{clear:both;margin:20px 0}.wpbdp-payment-details .details dl dt{font-weight:bold}.wpbdp-payment-details table.wpbdp-payment-items-table{width:100%}.wpbdp-payment-details table.wpbdp-payment-items-table th{text-transform:uppercase}.wpbdp-payment-details table.wpbdp-payment-items-table td{border-top:1px solid #bbb;padding:6px 10px 6px 0}.wpbdp-payment-details .actions a.button-primary{color:#fff !important}.listing-fee-change .fee-selection .fee{padding-bottom:5px;margin-bottom:10px;border-bottom:dotted 1px #ccc;opacity:.85}.listing-fee-change .fee-selection .fee:hover{opacity:1}.listing-fee-change .fee-selection .fee .details{margin-left:10px}.listing-fee-change .fee-selection .fee .tag{float:right}.listing-fee-change .fee-selection .fee .choose-this{float:right}.wpbdp-draggable-highlight{background:#bbb}.wpbdp-module-compat-check .module-info{margin-bottom:3px}.wpbdp-module-compat-check .module-info .module-version,.wpbdp-module-compat-check .module-info .module-required{color:#666}.wpbdp-module-compat-check .module-info .module-version{margin-left:15px}.wpbdp-module-compat-check .module-info .module-version b{color:#333}.wpbdp-module-compat-check .module-info .module-required b{color:#900000}.toplevel_page_wpbdp_admin .welcome-message{padding:10px;font-size:105%}.toplevel_page_wpbdp_admin .welcome-message p{font-size:inherit}.toplevel_page_wpbdp_admin .welcome-message h4{font-size:120%}.toplevel_page_wpbdp_admin .welcome-message ul{list-style-position:inside;list-style-type:disc}.toplevel_page_wpbdp_admin ul.shortcuts{margin:auto}.toplevel_page_wpbdp_admin ul.shortcuts li{float:left;margin-right:10px}.toplevel_page_wpbdp_admin ul.shortcuts li.clear{margin:0}#wpbdp-uninstall-capture-form .reasons{margin-left:15px}#wpbdp-uninstall-capture-form .reasons .reason{margin-bottom:5px}#wpbdp-uninstall-capture-form textarea{margin:10px 0 0 0;width:50%;min-height:100px;display:none}#wpbdp-licensing-issues-warning ul li{list-style-position:inside;list-style-type:disc}#wpbdp-licensing-issues-warning span.item-name{background:#fff9aa;padding:2px 5px;margin:0 0 0 4px;border-radius:4px}.wp-admin.widgets-php .widget-content span.help{color:#666}.wpbdp-admin-tab-nav{float:none;margin:0 0 .5em 0}.wpbdp-admin-tab-content{padding:5px 0 0 0;display:none}.wpbdp-admin-box label{vertical-align:top}a.wpbdp-admin-delete-link{color:#a00;text-decoration:none}a.wpbdp-admin-delete-link:hover{color:red}#wpbdp-admin-payment-info-box .inside{margin:0;padding:0}#wpbdp-admin-payment-info-box .wpbdp-admin-box-row{border-bottom:1px solid #eee;clear:both;padding:6px 12px;margin:0;line-height:1.5}#wpbdp-admin-payment-info-box label{font-weight:bold}#wpbdp-admin-payment-items-box .payment-item,#wpbdp-admin-payment-items-box .payment-item-header{margin:0 12px;padding:6px 0}#wpbdp-admin-payment-items-box .payment-item .payment-item-type,#wpbdp-admin-payment-items-box .payment-item-header .payment-item-type{display:block;width:20%;float:left}#wpbdp-admin-payment-items-box .payment-item .payment-item-description,#wpbdp-admin-payment-items-box .payment-item-header .payment-item-description{display:block;width:60%;float:left}#wpbdp-admin-payment-items-box .payment-item .payment-item-amount,#wpbdp-admin-payment-items-box .payment-item-header .payment-item-amount{display:block;width:20%;float:left}#wpbdp-admin-payment-items-box .payment-item.payment-totals,#wpbdp-admin-payment-items-box .payment-item-header.payment-totals{border-top:1px solid #eee;font-weight:bold}#wpbdp-admin-payment-items-box .payment-item-header{font-weight:bold}#wpbdp-admin-payment-details-box *{box-sizing:border-box}#wpbdp-admin-payment-details-box .wpbdp-admin-box-row>div{padding:6px 0}#wpbdp-admin-payment-details-box label{display:block}#wpbdp-admin-payment-details-box .customer-email,#wpbdp-admin-payment-details-box .customer-address-line1,#wpbdp-admin-payment-details-box .customer-address-line2{clear:both;width:100%}#wpbdp-admin-payment-details-box .customer-email input,#wpbdp-admin-payment-details-box .customer-address-line1 input,#wpbdp-admin-payment-details-box .customer-address-line2 input{width:100%}#wpbdp-admin-payment-details-box .customer-first-name,#wpbdp-admin-payment-details-box .customer-address-country,#wpbdp-admin-payment-details-box .customer-address-city{padding-right:3px !important}#wpbdp-admin-payment-details-box .customer-last-name,#wpbdp-admin-payment-details-box .customer-address-state,#wpbdp-admin-payment-details-box .customer-address-zipcode{padding-left:3px !important}#wpbdp-admin-payment-details-box .customer-first-name,#wpbdp-admin-payment-details-box .customer-last-name,#wpbdp-admin-payment-details-box .customer-address-country,#wpbdp-admin-payment-details-box .customer-address-state,#wpbdp-admin-payment-details-box .customer-address-city,#wpbdp-admin-payment-details-box .customer-address-zipcode{float:left;width:50%}#wpbdp-admin-payment-details-box .customer-first-name input,#wpbdp-admin-payment-details-box .customer-last-name input,#wpbdp-admin-payment-details-box .customer-address-country input,#wpbdp-admin-payment-details-box .customer-address-state input,#wpbdp-admin-payment-details-box .customer-address-city input,#wpbdp-admin-payment-details-box .customer-address-zipcode input{width:100%}#wpbdp-payment-notes .wpbdp-payment-note{margin-bottom:12px;line-height:1.5}#wpbdp-payment-notes .wpbdp-payment-note .wpbdp-payment-note-meta-user{font-weight:bold}#wpbdp-payment-notes .wpbdp-payment-note .wpbdp-payment-note-meta-date{color:#666}#wpbdp-payment-notes .wpbdp-payment-note .wpbdp-admin-delete-link{float:right;display:none}#wpbdp-payment-notes .wpbdp-payment-note:hover .wpbdp-admin-delete-link{display:block}.wpbdp-form-field{margin:12px 0}.wpbdp-form-field:first-child{margin-top:0}.wpbdp-form-field .wpbdp-form-field-label{margin:0 0 3px 0}.wpbdp-form-field .wpbdp-form-field-label label{display:inline-block;font-weight:bold}.wpbdp-form-field .wpbdp-form-field-label .wpbdp-form-field-required-indicator{margin-left:3px;font-size:90%}.wpbdp-form-field.wpbdp-form-field-has-description .wpbdp-form-field-label{margin-bottom:0}.wpbdp-form-field.wpbdp-form-field-has-description .wpbdp-form-field-description{margin-bottom:3px}.wpbdp-form-field .wpbdp-form-field-description{padding-left:6px;color:#666}.wpbdp-form-field .wpbdp-form-field-inner{padding-left:6px}.wpbdp-form-field.wpbdp-form-field-type-textarea textarea,.wpbdp-form-field.wpbdp-form-field-type-textfield input[type="text"]{width:100%;font-size:inherit}.wpbdp-form-field.wpbdp-form-field-type-textarea textarea{min-height:50px}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col{box-sizing:border-box;float:left;width:50%}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col:first-child{padding-right:10pt}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col:last-child{padding-left:10pt}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col .sublabel{margin:0;display:block}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col input{width:100%}.wpbdp-form-field.wpbdp-form-field-association-content textarea{min-height:80px}.wpbdp-form-field .field-description{font-size:90%;color:#696969;float:right}.wpbdp-form-field .sublabel{font-size:90%;margin-left:10px;margin-right:10px}.wpbdp-form-field-validation-error-wrapper{margin:24px 0}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors{font-size:80%;color:#d64226;position:relative;background:#fff;border:1px solid #d64226;border-radius:4px;padding:4px 6px;margin:0 12px 3px 6px}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:after,.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:before{top:100%;left:12px;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:after{border-color:rgba(255,255,255,0);border-top-color:#fff;border-width:4px;margin-left:-4px}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:before{border-color:rgba(214,66,38,0);border-top-color:#d64226;border-width:5px;margin-left:-5px}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field{margin:0}.select2-results{font-size:11px}#wpbdp-submit-listing input[type="text"],#wpbdp-submit-listing textarea{box-sizing:border-box}#wpbdp-submit-listing .wpbdp-submit-listing-section{margin:10px 0 0 0;display:block}#wpbdp-submit-listing .wpbdp-submit-listing-section.collapsed .collapse-indicator.expanded{display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section.collapsed .collapse-indicator.collapsed{display:inline}#wpbdp-submit-listing .wpbdp-submit-listing-section.collapsed .wpbdp-submit-listing-section-content{display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section.hidden{display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-header{background:#ccc;text-transform:uppercase;font-weight:bold;color:#333;padding:2px 10px;font-size:12px;cursor:pointer}#wpbdp-submit-listing .wpbdp-submit-listing-section-header .collapse-indicator{margin:0 10px 0 0;display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-header .collapse-indicator.expanded{display:inline}#wpbdp-submit-listing .wpbdp-submit-listing-section-content{padding:10px 20px;border:solid 1px #ccc;border-top:none;border-bottom-left-radius:4px;border-bottom-right-radius:4px}#wpbdp-submit-listing .wpbdp-submit-listing-section-content h4{margin:0 0 10px 0}#wpbdp-submit-listing .wpbdp-submit-listing-form-actions{margin:10px 0}#wpbdp-submit-listing .wpbdp-submit-listing-form-actions input[type="submit"]{float:right}#wpbdp-submit-listing .wpbdp-submit-listing-section-messages{margin:0 0 12px 0}#wpbdp-submit-listing .wpbdp-plan-selection-with-tip{margin:24px 0 0 0;display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-plan_selection ul.category-list{margin:0;padding:0;list-style-type:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-plan_selection ul.category-list li{font-size:10px;margin:0 5px 0 0;padding:1px 6px;border-radius:3px;background:#5bc0de;color:#fff;font-weight:700;text-align:center;white-space:nowrap;vertical-align:baseline;border:none;display:inline}#wpbdp-submit-listing .wpbdp-editor-area{height:422px}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images #image-upload-form{margin:15px 10px}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images #wpbdp-uploaded-images{margin:0 0 20px 0}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image{padding:10px 0;border-bottom:dotted 1px #efefef}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-img{width:60px;float:left}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-extra input[type="text"]{width:60%;display:block}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-delete-link{float:right;font-size:11px;text-decoration:none;color:#900000;display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-delete-link:hover{text-decoration:underline;color:#ff0000}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image:hover .wpbdp-image-delete-link{display:inline}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image-draggable-highlight{width:160px;height:160px;margin:0 10px;background:red;float:left}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images #image-upload-form-no-js{width:0;height:0;overflow:hidden;visibility:hidden}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-dnd-area{float:left;width:72%;box-sizing:border-box}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-dnd-area.no-conditions{float:none;width:100%}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-conditions{float:right;width:25%;color:#666;font-size:90%}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-conditions dl{margin:0}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-conditions dl dt{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}#wpbdp-submit-listing textarea.wpbdp-submit-listing-tos{width:100%;min-height:100px}#wpbdp-submit-listing #change-plan-link{text-align:right;font-size:90%}#wpbdp-submit-listing #wpbdp-submit-listing-account-details{margin:10px 0 0 0}#wpbdp-submit-listing #wpbdp-submit-listing-account-details input[type="password"]{width:70%;display:inline-block}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter{float:right;width:20%;padding:4px;text-align:center;border:1px solid}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-0{background-color:#f1adad;border-color:#e35b5b}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-2{background-color:#fbc5a9;border-color:#f78b53}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-3{background-color:#ffe399;border-color:#ffc733}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-4{background-color:#c1e1b9;border-color:#83c373}span.tag{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:10px !important;margin-right:2px;text-decoration:none !important;line-height:1.5 !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}span.tag.wpbdp-listing-attr-paid{background:green}span.tag.wpbdp-listing-attr-admin-posted{background:orange}span.tag.wpbdp-listing-attr-post-status-pending{background:blue;color:#fff}.wpbdp-tag.wpbdp-listing-attr-paid,span.tag.wpbdp-listing-attr-paid{background:green}.wpbdp-tag.wpbdp-listing-attr-admin-posted,span.tag.wpbdp-listing-attr-admin-posted{background:orange}.wpbdp-tag.wpbdp-listing-attr-post-status-pending,span.tag.wpbdp-listing-attr-post-status-pending{background:blue;color:#fff}.wp-list-table td .wpbdp-tag{display:inline-block}body.post-type-wpbdp_listing .wp-list-table .wpbdp-tag{font-size:10px !important;text-transform:none !important}
assets/css/less/admin-csv-import.less CHANGED
@@ -63,3 +63,56 @@
63
  margin: 0;
64
  padding: 0;
65
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  margin: 0;
64
  padding: 0;
65
  }
66
+
67
+ .wpbdp-csv-import-example {
68
+ width: 100%;
69
+ padding: 10px;
70
+ display: block;
71
+ background: #fff;
72
+ border: solid 1px #ddd;
73
+ font-size: 90%;
74
+ font-family: monospace;
75
+ height: 100%;
76
+ white-space: pre;
77
+ }
78
+
79
+ #wpbdp-csv-import-form input[type="file"] {
80
+ border: none;
81
+ }
82
+
83
+ table.wpbdp-csv-import-results, table.wpbdp-csv-import-warnings {
84
+ width: 100%;
85
+ }
86
+
87
+ table.wpbdp-csv-import-results .line-no, table.wpbdp-csv-import-warnings .line-no {
88
+ width: 50px;
89
+ }
90
+
91
+ table.wpbdp-csv-import-results td.line, table.wpbdp-csv-import-warnings td.line {
92
+ font-family: monospace;
93
+ font-size: 90%;
94
+ }
95
+
96
+ table.wpbdp-csv-import-results .error, table.wpbdp-csv-import-warnings .error {
97
+ width: 200px;
98
+ }
99
+
100
+ table.wpbdp-csv-import-headers {
101
+ width: 100%;
102
+ }
103
+
104
+ table.wpbdp-csv-import-headers td.field-is-required, table.wpbdp-csv-import-headers td.field-is-multivalued {
105
+ text-align: center;
106
+ }
107
+
108
+ table.wpbdp-csv-import-headers tbody tr {
109
+ background: #f9f9f9;
110
+ }
111
+
112
+ table.wpbdp-csv-import-headers tbody tr.alt {
113
+ background: inherit;
114
+ }
115
+
116
+ .wpbdp-csv-import-top-buttons {
117
+ float: right;
118
+ }
assets/css/less/admin-fees.less ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpbdp-admin-page-fees .tablenav {
2
+ display: none;
3
+ }
4
+
5
+ #wpbdp-admin-admin-page-fees .column-attributes .wpbdp-tag {
6
+ background: green;
7
+ color: #fff;
8
+ }
9
+
10
+ .wpbdp-admin-page-fees .wp-list-table .wpbdp-drag-handle {
11
+ margin-right: 15px;
12
+ display: none;
13
+ }
14
+
15
+ .wpbdp-admin-page-fees .purchase-gateways {
16
+ margin-left: 20px;
17
+ }
18
+
19
+ .wpbdp-admin-page-fees .purchase-gateways .gateway {
20
+ float: left;
21
+ width: 35%;
22
+ margin: 30px 20px 0 0;
23
+ /* height: 180px;*/
24
+ }
25
+
26
+ .wpbdp-admin-page-fees .purchase-gateways .gateway.installed {
27
+ opacity: 0.5;
28
+ }
29
+
30
+ .wpbdp-admin-page-fees .purchase-gateways .gateway a img.gateway-logo {
31
+ /* width: 30%;*/
32
+ height: 40px;
33
+ margin: 0;
34
+ padding: 0;
35
+ border: none;
36
+ }
37
+
38
+ .wpbdp-admin-page-fees .purchase-gateways .gateway a.price {
39
+ margin-top: 10px;
40
+ display: block;
41
+ color: green;
42
+ font-size: 22px;
43
+ font-weight: bold;
44
+ }
45
+
46
+ .wpbdp-admin-page-fees .purchase-gateways .gateway .check-mark {
47
+ font-size: 150%;
48
+ font-weight: bold;
49
+ color: green;
50
+ }
51
+
52
+ #wpbdp-fee-form {
53
+ #limit-categories-list {
54
+ font-size: 90%;
55
+
56
+ p {
57
+ margin: 10px 0;
58
+ }
59
+
60
+ select {
61
+ width: 100%;
62
+ }
63
+
64
+ .select2-selection {
65
+ padding: 0 0 2px 0;
66
+ margin: 0;
67
+ border-radius: 5px;
68
+ border-color: rgb(221, 221, 221);
69
+ min-height: 26px;
70
+ }
71
+
72
+ .select2-selection__choice {
73
+ border: none;
74
+ padding: 0;
75
+ margin: 2px 4px 0 0;
76
+ .wpbdp-tag;
77
+
78
+ .select2-selection__choice__remove {
79
+ color: #fff;
80
+ }
81
+ }
82
+
83
+ .select2-search {
84
+ margin-bottom: 0;
85
+ }
86
+
87
+ .wpbdp-category-item {
88
+ width: 33.33%;
89
+ float: left;
90
+ padding: 2px 0;
91
+ }
92
+ }
93
+
94
+ .pricing-details-variable {
95
+ &> td {
96
+ padding-top: 0;
97
+ }
98
+
99
+ table {
100
+ th {
101
+ font-weight: normal;
102
+ }
103
+
104
+ td:last-child {
105
+ width: 100%;
106
+ }
107
+
108
+ td {
109
+ &.category-name-col {
110
+ padding-right: 20px;
111
+ text-align: right;
112
+ }
113
+
114
+ &.category-price-col {
115
+ }
116
+
117
+ font-size: 90%;
118
+ padding: 0;
119
+ }
120
+ }
121
+
122
+ .wpbdp-variable-pricing-configurator-row {
123
+ input {
124
+ width: 100px;
125
+ }
126
+ }
127
+ }
128
+
129
+ .pricing-options {
130
+ label {
131
+ display: block;
132
+ }
133
+ }
134
+
135
+ .fee-pricing-details {
136
+ input[type="text"] {
137
+ width: 100px;
138
+ }
139
+ }
140
+ }
141
+
142
+ #wpbdp-fee-form #fee-bgcolor-picker {
143
+ position: relative;
144
+
145
+ input#fee-bgcolor-value {
146
+ border: none;
147
+ cursor: pointer;
148
+ }
149
+
150
+ .color-selection {
151
+ left: 5px;
152
+ display: none;
153
+ position: absolute;
154
+ background: #fff;
155
+ padding: 10px;
156
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
157
+ }
158
+
159
+ .color-selection-btns {
160
+ margin: 0 0 10px 0;
161
+ font-size: 12px;
162
+
163
+ a {
164
+ text-decoration: none;
165
+ }
166
+
167
+ a.close-btn {
168
+ float: right;
169
+ color: #999;
170
+ }
171
+
172
+ a.reset-btn .no-color-img {
173
+ background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 99 L99 0 L100 1 L1 100' fill='#ff0000' /></svg>");
174
+ background-repeat: no-repeat;
175
+ background-position: center center;
176
+ background-size: 100% 100%, auto;
177
+ background-color: #fff;
178
+ width: 10px;
179
+ height: 10px;
180
+ display: inline-block;
181
+ border: solid 1px #000;
182
+ }
183
+ }
184
+
185
+ }
assets/css/less/admin-listing-metabox.less CHANGED
@@ -43,89 +43,167 @@
43
  }
44
  /* @end */
45
 
46
- /* @group Categories. */
47
- .listing-metabox-tab .listing-categories {
48
- margin: 20px 0;
49
- }
50
-
51
- .listing-category {
52
  border-bottom: dotted 1px #bbb;
53
  }
54
 
55
- .listing-category .header {
56
- margin-top: 8px;
57
- min-height: 25px;
58
- }
59
-
60
- .listing-category .header .spinner {
61
- float: right;
62
- background-size: 15px 15px;
63
- }
64
-
65
- .listing-category .category-name {
66
  text-decoration: underline;
67
  font-weight: bold;
68
  }
69
 
70
- .listing-category.expired .category-name {
71
- text-decoration: line-through underline;
72
- }
73
-
74
- .listing-category .category-status {
75
- float: right;
76
  }
77
 
78
- .listing-category .category-status.ok { background: green; }
79
- .listing-category .category-status.pending { background: red; }
80
 
81
- .listing-category .category-details {
82
  margin-left: 25px;
83
  }
84
 
85
- .listing-category dl {
86
  margin: 0;
87
- clear: both;
88
  }
89
 
90
- .listing-category dt {
91
  float: left;
92
  color: #595959;
93
  width: 80px;
94
  }
95
 
96
- .listing-category dd {
97
  margin-bottom: 0;
98
  }
99
 
100
- .listing-category .expiration-date-info .spinner { float: left; }
101
-
102
- .listing-category a.expiration-change-link {
103
- float: right;
 
104
  }
105
 
106
- .listing-category .datepicker {
107
  position: absolute;
108
  z-index: 100;
109
  right: 10px;
110
  font-size: 80%;
111
  }
112
 
113
- .listing-category .admin-actions {
114
  margin-top: 10px;
115
  margin-left: 25px;
116
- clear: both;
117
  }
118
 
119
- .listing-category .admin-actions li {
120
  margin: 0;
121
  padding: 0;
122
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
- .listing-category .admin-actions li.delete {
125
- margin-top: 10px;
126
  }
127
-
128
- .listing-category .admin-actions a.category-delete {
129
- color: #ff0000;
 
 
 
 
 
 
130
  }
131
- /* @end */
43
  }
44
  /* @end */
45
 
46
+ /* @group Fees. */
47
+ #listing-metabox-fees .listing-plan {
 
 
 
 
48
  border-bottom: dotted 1px #bbb;
49
  }
50
 
51
+ #listing-metabox-fees .listing-plan .plan-label {
 
 
 
 
 
 
 
 
 
 
52
  text-decoration: underline;
53
  font-weight: bold;
54
  }
55
 
56
+ #listing-metabox-fees .listing-plan .plan-status {
 
 
 
 
 
57
  }
58
 
59
+ #listing-metabox-fees .listing-plan .plan-status.ok { background: green; }
60
+ #listing-metabox-fees .listing-plan .plan-status.pending { background: red; }
61
 
62
+ #listing-metabox-fees .listing-plan .plan-details {
63
  margin-left: 25px;
64
  }
65
 
66
+ a dl {
67
  margin: 0;
68
+ clear: both;
69
  }
70
 
71
+ #listing-metabox-fees .listing-plan dt {
72
  float: left;
73
  color: #595959;
74
  width: 80px;
75
  }
76
 
77
+ #listing-metabox-fees .listing-plan .listing-category dd {
78
  margin-bottom: 0;
79
  }
80
 
81
+ #listing-metabox-fees .listing-plan .spinner {
82
+ text-align: center;
83
+ display: block;
84
+ float: none;
85
+ margin: 10px auto;
86
  }
87
 
88
+ #listing-metabox-fees .listing-plan .datepicker {
89
  position: absolute;
90
  z-index: 100;
91
  right: 10px;
92
  font-size: 80%;
93
  }
94
 
95
+ #listing-metabox-fees .listing-plan .admin-actions {
96
  margin-top: 10px;
97
  margin-left: 25px;
98
+ clear: both;
99
  }
100
 
101
+ #listing-metabox-fees .listing-plan .admin-actions li {
102
  margin: 0;
103
  padding: 0;
104
  }
105
+ /* @end */
106
+
107
+ #wpbdp-listing-metabox-payments {
108
+
109
+ .wpbdp-payment-item {
110
+ padding: 2px;
111
+ border-bottom: solid 1px #efefef;
112
+ clear: both;
113
+ font-size: 95%;
114
+
115
+ &:first-child {
116
+ margin-top: 12px;
117
+ }
118
+
119
+ &.wpbdp-payment-status-completed {
120
+ color: green;
121
+ }
122
+
123
+ &.wpbdp-payment-status-pending {
124
+ color: red;
125
+ }
126
+
127
+ &.wpbdp-payment-status-rejected {
128
+ color: #bbb;
129
+ }
130
+
131
+ a {
132
+ color: inherit;
133
+ }
134
+
135
+ .wpbdp-payment-item-row {
136
+ clear: both;
137
+ }
138
+
139
+ .wpbdp-payment-date,
140
+ .wpbdp-payment-summary {
141
+ float: left;
142
+ }
143
+
144
+ .wpbdp-payment-summary {
145
+ width: 150px;
146
+ // text-overflow: ellipsis;
147
+ // white-space: nowrap;
148
+ // overflow: hidden;
149
+
150
+ a {
151
+ font-size: 95%;
152
+ }
153
+ }
154
+
155
+ .wpbdp-payment-status,
156
+ .wpbdp-payment-total {
157
+ text-align: right;
158
+ }
159
+
160
+ }
161
+
162
+ }
163
+
164
+ #wpbdp-listing-metabox-plan-info {
165
+ h4 {
166
+ margin: 0 0 5px 0;
167
+ font-size: 85%;
168
+ text-transform: uppercase;
169
+ }
170
+
171
+ dl {
172
+ margin: 0 0 20px 10px;
173
+
174
+ dt {
175
+ }
176
+
177
+ dd {
178
+ margin-left: 30px;
179
+ }
180
+ }
181
+
182
+ .display-value {
183
+ }
184
+
185
+ .value-editor {
186
+ display: none;
187
+
188
+ .update-value, .cancel-edit {
189
+ font-size: 85%;
190
+ }
191
+ }
192
+
193
+ a.edit-value-toggle {
194
+ margin: 0 0 0 10px;
195
+ font-size: 85%;
196
+ }
197
 
 
 
198
  }
199
+
200
+ /*
201
+ #wpbdp-listing-metabox-payments table tr a {
202
+ text-decoration: none;
203
+ color: inherit;
204
+ }
205
+
206
+ #wpbdp-listing-metabox-payments table tr a:hover {
207
+ text-decoration: underline;
208
  }
209
+ */
assets/css/less/admin-listing-timeline.less ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpbdp-listing-metabox-timeline:before {
2
+ position: absolute;
3
+ top: 0;
4
+ bottom: 0;
5
+ left: 10px;
6
+ width: 2px;
7
+ content: "";
8
+ display: block;
9
+ background: #f3f3f3;
10
+ height: 100%;
11
+ z-index: 0;
12
+ }
13
+
14
+ #wpbdp-listing-metabox-timeline:after {
15
+ content: '';
16
+ display: table;
17
+ clear: both;
18
+ }
19
+
20
+ #wpbdp-listing-metabox-timeline {
21
+ .timeline-item {
22
+ display: block;
23
+ padding: 5px 0 5px 20px;
24
+ border-bottom: 1px solid #f5f5f5;
25
+ margin: 10px 0;
26
+ position: relative;
27
+
28
+ .timeline-item-icon {
29
+ z-index: 1;
30
+ float: left;
31
+ width: 12px;
32
+ height: 12px;
33
+ background: #f3f3f3;
34
+ border: 2px solid #fff;
35
+ border-radius: 50%;
36
+ margin-left: -28px;
37
+ margin-top: 1px;
38
+ }
39
+
40
+ .timeline-item-header {
41
+ padding: 5px 0;
42
+ color: #000;
43
+ }
44
+
45
+ .timeline-item-description {
46
+ }
47
+
48
+ .timeline-item-datetime {
49
+ font-size: 90%;
50
+ color: #767676;
51
+ display: block;
52
+ }
53
+
54
+ .timeline-item-extra {
55
+ font-size: 90%;
56
+ }
57
+
58
+ .timeline-item-actions {
59
+ font-size: 80%;
60
+ }
61
+ }
62
+
63
+ .timeline-item-listing_payment {
64
+ .timeline-item-extra {
65
+ .payment-amount {
66
+ float: right;
67
+ }
68
+ }
69
+
70
+ .payment-status {
71
+ float: right;
72
+
73
+ &.pending {
74
+ background: #ff0000;
75
+ }
76
+ }
77
+ }
78
+
79
+
80
+ }
assets/css/less/admin-manual-upgrade.less ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpbdp-admin-page-manual-upgrade {
2
+
3
+ .wpbdp-admin-content {
4
+ margin: 20px 0 0 0;
5
+ padding: 16px;
6
+ background: #fff;
7
+ border-radius: 4px;
8
+ }
9
+
10
+ }
11
+
12
+ #wpbdp-manual-upgrade-18_0-config {
13
+ #add-fee-form {
14
+ display: none;
15
+ }
16
+
17
+ table#fee-decisions {
18
+ width: 90%;
19
+ border: 1px solid #ccc;
20
+ border-radius: 3px;
21
+ margin: 24px auto;
22
+ padding: 12px;
23
+
24
+ th {
25
+ text-align: left;
26
+ background: #efefef;
27
+ }
28
+
29
+ th, td {
30
+ padding: 8px;
31
+ vertical-align: top;
32
+ }
33
+
34
+ th.level-name, td.level-name {
35
+ width: 200px;
36
+ }
37
+ }
38
+
39
+ .option-description {
40
+ color: #666;
41
+ font-size: 90%;
42
+ margin: 6px 0;
43
+ display: none;
44
+ }
45
+
46
+ .option-configuration {
47
+ display: none;
48
+ }
49
+ }
assets/css/less/admin-payments.less ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpbdp-admin-payment-info-box {
2
+ .inside {
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpbdp-admin-box-row {
8
+ border-bottom: 1px solid #eee;
9
+ clear: both;
10
+ padding: 6px 12px;
11
+ margin: 0;
12
+ line-height: 1.5;
13
+ }
14
+
15
+ label {
16
+ font-weight: bold;
17
+ }
18
+ }
19
+
20
+ #wpbdp-admin-payment-items-box {
21
+ .payment-item, .payment-item-header {
22
+ margin: 0 12px;
23
+ padding: 6px 0;
24
+
25
+ .payment-item-type {
26
+ display: block;
27
+ width: 20%;
28
+ float: left;
29
+ }
30
+
31
+ .payment-item-description {
32
+ display: block;
33
+ width: 60%;
34
+ float: left;
35
+ }
36
+
37
+ .payment-item-amount {
38
+ display: block;
39
+ width: 20%;
40
+ float: left;
41
+ }
42
+
43
+ &.payment-totals {
44
+ border-top: 1px solid #eee;
45
+ font-weight: bold;
46
+ }
47
+ }
48
+
49
+ .payment-item-header {
50
+ font-weight: bold;
51
+ }
52
+ }
53
+
54
+ #wpbdp-admin-payment-details-box {
55
+ * {
56
+ box-sizing: border-box;
57
+ }
58
+
59
+ .wpbdp-admin-box-row > div {
60
+ padding: 6px 0;
61
+ }
62
+
63
+ label {
64
+ display: block;
65
+ }
66
+
67
+ .customer-email,
68
+ .customer-address-line1,
69
+ .customer-address-line2 {
70
+ clear: both;
71
+ width: 100%;
72
+
73
+ input {
74
+ width: 100%;
75
+ }
76
+ }
77
+
78
+ .customer-first-name,
79
+ .customer-address-country,
80
+ .customer-address-city {
81
+ padding-right: 3px !important;
82
+ }
83
+
84
+ .customer-last-name,
85
+ .customer-address-state,
86
+ .customer-address-zipcode {
87
+ padding-left: 3px !important;
88
+ }
89
+
90
+ .customer-first-name,
91
+ .customer-last-name,
92
+ .customer-address-country,
93
+ .customer-address-state,
94
+ .customer-address-city,
95
+ .customer-address-zipcode {
96
+ float: left;
97
+ width: 50%;
98
+
99
+ input {
100
+ width: 100%;
101
+ }
102
+ }
103
+
104
+
105
+ }
106
+
107
+ #wpbdp-payment-notes {
108
+ .wpbdp-payment-note {
109
+ margin-bottom: 12px;
110
+ line-height: 1.5;
111
+
112
+ .wpbdp-payment-note-meta-user {
113
+ font-weight: bold;
114
+ }
115
+
116
+ .wpbdp-payment-note-meta-date {
117
+ color: #666;
118
+ }
119
+
120
+ .wpbdp-admin-delete-link {
121
+ float: right;
122
+ display: none;
123
+ }
124
+
125
+ &:hover .wpbdp-admin-delete-link {
126
+ display: block;
127
+ }
128
+ }
129
+ }
assets/css/less/admin-settings.less ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpbdp-admin-page-settings {
2
+ .nav-tab {
3
+ &.tab-error {
4
+ border-top: solid 1px red;
5
+ }
6
+
7
+ &.tab-warning {
8
+ border-top: solid 1px yellow;
9
+ }
10
+ }
11
+
12
+ .form-table tr > th {
13
+ min-width: 250px;
14
+ }
15
+
16
+ .form-table tr > th > h3 {
17
+ font-size: 1.2em;
18
+ margin: 0 auto;
19
+ }
20
+
21
+ .wpbdp-setting-description {
22
+ color: #666;
23
+ font-style: italic;
24
+ display: block;
25
+ }
26
+
27
+ .wpbdp-setting-tooltip {
28
+ height: 18px;
29
+ width: 18px;
30
+ font-size: 18px;
31
+ line-height: 18px;
32
+ vertical-align: middle;
33
+ margin-right: 5px;
34
+ color: #666;
35
+ cursor: help;
36
+ }
37
+
38
+ input[type="text"], textarea {
39
+ padding: 6px;
40
+ width: 85%;
41
+ }
42
+
43
+ textarea {
44
+ min-height: 150px;
45
+ }
46
+
47
+ .wpbdp-license-key-activation-ui {
48
+ .wpbdp-license-key-activate-btn, .wpbdp-license-key-deactivate-btn {
49
+ margin-left: 10px;
50
+ margin-top: 2px;
51
+ display: none;
52
+ }
53
+ .wpbdp-license-key-activate-btn {
54
+ display: inline-block;
55
+ }
56
+
57
+ .wpbdp-license-warning-icon, .wpbdp-license-ok-icon {
58
+ display: none;
59
+ vertical-align: middle;
60
+ margin: 0 8px 2px 0;
61
+ }
62
+ .wpbdp-license-warning-icon {
63
+ display: inline-block;
64
+ }
65
+
66
+ &.wpbdp-license-status-valid {
67
+ .wpbdp-license-warning-icon {
68
+ display: none;
69
+ }
70
+ .wpbdp-license-ok-icon {
71
+ display: inline-block;
72
+ }
73
+
74
+ .wpbdp-license-key-activate-btn {
75
+ display: none;
76
+ }
77
+ .wpbdp-license-key-deactivate-btn {
78
+ display: inline-block;
79
+ }
80
+ }
81
+
82
+ .wpbdp-license-key-input {
83
+ width: 70%;
84
+ }
85
+
86
+ .wpbdp-license-key-activation-status-msg {
87
+ font-size: 90%;
88
+ position: relative;
89
+ border-radius: 4px;
90
+ padding: 8px;
91
+ margin: 10px 12px 3px 30px;
92
+ background: #fff;
93
+ color: #000;
94
+ box-sizing: border-box;
95
+ width: ~"calc(100% - 30px)";
96
+
97
+ &:after, &:before {
98
+ bottom: 100%;
99
+ left: 20px;
100
+ border: solid transparent;
101
+ content: " ";
102
+ height: 0;
103
+ width: 0;
104
+ position: absolute;
105
+ pointer-events: none;
106
+ border-width: 8px;
107
+ margin-left: -8px;
108
+ }
109
+
110
+ &:after {
111
+ border-color: rgba(255, 255, 255, 0);
112
+ border-bottom-color: #fff;
113
+ }
114
+
115
+ &:before {
116
+ border-color: rgba(214, 66, 38, 0);
117
+ border-bottom-color: #fff;
118
+ }
119
+
120
+ &.status-success {
121
+ background-color: #27a533;
122
+ color: #fff;
123
+
124
+ &:after {
125
+ border-bottom-color: #27a533;
126
+ }
127
+ }
128
+
129
+ &.status-error {
130
+ background-color: #d84747;
131
+ color: #fff;
132
+
133
+ &:after {
134
+ border-bottom-color: #d84747;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ tr.wpbdp-setting-disabled {
141
+ opacity: 0.7;
142
+ }
143
+ }
144
+
145
+ .wpbdp-tooltip-msg {
146
+ background: #333 !important;
147
+ border-width: 1px !important;
148
+ border-radius: 3px !important;
149
+ box-shadow: 1px 1px 2px 1px rgba(214,214,214,0.5) !important;
150
+ color: #dedede !important;
151
+ max-width: 300px !important;
152
+ padding: 7px !important;
153
+ text-rendering: optimizeLegibility;
154
+ text-shadow: none !important;
155
+ z-index: 9999 !important;
156
+ }
157
+
158
+ .directory-admin_page_wpbdp_settings select {
159
+ display: block;
160
+ }
161
+
162
+ #wpbdp-admin-page-settings {
163
+ .wpbdp-settings-choice-radio {
164
+ margin: 0 0 5px 0;
165
+ }
166
+ }
167
+
168
+ #wpbdp-admin-page-settings tr.disabled {
169
+ opacity: 0.7;
170
+ }
171
+
172
+ #wpbdp-admin-page-settings .text-fields-warning {
173
+ font-size: 90%;
174
+ display: block;
175
+ margin-bottom: 2px;
176
+ }
177
+
178
+ #wpbdp-admin-page-settings .wpbdp-expiration-notice-email-schedule-summary {
179
+ background: #ccc;
180
+ font-size: 85%;
181
+ padding: 5px;
182
+ }
183
+
184
+ #wpbdp-admin-page-settings .wpbdp-settings-email {
185
+ margin: 10px 0 0 0;
186
+ border: solid 1px #ccc;
187
+ padding: 5px;
188
+ background: #fff;
189
+
190
+ &.wpbdp-expiration-notice-email {
191
+ border-bottom: none;
192
+ }
193
+
194
+ .short-preview, .wpbdp-settings-email-preview {
195
+ color: #999;
196
+ font-size: 90%;
197
+ height: 45px;
198
+ cursor: pointer;
199
+ overflow: hidden;
200
+
201
+ h4 {
202
+ margin: 0 0 10px 0;
203
+ }
204
+
205
+ a.wpbdp-settings-email-edit-btn, .edit-toggle {
206
+ float: right;
207
+ color: #fff;
208
+ }
209
+
210
+ dl {
211
+ margin: 0;
212
+ padding: 0;
213
+
214
+ dt {
215
+ font-weight: bold;
216
+ margin: 0;
217
+ padding: 0;
218
+ }
219
+
220
+ dd {
221
+ margin: 0;
222
+ padding: 0 0 0 10px;
223
+ }
224
+ }
225
+ }
226
+
227
+ .editor, .wpbdp-settings-email-editor {
228
+ display: none;
229
+ margin-left: 10px;
230
+ font-size: 90%;
231
+
232
+ table.form-table {
233
+ margin: 0;
234
+ padding: 0;
235
+
236
+ th {
237
+ padding-left: 4px;
238
+ padding-right: 0;
239
+ min-width: 0;
240
+ width: 20%;
241
+ }
242
+ }
243
+
244
+ input[type="text"] {
245
+ width: 100%;
246
+ }
247
+
248
+ textarea {
249
+ width: 100%;
250
+ min-height: 150px;
251
+ }
252
+
253
+ .placeholders {
254
+ margin: 10px 0 0 0;
255
+ }
256
+
257
+ .placeholder {
258
+ font-size: 90%;
259
+
260
+ .placeholder-code {
261
+ font-family: monospace;
262
+ font-weight: bold;
263
+ }
264
+
265
+ .placeholder-description {
266
+ font-style: italic;
267
+ }
268
+ }
269
+
270
+ .placeholder-separator {
271
+ margin-top: 10px;
272
+ }
273
+
274
+ .buttons {
275
+ margin: 30px 0 0 0;
276
+ text-align: right;
277
+
278
+ .preview-email {
279
+ float: left;
280
+ }
281
+
282
+ .cancel {
283
+ margin-right: 10px;
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ #wpbdp-admin-page-settings .wpbdp-settings-expiration-notices {
290
+
291
+ #wpbdp-settings-expiration-notices-add-btn {
292
+ margin: 0 0 5px 0;
293
+ }
294
+
295
+ #wpbdp-settings-expiration-notices-add {
296
+ .wpbdp-expiration-notice-email {
297
+ display: none;
298
+ border-bottom: 1px solid #ccc;
299
+ }
300
+ }
301
+
302
+ .buttons .delete {
303
+ color: #a00;
304
+ float: left;
305
+ font-size: 13px;
306
+
307
+ &:hover {
308
+ color: red;
309
+ }
310
+ }
311
+ }
312
+
313
+ #wpbdp-admin-page-settings .wpbdp-settings-type-checkbox input[type="checkbox"] {
314
+ vertical-align: bottom;
315
+ }
316
+
317
+ #wpbdp-admin-page-settings .wpbdp-settings-radio-options,
318
+ #wpbdp-admin-page-settings .wpbdp-settings-multicheck-options {
319
+ .wpbdp-settings-radio-option, .wpbdp-settings-multicheck-option {
320
+ margin: 0 0 5px 0;
321
+
322
+ input[type="radio"], input[type="checkbox"] {
323
+ vertical-align: bottom;
324
+ }
325
+ }
326
+
327
+ & + .wpbdp-setting-description {
328
+ margin: 10px 0 0 0;
329
+ }
330
+ }
331
+
332
+ #wpbdp-admin-page-settings #wpbdp-settings-quick-search-fields {
333
+ .wpbdp-settings-multicheck-option {
334
+ width: 50%;
335
+ display: inline-block;
336
+ }
337
+ }
338
+
assets/css/less/admin.less CHANGED
@@ -1,3 +1,5 @@
 
 
1
  .cf:before, .cf:after {
2
  content: " ";
3
  display: table;
@@ -10,18 +12,6 @@
10
  *zoom: 1;
11
  }
12
 
13
- span.tag {
14
- background: #444;
15
- border-radius: 2px;
16
- padding: 2px 5px;
17
- color: #fff;
18
- font-size: 9px !important;
19
- margin-right: 2px;
20
- text-transform: uppercase;
21
- text-decoration: none !important;
22
- line-height: 1.5 !important;
23
- }
24
-
25
  .button-primary.next-to-secondary {
26
  margin-left: 30px;
27
  }
@@ -85,54 +75,8 @@ span.tag {
85
  font-size: 12px;
86
  }
87
 
88
- /* {{{ "Manage Fees" page. */
89
- .wpbdp-page-admin-fees .tablenav {
90
- display: none;
91
- }
92
-
93
- .wpbdp-page-admin-fees .wp-list-table .wpbdp-drag-handle {
94
- margin-right: 15px;
95
- display: none;
96
- }
97
-
98
- .wpbdp-page-admin-fees .purchase-gateways {
99
- margin-left: 20px;
100
- }
101
-
102
- .wpbdp-page-admin-fees .purchase-gateways .gateway {
103
- float: left;
104
- width: 35%;
105
- margin: 30px 20px 0 0;
106
- /* height: 180px;*/
107
- }
108
-
109
- .wpbdp-page-admin-fees .purchase-gateways .gateway.installed {
110
- opacity: 0.5;
111
- }
112
-
113
- .wpbdp-page-admin-fees .purchase-gateways .gateway a img.gateway-logo {
114
- /* width: 30%;*/
115
- height: 40px;
116
- margin: 0;
117
- padding: 0;
118
- border: none;
119
- }
120
-
121
- .wpbdp-page-admin-fees .purchase-gateways .gateway a.price {
122
- margin-top: 10px;
123
- display: block;
124
- color: green;
125
- font-size: 22px;
126
- font-weight: bold;
127
- }
128
-
129
- .wpbdp-page-admin-fees .purchase-gateways .gateway .check-mark {
130
- font-size: 150%;
131
- font-weight: bold;
132
- color: green;
133
- }
134
-
135
- /* }}} */
136
 
137
  /* Directory list-table */
138
  td.column-payment_status .status, td.column-sticky_status .status {
@@ -180,6 +124,7 @@ table.wp-list-table td .tag {
180
  color: #fff;
181
  font-size: 90%;
182
  margin-right: 2px;
 
183
  }
184
 
185
  table.wp-list-table.formfields th.column-label {
@@ -235,89 +180,6 @@ table.wp-list-table.formfields tr.ui-sortable-helper {
235
  font-size: 90%;
236
  }
237
 
238
- #wpbdp-listing-fields input[type="text"] {
239
- width: 70%;
240
- }
241
-
242
- #wpbdp-listing-fields .wpbdp-form-field.url .wpbdp-form-field-html {
243
- padding-left: 10px;
244
- }
245
-
246
- #wpbdp-listing-fields .wpbdp-form-field.url input[type="text"] {
247
- display: block;
248
- }
249
-
250
- #wpbdp-listing-fields #wpbdp-uploaded-images .wpbdp-image {
251
- padding: 5px;
252
- /*border-right: 1px solid #ddd;*/
253
- width: 150px;
254
- vertical-align: top;
255
- /*float: left;*/
256
- display: inline-block;
257
- zoom: 1;
258
- *display: inline;
259
- min-height: 210px;
260
- _height: 210px;
261
- }
262
-
263
- #wpbdp-listing-fields div.listing-images .image img {
264
- max-width: 150px;
265
- }
266
-
267
-
268
- /* FIXME: some front-end styles */
269
- ul#wpbusdirmanerrors { margin-left:20px; }
270
-
271
- /* CSV import */
272
- .wpbdp-csv-import-example {
273
- width: 100%;
274
- padding: 10px;
275
- display: block;
276
- background: #fff;
277
- border: solid 1px #ddd;
278
- font-size: 90%;
279
- font-family: monospace;
280
- height: 100%;
281
- white-space: pre;
282
- }
283
-
284
- #wpbdp-csv-import-form input[type="file"] {
285
- border: none;
286
- }
287
-
288
- table.wpbdp-csv-import-results, table.wpbdp-csv-import-warnings {
289
- width: 100%;
290
- }
291
-
292
- table.wpbdp-csv-import-results .line-no, table.wpbdp-csv-import-warnings .line-no {
293
- width: 50px;
294
- }
295
-
296
- table.wpbdp-csv-import-results td.line, table.wpbdp-csv-import-warnings td.line {
297
- font-family: monospace;
298
- font-size: 90%;
299
- }
300
-
301
- table.wpbdp-csv-import-results .error, table.wpbdp-csv-import-warnings .error {
302
- width: 200px;
303
- }
304
-
305
- table.wpbdp-csv-import-headers {
306
- width: 100%;
307
- }
308
-
309
- table.wpbdp-csv-import-headers td.field-is-required, table.wpbdp-csv-import-headers td.field-is-multivalued {
310
- text-align: center;
311
- }
312
-
313
- table.wpbdp-csv-import-headers tbody tr {
314
- background: #f9f9f9;
315
- }
316
-
317
- table.wpbdp-csv-import-headers tbody tr.alt {
318
- background: inherit;
319
- }
320
-
321
  .wpbdp-form-field.image .preview {
322
  float: none;
323
  }
@@ -440,73 +302,14 @@ body.taxonomy-wpbdp_category .column-id {
440
  border-color: #C00;
441
  }
442
 
443
- /* Admin settings. */
444
- .directory-admin_page_wpbdp_admin_settings table.form-table th, .directory-admin_page_wpbdp_admin_settings table.form-table td {
445
- font-size: 13px;
446
- line-height: 1.0;
447
- padding: 8px 20px;
448
- }
449
-
450
- .directory-admin_page_wpbdp_admin_settings table.form-table th {
451
- min-width: 150px;
452
- }
453
-
454
- .directory-admin_page_wpbdp_admin_settings input, .directory-admin_page_wpbdp_admin_settings select {
455
- font-size: 13px;
456
- line-height: 1.0;
457
- }
458
-
459
- .directory-admin_page_wpbdp_admin_settings textarea {
460
- font-size: 13px;
461
- width: 95%;
462
- }
463
-
464
- .directory-admin_page_wpbdp_admin_settings select {
465
- display: block;
466
- }
467
-
468
- .wpbdp-choices-list {
469
- margin-top: 0;
470
- padding: 0;
471
- }
472
-
473
- .directory-admin_page_wpbdp_admin_settings .license-activation .status-message {
474
- background: none;
475
- box-shadow: none;
476
- border: none;
477
- font-size: 85%;
478
- color: #595959;
479
- font-style: italic;
480
- margin: 0;
481
- padding: 0;
482
-
483
- -webkit-box-shadow: none;
484
- }
485
-
486
- .directory-admin_page_wpbdp_admin_settings .license-activation .status-message.ok {
487
- color: green;
488
- }
489
-
490
- .directory-admin_page_wpbdp_admin_settings .license-activation .status-message.error {
491
- color: red;
492
- }
493
- .directory-admin_page_wpbdp_admin_settings table.form-table .license-activation-error td {
494
- padding-top: 0;
495
- padding-right: 0;
496
- }
497
-
498
- .directory-admin_page_wpbdp_admin_settings .group-error {
499
- border-top: solid 1px red;
500
- }
501
-
502
- .directory-admin_page_wpbdp_admin_settings .group-warning {
503
- border-top: solid 1px yellow;
504
- }
505
-
506
  .wpbdp-notice.dismissible {
507
  position: relative;
508
  }
509
 
 
 
 
 
510
  .tag.paymentstatus.ok {
511
  background: green;
512
  }
@@ -520,164 +323,16 @@ body.taxonomy-wpbdp_category .column-id {
520
  background: red;
521
  }
522
 
523
- #wpbdp-admin-settings tr.disabled {
524
- opacity: 0.7;
525
- }
526
-
527
- #wpbdp-admin-settings .text-fields-warning {
528
- font-size: 90%;
529
- display: block;
530
- margin-bottom: 2px;
531
- }
532
-
533
- #wpbdp-admin-settings .wpbdp-settings-email {
534
- margin: 5px 0 0 0;
535
- border: solid 1px #ccc;
536
- padding: 5px;
537
- background: #fff;
538
- }
539
-
540
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview {
541
- color: #999;
542
- font-size: 90%;
543
- height: 45px;
544
- cursor: pointer;
545
- overflow: hidden;
546
- }
547
-
548
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview h4 {
549
- margin: 0 0 10px 0;
550
- }
551
-
552
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview .edit-toggle {
553
- /* visibility: hidden;*/
554
- float: right;
555
- }
556
-
557
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview:hover .edit-toggle {
558
- visibility: visible;
559
- }
560
-
561
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview dl {
562
  margin: 0;
563
- padding: 0;
564
- }
565
-
566
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview dt {
567
- font-weight: bold;
568
- margin: 0;
569
- padding: 0;
570
- }
571
-
572
- #wpbdp-admin-settings .wpbdp-settings-email .short-preview dd {
573
- margin: 0;
574
- padding: 0 0 0 10px;
575
- }
576
-
577
- #wpbdp-admin-settings .wpbdp-settings-email .editor {
578
- margin-left: 10px;
579
- font-size: 90%;
580
- }
581
-
582
- #wpbdp-admin-settings .wpbdp-settings-email .editor table.form-table {
583
- margin: 0;
584
- padding: 0;
585
- }
586
-
587
- #wpbdp-admin-settings .wpbdp-settings-email table.form-table th {
588
- padding-left: 4px;
589
- padding-right: 0;
590
- min-width: 0;
591
- width: 20%;
592
- }
593
-
594
- #wpbdp-admin-settings .wpbdp-settings-email .editor input[type="text"] {
595
- width: 70%;
596
- }
597
-
598
- #wpbdp-admin-settings .wpbdp-settings-email .editor textarea {
599
- width: 100%;
600
- min-height: 150px;
601
- }
602
-
603
- #wpbdp-admin-settings .wpbdp-settings-email .editor .placeholders {
604
- margin: 10px 0 0 0;
605
- }
606
-
607
- #wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder {
608
- font-size: 90%;
609
- }
610
-
611
- #wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder-separator {
612
- margin-top: 10px;;
613
- }
614
-
615
- #wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder .placeholder-code {
616
- font-family: monospace;
617
- font-weight: bold;
618
- }
619
-
620
- #wpbdp-admin-settings .wpbdp-settings-email .editor .placeholder .placeholder-description {
621
- font-style: italic;
622
- }
623
-
624
- #wpbdp-admin-settings .wpbdp-settings-email .editor .buttons {
625
- margin: 30px 0 0 0;
626
- text-align: right;
627
- }
628
-
629
- #wpbdp-admin-settings .wpbdp-settings-email .editor .buttons .preview-email {
630
- float: left;
631
- }
632
-
633
- #wpbdp-admin-settings .wpbdp-settings-email .editor .buttons .cancel {
634
- margin-right: 10px;
635
- }
636
-
637
- #quick-search-fields li {
638
- width: 50%;
639
- display: inline-block;
640
- }
641
-
642
- /* Listing metabox - Transactions. */
643
- #listing-metabox-transactions table.payments-list {
644
- width: 100%;
645
- border-spacing: 0;
646
  }
647
 
648
- #listing-metabox-transactions table.payments-list tr.payment td {
649
- border-bottom: solid 1px #efefef;
650
- padding: 2px 0;
651
- }
652
-
653
- #listing-metabox-transactions table.payments-list tr.payment td.status {
654
- text-align: right;
655
- }
656
-
657
- #listing-metabox-transactions table.payments-list tr.payment.completed td {
658
- color: green;
659
- }
660
-
661
- #listing-metabox-transactions table.payments-list tr.payment.pending td {
662
- color: red;
663
- }
664
-
665
- #listing-metabox-transactions table.payments-list tr.payment.rejected td {
666
- color: #bbb;
667
- }
668
-
669
- #listing-metabox-transactions table.payments-list tr.payment.canceled td {
670
- text-decoration: line-through;
671
- }
672
-
673
- #listing-metabox-transactions table.payments-list tr.payment a {
674
- text-decoration: none;
675
- color: inherit;
676
- }
677
-
678
- #listing-metabox-transactions table.payments-list tr.payment a:hover {
679
- text-decoration: underline;
680
- }
681
 
682
 
683
  /* Payment Details. */
@@ -743,17 +398,7 @@ body.taxonomy-wpbdp_category .column-id {
743
  /* @end */
744
 
745
  /* {{{ Drag and Drop. */
746
- .wpbdp-drag-handle {
747
- background: red;
748
- width: 6px;
749
- height: 10px;
750
- display: inline-block;
751
- background: url('../images/drag-handle.png') 0 0;
752
- cursor: move;
753
- float: left;
754
- margin: 5px 5px 0 0;
755
- vertical-align: middle;
756
- }
757
 
758
  .wpbdp-draggable-highlight {
759
  background: #bbb;
@@ -835,14 +480,18 @@ body.taxonomy-wpbdp_category .column-id {
835
  }
836
  /* }} */
837
 
838
- .wpbdp-license-expired-warning .module-name {
839
- background: #fff9aa;
840
- padding: 0 5px;
841
- color: #000;
842
- }
843
 
844
- .wpbdp-license-expired-warning .dismiss {
845
- margin-right: 10px;
 
 
 
 
846
  }
847
 
848
  /* {{ Widget config. */
@@ -850,3 +499,68 @@ body.taxonomy-wpbdp_category .column-id {
850
  color: #666;
851
  }
852
  /* }} */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import 'common.less';
2
+
3
  .cf:before, .cf:after {
4
  content: " ";
5
  display: table;
12
  *zoom: 1;
13
  }
14
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  .button-primary.next-to-secondary {
16
  margin-left: 30px;
17
  }
75
  font-size: 12px;
76
  }
77
 
78
+ @import 'admin-fees.less';
79
+ @import 'admin-settings.less';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  /* Directory list-table */
82
  td.column-payment_status .status, td.column-sticky_status .status {
124
  color: #fff;
125
  font-size: 90%;
126
  margin-right: 2px;
127
+ display: inline-block;
128
  }
129
 
130
  table.wp-list-table.formfields th.column-label {
180
  font-size: 90%;
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  .wpbdp-form-field.image .preview {
184
  float: none;
185
  }
302
  border-color: #C00;
303
  }
304
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  .wpbdp-notice.dismissible {
306
  position: relative;
307
  }
308
 
309
+ .tag.paymentstatus {
310
+ text-transform: capitalize;
311
+ }
312
+
313
  .tag.paymentstatus.ok {
314
  background: green;
315
  }
323
  background: red;
324
  }
325
 
326
+ /*
327
+ * {{ Listing information metabox.
328
+ */
329
+ .wpbdp-listing-metabox-tab dl {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  margin: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  }
332
 
333
+ /*
334
+ * }}
335
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
 
338
  /* Payment Details. */
398
  /* @end */
399
 
400
  /* {{{ Drag and Drop. */
401
+
 
 
 
 
 
 
 
 
 
 
402
 
403
  .wpbdp-draggable-highlight {
404
  background: #bbb;
480
  }
481
  /* }} */
482
 
483
+ #wpbdp-licensing-issues-warning {
484
+ ul li {
485
+ list-style-position: inside;
486
+ list-style-type: disc;
487
+ }
488
 
489
+ span.item-name {
490
+ background: #fff9aa;
491
+ padding: 2px 5px;
492
+ margin: 0 0 0 4px;
493
+ border-radius: 4px;
494
+ }
495
  }
496
 
497
  /* {{ Widget config. */
499
  color: #666;
500
  }
501
  /* }} */
502
+
503
+ .wpbdp-admin-tab-nav {
504
+ float: none;
505
+ margin: 0 0 .5em 0;
506
+ }
507
+
508
+ .wpbdp-admin-tab-content {
509
+ padding: 5px 0 0 0;
510
+ display: none;
511
+ }
512
+
513
+ .wpbdp-admin-box {
514
+ label {
515
+ vertical-align: top;
516
+ }
517
+ }
518
+
519
+ a.wpbdp-admin-delete-link {
520
+ color: #a00;
521
+ text-decoration: none;
522
+
523
+ &:hover {
524
+ color: red;
525
+ }
526
+ }
527
+
528
+ @import 'admin-payments.less';
529
+
530
+ // From core/.
531
+ @import 'form-fields.less';
532
+ @import 'submit-listing.less';
533
+
534
+ span.tag {
535
+ .wpbdp-tag;
536
+ }
537
+
538
+ .wpbdp-tag, span.tag {
539
+ &.wpbdp-listing-attr-paid {
540
+ background: green;
541
+ }
542
+
543
+ &.wpbdp-listing-attr-admin-posted {
544
+ background: orange;
545
+ }
546
+
547
+ &.wpbdp-listing-attr-post-status-pending {
548
+ background: blue;
549
+ color: #fff;
550
+ }
551
+ }
552
+
553
+ .wp-list-table td .wpbdp-tag {
554
+ display: inline-block;
555
+ }
556
+
557
+ body.post-type-wpbdp_listing {
558
+
559
+ .wp-list-table {
560
+ .wpbdp-tag {
561
+ font-size: 10px !important;
562
+ text-transform: none !important;
563
+ }
564
+ }
565
+
566
+ }
assets/css/less/checkout.less ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpbdp-checkout-section {
2
+ margin: 0 0 1.5em 0;
3
+ padding: 0.7em 1.2em;
4
+ border: solid 1px #efefef;
5
+
6
+ &.wpbdp-checkout-errors {
7
+ padding: 0;
8
+ border: none;
9
+ }
10
+
11
+ h3 {
12
+ margin: 0 0 1.0em 0;
13
+ padding: 0;
14
+ }
15
+ }
16
+
17
+ .wpbdp-checkout-gateway-selection {
18
+ label {
19
+ margin: 0 10px 0 0;
20
+
21
+ &:last-child {
22
+ margin-right: 0;
23
+ }
24
+ }
25
+ }
26
+
27
+ .wpbdp-billing-detail-field {
28
+ margin: 0 0 1.5em 0;
29
+ font-size: 95%;
30
+
31
+ label {
32
+ margin: 0;
33
+ padding: 0;
34
+ font-weight: bold;
35
+ display: block;
36
+ }
37
+
38
+ .wpbdp-description {
39
+ margin: 0 0 4px 0;
40
+ font-size: 80%;
41
+ color: #666;
42
+ display: block;
43
+ }
44
+
45
+ input[type="text"] {
46
+ width: 100%;
47
+ box-sizing: border-box;
48
+ padding: 4px 6px;
49
+ }
50
+
51
+ &:last-child {
52
+ margin-bottom: 0;
53
+ }
54
+
55
+ &.wpbdp-required label:after {
56
+ content: ' *';
57
+ color: #900000;
58
+ }
59
+ }
60
+
61
+ .wpbdp-payment-receipt {
62
+ border: 1px solid #ccc;
63
+ padding: 1.0em 1.5em;
64
+ margin: 1.5em 0;
65
+ font-size: 90%;
66
+
67
+ h4 {
68
+ margin: 0;
69
+ padding: 0;
70
+ }
71
+
72
+ .wpbdp-payment-receipt-date {
73
+ color: #666;
74
+ }
75
+
76
+ .wpbdp-payment-status {
77
+ float: right;
78
+ }
79
+
80
+ .wpbdp-payment-receipt-details {
81
+ margin: 1.5em 0.5em;
82
+
83
+ dl {
84
+ margin: 0;
85
+ padding: 0;
86
+
87
+ dt {
88
+ margin: 0;
89
+ padding: 0;
90
+ float: left;
91
+ width: 200px;
92
+ }
93
+
94
+ dd {
95
+ margin: 0 0 5px 200px;
96
+ padding: 0;
97
+ }
98
+ }
99
+ }
100
+
101
+ .wpbdp-payment-receipt-print {
102
+ margin: 1.5em 0 0 0;
103
+ }
104
+ }
105
+
106
+ .wpbdp-checkout-invoice {
107
+ table.wpbdp-payment-items-table {
108
+ th, td {
109
+ font-size: 95%;
110
+ }
111
+ }
112
+ }
assets/css/less/common.less ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpbdp-tag {
2
+ background: #444;
3
+ border-radius: 2px;
4
+ padding: 2px 5px;
5
+ color: #fff;
6
+ font-size: 10px !important;
7
+ margin-right: 2px;
8
+ text-decoration: none !important;
9
+ line-height: 1.5 !important;
10
+ white-space: nowrap;
11
+ overflow: hidden;
12
+ text-overflow: ellipsis;
13
+ // text-transform: uppercase;
14
+ }
assets/css/less/form-fields.less ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpbdp-form-field {
2
+ margin: 12px 0;
3
+
4
+ &:first-child {
5
+ margin-top: 0;
6
+ }
7
+
8
+ .wpbdp-form-field-label {
9
+ margin: 0 0 3px 0;
10
+
11
+ label {
12
+ display: inline-block;
13
+ font-weight: bold;
14
+ }
15
+
16
+ .wpbdp-form-field-required-indicator {
17
+ margin-left: 3px;
18
+ font-size: 90%;
19
+ }
20
+ }
21
+
22
+ &.wpbdp-form-field-has-description {
23
+ .wpbdp-form-field-label {
24
+ margin-bottom: 0;
25
+ }
26
+
27
+ .wpbdp-form-field-description {
28
+ margin-bottom: 3px;
29
+ }
30
+ }
31
+
32
+ .wpbdp-form-field-description {
33
+ padding-left: 6px;
34
+ color: #666;
35
+ }
36
+
37
+ .wpbdp-form-field-inner {
38
+ padding-left: 6px;
39
+ }
40
+
41
+ &.wpbdp-form-field-type-textarea textarea,
42
+ &.wpbdp-form-field-type-textfield input[type="text"] {
43
+ width: 100%;
44
+ font-size: inherit;
45
+ }
46
+
47
+ &.wpbdp-form-field-type-textarea textarea {
48
+ min-height: 50px;
49
+ }
50
+
51
+ &.wpbdp-form-field-type-url {
52
+ .wpbdp-url-field-col {
53
+ box-sizing: border-box;
54
+ float: left;
55
+ width: 50%;
56
+
57
+ &:first-child {
58
+ padding-right: 10pt;
59
+ }
60
+
61
+ &:last-child {
62
+ padding-left: 10pt;
63
+ }
64
+
65
+ .sublabel {
66
+ margin: 0;
67
+ display: block;
68
+ }
69
+
70
+ input {
71
+ width: 100%;
72
+ }
73
+ }
74
+ }
75
+
76
+ &.wpbdp-form-field-association-content textarea {
77
+ min-height: 80px;
78
+ }
79
+
80
+ .field-description {
81
+ font-size: 90%;
82
+ color: #696969;
83
+ float: right;
84
+ }
85
+
86
+ .sublabel {
87
+ font-size: 90%;
88
+ margin-left: 10px;
89
+ margin-right: 10px;
90
+ }
91
+ }
92
+
93
+ .wpbdp-form-field-validation-error-wrapper {
94
+ margin: 24px 0;
95
+
96
+ .wpbdp-form-field-validation-errors {
97
+ font-size: 80%;
98
+ color: #d64226;
99
+ position: relative;
100
+ background: #fff;
101
+ border: 1px solid #d64226;
102
+ border-radius: 4px;
103
+ padding: 4px 6px;
104
+ margin: 0 12px 3px 6px;
105
+
106
+ &:after, &:before {
107
+ top: 100%;
108
+ left: 12px;
109
+ border: solid transparent;
110
+ content: " ";
111
+ height: 0;
112
+ width: 0;
113
+ position: absolute;
114
+ pointer-events: none;
115
+ }
116
+
117
+ &:after {
118
+ border-color: rgba(255, 255, 255, 0);
119
+ border-top-color: #fff;
120
+ border-width: 4px;
121
+ margin-left: -4px;
122
+ }
123
+
124
+ &:before {
125
+ border-color: rgba(214, 66, 38, 0);
126
+ border-top-color: #d64226;
127
+ border-width: 5px;
128
+ margin-left: -5px;
129
+ }
130
+ }
131
+
132
+ .wpbdp-form-field {
133
+ margin: 0;
134
+ }
135
+
136
+ .wpbdp-form-field .wpbdp-form-field-label {
137
+ }
138
+
139
+ .wpbdp-form-field-inner {
140
+ }
141
+
142
+ .wpbdp-form-field-type-textfield .wpbdp-form-field-inner input,
143
+ .wpbdp-form-field-type-textarea .wpbdp-form-field-inner textarea {
144
+ // border-color: #d64226;
145
+ }
146
+ }
147
+
assets/css/less/login.less ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpbdp-login-view {
2
+ .wpbdp-login-options {
3
+ margin: 30px 0 0 0;
4
+ box-sizing: border-box;
5
+
6
+ &.options-2 {
7
+ .wpbdp-login-option {
8
+ width: 50%;
9
+ float: left;
10
+ box-sizing: border-box;
11
+
12
+ &:first-child {
13
+ padding: 0 20px 0 0;
14
+ }
15
+
16
+ &:last-child {
17
+ border-left: 1px solid #ccc;
18
+ padding: 0 0 0 20px;
19
+ }
20
+ }
21
+
22
+ }
23
+
24
+ }
25
+ }
assets/css/less/plan-selection.less ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpbdp-plan-info-box {
2
+ padding: 10px;
3
+ margin: 0 0 6px 0;
4
+ border: 1px solid #d2d2d2;
5
+ border-radius: 2px;
6
+ background: #fafafa;
7
+ }
8
+
9
+ .wpbdp-plan-selection-list .wpbdp-plan-info-box:last-child {
10
+ margin-bottom: 0;
11
+ }
12
+
13
+ .wpbdp-plan-info-box .wpbdp-plan-duration,
14
+ .wpbdp-plan-info-box .wpbdp-plan-details,
15
+ .wpbdp-plan-info-box .wpbdp-plan-price {
16
+ float: left;
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ .wpbdp-plan-info-box .wpbdp-plan-duration {
21
+ width: 15%;
22
+ text-align: center;
23
+ }
24
+
25
+ .wpbdp-plan-info-box .wpbdp-plan-duration-never-expires {
26
+ font-size: 21px;
27
+ font-weight: bold;
28
+ display: block;
29
+ line-height: 1.0em;
30
+ text-transform: uppercase;
31
+ word-wrap: break-word;
32
+ }
33
+
34
+ .wpbdp-plan-info-box .wpbdp-plan-duration-amount {
35
+ font-size: 34px;
36
+ font-weight: bold;
37
+ display: block;
38
+ line-height: 1.0em;
39
+ }
40
+
41
+ .wpbdp-plan-info-box .wpbdp-plan-duration-period {
42
+ font-size: 24px;
43
+ display: block;
44
+ line-height: 1.0em;
45
+ }
46
+
47
+ .wpbdp-plan-info-box .wpbdp-plan-details {
48
+ width: 60%;
49
+ padding: 0 10px;
50
+ }
51
+
52
+ .wpbdp-plan-info-box .wpbdp-plan-description {
53
+ margin: 0 0 10px 0;
54
+ }
55
+
56
+ .wpbdp-plan-info-box .wpbdp-plan-label {
57
+ font-size: 1.1em;
58
+ font-weight: bold;
59
+ margin-bottom: 10px;
60
+ }
61
+
62
+ .wpbdp-plan-info-box .wpbdp-plan-feature-list {
63
+ margin: 0 0 0 10px;
64
+ }
65
+
66
+ .wpbdp-plan-info-box .wpbdp-plan-details p {
67
+ margin: 0;
68
+ }
69
+
70
+ .wpbdp-plan-info-box .wpbdp-plan-feature-list li {
71
+ list-style-position: inside;
72
+ margin: 0;
73
+ }
74
+
75
+ .wpbdp-plan-info-box .wpbdp-plan-price {
76
+ width: 25%;
77
+ }
78
+
79
+ .wpbdp-plan-info-box .wpbdp-plan-price label {
80
+ font-size: 20px;
81
+ border: 1px solid #f3f3f3;
82
+ background: #fdfdfd;
83
+ border-radius: 2px;
84
+ display: block;
85
+ padding: 4px 8px;
86
+ }
87
+
88
+ .wpbdp-plan-info-box:not(.display-only) .wpbdp-plan-price label {
89
+ cursor: pointer;
90
+
91
+ &:hover {
92
+ border-color: #d0d0d0;
93
+ background: #fff;
94
+ }
95
+ }
96
+
97
+ .wpbdp-plan-info-box .wpbdp-plan-price label:hover {
98
+ }
99
+
100
+ .wpbdp-plan-info-box .wpbdp-plan-price label input {
101
+ margin: 0 4px 0 0;
102
+ vertical-align: 2px;
103
+ }
104
+ .wpbdp-plan-info-box {
105
+ .wpbdp-plan-disabled-msg {
106
+ clear: both;
107
+ }
108
+ }
109
+
110
+ .wpbdp-plan-selection-wrapper {
111
+ &.wpbdp-size-tiny {
112
+ .wpbdp-plan-duration, .wpbdp-plan-details, .wpbdp-plan-price {
113
+ width: 100%;
114
+ }
115
+
116
+ .wpbdp-plan-duration-amount, .wpbdp-plan-duration-period {
117
+ display: inline;
118
+ }
119
+
120
+ .wpbdp-plan-details {
121
+ padding: 0 0 4pt;
122
+ }
123
+
124
+ .wpbdp-plan-label {
125
+ font-size: 1.5em;
126
+ margin-bottom: 5px;
127
+ }
128
+
129
+ .wpbdp-plan-description {
130
+ margin-bottom: 5px;
131
+ }
132
+ }
133
+
134
+ &.wpbdp-size-small {
135
+ .wpbdp-plan-details {
136
+ width: 50%;
137
+ }
138
+ .wpbdp-plan-price {
139
+ width: 35%;
140
+ }
141
+ }
142
+
143
+ }
144
+
assets/css/less/submit-listing.less ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .select2-results {
2
+ font-size: 11px;
3
+ }
4
+
5
+ #wpbdp-submit-listing {
6
+
7
+ .category_list_item() {
8
+ font-size: 10px;
9
+ margin: 0 5px 0 0;
10
+ padding: 1px 6px;
11
+ border-radius: 3px;
12
+ background: #5bc0de;
13
+ color: #fff;
14
+ font-weight: 700;
15
+ text-align: center;
16
+ white-space: nowrap;
17
+ vertical-align: baseline;
18
+ border: none;
19
+ }
20
+
21
+ input[type="text"], textarea {
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ .wpbdp-submit-listing-section {
26
+ margin: 10px 0 0 0;
27
+ display: block;
28
+
29
+ &.collapsed {
30
+ .collapse-indicator {
31
+ &.expanded {
32
+ display: none;
33
+ }
34
+
35
+ &.collapsed {
36
+ display: inline;
37
+ }
38
+ }
39
+
40
+ .wpbdp-submit-listing-section-content {
41
+ display: none;
42
+ }
43
+ }
44
+
45
+ &.hidden {
46
+ display: none;
47
+ }
48
+ }
49
+
50
+ .wpbdp-submit-listing-section-header {
51
+ background: #ccc;
52
+ text-transform: uppercase;
53
+ font-weight: bold;
54
+ color: #333;
55
+ padding: 2px 10px;
56
+ font-size: 12px;
57
+ cursor: pointer;
58
+
59
+ .collapse-indicator {
60
+ margin: 0 10px 0 0;
61
+ display: none;
62
+
63
+ &.expanded {
64
+ display: inline;
65
+ }
66
+ }
67
+ }
68
+
69
+ .wpbdp-submit-listing-section-content {
70
+ padding: 10px 20px;
71
+ border: solid 1px #ccc;
72
+ border-top: none;
73
+ border-bottom-left-radius: 4px;
74
+ border-bottom-right-radius: 4px;
75
+
76
+ h4 {
77
+ margin: 0 0 10px 0;
78
+ }
79
+ }
80
+
81
+ .wpbdp-submit-listing-form-actions {
82
+ margin: 10px 0;
83
+
84
+ input[type="submit"] {
85
+ float: right;
86
+ }
87
+ }
88
+
89
+ .wpbdp-submit-listing-section-messages {
90
+ margin: 0 0 12px 0;
91
+ }
92
+
93
+ .wpbdp-plan-selection-with-tip {
94
+ margin: 24px 0 0 0;
95
+ display: none;
96
+ }
97
+
98
+ .wpbdp-submit-listing-section-plan_selection {
99
+ ul.category-list {
100
+ margin: 0;
101
+ padding: 0;
102
+ list-style-type: none;
103
+
104
+ li {
105
+ .category_list_item();
106
+ display: inline;
107
+ }
108
+ }
109
+ }
110
+
111
+ .wpbdp-editor-area {
112
+ height: 422px;
113
+ }
114
+
115
+ .wpbdp-submit-listing-section-listing_images {
116
+
117
+ #image-upload-form {
118
+ margin: 15px 10px;
119
+ }
120
+
121
+ #wpbdp-uploaded-images {
122
+ margin: 0 0 20px 0;
123
+ }
124
+
125
+ .wpbdp-image {
126
+ padding: 10px 0;
127
+ border-bottom: dotted 1px #efefef;
128
+
129
+ .wpbdp-image-img {
130
+ width: 60px;
131
+ float: left;
132
+ }
133
+
134
+ .wpbdp-image-extra {
135
+ input[type="text"] {
136
+ width: 60%;
137
+ display: block;
138
+ }
139
+ }
140
+
141
+ .wpbdp-image-delete-link {
142
+ float: right;
143
+ font-size: 11px;
144
+ text-decoration: none;
145
+ color: #900000;
146
+ display: none;
147
+
148
+ &:hover {
149
+ text-decoration: underline;
150
+ color: #ff0000;
151
+ }
152
+ }
153
+
154
+ &:hover {
155
+ .wpbdp-image-delete-link {
156
+ display: inline;
157
+ }
158
+ }
159
+ }
160
+
161
+ // .wpbdp-image {
162
+ // border-bottom: dotted 1px #efefef;
163
+ // margin-right: 10px;
164
+ // margin-bottom: 10px;
165
+ // vertical-align: top;
166
+ //
167
+ // img {
168
+ // vertical-align: top;
169
+ // text-align: center;
170
+ // max-width: 150px;
171
+ // height: auto;
172
+ // }
173
+ //
174
+ // .delete-image {
175
+ // color: #ff0000;
176
+ // }
177
+ // }
178
+
179
+ .wpbdp-image-draggable-highlight {
180
+ width: 160px;
181
+ height: 160px;
182
+ margin: 0 10px;
183
+ background: red;
184
+ float: left;
185
+ }
186
+
187
+ #image-upload-form-no-js {
188
+ width: 0;
189
+ height: 0;
190
+ overflow: hidden;
191
+ visibility: hidden;
192
+ }
193
+
194
+ .area-and-conditions {
195
+ #image-upload-dnd-area {
196
+ float: left;
197
+ width: 72%;
198
+ box-sizing: border-box;
199
+
200
+ &.no-conditions {
201
+ float: none;
202
+ width: 100%;
203
+ }
204
+ }
205
+
206
+ #image-upload-conditions {
207
+ float: right;
208
+ width: 25%;
209
+ color: #666;
210
+ font-size: 90%;
211
+
212
+ dl {
213
+ margin: 0;
214
+
215
+ dt {
216
+ text-overflow: ellipsis;
217
+ white-space: nowrap;
218
+ overflow: hidden;
219
+ }
220
+ }
221
+ }
222
+ }
223
+
224
+ }
225
+
226
+ textarea.wpbdp-submit-listing-tos {
227
+ width: 100%;
228
+ min-height: 100px;
229
+ }
230
+
231
+ #change-plan-link {
232
+ text-align: right;
233
+ font-size: 90%;
234
+ }
235
+
236
+ #wpbdp-submit-listing-account-details {
237
+ margin: 10px 0 0 0;
238
+
239
+ input[type="password"] {
240
+ width: 70%;
241
+ display: inline-block;
242
+ }
243
+
244
+ .wpbdp-password-strength-meter {
245
+ float: right;
246
+ width: 20%;
247
+ padding: 4px;
248
+ text-align: center;
249
+ border: 1px solid;
250
+
251
+ &.strength-0 {
252
+ // Very weak.
253
+ background-color: #f1adad;
254
+ border-color: #e35b5b;
255
+ }
256
+
257
+ &.strength-2 {
258
+ // Weak.
259
+ background-color: #fbc5a9;
260
+ border-color: #f78b53;
261
+ }
262
+
263
+ &.strength-3 {
264
+ // Medium.
265
+ background-color: #ffe399;
266
+ border-color: #ffc733;
267
+ }
268
+
269
+ &.strength-4 {
270
+ // Strong.
271
+ background-color: #c1e1b9;
272
+ border-color: #83c373;
273
+ }
274
+ }
275
+ }
276
+
277
+ }
278
+
assets/css/less/wpbdp-legacy.less CHANGED
@@ -184,4 +184,5 @@ textarea { margin-bottom:15px; }
184
 
185
  #lco input[type="submit"] {
186
  cursor: pointer;
187
- }
 
184
 
185
  #lco input[type="submit"] {
186
  cursor: pointer;
187
+ }
188
+
assets/css/less/wpbdp.less CHANGED
@@ -1,3 +1,5 @@
 
 
1
  .wpbdp-cf:before, .wpbdp-cf:after,
2
  .cf:before, .cf:after {
3
  content: " "; /* 1 */
@@ -51,10 +53,12 @@ form#wpbdmsearchform a.advanced-search-link {
51
  }
52
 
53
  #wpbdp-search-form .wpbdp-search-filter > div.field > input[type="text"] {
 
54
  width: 90%;
55
  }
56
 
57
  #wpbdp-search-form .wpbdp-search-filter > div.field > select {
 
58
  width: 90%;
59
  }
60
 
@@ -63,6 +67,15 @@ form#wpbdmsearchform a.advanced-search-link {
63
  margin: auto;
64
  }
65
 
 
 
 
 
 
 
 
 
 
66
  .wpbdp-pagination {
67
  margin: 25px 0 0 0;
68
  }
@@ -92,7 +105,7 @@ form#wpbdmsearchform a.advanced-search-link {
92
  /* margin-left: 25px;*/
93
  }
94
 
95
- .wpbdp-with-button-styles .listing-actions .wpbdp-button {
96
  padding: 5px 10px;
97
  font-size: 11px;
98
  text-decoration: none;
@@ -110,7 +123,7 @@ form#wpbdmsearchform a.advanced-search-link {
110
  margin-right: 3px;
111
  }
112
 
113
- .wpbdp-with-button-styles .listing-actions .wpbdp-button:hover {
114
  color: #5e5e5e;
115
  background-color: #ebebeb;
116
  background-repeat: repeat-x;
@@ -121,7 +134,7 @@ form#wpbdmsearchform a.advanced-search-link {
121
  background-image: linear-gradient(top, #f9f9f9, #ebebeb);
122
  }
123
 
124
- .wpbdp-with-button-styles .listing-actions .wpbdp-button.delete-listing {
125
  margin-left: 20px;
126
  color: #ff0000;
127
  }
@@ -359,140 +372,15 @@ form#wpbdmsearchform a.advanced-search-link {
359
  clear: none;
360
  }
361
 
362
- /* submit listing page */
363
- .wpbdp-submit-page h3 {
364
- margin-bottom: 10px;
365
- }
366
-
367
- .wpbdp-submit-page .wpbdmp {
368
- margin: 0;
369
- }
370
-
371
- .wpbdp-submit-page legend {
372
- font-size: 85%;
373
- margin-bottom: 20px;
374
- }
375
-
376
- .wpbdp-submit-page .wpbdp-form-field {
377
- margin-bottom: 8px;
378
- }
379
-
380
- .wpbdp-submit-page .wpbdp-form-field .wpbdmcheckboxclass checkbox {
381
- margin-left: 0px;
382
- }
383
-
384
- .wpbdp-submit-page .wpbdp-form-field.required .wpbdp-form-field-label:after {
385
- content: ' *';
386
- font-size: 80%;
387
- }
388
-
389
- .wpbdp-submit-page .wpbdp-form-field-type-textarea textarea {
390
- min-width: 90%;
391
- min-height: 50px;
392
- }
393
-
394
- .wpbdp-submit-page .wpbdp-form-field-association-content textarea {
395
- min-height: 80px;
396
- }
397
-
398
- .wpbdp-form-field .field-description {
399
- font-size: 90%;
400
- color: #696969;
401
- float: right;
402
- }
403
-
404
- .wpbdp-form-field span.sublabel {
405
- font-size: 90%;
406
- margin-left: 10px;
407
- margin-right: 10px;
408
- }
409
-
410
- .wpbdp-form-field.image a.delete {
411
- margin-left: 10px;
412
- }
413
-
414
- ul.validation-errors {
415
- margin: 15px 0 15px 0;
416
- }
417
-
418
- ul.validation-errors li {
419
- color: #ff0000;
420
- margin: 3px 0px;
421
- list-style-position: inside;
422
- }
423
-
424
- .wpbdp-submit-page.step-fees h4 {
425
- background: #ddd;
426
- color: #333;
427
- padding: 10px;
428
- margin-bottom: 5px;
429
- }
430
-
431
- .wpbdp-submit-page.step-images #image-upload-form {
432
- margin: 15px 10px;
433
- }
434
-
435
- .wpbdp-submit-page.step-images .wpbdp-image {
436
- float: left;
437
- border-bottom: dotted 1px #efefef;
438
- margin-right: 10px;
439
- margin-bottom: 10px;
440
- vertical-align: top;
441
- }
442
-
443
- .wpbdp-submit-page.step-images .wpbdp-image img {
444
- vertical-align: top;
445
- text-align: center;
446
- max-width: 150px;
447
- height: auto;
448
- }
449
-
450
- .wpbdp-submit-page.step-images .wpbdp-image-draggable-highlight {
451
- width: 160px;
452
- height: 160px;
453
- margin: 0 10px;
454
- background: red;
455
- float: left;
456
- }
457
-
458
- .wpbdp-submit-page.step-images .area-and-conditions #image-upload-dnd-area {
459
- float: left;
460
- width: 72%;
461
- }
462
-
463
- .wpbdp-submit-page.step-images .area-and-conditions #image-upload-conditions {
464
- float: right;
465
- width: 25%;
466
- color: #666;
467
- }
468
-
469
- .wpbdp-submit-page.step-images .area-and-conditions #image-upload-conditions dl {
470
- margin: 0;
471
- }
472
-
473
- .wpbdp-submit-page.step-images #image-upload-form-no-js {
474
- width: 0;
475
- height: 0;
476
- overflow: hidden;
477
- visibility: hidden;
478
- }
479
-
480
- .wpbdp-submit-page.step-images .wpbdp-image .delete-image {
481
- color: #ff0000;
482
- }
483
-
484
- .wpbdp-submit-page .upgrade-to-featured-option {
485
- border: solid 1px #666;
486
- padding: 5px 10px;
487
- margin: 25px 0 25px 0;
488
- font-size: 90%;
489
- }
490
 
491
  /* error and status messages */
492
  .wpbdp-msg {
493
  font-size: 85%;
494
- padding: 0.6em;
495
- border: solid 1px #e6db55;
496
  color: #555;
497
  margin: 5px 0;
498
  background: #fffbcc;
@@ -500,8 +388,12 @@ ul.validation-errors li {
500
  }
501
 
502
  .wpbdp-msg.error {
503
- background-color: #FFEBE8;
504
- border-color: #C00;
 
 
 
 
505
  }
506
 
507
  /*.wpbusdirmanerroralert { color:#ff0000;font-weight:bold;font-size:14px; }*/
@@ -565,6 +457,22 @@ ul.validation-errors li {
565
  color: #c00;
566
  }
567
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  /*
569
  * Manage Recurring Payments.
570
  */
@@ -632,7 +540,7 @@ table#wpbdp-manage-recurring a.cancel-subscription {
632
 
633
  /* {{ Mobile CSS. */
634
  .wpbdp-show-on-mobile {
635
- display: none !important;
636
  }
637
 
638
  @media screen and (max-width: 500px) {
@@ -641,7 +549,7 @@ table#wpbdp-manage-recurring a.cancel-subscription {
641
  }
642
 
643
  .wpbdp-hide-on-mobile {
644
- display: none !important;
645
  }
646
 
647
  .wpbdp-bar form.wpbdp-search-form {
@@ -769,7 +677,8 @@ body.business-directory #TB_prev {
769
  }
770
 
771
  body.business-directory #TB_caption {
772
- float: none !important;
 
773
  }
774
 
775
  body.business-directory #TB_closeWindow {
@@ -782,7 +691,8 @@ body.business-directory #TB_closeWindow .screen-reader-text {
782
  }
783
 
784
  body.business-directory #TB_secondLine {
785
- text-align: center;
 
786
  }
787
 
788
  /* }} */
@@ -965,8 +875,7 @@ body.business-directory #TB_secondLine {
965
  .wpbdp-view-show_category .wpbdp-view-content-wrapper header.entry-header,
966
  .wpbdp-view-show_tag .wpbdp-view-content-wrapper header.entry-header,
967
  .wpbdp-view-search .wpbdp-view-content-wrapper header.entry-header,
968
- .wpbdp-view-submit_listing .wpbdp-view-content-wrapper header.entry-header,
969
- .wpbdp-view-taxonomy .wpbdp-view-content-wrapper header.entry-header {
970
  display: none;
971
  }
972
 
@@ -1008,154 +917,85 @@ body.business-directory #TB_secondLine {
1008
  * }}
1009
  */
1010
 
1011
- /*
1012
- * Login form {{
1013
- */
1014
- .wpbdp-login-form h2,
1015
- .wpbdp-login-form .wpbdp-login-form-extra-links {
1016
- text-align: center;
1017
- }
1018
- .wpbdp-login-form form {
1019
- margin: 0 auto;
1020
- width: 320px;
1021
- }
1022
- .wpbdp-login-form p {
1023
- margin-bottom: 0;
1024
- }
1025
- .wpbdp-login-form .login-username input,
1026
- .wpbdp-login-form .login-password input {
1027
- display: block;
1028
- width: 100%;
1029
- }
1030
- /*
1031
- * }}
1032
- */
1033
-
1034
 
1035
- /*
1036
- * Plan Selection styles from fees-revamp {{
1037
- */
1038
- .wpbdp-plan-info-box {
1039
- padding: 10px;
1040
- margin: 0 0 6px 0;
1041
- border: 1px solid #d2d2d2;
1042
- border-radius: 2px;
1043
- background: #fafafa;
1044
- }
1045
-
1046
- .wpbdp-plan-selection-list .wpbdp-plan-info-box:last-child {
1047
- margin-bottom: 0;
1048
- }
1049
-
1050
- .wpbdp-plan-info-box .wpbdp-plan-duration,
1051
- .wpbdp-plan-info-box .wpbdp-plan-details,
1052
- .wpbdp-plan-info-box .wpbdp-plan-price {
1053
  float: left;
1054
- box-sizing: border-box;
1055
- }
1056
-
1057
- .wpbdp-plan-info-box .wpbdp-plan-duration {
1058
- width: 15%;
1059
- text-align: center;
1060
- }
1061
-
1062
- .wpbdp-plan-info-box .wpbdp-plan-duration-amount {
1063
- font-size: 34px;
1064
- font-weight: bold;
1065
- display: block;
1066
- line-height: 1.0em;
1067
- }
1068
-
1069
- .wpbdp-plan-info-box .wpbdp-plan-duration-period {
1070
- font-size: 24px;
1071
- display: block;
1072
- line-height: 1.0em;
1073
  }
1074
 
1075
- .wpbdp-plan-info-box .wpbdp-plan-details {
1076
- width: 60%;
1077
- padding: 0 10px;
1078
- }
1079
 
1080
- .wpbdp-plan-info-box .wpbdp-plan-description {
1081
- margin: 0 0 10px 0;
1082
- }
1083
 
1084
- .wpbdp-plan-info-box .wpbdp-plan-label {
1085
- font-size: 1.1em;
1086
- font-weight: bold;
1087
- margin-bottom: 10px;
1088
- }
1089
 
1090
- .wpbdp-plan-info-box .wpbdp-plan-feature-list {
1091
- margin: 0 0 0 10px;
1092
- padding: 0 0 0 10px;
1093
- }
1094
 
1095
- .wpbdp-plan-info-box .wpbdp-plan-details p {
1096
- margin: 0;
 
 
 
 
1097
  }
1098
 
1099
- .wpbdp-plan-info-box .wpbdp-plan-feature-list li {
1100
- margin: 0;
1101
  }
1102
 
1103
- .wpbdp-plan-info-box .wpbdp-plan-price {
1104
- width: 25%;
 
1105
  }
1106
 
1107
- .wpbdp-plan-info-box .wpbdp-plan-price label {
1108
- font-size: 20px;
1109
- border: 1px solid #f3f3f3;
1110
- background: #fdfdfd;
1111
- border-radius: 2px;
1112
- display: block;
1113
- padding: 4px 8px;
1114
  }
1115
 
1116
- .wpbdp-plan-info-box:not(.display-only) .wpbdp-plan-price label {
1117
- cursor: pointer;
1118
 
1119
- &:hover {
1120
- border-color: #d0d0d0;
1121
- background: #fff;
1122
  }
1123
- }
1124
 
1125
- .wpbdp-plan-info-box .wpbdp-plan-price label:hover {
1126
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1127
 
1128
- .wpbdp-plan-info-box .wpbdp-plan-price label input {
1129
- margin: 0 4px 0 0;
1130
- vertical-align: 2px;
1131
- }
1132
 
1133
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-duration,
1134
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-details,
1135
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-price {
1136
- width: 100%;
1137
- }
1138
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-duration-amount,
1139
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-duration-period {
1140
- display: inline;
1141
- }
1142
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-details {
1143
- padding: 0 0 4pt;
1144
- }
1145
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-label {
1146
- font-size: 1.5em;
1147
- margin-bottom: 5px;
1148
- }
1149
- .wpbdp-fee-options-for-category-tiny .wpbdp-plan-description {
1150
- margin-bottom: 5px;
1151
- }
1152
-
1153
- .wpbdp-fee-options-for-category-small .wpbdp-plan-details {
1154
- width: 50%;
1155
- }
1156
- .wpbdp-fee-options-for-category-small .wpbdp-plan-price {
1157
- width: 35%;
1158
  }
1159
- /*
1160
- * }}
1161
- */
1
+ @import 'common.less';
2
+
3
  .wpbdp-cf:before, .wpbdp-cf:after,
4
  .cf:before, .cf:after {
5
  content: " "; /* 1 */
53
  }
54
 
55
  #wpbdp-search-form .wpbdp-search-filter > div.field > input[type="text"] {
56
+ box-sizing: border-box;
57
  width: 90%;
58
  }
59
 
60
  #wpbdp-search-form .wpbdp-search-filter > div.field > select {
61
+ box-sizing: border-box;
62
  width: 90%;
63
  }
64
 
67
  margin: auto;
68
  }
69
 
70
+ .wpbdp-clearfix:after,
71
+ .cf:before, .cf:after {
72
+ content: " "; /* 1 */
73
+ display: table; /* 2 */
74
+ }
75
+
76
+ .wpbdp-clearfix:after, .cf:after { clear: both; }
77
+ .wpbdp-clearfix, .cf { *zoom: 1; }
78
+
79
  .wpbdp-pagination {
80
  margin: 25px 0 0 0;
81
  }
105
  /* margin-left: 25px;*/
106
  }
107
 
108
+ .listing-actions a.button {
109
  padding: 5px 10px;
110
  font-size: 11px;
111
  text-decoration: none;
123
  margin-right: 3px;
124
  }
125
 
126
+ .listing-actions a.button:hover {
127
  color: #5e5e5e;
128
  background-color: #ebebeb;
129
  background-repeat: repeat-x;
134
  background-image: linear-gradient(top, #f9f9f9, #ebebeb);
135
  }
136
 
137
+ .listing-actions a.delete-listing {
138
  margin-left: 20px;
139
  color: #ff0000;
140
  }
372
  clear: none;
373
  }
374
 
375
+ @import 'form-fields.less';
376
+ @import 'checkout.less';
377
+ @import 'submit-listing.less';
378
+ @import 'login.less';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
 
380
  /* error and status messages */
381
  .wpbdp-msg {
382
  font-size: 85%;
383
+ padding: 6px 12px;
 
384
  color: #555;
385
  margin: 5px 0;
386
  background: #fffbcc;
388
  }
389
 
390
  .wpbdp-msg.error {
391
+ color: #fff;
392
+ background: #d64226;
393
+ }
394
+
395
+ .wpbdp-msg.tip {
396
+ background: #d7f5ff;
397
  }
398
 
399
  /*.wpbusdirmanerroralert { color:#ff0000;font-weight:bold;font-size:14px; }*/
457
  color: #c00;
458
  }
459
 
460
+ /*
461
+ * Google Wallet gateway.
462
+ */
463
+
464
+ #googlewallet-buy img {
465
+ border: none;
466
+ box-shadow: none
467
+ }
468
+
469
+ .wpbdp-checkout input[type="image"] {
470
+ padding: 0;
471
+ border: none;
472
+ box-shadow: none;
473
+ width: auto;
474
+ }
475
+
476
  /*
477
  * Manage Recurring Payments.
478
  */
540
 
541
  /* {{ Mobile CSS. */
542
  .wpbdp-show-on-mobile {
543
+ display: none;
544
  }
545
 
546
  @media screen and (max-width: 500px) {
549
  }
550
 
551
  .wpbdp-hide-on-mobile {
552
+ display: none;
553
  }
554
 
555
  .wpbdp-bar form.wpbdp-search-form {
677
  }
678
 
679
  body.business-directory #TB_caption {
680
+ text-align: center;
681
+ width: 70%;
682
  }
683
 
684
  body.business-directory #TB_closeWindow {
691
  }
692
 
693
  body.business-directory #TB_secondLine {
694
+ font-size: 11px;
695
+ color: #666;
696
  }
697
 
698
  /* }} */
875
  .wpbdp-view-show_category .wpbdp-view-content-wrapper header.entry-header,
876
  .wpbdp-view-show_tag .wpbdp-view-content-wrapper header.entry-header,
877
  .wpbdp-view-search .wpbdp-view-content-wrapper header.entry-header,
878
+ .wpbdp-view-submit_listing .wpbdp-view-content-wrapper header.entry-header {
 
879
  display: none;
880
  }
881
 
917
  * }}
918
  */
919
 
920
+ @import 'plan-selection.less';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
 
922
+ .wpbdp-drag-handle {
923
+ width: 6px;
924
+ height: 10px;
925
+ display: inline-block;
926
+ background: url('../../assets/images/drag-handle.png') 0 0;
927
+ cursor: move;
 
 
 
 
 
 
 
 
 
 
 
 
928
  float: left;
929
+ margin: 5px 5px 0 0;
930
+ vertical-align: middle;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
931
  }
932
 
933
+ .wpbdp-help-tip {
934
+ margin: 10px 0;
 
 
935
 
936
+ .dashicons {
937
+ vertical-align: middle;
938
+ }
939
 
940
+ .message {
941
+ display: inline-block;
942
+ }
 
 
943
 
944
+ &.small {
945
+ font-size: 12px;
 
 
946
 
947
+ .dashicons {
948
+ font-size: 15px;
949
+ width: 15px;
950
+ height: 15px;
951
+ }
952
+ }
953
  }
954
 
955
+ .wpbdp-hidden {
956
+ display: none;
957
  }
958
 
959
+ .wpbdp-form-field-association-category .wpbdp-form-field-checkbox-item.disabled,
960
+ .wpbdp-form-field-association-category .wpbdp-form-field-radio-item.disabled {
961
+ opacity: 0.65;
962
  }
963
 
964
+ .wpbdp-form-field-association-category select {
965
+ width: 100%;
 
 
 
 
 
966
  }
967
 
968
+ .wpbdp-form-field-association-category .select2 {
969
+ width: 100%;
970
 
971
+ .select2-selection {
972
+ border-radius: 0;
 
973
  }
 
974
 
975
+ ul.select2-selection__rendered {
976
+ li.select2-selection__choice {
977
+ font-size: 11px;
978
+ padding: 1px 6px;
979
+ border-radius: 3px;
980
+ font-weight: normal;
981
+ white-space: nowrap;
982
+ vertical-align: baseline;
983
+ border: none;
984
+
985
+ .select2-selection__choice__remove {
986
+ margin-right: 5px;
987
+ }
988
+ }
989
+ li.select2-selection__choice,
990
+ li.select2-search--inline {
991
+ margin: 5px 5px 0 0;
992
+ }
993
+ }
994
 
 
 
 
 
995
 
996
+ .select2-search {
997
+ .select2-search__field {
998
+ font-size: 11px;
999
+ }
1000
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1001
  }
 
 
 
assets/css/wpbdp.min.css CHANGED
@@ -1 +1 @@
1
- .wpbdp-cf:before,.wpbdp-cf:after,.cf:before,.cf:after{content:" ";display:table}.wpbdp-cf:after,.cf:after{clear:both}.wpbdp-cf,.cf{*zoom:1}form#wpbdmsearchform{padding:12px 0;text-align:center}form#wpbdmsearchform input{display:inline}form#wpbdmsearchform .wpbdmsearchbutton{margin-top:5px}form#wpbdmsearchform a.advanced-search-link{font-size:70%;display:block}#wpbdp-search-form{padding-left:10px}#wpbdp-search-form .wpbdp-search-filter{margin-bottom:10px;clear:both}#wpbdp-search-form .wpbdp-search-filter>.wpbdp-search-field-label{display:block;width:40%;float:left}#wpbdp-search-form .wpbdp-search-filter>div.field{display:block;width:60%;margin-left:40%;padding-left:5px}#wpbdp-search-form .wpbdp-search-filter>div.field>input[type="text"]{width:90%}#wpbdp-search-form .wpbdp-search-filter>div.field>select{width:90%}#wpbdp-search-form input[type="submit"]{float:none;margin:auto}.wpbdp-pagination{margin:25px 0 0 0}.wpbdp-pagination .next{float:right}.listing-actions form{margin:0;padding:0;display:inline}.listing-actions input{margin:0}.listing-actions input.delete-listing{margin-left:5px;margin-right:30px;color:#ff0000 !important}.wpbdp-with-button-styles .listing-actions .wpbdp-button{padding:5px 10px;font-size:11px;text-decoration:none;background-color:#e6e6e6;color:#7c7c7c;background-repeat:repeat-x;background-image:-moz-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:-ms-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:-webkit-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:-o-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:linear-gradient(top, #f4f4f4, #e6e6e6);border:1px solid #d2d2d2;border-radius:3px;box-shadow:0 1px 2px rgba(64,64,64,0.1);margin-right:3px}.wpbdp-with-button-styles .listing-actions .wpbdp-button:hover{color:#5e5e5e;background-color:#ebebeb;background-repeat:repeat-x;background-image:-moz-linear-gradient(top, #f9f9f9, #ebebeb);background-image:-ms-linear-gradient(top, #f9f9f9, #ebebeb);background-image:-webkit-linear-gradient(top, #f9f9f9, #ebebeb);background-image:-o-linear-gradient(top, #f9f9f9, #ebebeb);background-image:linear-gradient(top, #f9f9f9, #ebebeb)}.wpbdp-with-button-styles .listing-actions .wpbdp-button.delete-listing{margin-left:20px;color:#ff0000}.wpbdp-listing .listing-details .field-value{margin-bottom:10px;width:100%;float:none}.wpbdmsingledetails .singledetailsview .field-value{margin-bottom:10px}.field-value label{color:#444;font-weight:bold}.wpbdp-listing-excerpt{padding:10px;border-bottom:dotted 1px #ddd}.wpbdp-listing-excerpt.odd{background:#eee}.wpbdp-listing-excerpt.sticky{background:#fff0cf;border-bottom:solid 1px #b37800}.wpbdp-listing-excerpt .listing-thumbnail{float:right;margin:0 10px 0 0}.wpbdp-listing-excerpt .listing-actions{margin-top:15px}.wpbdp-listing-single .listing-actions{margin-bottom:25px}.wpbdp-listing-single.sticky{margin-top:30px}.wpbdp-listing-single .stickytag{float:right;margin-top:-68px}.wpbdp-listing-single .stickytag img{border:0;box-shadow:none;background:transparent}.wpbdp-listing-single .listing-title{padding:2px 8px;background:#efefef;border:dotted 1px #ddd;margin-bottom:7px}.wpbdp-listing-single .listing-title h2{clear:none;margin:0}.wpbdp-listing-single .main-image{float:right;margin-left:10px;padding:5px}.wpbdp-listing-single .main-image a{position:relative !important}.wpbdp-listing-single .main-image img{border:solid 1px #333}.wpbdp-listing-single .extra-images{margin-top:10px;clear:both}.wpbdp-listing-single .extra-images ul{margin:0 auto;width:100%}.wpbdp-listing-single .extra-images ul li{list-style-type:none;display:inline;margin-left:5px}.wpbdp-listing-single .extra-images ul li img{display:inline;vertical-align:top;margin:0 auto;max-width:150px;border:solid 1px #333}.wpbdp-listing .social-fields{margin:20px 0}.wpbdp-listing .social-field{margin:5px 0;height:20px;vertical-align:middle}.social-field.facebook .fb-like>span{overflow:visible !important;width:450px !important;vertical-align:top !important}@media screen and (max-width:500px){.social-field.facebook .fb-like>span{width:100% !important}}.wpbdp-listing-contact-form{margin-top:20px;border-top:dotted 1px #ddd;padding-top:20px;padding-left:10px}.wpbdp-listing-contact-form .send-message-button{margin-left:-10px}.wpbdp-listing-contact-form h3{margin-left:-10px}.wpbdp-listing-contact-form textarea{width:98% !important}.wpbdp-listing .comments{margin-top:20px}.wpbdp-bar{background:#f7f7f7;margin:10px 0 20px 0;padding:5px 10px}.wpbdp-bar:before,.wpbdp-bar:after{content:" ";display:table;clear:both}.wpbdp-bar .wpbdp-search-form{margin:0;padding:0 !important;margin-left:50%}.wpbdp-main-links a{margin-right:15px}.wpbdp-bar .left{float:left;text-align:center}.wpbdp-bar .right{width:300px;float:right}.wpbdp-listings-sort-options{font-size:90%;margin:5px 0;text-align:right}.wpbdp-listings-sort-options .current{font-weight:bold}#wpbdp-categories{clear:both}.wpbdp-categories{margin:0;padding-left:20px}.wpbdp-categories .cat-item{box-sizing:border-box;float:left;margin:0 0 20px;width:50%}.wpbdp-categories .cat-item:nth-child(2n+1){clear:left}.wpbdp-categories .cat-item .cat-item{margin:0;width:100%}.wpbdp-categories-tiny .cat-item{float:none;width:100%}.wpbdp-categories-tiny .cat-item:nth-child(2n+1){clear:none}.wpbdp-submit-page h3{margin-bottom:10px}.wpbdp-submit-page .wpbdmp{margin:0}.wpbdp-submit-page legend{font-size:85%;margin-bottom:20px}.wpbdp-submit-page .wpbdp-form-field{margin-bottom:8px}.wpbdp-submit-page .wpbdp-form-field .wpbdmcheckboxclass checkbox{margin-left:0}.wpbdp-submit-page .wpbdp-form-field.required .wpbdp-form-field-label:after{content:' *';font-size:80%}.wpbdp-submit-page .wpbdp-form-field-type-textarea textarea{min-width:90%;min-height:50px}.wpbdp-submit-page .wpbdp-form-field-association-content textarea{min-height:80px}.wpbdp-form-field .field-description{font-size:90%;color:#696969;float:right}.wpbdp-form-field span.sublabel{font-size:90%;margin-left:10px;margin-right:10px}.wpbdp-form-field.image a.delete{margin-left:10px}ul.validation-errors{margin:15px 0 15px 0}ul.validation-errors li{color:#ff0000;margin:3px 0;list-style-position:inside}.wpbdp-submit-page.step-fees h4{background:#ddd;color:#333;padding:10px;margin-bottom:5px}.wpbdp-submit-page.step-images #image-upload-form{margin:15px 10px}.wpbdp-submit-page.step-images .wpbdp-image{float:left;border-bottom:dotted 1px #efefef;margin-right:10px;margin-bottom:10px;vertical-align:top}.wpbdp-submit-page.step-images .wpbdp-image img{vertical-align:top;text-align:center;max-width:150px;height:auto}.wpbdp-submit-page.step-images .wpbdp-image-draggable-highlight{width:160px;height:160px;margin:0 10px;background:red;float:left}.wpbdp-submit-page.step-images .area-and-conditions #image-upload-dnd-area{float:left;width:72%}.wpbdp-submit-page.step-images .area-and-conditions #image-upload-conditions{float:right;width:25%;color:#666}.wpbdp-submit-page.step-images .area-and-conditions #image-upload-conditions dl{margin:0}.wpbdp-submit-page.step-images #image-upload-form-no-js{width:0;height:0;overflow:hidden;visibility:hidden}.wpbdp-submit-page.step-images .wpbdp-image .delete-image{color:#ff0000}.wpbdp-submit-page .upgrade-to-featured-option{border:solid 1px #666;padding:5px 10px;margin:25px 0 25px 0;font-size:90%}.wpbdp-msg{font-size:85%;padding:.6em;border:solid 1px #e6db55;color:#555;margin:5px 0;background:#fffbcc;border-radius:3px}.wpbdp-msg.error{background-color:#FFEBE8;border-color:#C00}.wpbdp-submit-page table.fee-options{width:100%}.wpbdp-submit-page table.fee-options th,.wpbdp-submit-page table.fee-options td{text-align:center}.wpbdp-submit-page table.fee-options td.fee-label,.wpbdp-submit-page table.fee-options tr.fee-description td{text-align:left}.wpbdp-submit-page table.fee-options .fee-selection{width:5%}.wpbdp-submit-page table.fee-options tr.fee-option td.fee-label{font-weight:bold}.wpbdp-submit-page table.fee-options td.fee-description{font-size:90%;color:#666}#wpbdp-renewal-page .do-not-renew-listing{margin:40px 0;border:solid 1px #eee;font-size:95%}#wpbdp-renewal-page .do-not-renew-listing .header{background:#bc0b0b;color:#fff;text-align:center;font-weight:bold;padding:2px 0}#wpbdp-renewal-page .do-not-renew-listing input[type="submit"]{color:#900000}.wpbdp-recaptcha-error{color:#ff0000}#wpbdp-delete-listing-page form.confirm-form{margin-top:30px}#wpbdp-delete-listing-page input.delete-listing-confirm{margin-left:20px;color:#c00}table#wpbdp-manage-recurring th.listing-title,table#wpbdp-manage-recurring td.listing-title{min-width:200px}table#wpbdp-manage-recurring a.cancel-subscription{color:#ff0000}#wpbdp-manage-recurring-cancel dl dd{margin-left:10px}.wpbdp-cc-form{padding:0;width:90%}.wpbdp-cc-form h4{margin:0}.wpbdp-cc-field input{width:auto}.wpbdp-cc-field label{display:block;font-weight:bold;text-align:right;padding-right:10px}#wpbdp-billing-information .billing-info-section h4{margin:10px 0 5px 0}#wpbdp-billing-information .billing-info-section table{margin:1.75em 0}#wpbdp-billing-information #wpbdp-billing-field-exp,#wpbdp-billing-information #wpbdp-billing-field-exp-year{width:40%;display:inline}#wpbdp-billing-information .form-buttons{margin:15px 0}.wpbdp-show-on-mobile{display:none !important}@media screen and (max-width:500px){.wpbdp-show-on-mobile{display:inline !important}.wpbdp-hide-on-mobile{display:none !important}.wpbdp-bar form.wpbdp-search-form{display:block;margin-left:0;margin-top:10px}.wpbdp-bar form.wpbdp-search-form #intextbox{margin-bottom:5px;padding:4px}.wpbdp-bar form.wpbdp-search-form input[type="text"]{padding:4px 0;margin:0 0 2px 0}.wpbdp-listings-sort-options{font-size:90%}.wpbdp-listing.wpbdp-listing{font-size:90%}.wpbdp-listing.wpbdp-listing-excerpt .field-value>label{display:block}.wpbdp-listing.wpbdp-listing-excerpt .listing-thumbnail,.wpbdp-listing.wpbdp-listing-single .listing-thumbnail{float:none;padding:5px}.wpbdp-listing.wpbdp-listing-excerpt .listing-details,.wpbdp-listing.wpbdp-listing-single .listing-details{margin:0 5px;float:none;display:block}.wpbdp-listing .listing-actions input{font-size:85%}.wpbdp-listing .listing-actions input.back-to-dir{float:right}.wpbdp-listing.wpbdp-listing-single .main-image{display:block;float:none;padding:0;margin:0 0 10px 0;text-align:center;max-width:90%}.wpbdp-listing.wpbdp-listing-single .field-value>label{display:block}.wpbdp-submit-page.step-images #image-upload-dnd-area{font-size:90%;float:none !important;width:100% !important}.wpbdp-submit-page.step-images .dnd-area-inside-error{margin-top:30px}.wpbdp-submit-page.step-images #image-upload-conditions{width:100% !important;float:none !important;font-size:90%}.wpbdp-submit-page.step-images #image-upload-conditions dl{margin:0;padding:0}.wpbdp-submit-page.step-images #image-upload-conditions dl dt{margin:0;margin-right:5px;padding:0;float:left}.wpbdp-submit-page.step-images #image-upload-conditions dl dd{margin:0;padding:0;display:block}.wpbdp-submit-page.step-images .wpbdp-image img{max-width:50%}.wpbdp-listings-sort-options.wpbdp-show-on-mobile{margin-bottom:10px}}body.business-directory #TB_ImageOff .screen-reader-text,body.business-directory #TB_closeWindowButton .screen-reader-text{visibility:hidden}body.business-directory #TB_next{float:right}body.business-directory #TB_prev{float:left}body.business-directory #TB_caption{float:none !important}body.business-directory #TB_closeWindow{padding:0;height:0}body.business-directory #TB_closeWindow .screen-reader-text{display:none}body.business-directory #TB_secondLine{text-align:center}.wpbdp-form-row label{display:block}.wpbdp-form-row.wpbdp-form-textfield input[type="text"]{width:400px}.wpbdp-main-box,.wpbdp-main-box .box-row,.wpbdp-main-box .box-col{box-sizing:border-box}.wpbdp-main-box{background:#f7f7f7;margin:10px 0 20px 0;border-radius:4px;padding:10px;width:100%}.wpbdp-main-box .box-row{margin-bottom:4px}.wpbdp-main-box .box-col{margin-bottom:4px;width:100%}.wpbdp-main-box .box-col input{width:100%}.wpbdp-main-box .submit-btn input[type="submit"]{margin-top:0}.wpbdp-main-box .advanced-search-link{border:none;box-shadow:none;display:block;font-size:11px;text-align:right;text-decoration:none}.wpbdp-main-box-medium .box-col,.wpbdp-main-box-large .box-col{float:left}.wpbdp-main-box-medium .search-fields>.cols-1 .box-col,.wpbdp-main-box-large .search-fields>.cols-1 .box-col{width:100%}.wpbdp-main-box-medium .search-fields>.cols-2 .box-col,.wpbdp-main-box-large .search-fields>.cols-2 .box-col{width:50%}.wpbdp-main-box-medium .search-fields>.cols-2 .box-col:first-child,.wpbdp-main-box-large .search-fields>.cols-2 .box-col:first-child{padding-right:5px;width:50%}.wpbdp-main-box-medium .search-fields>.cols-2 .box-col:last-child,.wpbdp-main-box-large .search-fields>.cols-2 .box-col:last-child{padding-left:5px;width:50%}.wpbdp-main-box-medium .search-fields>.cols-3 .box-col,.wpbdp-main-box-large .search-fields>.cols-3 .box-col{padding-left:5px;width:50%}.wpbdp-main-box-medium .search-fields>.cols-3 .box-col:first-child,.wpbdp-main-box-large .search-fields>.cols-3 .box-col:first-child{padding-right:5px}.wpbdp-main-box-medium .search-fields>.cols-3 .box-col:first-child,.wpbdp-main-box-large .search-fields>.cols-3 .box-col:first-child{padding:0;width:100%}.wpbdp-main-box-large .box-row{margin-bottom:0}.wpbdp-main-box-large .search-fields{padding-right:5px;width:78%}.wpbdp-main-box-large .submit-btn{padding-left:5px;width:22%}.wpbdp-main-links{text-align:right}.wpbdp-main-links .button{margin:0 5px}.wpbdp-main-links .button:first-child{margin-left:0}.wpbdp-main-links .button:last-child{margin-right:0}.wpbdp-main-links-tiny .wpbdp-main-links .button{padding-top:10px;padding-bottom:10px;width:100%;margin:0 0 4px}.wpbdp-main-links-small .button{padding-top:10px;padding-bottom:10px;width:100%;margin:0 0 4px}.wpbdp-main-links-small .wpbdp-main-links-2-buttons .button{width:49%}.wpbdp-main-links-small .wpbdp-main-links-2-buttons .button:first-child{margin-right:1%}.wpbdp-main-links-small .wpbdp-main-links-2-buttons .button:last-child{margin-left:1%}.wpbdp-main-links-small .wpbdp-main-links-3-buttons .button:nth-child(2n){width:49%;margin-top:1%;margin-right:1%}.wpbdp-main-links-small .wpbdp-main-links-3-buttons .button:nth-child(2n+3){width:49%;margin-top:1%;margin-left:1%}.wpbdp-main-links-medium .wpbdp-main-links .button{padding-top:8px;padding-bottom:8px}.wpbdp-main-links-large .button{margin:0 3px}.single-wpbdp_listing .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-show_category .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-show_tag .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-search .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-submit_listing .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-taxonomy .wpbdp-view-content-wrapper header.entry-header{display:none}.wpbdp-wp-theme-graphene.single-wpbdp_listing h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-show_category h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-show_tag h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-search h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-submit_listing h1.post-title{display:none}.wpbdp-wp-theme-genesis.wpbdp-view-show_category .archive-description,.wpbdp-wp-theme-genesis.wpbdp-view-show_tag .archive-description{display:none}.wpbdp-wp-theme-hmtpro5.wpbdp-view-show_category .post-details,.wpbdp-wp-theme-hmtpro5.wpbdp-view-show_tag .post-details{display:none}.wpbdp-wp-theme-atahualpa.wpbdp-view-show_category .post-footer,.wpbdp-wp-theme-atahualpa.wpbdp-view-show_tag .post-footer,.wpbdp-wp-theme-atahualpa.wpbdp-view-show_listing .post-footer{display:none}.wpbdp-wp-theme-ultimate-silostorm-pro.wpbdp-view-show_category .entry-content .featured-image,.wpbdp-wp-theme-ultimate-silostorm-pro.wpbdp-view-show_tag .entry-content .featured-image,.wpbdp-wp-theme-ultimate-silostorm-pro.wpbdp-view-show_listing .entry-content .featured-image{display:none}.wpbdp-login-form h2,.wpbdp-login-form .wpbdp-login-form-extra-links{text-align:center}.wpbdp-login-form form{margin:0 auto;width:320px}.wpbdp-login-form p{margin-bottom:0}.wpbdp-login-form .login-username input,.wpbdp-login-form .login-password input{display:block;width:100%}.wpbdp-plan-info-box{padding:10px;margin:0 0 6px 0;border:1px solid #d2d2d2;border-radius:2px;background:#fafafa}.wpbdp-plan-selection-list .wpbdp-plan-info-box:last-child{margin-bottom:0}.wpbdp-plan-info-box .wpbdp-plan-duration,.wpbdp-plan-info-box .wpbdp-plan-details,.wpbdp-plan-info-box .wpbdp-plan-price{float:left;box-sizing:border-box}.wpbdp-plan-info-box .wpbdp-plan-duration{width:15%;text-align:center}.wpbdp-plan-info-box .wpbdp-plan-duration-amount{font-size:34px;font-weight:bold;display:block;line-height:1em}.wpbdp-plan-info-box .wpbdp-plan-duration-period{font-size:24px;display:block;line-height:1em}.wpbdp-plan-info-box .wpbdp-plan-details{width:60%;padding:0 10px}.wpbdp-plan-info-box .wpbdp-plan-description{margin:0 0 10px 0}.wpbdp-plan-info-box .wpbdp-plan-label{font-size:1.1em;font-weight:bold;margin-bottom:10px}.wpbdp-plan-info-box .wpbdp-plan-feature-list{margin:0 0 0 10px;padding:0 0 0 10px}.wpbdp-plan-info-box .wpbdp-plan-details p{margin:0}.wpbdp-plan-info-box .wpbdp-plan-feature-list li{margin:0}.wpbdp-plan-info-box .wpbdp-plan-price{width:25%}.wpbdp-plan-info-box .wpbdp-plan-price label{font-size:20px;border:1px solid #f3f3f3;background:#fdfdfd;border-radius:2px;display:block;padding:4px 8px}.wpbdp-plan-info-box:not(.display-only) .wpbdp-plan-price label{cursor:pointer}.wpbdp-plan-info-box:not(.display-only) .wpbdp-plan-price label:hover{border-color:#d0d0d0;background:#fff}.wpbdp-plan-info-box .wpbdp-plan-price label input{margin:0 4px 0 0;vertical-align:2px}.wpbdp-fee-options-for-category-tiny .wpbdp-plan-duration,.wpbdp-fee-options-for-category-tiny .wpbdp-plan-details,.wpbdp-fee-options-for-category-tiny .wpbdp-plan-price{width:100%}.wpbdp-fee-options-for-category-tiny .wpbdp-plan-duration-amount,.wpbdp-fee-options-for-category-tiny .wpbdp-plan-duration-period{display:inline}.wpbdp-fee-options-for-category-tiny .wpbdp-plan-details{padding:0 0 4pt}.wpbdp-fee-options-for-category-tiny .wpbdp-plan-label{font-size:1.5em;margin-bottom:5px}.wpbdp-fee-options-for-category-tiny .wpbdp-plan-description{margin-bottom:5px}.wpbdp-fee-options-for-category-small .wpbdp-plan-details{width:50%}.wpbdp-fee-options-for-category-small .wpbdp-plan-price{width:35%}
1
+ .wpbdp-tag{background:#444;border-radius:2px;padding:2px 5px;color:#fff;font-size:10px !important;margin-right:2px;text-decoration:none !important;line-height:1.5 !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wpbdp-cf:before,.wpbdp-cf:after,.cf:before,.cf:after{content:" ";display:table}.wpbdp-cf:after,.cf:after{clear:both}.wpbdp-cf,.cf{*zoom:1}form#wpbdmsearchform{padding:12px 0;text-align:center}form#wpbdmsearchform input{display:inline}form#wpbdmsearchform .wpbdmsearchbutton{margin-top:5px}form#wpbdmsearchform a.advanced-search-link{font-size:70%;display:block}#wpbdp-search-form{padding-left:10px}#wpbdp-search-form .wpbdp-search-filter{margin-bottom:10px;clear:both}#wpbdp-search-form .wpbdp-search-filter>.wpbdp-search-field-label{display:block;width:40%;float:left}#wpbdp-search-form .wpbdp-search-filter>div.field{display:block;width:60%;margin-left:40%;padding-left:5px}#wpbdp-search-form .wpbdp-search-filter>div.field>input[type="text"]{box-sizing:border-box;width:90%}#wpbdp-search-form .wpbdp-search-filter>div.field>select{box-sizing:border-box;width:90%}#wpbdp-search-form input[type="submit"]{float:none;margin:auto}.wpbdp-clearfix:after,.cf:before,.cf:after{content:" ";display:table}.wpbdp-clearfix:after,.cf:after{clear:both}.wpbdp-clearfix,.cf{*zoom:1}.wpbdp-pagination{margin:25px 0 0 0}.wpbdp-pagination .next{float:right}.listing-actions form{margin:0;padding:0;display:inline}.listing-actions input{margin:0}.listing-actions input.delete-listing{margin-left:5px;margin-right:30px;color:#ff0000 !important}.listing-actions a.button{padding:5px 10px;font-size:11px;text-decoration:none;background-color:#e6e6e6;color:#7c7c7c;background-repeat:repeat-x;background-image:-moz-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:-ms-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:-webkit-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:-o-linear-gradient(top, #f4f4f4, #e6e6e6);background-image:linear-gradient(top, #f4f4f4, #e6e6e6);border:1px solid #d2d2d2;border-radius:3px;box-shadow:0 1px 2px rgba(64,64,64,0.1);margin-right:3px}.listing-actions a.button:hover{color:#5e5e5e;background-color:#ebebeb;background-repeat:repeat-x;background-image:-moz-linear-gradient(top, #f9f9f9, #ebebeb);background-image:-ms-linear-gradient(top, #f9f9f9, #ebebeb);background-image:-webkit-linear-gradient(top, #f9f9f9, #ebebeb);background-image:-o-linear-gradient(top, #f9f9f9, #ebebeb);background-image:linear-gradient(top, #f9f9f9, #ebebeb)}.listing-actions a.delete-listing{margin-left:20px;color:#ff0000}.wpbdp-listing .listing-details .field-value{margin-bottom:10px;width:100%;float:none}.wpbdmsingledetails .singledetailsview .field-value{margin-bottom:10px}.field-value label{color:#444;font-weight:bold}.wpbdp-listing-excerpt{padding:10px;border-bottom:dotted 1px #ddd}.wpbdp-listing-excerpt.odd{background:#eee}.wpbdp-listing-excerpt.sticky{background:#fff0cf;border-bottom:solid 1px #b37800}.wpbdp-listing-excerpt .listing-thumbnail{float:right;margin:0 10px 0 0}.wpbdp-listing-excerpt .listing-actions{margin-top:15px}.wpbdp-listing-single .listing-actions{margin-bottom:25px}.wpbdp-listing-single.sticky{margin-top:30px}.wpbdp-listing-single .stickytag{float:right;margin-top:-68px}.wpbdp-listing-single .stickytag img{border:0;box-shadow:none;background:transparent}.wpbdp-listing-single .listing-title{padding:2px 8px;background:#efefef;border:dotted 1px #ddd;margin-bottom:7px}.wpbdp-listing-single .listing-title h2{clear:none;margin:0}.wpbdp-listing-single .main-image{float:right;margin-left:10px;padding:5px}.wpbdp-listing-single .main-image a{position:relative !important}.wpbdp-listing-single .main-image img{border:solid 1px #333}.wpbdp-listing-single .extra-images{margin-top:10px;clear:both}.wpbdp-listing-single .extra-images ul{margin:0 auto;width:100%}.wpbdp-listing-single .extra-images ul li{list-style-type:none;display:inline;margin-left:5px}.wpbdp-listing-single .extra-images ul li img{display:inline;vertical-align:top;margin:0 auto;max-width:150px;border:solid 1px #333}.wpbdp-listing .social-fields{margin:20px 0}.wpbdp-listing .social-field{margin:5px 0;height:20px;vertical-align:middle}.social-field.facebook .fb-like>span{overflow:visible !important;width:450px !important;vertical-align:top !important}@media screen and (max-width:500px){.social-field.facebook .fb-like>span{width:100% !important}}.wpbdp-listing-contact-form{margin-top:20px;border-top:dotted 1px #ddd;padding-top:20px;padding-left:10px}.wpbdp-listing-contact-form .send-message-button{margin-left:-10px}.wpbdp-listing-contact-form h3{margin-left:-10px}.wpbdp-listing-contact-form textarea{width:98% !important}.wpbdp-listing .comments{margin-top:20px}.wpbdp-bar{background:#f7f7f7;margin:10px 0 20px 0;padding:5px 10px}.wpbdp-bar:before,.wpbdp-bar:after{content:" ";display:table;clear:both}.wpbdp-bar .wpbdp-search-form{margin:0;padding:0 !important;margin-left:50%}.wpbdp-main-links a{margin-right:15px}.wpbdp-bar .left{float:left;text-align:center}.wpbdp-bar .right{width:300px;float:right}.wpbdp-listings-sort-options{font-size:90%;margin:5px 0;text-align:right}.wpbdp-listings-sort-options .current{font-weight:bold}#wpbdp-categories{clear:both}.wpbdp-categories{margin:0;padding-left:20px}.wpbdp-categories .cat-item{box-sizing:border-box;float:left;margin:0 0 20px;width:50%}.wpbdp-categories .cat-item:nth-child(2n+1){clear:left}.wpbdp-categories .cat-item .cat-item{margin:0;width:100%}.wpbdp-categories-tiny .cat-item{float:none;width:100%}.wpbdp-categories-tiny .cat-item:nth-child(2n+1){clear:none}.wpbdp-form-field{margin:12px 0}.wpbdp-form-field:first-child{margin-top:0}.wpbdp-form-field .wpbdp-form-field-label{margin:0 0 3px 0}.wpbdp-form-field .wpbdp-form-field-label label{display:inline-block;font-weight:bold}.wpbdp-form-field .wpbdp-form-field-label .wpbdp-form-field-required-indicator{margin-left:3px;font-size:90%}.wpbdp-form-field.wpbdp-form-field-has-description .wpbdp-form-field-label{margin-bottom:0}.wpbdp-form-field.wpbdp-form-field-has-description .wpbdp-form-field-description{margin-bottom:3px}.wpbdp-form-field .wpbdp-form-field-description{padding-left:6px;color:#666}.wpbdp-form-field .wpbdp-form-field-inner{padding-left:6px}.wpbdp-form-field.wpbdp-form-field-type-textarea textarea,.wpbdp-form-field.wpbdp-form-field-type-textfield input[type="text"]{width:100%;font-size:inherit}.wpbdp-form-field.wpbdp-form-field-type-textarea textarea{min-height:50px}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col{box-sizing:border-box;float:left;width:50%}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col:first-child{padding-right:10pt}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col:last-child{padding-left:10pt}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col .sublabel{margin:0;display:block}.wpbdp-form-field.wpbdp-form-field-type-url .wpbdp-url-field-col input{width:100%}.wpbdp-form-field.wpbdp-form-field-association-content textarea{min-height:80px}.wpbdp-form-field .field-description{font-size:90%;color:#696969;float:right}.wpbdp-form-field .sublabel{font-size:90%;margin-left:10px;margin-right:10px}.wpbdp-form-field-validation-error-wrapper{margin:24px 0}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors{font-size:80%;color:#d64226;position:relative;background:#fff;border:1px solid #d64226;border-radius:4px;padding:4px 6px;margin:0 12px 3px 6px}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:after,.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:before{top:100%;left:12px;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:after{border-color:rgba(255,255,255,0);border-top-color:#fff;border-width:4px;margin-left:-4px}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field-validation-errors:before{border-color:rgba(214,66,38,0);border-top-color:#d64226;border-width:5px;margin-left:-5px}.wpbdp-form-field-validation-error-wrapper .wpbdp-form-field{margin:0}.wpbdp-checkout-section{margin:0 0 1.5em 0;padding:.7em 1.2em;border:solid 1px #efefef}.wpbdp-checkout-section.wpbdp-checkout-errors{padding:0;border:none}.wpbdp-checkout-section h3{margin:0 0 1em 0;padding:0}.wpbdp-checkout-gateway-selection label{margin:0 10px 0 0}.wpbdp-checkout-gateway-selection label:last-child{margin-right:0}.wpbdp-billing-detail-field{margin:0 0 1.5em 0;font-size:95%}.wpbdp-billing-detail-field label{margin:0;padding:0;font-weight:bold;display:block}.wpbdp-billing-detail-field .wpbdp-description{margin:0 0 4px 0;font-size:80%;color:#666;display:block}.wpbdp-billing-detail-field input[type="text"]{width:100%;box-sizing:border-box;padding:4px 6px}.wpbdp-billing-detail-field:last-child{margin-bottom:0}.wpbdp-billing-detail-field.wpbdp-required label:after{content:' *';color:#900000}.wpbdp-payment-receipt{border:1px solid #ccc;padding:1em 1.5em;margin:1.5em 0;font-size:90%}.wpbdp-payment-receipt h4{margin:0;padding:0}.wpbdp-payment-receipt .wpbdp-payment-receipt-date{color:#666}.wpbdp-payment-receipt .wpbdp-payment-status{float:right}.wpbdp-payment-receipt .wpbdp-payment-receipt-details{margin:1.5em .5em}.wpbdp-payment-receipt .wpbdp-payment-receipt-details dl{margin:0;padding:0}.wpbdp-payment-receipt .wpbdp-payment-receipt-details dl dt{margin:0;padding:0;float:left;width:200px}.wpbdp-payment-receipt .wpbdp-payment-receipt-details dl dd{margin:0 0 5px 200px;padding:0}.wpbdp-payment-receipt .wpbdp-payment-receipt-print{margin:1.5em 0 0 0}.wpbdp-checkout-invoice table.wpbdp-payment-items-table th,.wpbdp-checkout-invoice table.wpbdp-payment-items-table td{font-size:95%}.select2-results{font-size:11px}#wpbdp-submit-listing input[type="text"],#wpbdp-submit-listing textarea{box-sizing:border-box}#wpbdp-submit-listing .wpbdp-submit-listing-section{margin:10px 0 0 0;display:block}#wpbdp-submit-listing .wpbdp-submit-listing-section.collapsed .collapse-indicator.expanded{display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section.collapsed .collapse-indicator.collapsed{display:inline}#wpbdp-submit-listing .wpbdp-submit-listing-section.collapsed .wpbdp-submit-listing-section-content{display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section.hidden{display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-header{background:#ccc;text-transform:uppercase;font-weight:bold;color:#333;padding:2px 10px;font-size:12px;cursor:pointer}#wpbdp-submit-listing .wpbdp-submit-listing-section-header .collapse-indicator{margin:0 10px 0 0;display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-header .collapse-indicator.expanded{display:inline}#wpbdp-submit-listing .wpbdp-submit-listing-section-content{padding:10px 20px;border:solid 1px #ccc;border-top:none;border-bottom-left-radius:4px;border-bottom-right-radius:4px}#wpbdp-submit-listing .wpbdp-submit-listing-section-content h4{margin:0 0 10px 0}#wpbdp-submit-listing .wpbdp-submit-listing-form-actions{margin:10px 0}#wpbdp-submit-listing .wpbdp-submit-listing-form-actions input[type="submit"]{float:right}#wpbdp-submit-listing .wpbdp-submit-listing-section-messages{margin:0 0 12px 0}#wpbdp-submit-listing .wpbdp-plan-selection-with-tip{margin:24px 0 0 0;display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-plan_selection ul.category-list{margin:0;padding:0;list-style-type:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-plan_selection ul.category-list li{font-size:10px;margin:0 5px 0 0;padding:1px 6px;border-radius:3px;background:#5bc0de;color:#fff;font-weight:700;text-align:center;white-space:nowrap;vertical-align:baseline;border:none;display:inline}#wpbdp-submit-listing .wpbdp-editor-area{height:422px}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images #image-upload-form{margin:15px 10px}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images #wpbdp-uploaded-images{margin:0 0 20px 0}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image{padding:10px 0;border-bottom:dotted 1px #efefef}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-img{width:60px;float:left}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-extra input[type="text"]{width:60%;display:block}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-delete-link{float:right;font-size:11px;text-decoration:none;color:#900000;display:none}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image .wpbdp-image-delete-link:hover{text-decoration:underline;color:#ff0000}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image:hover .wpbdp-image-delete-link{display:inline}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .wpbdp-image-draggable-highlight{width:160px;height:160px;margin:0 10px;background:red;float:left}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images #image-upload-form-no-js{width:0;height:0;overflow:hidden;visibility:hidden}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-dnd-area{float:left;width:72%;box-sizing:border-box}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-dnd-area.no-conditions{float:none;width:100%}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-conditions{float:right;width:25%;color:#666;font-size:90%}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-conditions dl{margin:0}#wpbdp-submit-listing .wpbdp-submit-listing-section-listing_images .area-and-conditions #image-upload-conditions dl dt{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}#wpbdp-submit-listing textarea.wpbdp-submit-listing-tos{width:100%;min-height:100px}#wpbdp-submit-listing #change-plan-link{text-align:right;font-size:90%}#wpbdp-submit-listing #wpbdp-submit-listing-account-details{margin:10px 0 0 0}#wpbdp-submit-listing #wpbdp-submit-listing-account-details input[type="password"]{width:70%;display:inline-block}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter{float:right;width:20%;padding:4px;text-align:center;border:1px solid}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-0{background-color:#f1adad;border-color:#e35b5b}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-2{background-color:#fbc5a9;border-color:#f78b53}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-3{background-color:#ffe399;border-color:#ffc733}#wpbdp-submit-listing #wpbdp-submit-listing-account-details .wpbdp-password-strength-meter.strength-4{background-color:#c1e1b9;border-color:#83c373}#wpbdp-login-view .wpbdp-login-options{margin:30px 0 0 0;box-sizing:border-box}#wpbdp-login-view .wpbdp-login-options.options-2 .wpbdp-login-option{width:50%;float:left;box-sizing:border-box}#wpbdp-login-view .wpbdp-login-options.options-2 .wpbdp-login-option:first-child{padding:0 20px 0 0}#wpbdp-login-view .wpbdp-login-options.options-2 .wpbdp-login-option:last-child{border-left:1px solid #ccc;padding:0 0 0 20px}.wpbdp-msg{font-size:85%;padding:6px 12px;color:#555;margin:5px 0;background:#fffbcc;border-radius:3px}.wpbdp-msg.error{color:#fff;background:#d64226}.wpbdp-msg.tip{background:#d7f5ff}.wpbdp-submit-page table.fee-options{width:100%}.wpbdp-submit-page table.fee-options th,.wpbdp-submit-page table.fee-options td{text-align:center}.wpbdp-submit-page table.fee-options td.fee-label,.wpbdp-submit-page table.fee-options tr.fee-description td{text-align:left}.wpbdp-submit-page table.fee-options .fee-selection{width:5%}.wpbdp-submit-page table.fee-options tr.fee-option td.fee-label{font-weight:bold}.wpbdp-submit-page table.fee-options td.fee-description{font-size:90%;color:#666}#wpbdp-renewal-page .do-not-renew-listing{margin:40px 0;border:solid 1px #eee;font-size:95%}#wpbdp-renewal-page .do-not-renew-listing .header{background:#bc0b0b;color:#fff;text-align:center;font-weight:bold;padding:2px 0}#wpbdp-renewal-page .do-not-renew-listing input[type="submit"]{color:#900000}.wpbdp-recaptcha-error{color:#ff0000}#wpbdp-delete-listing-page form.confirm-form{margin-top:30px}#wpbdp-delete-listing-page input.delete-listing-confirm{margin-left:20px;color:#c00}#googlewallet-buy img{border:none;box-shadow:none}.wpbdp-checkout input[type="image"]{padding:0;border:none;box-shadow:none;width:auto}table#wpbdp-manage-recurring th.listing-title,table#wpbdp-manage-recurring td.listing-title{min-width:200px}table#wpbdp-manage-recurring a.cancel-subscription{color:#ff0000}#wpbdp-manage-recurring-cancel dl dd{margin-left:10px}.wpbdp-cc-form{padding:0;width:90%}.wpbdp-cc-form h4{margin:0}.wpbdp-cc-field input{width:auto}.wpbdp-cc-field label{display:block;font-weight:bold;text-align:right;padding-right:10px}#wpbdp-billing-information .billing-info-section h4{margin:10px 0 5px 0}#wpbdp-billing-information .billing-info-section table{margin:1.75em 0}#wpbdp-billing-information #wpbdp-billing-field-exp,#wpbdp-billing-information #wpbdp-billing-field-exp-year{width:40%;display:inline}#wpbdp-billing-information .form-buttons{margin:15px 0}.wpbdp-show-on-mobile{display:none}@media screen and (max-width:500px){.wpbdp-show-on-mobile{display:inline !important}.wpbdp-hide-on-mobile{display:none}.wpbdp-bar form.wpbdp-search-form{display:block;margin-left:0;margin-top:10px}.wpbdp-bar form.wpbdp-search-form #intextbox{margin-bottom:5px;padding:4px}.wpbdp-bar form.wpbdp-search-form input[type="text"]{padding:4px 0;margin:0 0 2px 0}.wpbdp-listings-sort-options{font-size:90%}.wpbdp-listing.wpbdp-listing{font-size:90%}.wpbdp-listing.wpbdp-listing-excerpt .field-value>label{display:block}.wpbdp-listing.wpbdp-listing-excerpt .listing-thumbnail,.wpbdp-listing.wpbdp-listing-single .listing-thumbnail{float:none;padding:5px}.wpbdp-listing.wpbdp-listing-excerpt .listing-details,.wpbdp-listing.wpbdp-listing-single .listing-details{margin:0 5px;float:none;display:block}.wpbdp-listing .listing-actions input{font-size:85%}.wpbdp-listing .listing-actions input.back-to-dir{float:right}.wpbdp-listing.wpbdp-listing-single .main-image{display:block;float:none;padding:0;margin:0 0 10px 0;text-align:center;max-width:90%}.wpbdp-listing.wpbdp-listing-single .field-value>label{display:block}.wpbdp-submit-page.step-images #image-upload-dnd-area{font-size:90%;float:none !important;width:100% !important}.wpbdp-submit-page.step-images .dnd-area-inside-error{margin-top:30px}.wpbdp-submit-page.step-images #image-upload-conditions{width:100% !important;float:none !important;font-size:90%}.wpbdp-submit-page.step-images #image-upload-conditions dl{margin:0;padding:0}.wpbdp-submit-page.step-images #image-upload-conditions dl dt{margin:0;margin-right:5px;padding:0;float:left}.wpbdp-submit-page.step-images #image-upload-conditions dl dd{margin:0;padding:0;display:block}.wpbdp-submit-page.step-images .wpbdp-image img{max-width:50%}.wpbdp-listings-sort-options.wpbdp-show-on-mobile{margin-bottom:10px}}body.business-directory #TB_ImageOff .screen-reader-text,body.business-directory #TB_closeWindowButton .screen-reader-text{visibility:hidden}body.business-directory #TB_next{float:right}body.business-directory #TB_prev{float:left}body.business-directory #TB_caption{text-align:center;width:70%}body.business-directory #TB_closeWindow{padding:0;height:0}body.business-directory #TB_closeWindow .screen-reader-text{display:none}body.business-directory #TB_secondLine{font-size:11px;color:#666}.wpbdp-form-row label{display:block}.wpbdp-form-row.wpbdp-form-textfield input[type="text"]{width:400px}.wpbdp-main-box,.wpbdp-main-box .box-row,.wpbdp-main-box .box-col{box-sizing:border-box}.wpbdp-main-box{background:#f7f7f7;margin:10px 0 20px 0;border-radius:4px;padding:10px;width:100%}.wpbdp-main-box .box-row{margin-bottom:4px}.wpbdp-main-box .box-col{margin-bottom:4px;width:100%}.wpbdp-main-box .box-col input{width:100%}.wpbdp-main-box .submit-btn input[type="submit"]{margin-top:0}.wpbdp-main-box .advanced-search-link{border:none;box-shadow:none;display:block;font-size:11px;text-align:right;text-decoration:none}.wpbdp-main-box-medium .box-col,.wpbdp-main-box-large .box-col{float:left}.wpbdp-main-box-medium .search-fields>.cols-1 .box-col,.wpbdp-main-box-large .search-fields>.cols-1 .box-col{width:100%}.wpbdp-main-box-medium .search-fields>.cols-2 .box-col,.wpbdp-main-box-large .search-fields>.cols-2 .box-col{width:50%}.wpbdp-main-box-medium .search-fields>.cols-2 .box-col:first-child,.wpbdp-main-box-large .search-fields>.cols-2 .box-col:first-child{padding-right:5px;width:50%}.wpbdp-main-box-medium .search-fields>.cols-2 .box-col:last-child,.wpbdp-main-box-large .search-fields>.cols-2 .box-col:last-child{padding-left:5px;width:50%}.wpbdp-main-box-medium .search-fields>.cols-3 .box-col,.wpbdp-main-box-large .search-fields>.cols-3 .box-col{padding-left:5px;width:50%}.wpbdp-main-box-medium .search-fields>.cols-3 .box-col:first-child,.wpbdp-main-box-large .search-fields>.cols-3 .box-col:first-child{padding-right:5px}.wpbdp-main-box-medium .search-fields>.cols-3 .box-col:first-child,.wpbdp-main-box-large .search-fields>.cols-3 .box-col:first-child{padding:0;width:100%}.wpbdp-main-box-large .box-row{margin-bottom:0}.wpbdp-main-box-large .search-fields{padding-right:5px;width:78%}.wpbdp-main-box-large .submit-btn{padding-left:5px;width:22%}.wpbdp-main-links{text-align:right}.wpbdp-main-links .button{margin:0 5px}.wpbdp-main-links .button:first-child{margin-left:0}.wpbdp-main-links .button:last-child{margin-right:0}.wpbdp-main-links-tiny .wpbdp-main-links .button{padding-top:10px;padding-bottom:10px;width:100%;margin:0 0 4px}.wpbdp-main-links-small .button{padding-top:10px;padding-bottom:10px;width:100%;margin:0 0 4px}.wpbdp-main-links-small .wpbdp-main-links-2-buttons .button{width:49%}.wpbdp-main-links-small .wpbdp-main-links-2-buttons .button:first-child{margin-right:1%}.wpbdp-main-links-small .wpbdp-main-links-2-buttons .button:last-child{margin-left:1%}.wpbdp-main-links-small .wpbdp-main-links-3-buttons .button:nth-child(2n){width:49%;margin-top:1%;margin-right:1%}.wpbdp-main-links-small .wpbdp-main-links-3-buttons .button:nth-child(2n+3){width:49%;margin-top:1%;margin-left:1%}.wpbdp-main-links-medium .wpbdp-main-links .button{padding-top:8px;padding-bottom:8px}.wpbdp-main-links-large .button{margin:0 3px}.single-wpbdp_listing .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-show_category .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-show_tag .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-search .wpbdp-view-content-wrapper header.entry-header,.wpbdp-view-submit_listing .wpbdp-view-content-wrapper header.entry-header{display:none}.wpbdp-wp-theme-graphene.single-wpbdp_listing h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-show_category h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-show_tag h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-search h1.post-title,.wpbdp-wp-theme-graphene.wpbdp-view-submit_listing h1.post-title{display:none}.wpbdp-wp-theme-genesis.wpbdp-view-show_category .archive-description,.wpbdp-wp-theme-genesis.wpbdp-view-show_tag .archive-description{display:none}.wpbdp-wp-theme-hmtpro5.wpbdp-view-show_category .post-details,.wpbdp-wp-theme-hmtpro5.wpbdp-view-show_tag .post-details{display:none}.wpbdp-wp-theme-atahualpa.wpbdp-view-show_category .post-footer,.wpbdp-wp-theme-atahualpa.wpbdp-view-show_tag .post-footer,.wpbdp-wp-theme-atahualpa.wpbdp-view-show_listing .post-footer{display:none}.wpbdp-wp-theme-ultimate-silostorm-pro.wpbdp-view-show_category .entry-content .featured-image,.wpbdp-wp-theme-ultimate-silostorm-pro.wpbdp-view-show_tag .entry-content .featured-image,.wpbdp-wp-theme-ultimate-silostorm-pro.wpbdp-view-show_listing .entry-content .featured-image{display:none}.wpbdp-plan-info-box{padding:10px;margin:0 0 6px 0;border:1px solid #d2d2d2;border-radius:2px;background:#fafafa}.wpbdp-plan-selection-list .wpbdp-plan-info-box:last-child{margin-bottom:0}.wpbdp-plan-info-box .wpbdp-plan-duration,.wpbdp-plan-info-box .wpbdp-plan-details,.wpbdp-plan-info-box .wpbdp-plan-price{float:left;box-sizing:border-box}.wpbdp-plan-info-box .wpbdp-plan-duration{width:15%;text-align:center}.wpbdp-plan-info-box .wpbdp-plan-duration-never-expires{font-size:21px;font-weight:bold;display:block;line-height:1em;text-transform:uppercase;word-wrap:break-word}.wpbdp-plan-info-box .wpbdp-plan-duration-amount{font-size:34px;font-weight:bold;display:block;line-height:1em}.wpbdp-plan-info-box .wpbdp-plan-duration-period{font-size:24px;display:block;line-height:1em}.wpbdp-plan-info-box .wpbdp-plan-details{width:60%;padding:0 10px}.wpbdp-plan-info-box .wpbdp-plan-description{margin:0 0 10px 0}.wpbdp-plan-info-box .wpbdp-plan-label{font-size:1.1em;font-weight:bold;margin-bottom:10px}.wpbdp-plan-info-box .wpbdp-plan-feature-list{margin:0 0 0 10px}.wpbdp-plan-info-box .wpbdp-plan-details p{margin:0}.wpbdp-plan-info-box .wpbdp-plan-feature-list li{list-style-position:inside;margin:0}.wpbdp-plan-info-box .wpbdp-plan-price{width:25%}.wpbdp-plan-info-box .wpbdp-plan-price label{font-size:20px;border:1px solid #f3f3f3;background:#fdfdfd;border-radius:2px;display:block;padding:4px 8px}.wpbdp-plan-info-box:not(.display-only) .wpbdp-plan-price label{cursor:pointer}.wpbdp-plan-info-box:not(.display-only) .wpbdp-plan-price label:hover{border-color:#d0d0d0;background:#fff}.wpbdp-plan-info-box .wpbdp-plan-price label input{margin:0 4px 0 0;vertical-align:2px}.wpbdp-plan-info-box .wpbdp-plan-disabled-msg{clear:both}.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-duration,.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-details,.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-price{width:100%}.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-duration-amount,.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-duration-period{display:inline}.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-details{padding:0 0 4pt}.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-label{font-size:1.5em;margin-bottom:5px}.wpbdp-plan-selection-wrapper.wpbdp-size-tiny .wpbdp-plan-description{margin-bottom:5px}.wpbdp-plan-selection-wrapper.wpbdp-size-small .wpbdp-plan-details{width:50%}.wpbdp-plan-selection-wrapper.wpbdp-size-small .wpbdp-plan-price{width:35%}.wpbdp-drag-handle{width:6px;height:10px;display:inline-block;background:url('../../assets/images/drag-handle.png') 0 0;cursor:move;float:left;margin:5px 5px 0 0;vertical-align:middle}.wpbdp-help-tip{margin:10px 0}.wpbdp-help-tip .dashicons{vertical-align:middle}.wpbdp-help-tip .message{display:inline-block}.wpbdp-help-tip.small{font-size:12px}.wpbdp-help-tip.small .dashicons{font-size:15px;width:15px;height:15px}.wpbdp-hidden{display:none}.wpbdp-form-field-association-category .wpbdp-form-field-checkbox-item.disabled,.wpbdp-form-field-association-category .wpbdp-form-field-radio-item.disabled{opacity:.65}.wpbdp-form-field-association-category select{width:100%}.wpbdp-form-field-association-category .select2{width:100%}.wpbdp-form-field-association-category .select2 .select2-selection{border-radius:0}.wpbdp-form-field-association-category .select2 ul.select2-selection__rendered li.select2-selection__choice{font-size:11px;padding:1px 6px;border-radius:3px;font-weight:normal;white-space:nowrap;vertical-align:baseline;border:none}.wpbdp-form-field-association-category .select2 ul.select2-selection__rendered li.select2-selection__choice .select2-selection__choice__remove{margin-right:5px}.wpbdp-form-field-association-category .select2 ul.select2-selection__rendered li.select2-selection__choice,.wpbdp-form-field-association-category .select2 ul.select2-selection__rendered li.select2-search--inline{margin:5px 5px 0 0}.wpbdp-form-field-association-category .select2 .select2-search .select2-search__field{font-size:11px}
assets/images/default.png DELETED
Binary file
assets/js/admin-export.js CHANGED
@@ -28,7 +28,7 @@ jQuery(function($) {
28
  return;
29
 
30
  lastState = state;
31
-
32
  if (cancelExport) {
33
  exportInProgress = false
34
  cancelExport = false;
28
  return;
29
 
30
  lastState = state;
31
+
32
  if (cancelExport) {
33
  exportInProgress = false
34
  cancelExport = false;
assets/js/admin-fees.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($) {
2
+ var $form = $( 'form#wpbdp-fee-form' );
3
+
4
+ if ( 0 == $form.length )
5
+ return;
6
+
7
+ var update_form_ui = function( event ) {
8
+ // Listing run.
9
+ var fee__days = $( 'input[name="_days"]:checked', $form ).val(),
10
+ $textfield = $( 'input[name="fee[days]"]', $form );
11
+
12
+ if ( 0 == fee__days ) {
13
+ $textfield.prop( 'disabled', true ).val( '0' );
14
+ } else {
15
+ // A field cannot gain focus if it is disabled
16
+ $textfield.prop( 'disabled', false );
17
+
18
+ if ( event && $( '#wpbdp-fee-form-days', $form ).is( event.target ) ) {
19
+ $textfield.focus();
20
+ }
21
+ }
22
+
23
+ // Category Policy.
24
+ var $pricing = $( 'input[name="fee[pricing_model]"]', $form );
25
+ var limit_categories = $( 'select[name="limit_categories"]', $form ).val() == '1',
26
+ pricing = $pricing.filter( ':checked' ).val();
27
+ var $category_chooser = $( '#limit-categories-list', $form );
28
+ var selected_categories = [];
29
+
30
+ if ( limit_categories ) {
31
+ $category_chooser.removeClass( 'hidden' );
32
+
33
+ if ( $( 'select', $category_chooser ).length > 0 ) {
34
+ selected_categories = $( 'select', $category_chooser ).val();
35
+
36
+ if ( ! selected_categories ) {
37
+ selected_categories = [];
38
+ }
39
+ } else {
40
+ selected_categories = $( 'input:checked', $category_chooser ).map( function( i, cb ){ return $( cb ).val() } ).get();
41
+ }
42
+
43
+ if ( selected_categories.length > 0 ) {
44
+ $pricing.filter( '[value="variable"]' ).parent().show();
45
+ } else {
46
+ $pricing.filter( '[value="variable"]' ).parent().hide();
47
+ pricing = $pricing.val(['flat']).val();
48
+ }
49
+ } else {
50
+ $category_chooser.addClass( 'hidden' );
51
+ $pricing.filter( '[value="variable"]' ).parent().show();
52
+ }
53
+
54
+ // Show pricing details.
55
+ $( '.fee-pricing-details' ).not( '.pricing-details-' + pricing ).addClass( 'hidden' );
56
+ $( '.fee-pricing-details.pricing-details-' + pricing, $form ).removeClass( 'hidden' );
57
+
58
+ // Show only the price-rows that match the category selection.
59
+ if ( 'variable' == pricing ) {
60
+ var $rows = $( '.wpbdp-variable-pricing-configurator-row', $form );
61
+
62
+ if ( ! limit_categories ) {
63
+ $rows.removeClass( 'hidden' );
64
+ } else {
65
+ $rows.addClass( 'hidden' );
66
+ $.each( selected_categories, function( i, val ) {
67
+ $rows.filter( '[data-term-id="' + val + '"]' ).removeClass( 'hidden' );
68
+ });
69
+ }
70
+ }
71
+ };
72
+ update_form_ui();
73
+
74
+
75
+ $( 'input[name="fee[days]"]', $form ).blur( function() {
76
+ var val = parseInt( $.trim( $( this ).val() ), 10 );
77
+ $( this ).val( isNaN( val ) ? '0' : Math.max( 0, Math.round( val ) ) );
78
+ } );
79
+
80
+ $( 'input[name="_days"],' +
81
+ 'select[name="limit_categories"],' +
82
+ 'input[name="fee[pricing_model]"],' +
83
+ '#limit-categories-list input[type="checkbox"],' +
84
+ '#limit-categories-list select'
85
+ ).change( update_form_ui );
86
+
87
+ $( '#limit-categories-list select' ).select2({
88
+ placeholder: $( '#limit-categories-list select' ).attr( 'placeholder' )
89
+ });
90
+
91
+ $form.submit(function() {
92
+ $( 'input[name="fee[days]"]', $form ).prop( 'disabled', false );
93
+ return true;
94
+ });
95
+
96
+ // Color picker.
97
+ var $color_picker = $form.find( '#fee-bgcolor-picker' );
98
+ var $color_picker_field = $color_picker.find( '#fee-bgcolor-value' );
99
+
100
+ // Initial color.
101
+ if ( $color_picker_field.val() ) {
102
+ $color_picker_field.css( 'color', $color_picker_field.val() );
103
+ $color_picker_field.css( 'background-color', $color_picker_field.val() );
104
+ }
105
+
106
+ $color_picker_field.iris({
107
+ mode: 'hsl',
108
+ hide: false,
109
+ width: 200,
110
+ palettes: true,
111
+ border: false,
112
+ target: '#fee-bgcolor-picker-iris',
113
+ change: function(event, ui) {
114
+ $(this).css( 'color', ui.color.toString() );
115
+ $(this).css( 'background-color', ui.color.toString() );
116
+ }
117
+ }).focus(function() {
118
+ $color_picker.find( '.color-selection' ).show();
119
+ });
120
+
121
+ $color_picker.find( 'a.iris-square-value' ).click(function(e) {
122
+ e.preventDefault();
123
+ $color_picker.find( '.color-selection' ).hide();
124
+ });
125
+ $( 'a.reset-btn', $color_picker ).click(function(e) {
126
+ e.preventDefault();
127
+ $color_picker_field.val( '' ).css( 'background-color', '#ffffff' );
128
+ $color_picker.find( '.color-selection' ).hide();
129
+ });
130
+ $( 'a.close-btn', $color_picker ).click(function(e) {
131
+ e.preventDefault();
132
+ $color_picker.find( '.color-selection' ).hide();
133
+ });
134
+
135
+ });
assets/js/admin-fees.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function($){var $form=$("form#wpbdp-fee-form");if(0!=$form.length){var update_form_ui=function(event){var fee__days=$('input[name="_days"]:checked',$form).val(),$textfield=$('input[name="fee[days]"]',$form);0==fee__days?$textfield.prop("disabled",!0).val("0"):($textfield.prop("disabled",!1),event&&$("#wpbdp-fee-form-days",$form).is(event.target)&&$textfield.focus());var $pricing=$('input[name="fee[pricing_model]"]',$form),limit_categories="1"==$('select[name="limit_categories"]',$form).val(),pricing=$pricing.filter(":checked").val(),$category_chooser=$("#limit-categories-list",$form),selected_categories=[];if(limit_categories?($category_chooser.removeClass("hidden"),$("select",$category_chooser).length>0?(selected_categories=$("select",$category_chooser).val(),selected_categories||(selected_categories=[])):selected_categories=$("input:checked",$category_chooser).map(function(i,cb){return $(cb).val()}).get(),selected_categories.length>0?$pricing.filter('[value="variable"]').parent().show():($pricing.filter('[value="variable"]').parent().hide(),pricing=$pricing.val(["flat"]).val())):($category_chooser.addClass("hidden"),$pricing.filter('[value="variable"]').parent().show()),$(".fee-pricing-details").not(".pricing-details-"+pricing).addClass("hidden"),$(".fee-pricing-details.pricing-details-"+pricing,$form).removeClass("hidden"),"variable"==pricing){var $rows=$(".wpbdp-variable-pricing-configurator-row",$form);limit_categories?($rows.addClass("hidden"),$.each(selected_categories,function(i,val){$rows.filter('[data-term-id="'+val+'"]').removeClass("hidden")})):$rows.removeClass("hidden")}};update_form_ui(),$('input[name="fee[days]"]',$form).blur(function(){var val=parseInt($.trim($(this).val()),10);$(this).val(isNaN(val)?"0":Math.max(0,Math.round(val)))}),$('input[name="_days"],select[name="limit_categories"],input[name="fee[pricing_model]"],#limit-categories-list input[type="checkbox"],#limit-categories-list select').change(update_form_ui),$("#limit-categories-list select").select2({placeholder:$("#limit-categories-list select").attr("placeholder")}),$form.submit(function(){return $('input[name="fee[days]"]',$form).prop("disabled",!1),!0});var $color_picker=$form.find("#fee-bgcolor-picker"),$color_picker_field=$color_picker.find("#fee-bgcolor-value");$color_picker_field.val()&&($color_picker_field.css("color",$color_picker_field.val()),$color_picker_field.css("background-color",$color_picker_field.val())),$color_picker_field.iris({mode:"hsl",hide:!1,width:200,palettes:!0,border:!1,target:"#fee-bgcolor-picker-iris",change:function(event,ui){$(this).css("color",ui.color.toString()),$(this).css("background-color",ui.color.toString())}}).focus(function(){$color_picker.find(".color-selection").show()}),$color_picker.find("a.iris-square-value").click(function(e){e.preventDefault(),$color_picker.find(".color-selection").hide()}),$("a.reset-btn",$color_picker).click(function(e){e.preventDefault(),$color_picker_field.val("").css("background-color","#ffffff"),$color_picker.find(".color-selection").hide()}),$("a.close-btn",$color_picker).click(function(e){e.preventDefault(),$color_picker.find(".color-selection").hide()})}});
assets/js/admin-listing-metabox.js ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( function( $ ) {
2
+ // Datepicker for expiration date editing.
3
+ var _addNeverButton = function( instance ) {
4
+ setTimeout( function() {
5
+ var $buttonPane = $(instance.dpDiv).find( '.ui-datepicker-buttonpane' );
6
+
7
+ if ( $buttonPane.find( '.ui-datepicker-never' ).length > 0 )
8
+ return;
9
+
10
+ var $button = $( '<button>', {
11
+ text: 'Never Expires',
12
+ click: function() {
13
+ $(instance.input).val('');
14
+ $(instance.input).datepicker( 'hide' );
15
+ },
16
+ }).addClass( 'ui-datepicker-never ui-state-default ui-priority-primary ui-corner-all' );
17
+
18
+ $buttonPane.append($button);
19
+ }, 1 );
20
+ };
21
+
22
+ $( '#wpbdp-listing-metabox-plan-info input[name="listing_plan[expiration_date]"]' ).datepicker({
23
+ dateFormat: 'yy-mm-dd',
24
+ showButtonPanel: true,
25
+ beforeShow: function( input, instance ) {
26
+ _addNeverButton( instance );
27
+ },
28
+ onChangeMonthYear: function( year, month, instance ) {
29
+ _addNeverButton( instance );
30
+ }
31
+ });
32
+
33
+ var $metabox_tab = $('#wpbdp-listing-metabox-plan-info');
34
+
35
+ // Makes sure texts displayed inside the metabox are in sync with the settings.
36
+ var updateText = function() {
37
+ var plan_id = $( 'input[name="listing_plan[fee_id]"]').val();
38
+ var expiration = $('input[name="listing_plan[expiration_date]"]').val();
39
+ var images = $('input[name="listing_plan[fee_images]"]').val();
40
+ var is_sticky = $('input[name="listing_plan[is_sticky]"]').is(':checked');
41
+
42
+ var $plan = $('select#wpbdp-listing-plan-select').find('option[value="' + plan_id + '"]');
43
+ if ( $plan.length > 0) {
44
+ var plan_data = $.parseJSON($plan.attr('data-plan-info'));
45
+
46
+ $('#wpbdp-listing-plan-prop-label').html(
47
+ wpbdpListingMetaboxL10n.planDisplayFormat.replace('{{plan_id}}', plan_data.id)
48
+ .replace('{{plan_label}}', plan_data.label));
49
+ }
50
+
51
+ $('#wpbdp-listing-plan-prop-expiration').html(expiration ? expiration : wpbdpListingMetaboxL10n.noExpiration);
52
+ $('#wpbdp-listing-plan-prop-images').html(images);
53
+ $('#wpbdp-listing-plan-prop-is_sticky').html(is_sticky ? wpbdpListingMetaboxL10n.yes : wpbdpListingMetaboxL10n.no);
54
+ };
55
+
56
+ // Properties editing.
57
+ $metabox_tab.find('a.edit-value-toggle').click(function(e) {
58
+ e.preventDefault();
59
+
60
+ var $dd = $(this).parents('dd');
61
+ var $editor = $dd.find('.value-editor');
62
+ var $display = $dd.find('.display-value');
63
+ var $input = $editor.find('input[type="text"], input[type="checkbox"], select');
64
+ var current_value = $input.is(':checkbox') ? $input.is(':checked') : $input.val();
65
+
66
+ $input.data('before-edit-value', current_value);
67
+
68
+ $(this).hide();
69
+ $display.hide();
70
+ $editor.show();
71
+ });
72
+ $metabox_tab.find('.value-editor a.update-value, .value-editor a.cancel-edit').click(function(e) {
73
+ e.preventDefault();
74
+
75
+ var $dd = $(this).parents('dd');
76
+ var $editor = $dd.find('.value-editor');
77
+ var $display = $dd.find('.display-value');
78
+ var $input = $editor.find('input[type="text"], input[type="checkbox"], select');
79
+
80
+ if ( $(this).is( '.cancel-edit' ) ) {
81
+ var prev_value = $input.data('before-edit-value');
82
+
83
+ if ($input.is(':checkbox'))
84
+ $input.prop('checked', prev_value);
85
+ else
86
+ $input.val(prev_value);
87
+ } else {
88
+ // Plan changes are handled in a special way.
89
+ if ($input.is('#wpbdp-listing-plan-select')) {
90
+ var plan = $.parseJSON( $input.find( 'option:selected' ).attr( 'data-plan-info' ) );
91
+
92
+ $metabox_tab.find('input[name="listing_plan[fee_id]"]').val(plan.id);
93
+ $metabox_tab.find('input[name="listing_plan[expiration_date]"]').val(plan.expiration_date);
94
+ $metabox_tab.find('input[name="listing_plan[fee_images]"]').val(plan.images);
95
+ $metabox_tab.find('input[name="listing_plan[is_sticky]"]').prop( 'checked', plan.sticky );
96
+ }
97
+
98
+ updateText();
99
+ }
100
+
101
+ $editor.hide();
102
+ $display.show();
103
+ $dd.find('.edit-value-toggle').show();
104
+ });
105
+
106
+ } );
assets/js/admin-listing-metabox.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function($){var _addNeverButton=function(instance){setTimeout(function(){var $buttonPane=$(instance.dpDiv).find(".ui-datepicker-buttonpane");if(!($buttonPane.find(".ui-datepicker-never").length>0)){var $button=$("<button>",{text:"Never Expires",click:function(){$(instance.input).val(""),$(instance.input).datepicker("hide")}}).addClass("ui-datepicker-never ui-state-default ui-priority-primary ui-corner-all");$buttonPane.append($button)}},1)};$('#wpbdp-listing-metabox-plan-info input[name="listing_plan[expiration_date]"]').datepicker({dateFormat:"yy-mm-dd",showButtonPanel:!0,beforeShow:function(input,instance){_addNeverButton(instance)},onChangeMonthYear:function(year,month,instance){_addNeverButton(instance)}});var $metabox_tab=$("#wpbdp-listing-metabox-plan-info"),updateText=function(){var plan_id=$('input[name="listing_plan[fee_id]"]').val(),expiration=$('input[name="listing_plan[expiration_date]"]').val(),images=$('input[name="listing_plan[fee_images]"]').val(),is_sticky=$('input[name="listing_plan[is_sticky]"]').is(":checked"),$plan=$("select#wpbdp-listing-plan-select").find('option[value="'+plan_id+'"]');if($plan.length>0){var plan_data=$.parseJSON($plan.attr("data-plan-info"));$("#wpbdp-listing-plan-prop-label").html(wpbdpListingMetaboxL10n.planDisplayFormat.replace("{{plan_id}}",plan_data.id).replace("{{plan_label}}",plan_data.label))}$("#wpbdp-listing-plan-prop-expiration").html(expiration?expiration:wpbdpListingMetaboxL10n.noExpiration),$("#wpbdp-listing-plan-prop-images").html(images),$("#wpbdp-listing-plan-prop-is_sticky").html(is_sticky?wpbdpListingMetaboxL10n.yes:wpbdpListingMetaboxL10n.no)};$metabox_tab.find("a.edit-value-toggle").click(function(e){e.preventDefault();var $dd=$(this).parents("dd"),$editor=$dd.find(".value-editor"),$display=$dd.find(".display-value"),$input=$editor.find('input[type="text"], input[type="checkbox"], select'),current_value=$input.is(":checkbox")?$input.is(":checked"):$input.val();$input.data("before-edit-value",current_value),$(this).hide(),$display.hide(),$editor.show()}),$metabox_tab.find(".value-editor a.update-value, .value-editor a.cancel-edit").click(function(e){e.preventDefault();var $dd=$(this).parents("dd"),$editor=$dd.find(".value-editor"),$display=$dd.find(".display-value"),$input=$editor.find('input[type="text"], input[type="checkbox"], select');if($(this).is(".cancel-edit")){var prev_value=$input.data("before-edit-value");$input.is(":checkbox")?$input.prop("checked",prev_value):$input.val(prev_value)}else{if($input.is("#wpbdp-listing-plan-select")){var plan=$.parseJSON($input.find("option:selected").attr("data-plan-info"));$metabox_tab.find('input[name="listing_plan[fee_id]"]').val(plan.id),$metabox_tab.find('input[name="listing_plan[expiration_date]"]').val(plan.expiration_date),$metabox_tab.find('input[name="listing_plan[fee_images]"]').val(plan.images),$metabox_tab.find('input[name="listing_plan[is_sticky]"]').prop("checked",plan.sticky)}updateText()}$editor.hide(),$display.show(),$dd.find(".edit-value-toggle").show()})});
assets/js/admin-manual-upgrade.js CHANGED
@@ -1,6 +1,6 @@
1
  jQuery(function($) {
2
- var $startButton = $('.wpbdp-page-manual-upgrade a.start-upgrade');
3
- var $pauseButton = $('.wpbdp-page-manual-upgrade a.pause-upgrade');
4
  var $progressArea = $('textarea#manual-upgrade-progress');
5
  var inProgress = false;
6
 
@@ -39,4 +39,56 @@ jQuery(function($) {
39
  inProgress = false;
40
  });
41
 
42
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  jQuery(function($) {
2
+ var $startButton = $('.wpbdp-admin-page-manual-upgrade a.start-upgrade');
3
+ var $pauseButton = $('.wpbdp-admin-page-manual-upgrade a.pause-upgrade');
4
  var $progressArea = $('textarea#manual-upgrade-progress');
5
  var inProgress = false;
6
 
39
  inProgress = false;
40
  });
41
 
42
+ // Migration specific.
43
+ $( '#wpbdp-manual-upgrade-18_0-config #add-fee-form form#wpbdp-fee-form' ).submit(function(e) {
44
+ e.preventDefault();
45
+
46
+ var level_id = $( this ).data( 'levelId' );
47
+
48
+ if ( ! level_id ) {
49
+ $( '#TB_closeWindowButton' ).click();
50
+ return;
51
+ }
52
+
53
+ var data = $( this ).serialize();
54
+ $( 'input[name="level[' + level_id + '][details]"]' ).val( data );
55
+
56
+ // Extract some data for the summary.
57
+ $( 'table.new-fee-summary[data-level-id="' + level_id + '"] td[data-attr="fee_label"]' ).html( $( this ).find( 'input[name="fee[label]"]' ).val() );
58
+ $( 'table.new-fee-summary[data-level-id="' + level_id + '"] td[data-attr="fee_amount"]' ).html( $( this ).find( 'input[name="fee[amount]"]' ).val() );
59
+ $( 'table.new-fee-summary[data-level-id="' + level_id + '"] td[data-attr="fee_duration"]' ).html( $( this ).find( 'input[name="fee[days]"]' ).val() );
60
+ $( 'table.new-fee-summary[data-level-id="' + level_id + '"] td[data-attr="fee_images"]' ).html( $( this ).find( 'input[name="fee[images]"]' ).val() );
61
+
62
+ $( '#TB_closeWindowButton' ).click();
63
+ });
64
+
65
+ $( '#wpbdp-manual-upgrade-18_0-config select.level-migration' ).change(function(e) {
66
+ var selection = $( this ).find( 'option:selected' );
67
+ var $desc = $( this ).siblings( '.option-description' );
68
+
69
+ $( this ).siblings( '.option-configuration' ).hide();
70
+
71
+ if ( ! selection.val() ) {
72
+ $desc.hide();
73
+ $( this ).siblings( '.option-configuration' ).hide();
74
+ return;
75
+ }
76
+
77
+ $desc.html( selection.data( 'description' ) ).show();
78
+
79
+ var $config = $( this ).siblings( '.option-configuration' ).filter( '.option-' + selection.val() );
80
+ if ( $config.length > 0 ) {
81
+ $config.show();
82
+ }
83
+
84
+ if ( 'create' == selection.val() ) {
85
+ $( 'form#wpbdp-fee-form' ).get(0).reset();
86
+ $( 'form#wpbdp-fee-form' ).data( 'levelId', $( this ).attr( 'data-level-id' ) );
87
+ $config.find( '.new-fee-summary tbody td' ).html( '-' );
88
+ tb_show( $( '#add-fee-form' ).attr( 'data-title' ), '#TB_inline?inlineId=add-fee-form' );
89
+ $( 'form#wpbdp-fee-form input:first' ).focus();
90
+ }
91
+ });
92
+
93
+ });
94
+
assets/js/admin-manual-upgrade.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function($){var $startButton=$(".wpbdp-page-manual-upgrade a.start-upgrade"),$pauseButton=$(".wpbdp-page-manual-upgrade a.pause-upgrade"),$progressArea=$("textarea#manual-upgrade-progress"),inProgress=!1,makeProgress=function(){if(inProgress){var data={action:"wpbdp-manual-upgrade"};$.get(ajaxurl,data,function(response){var currentText=$progressArea.val(),newLine=(response.ok?"*":"!")+" "+response.status;$progressArea.val(currentText+newLine+"\n"),$progressArea.scrollTop($progressArea[0].scrollHeight-$progressArea.height()),response.done?$("div.step-upgrade").fadeOut(function(){$("div.step-done").fadeIn()}):makeProgress()},"json")}};$startButton.click(function(e){e.preventDefault(),inProgress||(inProgress=!0,makeProgress())}),$pauseButton.click(function(e){e.preventDefault(),inProgress=!1})});
1
+ jQuery(function($){var $startButton=$(".wpbdp-admin-page-manual-upgrade a.start-upgrade"),$pauseButton=$(".wpbdp-admin-page-manual-upgrade a.pause-upgrade"),$progressArea=$("textarea#manual-upgrade-progress"),inProgress=!1,makeProgress=function(){if(inProgress){var data={action:"wpbdp-manual-upgrade"};$.get(ajaxurl,data,function(response){var currentText=$progressArea.val(),newLine=(response.ok?"*":"!")+" "+response.status;$progressArea.val(currentText+newLine+"\n"),$progressArea.scrollTop($progressArea[0].scrollHeight-$progressArea.height()),response.done?$("div.step-upgrade").fadeOut(function(){$("div.step-done").fadeIn()}):makeProgress()},"json")}};$startButton.click(function(e){e.preventDefault(),inProgress||(inProgress=!0,makeProgress())}),$pauseButton.click(function(e){e.preventDefault(),inProgress=!1}),$("#wpbdp-manual-upgrade-18_0-config #add-fee-form form#wpbdp-fee-form").submit(function(e){e.preventDefault();var level_id=$(this).data("levelId");if(!level_id)return void $("#TB_closeWindowButton").click();var data=$(this).serialize();$('input[name="level['+level_id+'][details]"]').val(data),$('table.new-fee-summary[data-level-id="'+level_id+'"] td[data-attr="fee_label"]').html($(this).find('input[name="fee[label]"]').val()),$('table.new-fee-summary[data-level-id="'+level_id+'"] td[data-attr="fee_amount"]').html($(this).find('input[name="fee[amount]"]').val()),$('table.new-fee-summary[data-level-id="'+level_id+'"] td[data-attr="fee_duration"]').html($(this).find('input[name="fee[days]"]').val()),$('table.new-fee-summary[data-level-id="'+level_id+'"] td[data-attr="fee_images"]').html($(this).find('input[name="fee[images]"]').val()),$("#TB_closeWindowButton").click()}),$("#wpbdp-manual-upgrade-18_0-config select.level-migration").change(function(e){var selection=$(this).find("option:selected"),$desc=$(this).siblings(".option-description");if($(this).siblings(".option-configuration").hide(),!selection.val())return $desc.hide(),void $(this).siblings(".option-configuration").hide();$desc.html(selection.data("description")).show();var $config=$(this).siblings(".option-configuration").filter(".option-"+selection.val());$config.length>0&&$config.show(),"create"==selection.val()&&($("form#wpbdp-fee-form").get(0).reset(),$("form#wpbdp-fee-form").data("levelId",$(this).attr("data-level-id")),$config.find(".new-fee-summary tbody td").html("-"),tb_show($("#add-fee-form").attr("data-title"),"#TB_inline?inlineId=add-fee-form"),$("form#wpbdp-fee-form input:first").focus())})});
assets/js/admin-payments.js ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($) {
2
+ $( 'body.directory-admin_page_wpbdp_admin_payments .postbox .handlediv.button-link' ).click( function(e) {
3
+ var $p = $( this ).parents( '.postbox' );
4
+ $p.toggleClass( 'closed' );
5
+ $( this ).attr( 'aria-expanded', ! $p.hasClass( 'closed' ) );
6
+ });
7
+
8
+ $( '#wpbdp-admin-payment-info-box input[name="payment[created_on_date]"]' ).datepicker({
9
+ dateFormat: 'yy-mm-dd'
10
+ });
11
+
12
+ $( '#wpbdp-payment-notes-add' ).click(function(e) {
13
+ e.preventDefault();
14
+ var $note = $( 'textarea[name="payment_note"]' );
15
+
16
+ $.ajax({
17
+ url: ajaxurl,
18
+ method: 'POST',
19
+ dataType: 'json',
20
+ data: {
21
+ action: 'wpbdp_admin_ajax',
22
+ handler: 'payments__add_note',
23
+ payment_id: $( this ).data( 'payment-id' ),
24
+ note: $note.val()
25
+ },
26
+ success: function( res ) {
27
+ if ( ! res.success )
28
+ return;
29
+
30
+ $( '#wpbdp-payment-notes .no-notes' ).hide();
31
+ $( '#wpbdp-payment-notes' ).append( res.data.html );
32
+
33
+ $note.val('');
34
+ }
35
+ });
36
+
37
+ // var border_color = $('#edd-payment-note').css('border-color');
38
+ // $('#edd-payment-note').css('border-color', 'red');
39
+ // setTimeout( function() {
40
+ // $('#edd-payment-note').css('border-color', border_color );
41
+ // }, 500 );
42
+ });
43
+
44
+ $( document ).on( 'click', '.wpbdp-payment-note .wpbdp-admin-delete-link', function( e ) {
45
+ e.preventDefault();
46
+
47
+ var url = $( this ).attr( 'href' );
48
+ $.ajax({
49
+ url: url,
50
+ method: 'GET',
51
+ dataType: 'json',
52
+ success: function( res ) {
53
+ if ( ! res.success )
54
+ return;
55
+
56
+ $( '.wpbdp-payment-note[data-id="' + res.data.note.id + '"]' ).remove();
57
+
58
+ if ( 0 == $( '.wpbdp-payment-note' ).length )
59
+ $( '#wpbdp-payment-notes .no-notes' ).show();
60
+ }
61
+ });
62
+ } );
63
+
64
+ });
assets/js/admin-payments.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function($){$("body.directory-admin_page_wpbdp_admin_payments .postbox .handlediv.button-link").click(function(e){var $p=$(this).parents(".postbox");$p.toggleClass("closed"),$(this).attr("aria-expanded",!$p.hasClass("closed"))}),$('#wpbdp-admin-payment-info-box input[name="payment[created_on_date]"]').datepicker({dateFormat:"yy-mm-dd"}),$("#wpbdp-payment-notes-add").click(function(e){e.preventDefault();var $note=$('textarea[name="payment_note"]');$.ajax({url:ajaxurl,method:"POST",dataType:"json",data:{action:"wpbdp_admin_ajax",handler:"payments__add_note",payment_id:$(this).data("payment-id"),note:$note.val()},success:function(res){res.success&&($("#wpbdp-payment-notes .no-notes").hide(),$("#wpbdp-payment-notes").append(res.data.html),$note.val(""))}})}),$(document).on("click",".wpbdp-payment-note .wpbdp-admin-delete-link",function(e){e.preventDefault();var url=$(this).attr("href");$.ajax({url:url,method:"GET",dataType:"json",success:function(res){res.success&&($('.wpbdp-payment-note[data-id="'+res.data.note.id+'"]').remove(),0==$(".wpbdp-payment-note").length&&$("#wpbdp-payment-notes .no-notes").show())}})})});
assets/js/admin-settings.js ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($) {
2
+ var wpbdp_settings_dep_handling = {
3
+ init: function() {
4
+ var self = this;
5
+
6
+ self.watch = {};
7
+ self.requirements = {};
8
+
9
+ $( '.wpbdp-settings-setting[data-requirements][data-requirements!=""]' ).each(function() {
10
+ var setting_id = $(this).data('setting-id');
11
+ var reqs = $( this ).data( 'requirements' );
12
+
13
+ self.requirements[ setting_id ] = reqs;
14
+
15
+ $.each( reqs, function(i, req) {
16
+ var rel_setting_id = req[0];
17
+
18
+ if ( 'undefined' === typeof self.watch[rel_setting_id] ) {
19
+ self.watch[ rel_setting_id ] = [];
20
+ }
21
+
22
+ self.watch[ rel_setting_id ].push(setting_id);
23
+ } );
24
+ });
25
+
26
+ $.each( self.watch, function( setting_id, affected_settings ) {
27
+ $( '[name="wpbdp_settings[' + setting_id + ']"], [name="wpbdp_settings[' + setting_id + '][]"]' ).change(function(){
28
+ $.each( affected_settings, function(i, v) {
29
+ self.check_requirements( v );
30
+ } );
31
+ });
32
+ } );
33
+
34
+ $.each( self.requirements, function( setting_id, reqs ) {
35
+ self.check_requirements( setting_id );
36
+ } );
37
+ },
38
+
39
+ check_requirements: function( setting_id ) {
40
+ var reqs = this.requirements[ setting_id ];
41
+ var $setting = $( '#wpbdp-settings-' + setting_id );
42
+ var $row = $setting.parents( 'tr' );
43
+ var passes = true;
44
+
45
+ for ( var i = 0; i < reqs.length; i++ ) {
46
+ var req_name = reqs[ i ][0].replace( '!', '' );
47
+ var not = ( -1 !== reqs[ i ][0].indexOf( '!' ) );
48
+ var value = reqs[ i ][1];
49
+
50
+ // Obtain updated value (if possible).
51
+ var $rel_setting = $( '#wpbdp-settings-' + req_name );
52
+ if ( $rel_setting.length > 0 ) {
53
+ if ( $rel_setting.parents( 'tr' ).hasClass( 'wpbdp-setting-disabled' ) ) {
54
+ console.log( req_name );
55
+ value = false;
56
+ } else {
57
+ var $field = $rel_setting.find( '[name="wpbdp_settings[' + req_name + ']"]:checked, [name="wpbdp_settings[' + req_name + '][]"]:checked' );
58
+ value = $field.length > 0;
59
+ }
60
+ }
61
+
62
+ passes = ( ( not && ! value ) || value );
63
+
64
+ if ( ! passes ) {
65
+ break;
66
+ }
67
+ }
68
+
69
+ if ( passes ) {
70
+ $row.removeClass( 'wpbdp-setting-disabled' );
71
+ } else {
72
+ $row.addClass( 'wpbdp-setting-disabled' );
73
+ }
74
+
75
+ // Propagate.
76
+ if ( 'undefined' !== typeof this.watch[ setting_id ] ) {
77
+ $setting.find( '[name="wpbdp_settings[' + setting_id + ']"], [name="wpbdp_settings[' + setting_id + '][]"]' ).trigger( 'change' );
78
+ }
79
+ }
80
+ };
81
+ wpbdp_settings_dep_handling.init();
82
+
83
+ /**
84
+ * License activation/deactivation.
85
+ */
86
+ var wpbdp_settings_licensing = {
87
+ init: function() {
88
+ var self = this;
89
+
90
+ if ( 0 == $( '.wpbdp-settings-type-license_key' ).length ) {
91
+ return;
92
+ }
93
+
94
+ $( '.wpbdp-license-key-activate-btn, .wpbdp-license-key-deactivate-btn' ).click(function(e) {
95
+ e.preventDefault();
96
+
97
+ var $button = $(this);
98
+ var $setting = $(this).parents( '.wpbdp-license-key-activation-ui' );
99
+ var $msg = $setting.find( '.wpbdp-license-key-activation-status-msg' );
100
+ var $spinner = $setting.find( '.spinner' );
101
+ var activate = $(this).is( '.wpbdp-license-key-activate-btn' );
102
+ var $field = $setting.find( 'input.wpbdp-license-key-input' );
103
+ var data = $setting.data( 'licensing' );
104
+
105
+ $msg.hide();
106
+ $button.data( 'original_label', $(this).val() );
107
+ $button.val( $(this).data( 'working-msg' ) );
108
+ $button.prop( 'disabled', true );
109
+
110
+ if ( activate ) {
111
+ data['action'] = 'wpbdp_activate_license';
112
+ } else {
113
+ data['action'] = 'wpbdp_deactivate_license';
114
+ }
115
+
116
+ data['license_key'] = $field.val();
117
+
118
+ $.post(
119
+ ajaxurl,
120
+ data,
121
+ function( res ) {
122
+ if ( res.success ) {
123
+ $msg.removeClass( 'status-error' ).addClass( 'status-success' ).html( res.message ).show();
124
+
125
+ if ( activate ) {
126
+ var classes = $setting.attr( 'class' ).split( ' ' ).filter( function( item ) {
127
+ var className = item.trim();
128
+
129
+ if ( 0 === className.length ) {
130
+ return false;
131
+ }
132
+
133
+ if ( className.match( /^wpbdp-license-status/ ) ) {
134
+ return false;
135
+ }
136
+
137
+ return true;
138
+ } );
139
+
140
+ classes.push( 'wpbdp-license-status-valid' );
141
+
142
+ $setting.attr( 'class', classes.join( ' ' ) );
143
+ } else {
144
+ $setting.removeClass( 'wpbdp-license-status-valid' ).addClass( 'wpbdp-license-status-invalid' );
145
+ }
146
+
147
+ $field.prop( 'readonly', activate ? true : false );
148
+ } else {
149
+ $msg.removeClass( 'status-success' ).addClass( 'status-error' ).html( res.error ).show();
150
+ $setting.removeClass( 'wpbdp-license-status-valid' ).addClass( 'wpbdp-license-status-invalid' );
151
+ $field.prop( 'readonly', false );
152
+ }
153
+
154
+ $button.val( $button.data( 'original_label' ) );
155
+ $button.prop( 'disabled', false );
156
+ },
157
+ 'json'
158
+ );
159
+ });
160
+ }
161
+ };
162
+ wpbdp_settings_licensing.init();
163
+
164
+ /**
165
+ * E-Mail template editors.
166
+ */
167
+ var wpbdp_settings_email = {
168
+ init: function() {
169
+ var self = this;
170
+
171
+ $( '.wpbdp-settings-email-preview, .wpbdp-settings-email-edit-btn' ).click(function(e) {
172
+ e.preventDefault();
173
+
174
+ var $email = $( this ).parents( '.wpbdp-settings-email' );
175
+ $( this ).hide();
176
+ $email.find( '.wpbdp-settings-email-editor' ).show();
177
+ });
178
+
179
+ $( '.wpbdp-settings-email-editor .cancel' ).click(function(e) {
180
+ e.preventDefault();
181
+
182
+ var $email = $( this ).parents( '.wpbdp-settings-email' );
183
+ var $editor = $email.find( '.wpbdp-settings-email-editor' );
184
+
185
+ // Add-new editor.
186
+ if ( $email.parent().is( '#wpbdp-settings-expiration-notices-add' ) ) {
187
+ $email.hide();
188
+ $( '#wpbdp-settings-expiration-notices-add-btn' ).show();
189
+ return;
190
+ }
191
+
192
+ // Sync editor with old values.
193
+ var subject = $editor.find( '.stored-email-subject' ).val();
194
+ var body = $editor.find( '.stored-email-body' ).val();
195
+ $editor.find( '.email-subject' ).val( subject );
196
+ $editor.find( '.email-body' ).val( body );
197
+
198
+ if ( $email.hasClass( 'wpbdp-expiration-notice-email' ) ) {
199
+ var event = $editor.find( '.stored-notice-event' ).val();
200
+ var reltime = $editor.find( '.stored-notice-relative-time' ).val();
201
+
202
+ $editor.find( '.notice-event' ).val( event );
203
+ $editor.find( '.notice-relative-time' ).val( reltime );
204
+
205
+ if ( ! reltime ) {
206
+ reltime = '0 days';
207
+ }
208
+
209
+ $editor.find( 'select.relative-time-and-event' ).val( event + ',' + reltime );
210
+ }
211
+
212
+ // Hide editor.
213
+ $editor.hide();
214
+ $email.find( '.wpbdp-settings-email-preview' ).show();
215
+ });
216
+
217
+ $( '.wpbdp-settings-email-editor .delete' ).click(function(e) {
218
+ e.preventDefault();
219
+
220
+ var $email = $( this ).parents( '.wpbdp-settings-email' );
221
+ $email.next().remove();
222
+ $email.remove();
223
+ $( '#wpbdp-admin-page-settings form' ).get(0).submit();
224
+ });
225
+
226
+ // Expiration notices have some additional handling to do.
227
+ $( '.wpbdp-expiration-notice-email select.relative-time-and-event' ).change(function(e) {
228
+ var parts = $( this ).val().split(',');
229
+ var event = parts[0];
230
+ var relative_time = parts[1];
231
+
232
+ var $email = $( this ).parents( '.wpbdp-settings-email' );
233
+ $email.find( '.notice-event' ).val( event );
234
+ $email.find( '.notice-relative-time' ).val( relative_time );
235
+ });
236
+
237
+ $( '#wpbdp-settings-expiration-notices-add-btn' ).click(function(e) {
238
+ e.preventDefault();
239
+
240
+ var $container = $( '#wpbdp-settings-expiration-notices-add .wpbdp-expiration-notice-email' );
241
+ var $editor = $container.find( '.wpbdp-settings-email-editor' );
242
+
243
+ $( this ).hide();
244
+ $container.show();
245
+ $editor.show();
246
+ });
247
+
248
+ $( '#wpbdp-settings-expiration-notices-add input[type="submit"]' ).click(function(e) {
249
+ var $editor = $( this ).parents( '.wpbdp-settings-email-editor' );
250
+
251
+ $editor.find( 'input, textarea, select' ).each( function(i) {
252
+ var name = $( this ).attr( 'name' );
253
+
254
+ if ( ! name || -1 == name.indexOf( 'new_notice' ) )
255
+ return;
256
+
257
+ name = name.replace( 'new_notice', 'wpbdp_settings[expiration-notices]' );
258
+ $( this ).prop( 'name', name );
259
+ } );
260
+
261
+ return true;
262
+ });
263
+ },
264
+ };
265
+ wpbdp_settings_email.init();
266
+
267
+ });
268
+
assets/js/admin-settings.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function($){var wpbdp_settings_dep_handling={init:function(){var self=this;self.watch={},self.requirements={},$('.wpbdp-settings-setting[data-requirements][data-requirements!=""]').each(function(){var setting_id=$(this).data("setting-id"),reqs=$(this).data("requirements");self.requirements[setting_id]=reqs,$.each(reqs,function(i,req){var rel_setting_id=req[0];"undefined"==typeof self.watch[rel_setting_id]&&(self.watch[rel_setting_id]=[]),self.watch[rel_setting_id].push(setting_id)})}),$.each(self.watch,function(setting_id,affected_settings){$('[name="wpbdp_settings['+setting_id+']"], [name="wpbdp_settings['+setting_id+'][]"]').change(function(){$.each(affected_settings,function(i,v){self.check_requirements(v)})})}),$.each(self.requirements,function(setting_id,reqs){self.check_requirements(setting_id)})},check_requirements:function(setting_id){for(var reqs=this.requirements[setting_id],$setting=$("#wpbdp-settings-"+setting_id),$row=$setting.parents("tr"),passes=!0,i=0;i<reqs.length;i++){var req_name=reqs[i][0].replace("!",""),not=-1!==reqs[i][0].indexOf("!"),value=reqs[i][1],$rel_setting=$("#wpbdp-settings-"+req_name);if($rel_setting.length>0)if($rel_setting.parents("tr").hasClass("wpbdp-setting-disabled"))console.log(req_name),value=!1;else{var $field=$rel_setting.find('[name="wpbdp_settings['+req_name+']"]:checked, [name="wpbdp_settings['+req_name+'][]"]:checked');value=$field.length>0}if(passes=not&&!value||value,!passes)break}passes?$row.removeClass("wpbdp-setting-disabled"):$row.addClass("wpbdp-setting-disabled"),"undefined"!=typeof this.watch[setting_id]&&$setting.find('[name="wpbdp_settings['+setting_id+']"], [name="wpbdp_settings['+setting_id+'][]"]').trigger("change")}};wpbdp_settings_dep_handling.init();var wpbdp_settings_licensing={init:function(){0!=$(".wpbdp-settings-type-license_key").length&&$(".wpbdp-license-key-activate-btn, .wpbdp-license-key-deactivate-btn").click(function(e){e.preventDefault();var $button=$(this),$setting=$(this).parents(".wpbdp-license-key-activation-ui"),$msg=$setting.find(".wpbdp-license-key-activation-status-msg"),activate=($setting.find(".spinner"),$(this).is(".wpbdp-license-key-activate-btn")),$field=$setting.find("input.wpbdp-license-key-input"),data=$setting.data("licensing");$msg.hide(),$button.data("original_label",$(this).val()),$button.val($(this).data("working-msg")),$button.prop("disabled",!0),activate?data.action="wpbdp_activate_license":data.action="wpbdp_deactivate_license",data.license_key=$field.val(),$.post(ajaxurl,data,function(res){if(res.success){if($msg.removeClass("status-error").addClass("status-success").html(res.message).show(),activate){var classes=$setting.attr("class").split(" ").filter(function(item){var className=item.trim();return 0!==className.length&&!className.match(/^wpbdp-license-status/)});classes.push("wpbdp-license-status-valid"),$setting.attr("class",classes.join(" "))}else $setting.removeClass("wpbdp-license-status-valid").addClass("wpbdp-license-status-invalid");$field.prop("readonly",!!activate)}else $msg.removeClass("status-success").addClass("status-error").html(res.error).show(),$setting.removeClass("wpbdp-license-status-valid").addClass("wpbdp-license-status-invalid"),$field.prop("readonly",!1);$button.val($button.data("original_label")),$button.prop("disabled",!1)},"json")})}};wpbdp_settings_licensing.init();var wpbdp_settings_email={init:function(){$(".wpbdp-settings-email-preview, .wpbdp-settings-email-edit-btn").click(function(e){e.preventDefault();var $email=$(this).parents(".wpbdp-settings-email");$(this).hide(),$email.find(".wpbdp-settings-email-editor").show()}),$(".wpbdp-settings-email-editor .cancel").click(function(e){e.preventDefault();var $email=$(this).parents(".wpbdp-settings-email"),$editor=$email.find(".wpbdp-settings-email-editor");if($email.parent().is("#wpbdp-settings-expiration-notices-add"))return $email.hide(),void $("#wpbdp-settings-expiration-notices-add-btn").show();var subject=$editor.find(".stored-email-subject").val(),body=$editor.find(".stored-email-body").val();if($editor.find(".email-subject").val(subject),$editor.find(".email-body").val(body),$email.hasClass("wpbdp-expiration-notice-email")){var event=$editor.find(".stored-notice-event").val(),reltime=$editor.find(".stored-notice-relative-time").val();$editor.find(".notice-event").val(event),$editor.find(".notice-relative-time").val(reltime),reltime||(reltime="0 days"),$editor.find("select.relative-time-and-event").val(event+","+reltime)}$editor.hide(),$email.find(".wpbdp-settings-email-preview").show()}),$(".wpbdp-settings-email-editor .delete").click(function(e){e.preventDefault();var $email=$(this).parents(".wpbdp-settings-email");$email.next().remove(),$email.remove(),$("#wpbdp-admin-page-settings form").get(0).submit()}),$(".wpbdp-expiration-notice-email select.relative-time-and-event").change(function(e){var parts=$(this).val().split(","),event=parts[0],relative_time=parts[1],$email=$(this).parents(".wpbdp-settings-email");$email.find(".notice-event").val(event),$email.find(".notice-relative-time").val(relative_time)}),$("#wpbdp-settings-expiration-notices-add-btn").click(function(e){e.preventDefault();var $container=$("#wpbdp-settings-expiration-notices-add .wpbdp-expiration-notice-email"),$editor=$container.find(".wpbdp-settings-email-editor");$(this).hide(),$container.show(),$editor.show()}),$('#wpbdp-settings-expiration-notices-add input[type="submit"]').click(function(e){var $editor=$(this).parents(".wpbdp-settings-email-editor");return $editor.find("input, textarea, select").each(function(i){var name=$(this).attr("name");name&&-1!=name.indexOf("new_notice")&&(name=name.replace("new_notice","wpbdp_settings[expiration-notices]"),$(this).prop("name",name))}),!0})}};wpbdp_settings_email.init()});
assets/js/admin.js CHANGED
@@ -20,7 +20,7 @@ var WPBDP_associations_fieldtypes = {};
20
  if ( $( this ).hasClass( 'yes' ) ) {
21
  $( this ).parents( '.iframe-confirm' ).hide();
22
  } else {
23
- $( '#wpbdp-fieldsettings input[name="field[allow_iframes]"]' ).prop( 'checked', false );
24
  $( this ).parents( '.iframe-confirm' ).hide();
25
  }
26
  })
@@ -28,11 +28,15 @@ var WPBDP_associations_fieldtypes = {};
28
  $( '#wpbdp-fieldsettings input[name="field[allow_iframes]"]' ).change(function() {
29
  if ( $( this ).is(':checked') ) {
30
  $( '.iframe-confirm' ).show();
31
- } else {
32
  $( '.iframe-confirm' ).hide();
33
  }
34
  });
35
 
 
 
 
 
36
  $('table.formfields tbody').sortable({
37
  placeholder: 'wpbdp-draggable-highlight',
38
  handle: '.wpbdp-drag-handle',
@@ -61,10 +65,10 @@ var WPBDP_associations_fieldtypes = {};
61
 
62
  // URL fields can only have the 'url' validator.
63
  if ( 'url' == field_type ) {
64
- $( 'select#field-validator option' ).not( '[value="url"]' ).prop( { 'disabled': true, 'selected': false } );
65
- $( 'select#field-validator option[value="url"]' ).prop( 'selected', true );
66
  } else {
67
- $( 'select#field-validator option' ).prop( 'disabled', false );
68
  }
69
 
70
  var request_data = {
@@ -114,24 +118,7 @@ var WPBDP_associations_fieldtypes = {};
114
  jQuery(document).ready(function($){
115
 
116
  // {{ Manage Fees.
117
- $('form#wpbdp-fee-form input[name="_days"]').change(function(){
118
- var value = $(this).val();
119
-
120
- // alert(value);
121
-
122
- if (value == 0) {
123
- $('form input#wpbdp-fee-form-days-n').prop('disabled', true);
124
- $('form input[name="fee[days]"]').val('0');
125
- } else {
126
- $('form input#wpbdp-fee-form-days-n').prop('disabled', false);
127
- $('form input[name="fee[days]"]').val($('form input#wpbdp-fee-form-days-n').val());
128
- $('form input#wpbdp-fee-form-days-n').focus();
129
- }
130
-
131
- return true;
132
- });
133
-
134
- $('.wpbdp-page-admin-fees .wp-list-table.fees tbody').sortable({
135
  placeholder: 'wpbdp-draggable-highlight',
136
  handle: '.wpbdp-drag-handle',
137
  axis: 'y',
@@ -151,13 +138,6 @@ jQuery(document).ready(function($){
151
  }
152
  });
153
 
154
- $('form#wpbdp-fee-form').submit(function(){
155
- // alert($('form#wpbdp-fee-form input[name="fee[days]"]').val());
156
- // return false;
157
- $('form input[name="fee[days]"]').prop('disabled', false);
158
- return true;
159
- });
160
-
161
  $( 'select[name="fee_order[method]"], select[name="fee_order[order]"]' ).change(function(e) {
162
  $.ajax({
163
  url: ajaxurl,
@@ -172,56 +152,11 @@ jQuery(document).ready(function($){
172
  });
173
 
174
  if ( 'custom' == $('select[name="fee_order[method]"]').val() ) {
175
- $( '.wpbdp-page-admin-fees .wp-list-table .wpbdp-drag-handle' ).show();
176
  }
177
  // }}
178
 
179
 
180
- /* Listing Info Metabox */
181
-
182
- $('#BusinessDirectory_listinginfo .listing-metabox-tabs a').click(function(e){
183
- e.preventDefault();
184
-
185
- var href = $(this).attr('href');
186
-
187
- var $selected = $(this).parent('li').siblings('.selected');
188
-
189
- if ($selected.length > 0) {
190
- if ($selected.find('a:first').attr('href') == href) {
191
- return;
192
- } else {
193
- // hide current tab (if any)
194
- $selected.removeClass('selected');
195
- $($selected.find('a:first').attr('href')).hide();
196
- }
197
- }
198
-
199
- // show new tab
200
- $(this).parent('li').addClass('selected');
201
- $(href).show();
202
- $('.listing-fee-expiration-datepicker').hide();
203
- });
204
-
205
- var url_tab = $(location).attr( 'hash' );
206
- if ( url_tab && $( url_tab ).length > 0 ) {
207
- $( '#BusinessDirectory_listinginfo a[href="' + url_tab + '"]' ).click();
208
- } else {
209
- $('#BusinessDirectory_listinginfo .listing-metabox-tabs li.selected a').click();
210
- }
211
-
212
-
213
- /* Listing info metabox / fees */
214
-
215
- $('#listing-metabox-fees a.assignfee-link').click(function(e){
216
- e.preventDefault();
217
- $(this).siblings('.assignfee').show();
218
- });
219
-
220
- $('#listing-metabox-fees .assignfee .close-handle').click(function(e){
221
- e.preventDefault();
222
- $(this).parent('.assignfee').hide();
223
- });
224
-
225
  /* Ajax placeholders */
226
 
227
  $('.wpbdp-ajax-placeholder').each(function(i,v){
@@ -310,7 +245,6 @@ function wpbdp_load_placeholder($v) {
310
 
311
  var WPBDP_Admin = {};
312
  WPBDP_Admin.payments = {};
313
- WPBDP_Admin.listingMetabox = {};
314
 
315
  // TODO: integrate this into $.
316
  WPBDP_Admin.ProgressBar = function($item, settings) {
@@ -379,316 +313,40 @@ WPBDP_Admin.ProgressBar = function($item, settings) {
379
 
380
  })(jQuery);
381
 
382
- (function($) {
383
- var metabox = WPBDP_Admin.listingMetabox;
384
-
385
- metabox._initialize = function() {
386
- // Hack from
387
- // http://stackoverflow.com/questions/3961963/beforeshow-event-not-firing-on-jqueryui-datepicker.
388
- $.extend( $.datepicker, {
389
- _inlineDatepicker2: $.datepicker._inlineDatepicker,
390
- // Override the _inlineDatepicker method
391
- _inlineDatepicker: function (target, inst) {
392
- // Call the original
393
- this._inlineDatepicker2(target, inst);
394
- var beforeShow = $.datepicker._get(inst, 'beforeShow');
395
-
396
- if (beforeShow) {
397
- beforeShow.apply(target, [target, inst]);
398
- }
399
- }
400
- });
401
-
402
- // Expiration date changing.
403
- var _addNeverButton = function( instance ) {
404
- setTimeout( function() {
405
- var $buttonPane = $(instance).find( '.ui-datepicker-buttonpane' );
406
-
407
- if ( $buttonPane.find( '.ui-datepicker-never' ).length > 0 )
408
- return;
409
-
410
- var $button = $( '<button>', {
411
- text: 'Never Expires',
412
- click: function() {
413
- _updateExpiration( $(instance), 'never' );
414
- return false;
415
- },
416
- }).addClass( 'ui-datepicker-never ui-state-default ui-priority-primary ui-corner-all' );
417
-
418
- $buttonPane.append($button);
419
- }, 1 );
420
- };
421
-
422
- var _updateExpiration = function( $instance, newDate ) {
423
- if ( ! newDate )
424
- return;
425
-
426
- var $changeLink = $instance.siblings('a.expiration-change-link');
427
- var $expirationDate = $instance.siblings('.expiration-date');
428
- var $spinner = $instance.parents('.listing-category').find('.spinner:first');
429
-
430
- $expirationDate.text('--');
431
- $spinner.show();
432
-
433
- $instance.hide();
434
- _addNeverButton($instance.get(0));
435
-
436
- $.post(ajaxurl, {action: 'wpbdp-listing_set_expiration', renewal_id: $changeLink.attr('data-renewal_id'), expiration_date: newDate}, function(res) {
437
- if (res && res.success) {
438
- $spinner.hide();
439
- $expirationDate.text(res.data.formattedExpirationDate).show();
440
- }
441
- }, 'json');
442
- };
443
-
444
- $('#listing-metabox-generalinfo, #listing-metabox-fees').each(function(i, v) {
445
- var $tab = $(v);
446
- $tab.find('.expiration-date-info .datepicker').each(function(i, v) {
447
- var $dp = $(v);
448
- var $changeLink = $dp.siblings('a.expiration-change-link');
449
-
450
- $dp.hide().datepicker({
451
- dateFormat: 'yy-mm-dd',
452
- defaultDate: $changeLink.attr('data-date'),
453
- showButtonPanel: true,
454
- beforeShow: function( input ) {
455
- _addNeverButton( input );
456
- },
457
- onChangeMonthYear: function( year, month, instance ) {
458
- _addNeverButton(instance.input);
459
- },
460
- onSelect: function(newDate) {
461
- _updateExpiration( $(this), newDate );
462
- }
463
- });
464
- });
465
-
466
- $tab.find('a.expiration-change-link').click(function(e) {
467
- e.preventDefault();
468
-
469
- var renewal_id = $(this).attr('data-renewal_id');
470
- $('.expiration-date-info .datepicker').not('.renewal-' + renewal_id ).hide();
471
- $('.expiration-date-info .datepicker.renewal-' + renewal_id).toggle();
472
- });
473
- });
474
-
475
- // Listing category deletion.
476
- $('.listing-category a.category-delete').click(function(e) {
477
- e.preventDefault();
478
-
479
- var listingID = $(this).attr('data-listing');
480
- var categoryID = $(this).attr('data-category');
481
-
482
- if ( !listingID || !categoryID ) {
483
- return;
484
- }
485
-
486
- var $category = $('.listing-category-' + categoryID);
487
- $.post(ajaxurl, {action: 'wpbdp-listing_remove_category', 'listing': listingID, 'category': categoryID}, function(res) {
488
- if (res && res.success) {
489
- $('input[name="tax_input[wpbdp_category][]"][value="' + categoryID + '"]').prop( 'checked', false );
490
- $category.fadeOut(function(){ $(this).remove(); });
491
- }
492
- }, 'json');
493
- });
494
-
495
- // Listing category fee change.
496
- $('.listing-category a.category-change-fee').click(function(e) {
497
- e.preventDefault();
498
-
499
- if ($('#wpbdp-modal-dialog').length == 0) {
500
- $('body').append($('<div id="wpbdp-modal-dialog"></div>'));
501
- }
502
-
503
- $.post(ajaxurl, {'action': 'wpbdp-listing_change_fee', 'renewal': $(this).attr('data-renewal')}, function(res) {
504
- if (res && res.success) {
505
- $('#wpbdp-modal-dialog').html(res.data.html);
506
- tb_show('', '#TB_inline?inlineId=wpbdp-modal-dialog');
507
- $('#wpbdp-modal-dialog').remove();
508
- }
509
- }, 'json');
510
- });
511
- };
512
-
513
- $(document).ready(function(){
514
- if ( $('#listing-metabox-fees').length > 0 ) {
515
- metabox._initialize();
516
- }
517
- });
518
-
519
- })(jQuery);
520
-
521
  /* {{ Settings. */
522
  (function($) {
523
  var s = WPBDP_Admin.settings = {
524
- _whenTrueActivateChilds: {},
525
- _whenFalseActivateChilds: {},
526
-
527
  init: function() {
528
  var t = this;
529
 
530
- // E-mail template editors.
531
- $( '.wpbdp-settings-email' ).each(function(i, v) {
532
- var $email = $(v);
533
- var $preview = $email.find('.short-preview');
534
- var $editor = $email.find('.editor');
535
- var $subject = $editor.find('.subject-text');
536
- var $body = $editor.find('.body-text');
537
- var data = {'subject': '', 'body': ''};
538
-
539
- $preview.click(function(e) {
540
- data['subject'] = $subject.val();
541
- data['body'] = $body.val();
542
-
543
- $preview.hide();
544
- $editor.show();
545
- });
546
-
547
- $( '.cancel', $editor ).click(function(e) {
548
- e.preventDefault();
549
-
550
- $subject.val(data['subject']);
551
- $body.val(data['body']);
552
-
553
- $editor.hide();
554
- $preview.show();
555
- });
556
-
557
- $( '.save', $editor ).click(function(e) {
558
- e.preventDefault();
559
- $('form#wpbdp-admin-settings #submit').click();
560
- });
561
-
562
- $( '.preview-email', $editor ).click(function(e) {
563
- e.preventDefault();
564
-
565
- var subject = $subject.val();
566
- var body = $body.val();
567
-
568
- $.ajax({
569
- url: ajaxurl,
570
- data: { 'action': 'wpbdp-admin-settings-email-preview',
571
- 'nonce': $editor.attr('data-preview-nonce'),
572
- 'setting': $email.attr('data-setting'),
573
- 'subject': subject,
574
- 'body': body },
575
- dataType: 'json',
576
- type: 'POST',
577
- success: function(res) {
578
- if ( ! res.success ) {
579
- return;
580
- }
581
-
582
- if ( 0 == $( '#wpbdp-modal-dialog' ).length )
583
- $( 'body' ).append( '<div id="wpbdp-modal-dialog" style="display: none;"></div>' );
584
-
585
- $( '#wpbdp-modal-dialog' ).html(res.data.html);
586
- tb_show( '', '#TB_inline?inlineId=wpbdp-modal-dialog' );
587
- $( '#wpbdp-modal-dialog' ).remove();
588
  }
589
- });
590
-
591
- });
592
-
593
- });
594
-
595
- $( 'ul#quick-search-fields' ).on( 'change', ':checkbox', function() {
596
- var selected = $(this).closest( 'ul' ).find( '.textfield :checkbox:checked' ).length;
597
 
598
- if ( selected > 0 ) {
599
- $('span.text-fields-warning').fadeIn('fast');
600
- } else {
601
- $('span.text-fields-warning').fadeOut('fast');
602
  }
603
  });
604
-
605
- $.each( this._whenTrueActivateChilds, function( p, chs ) {
606
- $.each( chs, function( i, ch ) {
607
- var $ch = $( '[name="wpbdp-' + ch + '"], [name="wpbdp-' + ch + '[]"]' );
608
-
609
- $ch.change(function(e) {
610
- if ( ! $(this).data( 'wpbdp-disabled' ) ) {
611
- return true;
612
- }
613
-
614
- if ( $ch.is( '[type="checkbox"]' ) ) {
615
- if ( $ch[0].defaultChecked ) {
616
- $ch.prop( 'checked', true );
617
- } else {
618
- $ch.prop( 'checked', false );
619
- }
620
- } else if ( $ch.is( 'select' ) ) {
621
- // Nothing to do for now.
622
- } else {
623
- $ch.val( $ch[0].defaultValue );
624
- }
625
- });
626
- } );
627
-
628
- $('input[name="wpbdp-' + p + '"]').change(function(e) {
629
- t.handleToggle( p );
630
- });
631
-
632
- t.handleToggle( p );
633
- } );
634
- },
635
-
636
- handleToggle: function( setting ) {
637
- var childs_true = this._whenTrueActivateChilds[ setting ];
638
- var childs_false = this._whenFalseActivateChilds[ setting ];
639
- var childs = { 'true': childs_true, 'false': childs_false };
640
- var checked = $( 'input[name="wpbdp-' + setting + '"]' ).is( ':checked' );
641
-
642
- $.each( childs, function( req, settings ) {
643
- $.each( settings, function( i, s ) {
644
- var $s = $( '[name="wpbdp-' + s + '"], [name="wpbdp-' + s + '[]"]' );
645
- var $row = $s.parents( 'tr' );
646
-
647
- // FIXME: 'disabled' fields result in the setting being "cleared" in the backend. Why?
648
- if ( 'true' === req ) {
649
- if ( checked ) {
650
- $s.data( 'wpbdp-disabled', false );
651
- // $s.prop( 'contenteditable', true );
652
- $row.removeClass( 'disabled' );
653
- } else {
654
- $s.data( 'wpbdp-disabled', true );
655
- // $s.prop( 'contenteditable', false );
656
- $row.addClass( 'disabled' );
657
- }
658
- } else if ( 'false' === req ) {
659
- if ( checked ) {
660
- $s.data( 'wpbdp-disabled', true );
661
- // $s.pop( 'contenteditable', false );
662
- $row.addClass( 'disabled' );
663
- } else {
664
- $s.data( 'wpbdp-disabled', false );
665
- // $s.prop( 'contenteditable', true );
666
- $row.removeClass( 'disabled' );
667
- }
668
- }
669
- } );
670
- } );
671
- },
672
-
673
- add_requirement: function( setting, parent_, req ) {
674
- if ( 'undefined' === typeof this._whenTrueActivateChilds[ parent_ ] )
675
- this._whenTrueActivateChilds[ parent_ ] = [];
676
-
677
- if ( 'undefined' === typeof this._whenFalseActivateChilds[ parent_ ] )
678
- this._whenFalseActivateChilds[ parent_ ] = [];
679
-
680
- if ( 'boolean-true' == req )
681
- this._whenTrueActivateChilds[ parent_ ].push( setting );
682
- else if ( 'boolean-false' == req )
683
- this._whenFalseActivateChilds[ parent_ ].push( setting );
684
  }
685
  };
686
 
687
  $(document).ready(function(){
688
- if ( 0 == $('.wpbdp-page-admin-settings').length )
689
- return;
690
-
691
- s.init();
692
  });
693
  })(jQuery);
694
  /* }} */
@@ -768,108 +426,124 @@ WPBDP_Admin.ProgressBar = function($item, settings) {
768
  })(jQuery);
769
  // }}
770
 
771
- // {{ Settings - License Activation.
772
  (function($) {
773
- var l = WPBDP_Admin.licensing = {
774
- init: function() {
775
- $( 'input.license-activate' ).click(function(){
776
- var module = $(this).parent( '.license-activation' ).attr( 'data-module-id' );
777
- var license = $( 'input[type="text"]#license-key-' + module ).val();
778
- l.activation_change( module, license, 'activate' );
779
- });
780
 
781
- $( 'input.license-deactivate' ).click(function(){
782
- var module = $(this).parent( '.license-activation' ).attr( 'data-module-id' );
783
- var license = $( 'input[type="text"]#license-key-' + module );
784
- l.activation_change( module, '', 'deactivate' );
785
- });
786
- },
787
 
788
- activation_change: function(module, license, action) {
789
- var $container = $( '.license-activation[data-module-id="' + module + '"]' );
790
- var $msg = $( '.status-message', $container );
791
- var $error = $( '.license-activation-error[data-module-id="' + module + '"]', $container.closest( 'table' ) );
792
- var nonce = $( 'input[name="nonce"]', $container ).val();
 
 
 
 
793
 
794
- $msg.removeClass('ok error');
 
795
 
796
- if ( 0 === $error.length ) {
797
- $error = $( '<tr class="license-activation-error" data-module-id="' + module + '"><td colspan="2"></td></tr>' );
798
- $error.insertAfter( $container.closest( 'tr' ) );
799
- }
 
 
 
 
 
 
 
800
 
801
- $error.hide();
 
 
802
 
803
- $msg.html( $( 'input.license-' + action, $container ).attr('data-L10n') );
 
804
 
805
- $.post( ajaxurl, { 'action': 'wpbdp-' + action + '-license', 'module': module, 'key': license, 'nonce': nonce }, function(res) {
806
- if ( res.success ) {
807
- $msg.hide()
808
- .html(res.message)
809
- .removeClass('error')
810
- .addClass('ok')
811
- .show();
812
 
813
- $('input.license-' + action, $container).hide();
814
- $('input[type="button"]', $container).not( '.license-' + action ).show();
 
 
 
815
 
816
- if ( 'activate' == action )
817
- $( 'input[type="text"]#license-key-' + module ).prop('readonly', true);
818
- else
819
- $( 'input[type="text"]#license-key-' + module ).prop('readonly', false);
820
- } else {
821
- $msg.hide();
822
- $error.show();
823
 
824
- $( 'td', $error ).html( res.error );
 
825
 
826
- if ( 'deactivate' == action )
827
- $( 'input[type="text"]#license-key-' + module ).prop('readonly', false);
828
- }
829
- }, 'json' );
 
 
 
 
 
830
  }
 
831
 
832
- };
833
 
834
- $(document).ready(function() {
835
- if ( $( 'input.license-activate, input.license-deactivate' ).length > 0 )
836
- l.init();
 
 
 
837
 
838
- if ( $( '.wpbdp-license-expired-warning' ).length > 0 ) {
839
- $( '.wpbdp-license-expired-warning .dismiss' ).click(function (e) {
840
- e.preventDefault();
841
 
842
- var module_id = $(this).attr('data-module');
843
- var nonce = $(this).attr('data-nonce');
844
- var $warning = $(this).parents('.wpbdp-license-expired-warning');
845
 
846
- $.post( ajaxurl, {'action': 'wpbdp-license-expired-warning-dismiss', 'nonce': nonce, 'module': module_id}, function(res) {
847
- if ( res.success ) {
848
- $warning.fadeOut( 'fast' );
849
- }
850
- }, 'json' );
851
- });
852
- }
853
  });
854
- })(jQuery);
 
 
 
 
 
855
  // }}
 
856
 
857
- // Dismissible Messages
858
- (function($) {
859
- $(function(){
860
- $( '.wpbdp-notice.dismissible > .notice-dismiss' ).click( function( e ) {
861
- e.preventDefault();
862
 
863
- var $notice = $( this ).parent( '.wpbdp-notice' );
864
- var dismissible_id = $( this ).data( 'dismissible-id' );
865
- var nonce = $( this ).data( 'nonce' );
866
 
867
- $.post( ajaxurl,
868
- { action: 'wpbdp_dismiss_notification', id: dismissible_id, nonce: nonce },
869
- function() {
870
- $notice.fadeOut( 'fast', function(){ $notice.remove(); } );
871
- }
872
- );
 
873
  } );
874
- });
875
- })(jQuery);
20
  if ( $( this ).hasClass( 'yes' ) ) {
21
  $( this ).parents( '.iframe-confirm' ).hide();
22
  } else {
23
+ $( '#wpbdp-fieldsettings input[name="field[allow_iframes]"]' ).removeAttr( 'checked' );
24
  $( this ).parents( '.iframe-confirm' ).hide();
25
  }
26
  })
28
  $( '#wpbdp-fieldsettings input[name="field[allow_iframes]"]' ).change(function() {
29
  if ( $( this ).is(':checked') ) {
30
  $( '.iframe-confirm' ).show();
31
+ } else {
32
  $( '.iframe-confirm' ).hide();
33
  }
34
  });
35
 
36
+ $( '#wpbdp-formfield-form input[name="field[display_flags][]"][value="search"]' ).change(function(){
37
+ $( '.if-display-in-search' ).toggle( $( this ).is( ':checked' ) );
38
+ });
39
+
40
  $('table.formfields tbody').sortable({
41
  placeholder: 'wpbdp-draggable-highlight',
42
  handle: '.wpbdp-drag-handle',
65
 
66
  // URL fields can only have the 'url' validator.
67
  if ( 'url' == field_type ) {
68
+ $( 'select#field-validator option' ).not( '[value="url"]' ).attr( 'disabled', 'disabled' ).removeAttr( 'selected' );
69
+ $( 'select#field-validator option[value="url"]' ).attr( 'selected', 'selected' );
70
  } else {
71
+ $( 'select#field-validator option' ).removeAttr( 'disabled' );
72
  }
73
 
74
  var request_data = {
118
  jQuery(document).ready(function($){
119
 
120
  // {{ Manage Fees.
121
+ $('.wpbdp-admin-page-fees .wp-list-table.fees tbody').sortable({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  placeholder: 'wpbdp-draggable-highlight',
123
  handle: '.wpbdp-drag-handle',
124
  axis: 'y',
138
  }
139
  });
140
 
 
 
 
 
 
 
 
141
  $( 'select[name="fee_order[method]"], select[name="fee_order[order]"]' ).change(function(e) {
142
  $.ajax({
143
  url: ajaxurl,
152
  });
153
 
154
  if ( 'custom' == $('select[name="fee_order[method]"]').val() ) {
155
+ $( '.wpbdp-admin-page-fees .wp-list-table .wpbdp-drag-handle' ).show();
156
  }
157
  // }}
158
 
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  /* Ajax placeholders */
161
 
162
  $('.wpbdp-ajax-placeholder').each(function(i,v){
245
 
246
  var WPBDP_Admin = {};
247
  WPBDP_Admin.payments = {};
 
248
 
249
  // TODO: integrate this into $.
250
  WPBDP_Admin.ProgressBar = function($item, settings) {
313
 
314
  })(jQuery);
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  /* {{ Settings. */
317
  (function($) {
318
  var s = WPBDP_Admin.settings = {
 
 
 
319
  init: function() {
320
  var t = this;
321
 
322
+ $( '#wpbdp-settings-quick-search-fields' ).on( 'change', ':checkbox', function() {
323
+ var $container = $( '#wpbdp-settings-quick-search-fields' );
324
+ var text_fields = $container.data( 'text-fields' );
325
+ var selected = $container.find( ':checkbox:checked' ).map(function(){ return parseInt($(this).val()); }).get();
326
+ var show_warning = false;
327
+
328
+ if ( selected.length > 0 && text_fields.length > 0 ) {
329
+ for ( var i = 0; i < text_fields.length; i++ ) {
330
+ if ( $.inArray( text_fields[i], selected ) > -1 ) {
331
+ show_warning = true;
332
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  }
334
+ }
335
+ }
 
 
 
 
 
 
336
 
337
+ if ( show_warning ) {
338
+ $( '#wpbdp-settings-quick-search-fields .text-fields-warning' ).fadeIn( 'fast' );
339
+ } else {
340
+ $( '#wpbdp-settings-quick-search-fields .text-fields-warning' ).fadeOut( 'fast' );
341
  }
342
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
344
  };
345
 
346
  $(document).ready(function(){
347
+ if ( $( '#wpbdp-admin-page-settings' ).length > 0 ) {
348
+ s.init();
349
+ }
 
350
  });
351
  })(jQuery);
352
  /* }} */
426
  })(jQuery);
427
  // }}
428
 
429
+ // Dismissible Messages
430
  (function($) {
431
+ $(function(){
432
+ $( '.wpbdp-notice.dismissible > .notice-dismiss' ).click( function( e ) {
433
+ e.preventDefault();
 
 
 
 
434
 
435
+ var $notice = $( this ).parent( '.wpbdp-notice' );
436
+ var dismissible_id = $( this ).data( 'dismissible-id' );
437
+ var nonce = $( this ).data( 'nonce' );
 
 
 
438
 
439
+ $.post( ajaxurl,
440
+ { action: 'wpbdp_dismiss_notification', id: dismissible_id, nonce: nonce },
441
+ function() {
442
+ $notice.fadeOut( 'fast', function(){ $notice.remove(); } );
443
+ }
444
+ );
445
+ } );
446
+ });
447
+ })(jQuery);
448
 
449
+ // Some utilities for our admin forms.
450
+ jQuery(function( $ ) {
451
 
452
+ $( '.wpbdp-js-toggle' ).change(function() {
453
+ var name = $(this).attr('name');
454
+ var value = $(this).val();
455
+ var is_checkbox = $(this).is(':checkbox');
456
+ var is_radio = $(this).is(':radio');
457
+ var is_select = $(this).is('select');
458
+ var toggles = $(this).attr('data-toggles');
459
+
460
+ if ( is_select ) {
461
+ var $option = $( this ).find( ':selected' );
462
+ var toggles = $option.attr( 'data-toggles' );
463
 
464
+ if ( ! toggles || 'undefined' == typeof toggles )
465
+ toggles = '';
466
+ }
467
 
468
+ if ( toggles ) {
469
+ var $dest = ( toggles.startsWith('#') || toggles.startsWith('-') ) ? $(toggles) : $( '#' + toggles + ', .' + toggles );
470
 
471
+ if ( 0 == $dest.length || ( ! is_radio && ! is_checkbox && ! is_select ) )
472
+ return;
 
 
 
 
 
473
 
474
+ if ( is_checkbox && $(this).is(':checked') ) {
475
+ $dest.toggleClass('hidden');
476
+ return;
477
+ }
478
+ }
479
 
480
+ if ( is_select ) {
481
+ var other_opts = $( this ).find( 'option' ).not( '[value="' + value + '"]' );
482
+ } else {
483
+ var other_opts = $('input[name="' + name + '"]').not('[value="' + value + '"]');
484
+ }
 
 
485
 
486
+ other_opts.each(function() {
487
+ var toggles_i = $(this).attr('data-toggles');
488
 
489
+ if ( ! toggles_i )
490
+ return;
491
+
492
+ var $dest_i = ( toggles_i.startsWith('#') || toggles_i.startsWith('-') ) ? $(toggles_i) : $( '#' + toggles_i + ', .' + toggles_i );
493
+ $dest_i.addClass('hidden');
494
+ });
495
+
496
+ if ( toggles ) {
497
+ $dest.toggleClass('hidden');
498
  }
499
+ });
500
 
501
+ });
502
 
503
+ //
504
+ // {{ Admin tab selectors.
505
+ //
506
+ jQuery(function($) {
507
+ $('.wpbdp-admin-tab-nav a').click(function(e) {
508
+ e.preventDefault();
509
 
510
+ var $others = $( this ).parents( 'ul' ).find( 'li a' );
511
+ var $selected = $others.filter( '.current' );
 
512
 
513
+ $others.removeClass( 'current' );
514
+ $( this ).addClass( 'current' );
 
515
 
516
+ var href = $( this ).attr('href');
517
+ var $content = $( href );
518
+
519
+ if ( $selected.length > 0 )
520
+ $( $selected.attr( 'href' ) ).hide();
521
+
522
+ $content.show().focus();
523
  });
524
+
525
+ $( '.wpbdp-admin-tab-nav' ).each(function(i, v) {
526
+ $(this).find('a:first').click();
527
+ });
528
+ });
529
+ //
530
  // }}
531
+ //
532
 
533
+ jQuery( function( $ ) {
534
+ $( document ).on( 'click', '.wpbdp-admin-confirm', function( e ) {
535
+ // e.preventDefault();
 
 
536
 
537
+ var message = $( this ).data( 'confirm' );
538
+ if ( ! message || 'undefined' == typeof message )
539
+ message = 'Are you sure you want to do this?';
540
 
541
+ var confirm = window.confirm( message );
542
+ if ( ! confirm ) {
543
+ e.stopImmediatePropagation();
544
+ return false;
545
+ }
546
+
547
+ return true;
548
  } );
549
+ });
 
assets/js/admin.min.js CHANGED
@@ -1 +1 @@
1
- function wpbdp_load_placeholder($v){var action=$v.attr("data-action"),post_id=$v.attr("data-post_id"),baseurl=$v.attr("data-baseurl");$v.load(ajaxurl,{action:action,post_id:post_id,baseurl:baseurl})}var WPBDP_associations_fieldtypes={};!function($){var WPBDPAdmin_FormFields={$f_association:null,$f_fieldtype:null,init:function(){WPBDPAdmin_FormFields.$f_association=$("form#wpbdp-formfield-form select#field-association"),WPBDPAdmin_FormFields.$f_association.change(WPBDPAdmin_FormFields.onAssociationChange),WPBDPAdmin_FormFields.$f_fieldtype=$("form#wpbdp-formfield-form select#field-type"),WPBDPAdmin_FormFields.$f_fieldtype.change(WPBDPAdmin_FormFields.onFieldTypeChange),$("#wpbdp-fieldsettings .iframe-confirm a").click(function(e){e.preventDefault(),$(this).hasClass("yes")?$(this).parents(".iframe-confirm").hide():($('#wpbdp-fieldsettings input[name="field[allow_iframes]"]').prop("checked",!1),$(this).parents(".iframe-confirm").hide())}),$('#wpbdp-fieldsettings input[name="field[allow_iframes]"]').change(function(){$(this).is(":checked")?$(".iframe-confirm").show():$(".iframe-confirm").hide()}),$("table.formfields tbody").sortable({placeholder:"wpbdp-draggable-highlight",handle:".wpbdp-drag-handle",axis:"y",cursor:"move",opacity:.9,update:function(event,ui){var sorted_items=[];$(this).find(".wpbdp-drag-handle").each(function(i,v){sorted_items.push($(v).attr("data-field-id"))}),sorted_items&&$.post(ajaxurl,{action:"wpbdp-formfields-reorder",order:sorted_items})}})},onFieldTypeChange:function(){var $field_type=$(this).find("option:selected");if($field_type.length){var field_type=$field_type.val();"url"==field_type?($("select#field-validator option").not('[value="url"]').prop({disabled:!0,selected:!1}),$('select#field-validator option[value="url"]').prop("selected",!0)):$("select#field-validator option").prop("disabled",!1);var request_data={action:"wpbdp-renderfieldsettings",association:WPBDPAdmin_FormFields.$f_association.find("option:selected").val(),field_type:field_type,field_id:$('#wpbdp-formfield-form input[name="field[id]"]').val()};$.post(ajaxurl,request_data,function(response){response.ok&&response.html?($("#wpbdp-fieldsettings-html").html(response.html),$("#wpbdp-fieldsettings").show()):($("#wpbdp-fieldsettings-html").empty(),$("#wpbdp-fieldsettings").hide())},"json")}},onAssociationChange:function(){$f_fieldtype=WPBDPAdmin_FormFields.$f_fieldtype;var association=$(this).val(),valid_types=WPBDP_associations_fieldtypes[association];$f_fieldtype.find("option").prop("disabled",!1),$f_fieldtype.find("option").each(function(i,v){$.inArray($(v).val(),valid_types)<0&&$(v).prop("disabled",!0)}),$f_fieldtype.change()}};$(document).ready(function(){WPBDPAdmin_FormFields.init()})}(jQuery),jQuery(document).ready(function($){$('form#wpbdp-fee-form input[name="_days"]').change(function(){var value=$(this).val();return 0==value?($("form input#wpbdp-fee-form-days-n").prop("disabled",!0),$('form input[name="fee[days]"]').val("0")):($("form input#wpbdp-fee-form-days-n").prop("disabled",!1),$('form input[name="fee[days]"]').val($("form input#wpbdp-fee-form-days-n").val()),$("form input#wpbdp-fee-form-days-n").focus()),!0}),$(".wpbdp-page-admin-fees .wp-list-table.fees tbody").sortable({placeholder:"wpbdp-draggable-highlight",handle:".wpbdp-drag-handle",axis:"y",cursor:"move",opacity:.9,update:function(event,ui){var rel_rows=$(".free-fee-related-tr").remove();$("tr.free-fee").after(rel_rows);var sorted_items=[];$(this).find(".wpbdp-drag-handle").each(function(i,v){sorted_items.push($(v).attr("data-fee-id"))}),sorted_items&&$.post(ajaxurl,{action:"wpbdp-admin-fees-reorder",order:sorted_items})}}),$("form#wpbdp-fee-form").submit(function(){return $('form input[name="fee[days]"]').prop("disabled",!1),!0}),$('select[name="fee_order[method]"], select[name="fee_order[order]"]').change(function(e){$.ajax({url:ajaxurl,data:$(this).parent("form").serialize(),dataType:"json",type:"POST",success:function(res){res.success&&location.reload()}})}),"custom"==$('select[name="fee_order[method]"]').val()&&$(".wpbdp-page-admin-fees .wp-list-table .wpbdp-drag-handle").show(),$("#BusinessDirectory_listinginfo .listing-metabox-tabs a").click(function(e){e.preventDefault();var href=$(this).attr("href"),$selected=$(this).parent("li").siblings(".selected");if($selected.length>0){if($selected.find("a:first").attr("href")==href)return;$selected.removeClass("selected"),$($selected.find("a:first").attr("href")).hide()}$(this).parent("li").addClass("selected"),$(href).show(),$(".listing-fee-expiration-datepicker").hide()});var url_tab=$(location).attr("hash");url_tab&&$(url_tab).length>0?$('#BusinessDirectory_listinginfo a[href="'+url_tab+'"]').click():$("#BusinessDirectory_listinginfo .listing-metabox-tabs li.selected a").click(),$("#listing-metabox-fees a.assignfee-link").click(function(e){e.preventDefault(),$(this).siblings(".assignfee").show()}),$("#listing-metabox-fees .assignfee .close-handle").click(function(e){e.preventDefault(),$(this).parent(".assignfee").hide()}),$(".wpbdp-ajax-placeholder").each(function(i,v){wpbdp_load_placeholder($(v))}),$("input#doaction, input#doaction2").click(function(e){var action_name="doaction"==$(this).attr("id")?"action":"action2",$selected_option=$('select[name="'+action_name+'"] option:selected'),action_val=$selected_option.val();if("listing"==action_val.split("-")[0]){var action=action_val.split("-")[1];if("sep0"!=action&&"sep1"!=action&&"sep2"!=action){var $checked_posts=$('input[name="post[]"]:checked'),uri=$selected_option.attr("data-uri");return $checked_posts.each(function(i,v){uri+="&post[]="+$(v).val()}),window.location.href=uri,!1}}return!0}),$('.wpbdp-admin.wpbdp-page-formfields-preview form input[type="submit"]').click(function(e){e.preventDefault(),alert("This form is just a preview. It doesn't work.")}),$("#wpbdp-admin-debug-info-page a.nav-tab").click(function(e){e.preventDefault(),$("#wpbdp-admin-debug-info-page a.nav-tab").not(this).removeClass("nav-tab-active");var $selected_tab=$(this);$selected_tab.addClass("nav-tab-active"),$(".wpbdp-debug-section").hide(),$('.wpbdp-debug-section[data-id="'+$(this).attr("href")+'"]').show()}),$("#wpbdp-admin-debug-info-page a.nav-tab").length>0&&$("#wpbdp-admin-debug-info-page a.nav-tab").get(0).click(),$(".wpbdp-page-admin-transactions .column-actions a.details-link").click(function(e){e.preventDefault();var $tr=$(this).parents("tr"),$details=$tr.find("div.more-details"),$tr_details=$tr.next("tr.more-details-row");return $tr_details.length>0?($tr_details.remove(),void $(this).text($(this).text().replace("-","+"))):($(this).text($(this).text().replace("+","-")),void $tr.after('<tr class="more-details-row"><td colspan="7">'+$details.html()+"</td></tr>").show())})});var WPBDP_Admin={};WPBDP_Admin.payments={},WPBDP_Admin.listingMetabox={},WPBDP_Admin.ProgressBar=function($item,settings){$item.empty(),$item.html('<div class="wpbdp-progress-bar"><span class="progress-text">0%</span><div class="progress-bar"><div class="progress-bar-outer"><div class="progress-bar-inner" style="width: 0%;"></div></div></div>'),this.$item=$item,this.$text=$item.find(".progress-text"),this.$bar=$item.find(".progress-bar"),this.set=function(completed,total){var pcg=Math.round(100*parseInt(completed)/parseInt(total));this.$text.text(pcg+"%"),this.$bar.find(".progress-bar-inner").attr("style","width: "+pcg+"%;")}},function($){WPBDP_Admin.dialog={};WPBDP_Admin.dialog}(jQuery),function($){var payments=WPBDP_Admin.payments;payments._initialize=function(){$("#BusinessDirectory_listinginfo a.payment-details-link").click(function(e){e.preventDefault(),payments.viewPaymentDetails($(this).attr("data-id"))}),0==$("#wpbdp-modal-dialog").length&&$("body").append($('<div id="wpbdp-modal-dialog"></div>'))},payments.viewPaymentDetails=function(id){$.get(ajaxurl,{action:"wpbdp-payment-details",id:id},function(res){res&&res.success&&(0==$("#wpbdp-modal-dialog").length&&$("body").append($('<div id="wpbdp-modal-dialog"></div>')),$("#wpbdp-modal-dialog").html(res.data.html),tb_show("","#TB_inline?inlineId=wpbdp-modal-dialog"),$("#TB_window").width($("#TB_ajaxContent").outerWidth()),$("#TB_window").height()>$("#TB_ajaxContent").outerHeight()&&$("#TB_ajaxContent").height($("#TB_window").height()),$("#wpbdp-modal-dialog").remove())},"json")},$(document).ready(function(){payments._initialize()})}(jQuery),function($){var metabox=WPBDP_Admin.listingMetabox;metabox._initialize=function(){$.extend($.datepicker,{_inlineDatepicker2:$.datepicker._inlineDatepicker,_inlineDatepicker:function(target,inst){this._inlineDatepicker2(target,inst);var beforeShow=$.datepicker._get(inst,"beforeShow");beforeShow&&beforeShow.apply(target,[target,inst])}});var _addNeverButton=function(instance){setTimeout(function(){var $buttonPane=$(instance).find(".ui-datepicker-buttonpane");if(!($buttonPane.find(".ui-datepicker-never").length>0)){var $button=$("<button>",{text:"Never Expires",click:function(){return _updateExpiration($(instance),"never"),!1}}).addClass("ui-datepicker-never ui-state-default ui-priority-primary ui-corner-all");$buttonPane.append($button)}},1)},_updateExpiration=function($instance,newDate){if(newDate){var $changeLink=$instance.siblings("a.expiration-change-link"),$expirationDate=$instance.siblings(".expiration-date"),$spinner=$instance.parents(".listing-category").find(".spinner:first");$expirationDate.text("--"),$spinner.show(),$instance.hide(),_addNeverButton($instance.get(0)),$.post(ajaxurl,{action:"wpbdp-listing_set_expiration",renewal_id:$changeLink.attr("data-renewal_id"),expiration_date:newDate},function(res){res&&res.success&&($spinner.hide(),$expirationDate.text(res.data.formattedExpirationDate).show())},"json")}};$("#listing-metabox-generalinfo, #listing-metabox-fees").each(function(i,v){var $tab=$(v);$tab.find(".expiration-date-info .datepicker").each(function(i,v){var $dp=$(v),$changeLink=$dp.siblings("a.expiration-change-link");$dp.hide().datepicker({dateFormat:"yy-mm-dd",defaultDate:$changeLink.attr("data-date"),showButtonPanel:!0,beforeShow:function(input){_addNeverButton(input)},onChangeMonthYear:function(year,month,instance){_addNeverButton(instance.input)},onSelect:function(newDate){_updateExpiration($(this),newDate)}})}),$tab.find("a.expiration-change-link").click(function(e){e.preventDefault();var renewal_id=$(this).attr("data-renewal_id");$(".expiration-date-info .datepicker").not(".renewal-"+renewal_id).hide(),$(".expiration-date-info .datepicker.renewal-"+renewal_id).toggle()})}),$(".listing-category a.category-delete").click(function(e){e.preventDefault();var listingID=$(this).attr("data-listing"),categoryID=$(this).attr("data-category");if(listingID&&categoryID){var $category=$(".listing-category-"+categoryID);$.post(ajaxurl,{action:"wpbdp-listing_remove_category",listing:listingID,category:categoryID},function(res){res&&res.success&&($('input[name="tax_input[wpbdp_category][]"][value="'+categoryID+'"]').prop("checked",!1),$category.fadeOut(function(){$(this).remove()}))},"json")}}),$(".listing-category a.category-change-fee").click(function(e){e.preventDefault(),0==$("#wpbdp-modal-dialog").length&&$("body").append($('<div id="wpbdp-modal-dialog"></div>')),$.post(ajaxurl,{action:"wpbdp-listing_change_fee",renewal:$(this).attr("data-renewal")},function(res){res&&res.success&&($("#wpbdp-modal-dialog").html(res.data.html),tb_show("","#TB_inline?inlineId=wpbdp-modal-dialog"),$("#wpbdp-modal-dialog").remove())},"json")})},$(document).ready(function(){$("#listing-metabox-fees").length>0&&metabox._initialize()})}(jQuery),function($){var s=WPBDP_Admin.settings={_whenTrueActivateChilds:{},_whenFalseActivateChilds:{},init:function(){var t=this;$(".wpbdp-settings-email").each(function(i,v){var $email=$(v),$preview=$email.find(".short-preview"),$editor=$email.find(".editor"),$subject=$editor.find(".subject-text"),$body=$editor.find(".body-text"),data={subject:"",body:""};$preview.click(function(e){data.subject=$subject.val(),data.body=$body.val(),$preview.hide(),$editor.show()}),$(".cancel",$editor).click(function(e){e.preventDefault(),$subject.val(data.subject),$body.val(data.body),$editor.hide(),$preview.show()}),$(".save",$editor).click(function(e){e.preventDefault(),$("form#wpbdp-admin-settings #submit").click()}),$(".preview-email",$editor).click(function(e){e.preventDefault();var subject=$subject.val(),body=$body.val();$.ajax({url:ajaxurl,data:{action:"wpbdp-admin-settings-email-preview",nonce:$editor.attr("data-preview-nonce"),setting:$email.attr("data-setting"),subject:subject,body:body},dataType:"json",type:"POST",success:function(res){res.success&&(0==$("#wpbdp-modal-dialog").length&&$("body").append('<div id="wpbdp-modal-dialog" style="display: none;"></div>'),$("#wpbdp-modal-dialog").html(res.data.html),tb_show("","#TB_inline?inlineId=wpbdp-modal-dialog"),$("#wpbdp-modal-dialog").remove())}})})}),$("ul#quick-search-fields").on("change",":checkbox",function(){var selected=$(this).closest("ul").find(".textfield :checkbox:checked").length;selected>0?$("span.text-fields-warning").fadeIn("fast"):$("span.text-fields-warning").fadeOut("fast")}),$.each(this._whenTrueActivateChilds,function(p,chs){$.each(chs,function(i,ch){var $ch=$('[name="wpbdp-'+ch+'"], [name="wpbdp-'+ch+'[]"]');$ch.change(function(e){return!$(this).data("wpbdp-disabled")||void($ch.is('[type="checkbox"]')?$ch[0].defaultChecked?$ch.prop("checked",!0):$ch.prop("checked",!1):$ch.is("select")||$ch.val($ch[0].defaultValue))})}),$('input[name="wpbdp-'+p+'"]').change(function(e){t.handleToggle(p)}),t.handleToggle(p)})},handleToggle:function(setting){var childs_true=this._whenTrueActivateChilds[setting],childs_false=this._whenFalseActivateChilds[setting],childs={"true":childs_true,"false":childs_false},checked=$('input[name="wpbdp-'+setting+'"]').is(":checked");$.each(childs,function(req,settings){$.each(settings,function(i,s){var $s=$('[name="wpbdp-'+s+'"], [name="wpbdp-'+s+'[]"]'),$row=$s.parents("tr");"true"===req?checked?($s.data("wpbdp-disabled",!1),$row.removeClass("disabled")):($s.data("wpbdp-disabled",!0),$row.addClass("disabled")):"false"===req&&(checked?($s.data("wpbdp-disabled",!0),$row.addClass("disabled")):($s.data("wpbdp-disabled",!1),$row.removeClass("disabled")))})})},add_requirement:function(setting,parent_,req){"undefined"==typeof this._whenTrueActivateChilds[parent_]&&(this._whenTrueActivateChilds[parent_]=[]),"undefined"==typeof this._whenFalseActivateChilds[parent_]&&(this._whenFalseActivateChilds[parent_]=[]),"boolean-true"==req?this._whenTrueActivateChilds[parent_].push(setting):"boolean-false"==req&&this._whenFalseActivateChilds[parent_].push(setting)}};$(document).ready(function(){0!=$(".wpbdp-page-admin-settings").length&&s.init()})}(jQuery),function($){var u=WPBDP_Admin.uninstall={init:function(){$('form#wpbdp-uninstall-capture-form input[name="uninstall[reason_id]"]').change(function(e){var val=$(this).val();"0"==val?$('form#wpbdp-uninstall-capture-form textarea[name="uninstall[reason_text]"]').fadeIn():$('form#wpbdp-uninstall-capture-form textarea[name="uninstall[reason_text]"]').fadeOut("fast",function(){$(this).val("")})})}};$(document).ready(function(){$(".wpbdp-page-admin-uninstall").length>0&&u.init()})}(jQuery),function($){$(document).ready(function(){0!=$("body.wp-admin.widgets-php").length&&$("body.wp-admin.widgets-php").on("change","input.wpbdp-toggle-images",function(){var checked=$(this).is(":checked");checked?$(this).parents(".widget").find(".thumbnail-width-config, .thumbnail-height-config").fadeIn("fast"):$(this).parents(".widget").find(".thumbnail-width-config, .thumbnail-height-config").fadeOut("fast")})})}(jQuery),function($){$(document).ready(function(){$("a.wpbdp-create-main-page-button").click(function(e){e.preventDefault();var $msg=$(this).parents("div.error");$.ajax({url:ajaxurl,data:{action:"wpbdp-create-main-page",_wpnonce:$(this).attr("data-nonce")},dataType:"json",success:function(res){res.success&&$msg.fadeOut("fast",function(){$(this).html("<p>"+res.message+"</p>"),$(this).removeClass("error"),$(this).addClass("updated"),$(this).fadeIn("fast")})}})})})}(jQuery),function($){var l=WPBDP_Admin.licensing={init:function(){$("input.license-activate").click(function(){var module=$(this).parent(".license-activation").attr("data-module-id"),license=$('input[type="text"]#license-key-'+module).val();l.activation_change(module,license,"activate")}),$("input.license-deactivate").click(function(){var module=$(this).parent(".license-activation").attr("data-module-id");$('input[type="text"]#license-key-'+module);l.activation_change(module,"","deactivate")})},activation_change:function(module,license,action){var $container=$('.license-activation[data-module-id="'+module+'"]'),$msg=$(".status-message",$container),$error=$('.license-activation-error[data-module-id="'+module+'"]',$container.closest("table")),nonce=$('input[name="nonce"]',$container).val();$msg.removeClass("ok error"),0===$error.length&&($error=$('<tr class="license-activation-error" data-module-id="'+module+'"><td colspan="2"></td></tr>'),$error.insertAfter($container.closest("tr"))),$error.hide(),$msg.html($("input.license-"+action,$container).attr("data-L10n")),$.post(ajaxurl,{action:"wpbdp-"+action+"-license",module:module,key:license,nonce:nonce},function(res){res.success?($msg.hide().html(res.message).removeClass("error").addClass("ok").show(),$("input.license-"+action,$container).hide(),$('input[type="button"]',$container).not(".license-"+action).show(),"activate"==action?$('input[type="text"]#license-key-'+module).prop("readonly",!0):$('input[type="text"]#license-key-'+module).prop("readonly",!1)):($msg.hide(),$error.show(),$("td",$error).html(res.error),"deactivate"==action&&$('input[type="text"]#license-key-'+module).prop("readonly",!1))},"json")}};$(document).ready(function(){$("input.license-activate, input.license-deactivate").length>0&&l.init(),$(".wpbdp-license-expired-warning").length>0&&$(".wpbdp-license-expired-warning .dismiss").click(function(e){e.preventDefault();var module_id=$(this).attr("data-module"),nonce=$(this).attr("data-nonce"),$warning=$(this).parents(".wpbdp-license-expired-warning");$.post(ajaxurl,{action:"wpbdp-license-expired-warning-dismiss",nonce:nonce,module:module_id},function(res){res.success&&$warning.fadeOut("fast")},"json")})})}(jQuery),function($){$(function(){$(".wpbdp-notice.dismissible > .notice-dismiss").click(function(e){e.preventDefault();var $notice=$(this).parent(".wpbdp-notice"),dismissible_id=$(this).data("dismissible-id"),nonce=$(this).data("nonce");$.post(ajaxurl,{action:"wpbdp_dismiss_notification",id:dismissible_id,nonce:nonce},function(){$notice.fadeOut("fast",function(){$notice.remove()})})})})}(jQuery);
1
+ function wpbdp_load_placeholder($v){var action=$v.attr("data-action"),post_id=$v.attr("data-post_id"),baseurl=$v.attr("data-baseurl");$v.load(ajaxurl,{action:action,post_id:post_id,baseurl:baseurl})}var WPBDP_associations_fieldtypes={};!function($){var WPBDPAdmin_FormFields={$f_association:null,$f_fieldtype:null,init:function(){WPBDPAdmin_FormFields.$f_association=$("form#wpbdp-formfield-form select#field-association"),WPBDPAdmin_FormFields.$f_association.change(WPBDPAdmin_FormFields.onAssociationChange),WPBDPAdmin_FormFields.$f_fieldtype=$("form#wpbdp-formfield-form select#field-type"),WPBDPAdmin_FormFields.$f_fieldtype.change(WPBDPAdmin_FormFields.onFieldTypeChange),$("#wpbdp-fieldsettings .iframe-confirm a").click(function(e){e.preventDefault(),$(this).hasClass("yes")?$(this).parents(".iframe-confirm").hide():($('#wpbdp-fieldsettings input[name="field[allow_iframes]"]').removeAttr("checked"),$(this).parents(".iframe-confirm").hide())}),$('#wpbdp-fieldsettings input[name="field[allow_iframes]"]').change(function(){$(this).is(":checked")?$(".iframe-confirm").show():$(".iframe-confirm").hide()}),$('#wpbdp-formfield-form input[name="field[display_flags][]"][value="search"]').change(function(){$(".if-display-in-search").toggle($(this).is(":checked"))}),$("table.formfields tbody").sortable({placeholder:"wpbdp-draggable-highlight",handle:".wpbdp-drag-handle",axis:"y",cursor:"move",opacity:.9,update:function(event,ui){var sorted_items=[];$(this).find(".wpbdp-drag-handle").each(function(i,v){sorted_items.push($(v).attr("data-field-id"))}),sorted_items&&$.post(ajaxurl,{action:"wpbdp-formfields-reorder",order:sorted_items})}})},onFieldTypeChange:function(){var $field_type=$(this).find("option:selected");if($field_type.length){var field_type=$field_type.val();"url"==field_type?($("select#field-validator option").not('[value="url"]').attr("disabled","disabled").removeAttr("selected"),$('select#field-validator option[value="url"]').attr("selected","selected")):$("select#field-validator option").removeAttr("disabled");var request_data={action:"wpbdp-renderfieldsettings",association:WPBDPAdmin_FormFields.$f_association.find("option:selected").val(),field_type:field_type,field_id:$('#wpbdp-formfield-form input[name="field[id]"]').val()};$.post(ajaxurl,request_data,function(response){response.ok&&response.html?($("#wpbdp-fieldsettings-html").html(response.html),$("#wpbdp-fieldsettings").show()):($("#wpbdp-fieldsettings-html").empty(),$("#wpbdp-fieldsettings").hide())},"json")}},onAssociationChange:function(){$f_fieldtype=WPBDPAdmin_FormFields.$f_fieldtype;var association=$(this).val(),valid_types=WPBDP_associations_fieldtypes[association];$f_fieldtype.find("option").prop("disabled",!1),$f_fieldtype.find("option").each(function(i,v){$.inArray($(v).val(),valid_types)<0&&$(v).prop("disabled",!0)}),$f_fieldtype.change()}};$(document).ready(function(){WPBDPAdmin_FormFields.init()})}(jQuery),jQuery(document).ready(function($){$(".wpbdp-admin-page-fees .wp-list-table.fees tbody").sortable({placeholder:"wpbdp-draggable-highlight",handle:".wpbdp-drag-handle",axis:"y",cursor:"move",opacity:.9,update:function(event,ui){var rel_rows=$(".free-fee-related-tr").remove();$("tr.free-fee").after(rel_rows);var sorted_items=[];$(this).find(".wpbdp-drag-handle").each(function(i,v){sorted_items.push($(v).attr("data-fee-id"))}),sorted_items&&$.post(ajaxurl,{action:"wpbdp-admin-fees-reorder",order:sorted_items})}}),$('select[name="fee_order[method]"], select[name="fee_order[order]"]').change(function(e){$.ajax({url:ajaxurl,data:$(this).parent("form").serialize(),dataType:"json",type:"POST",success:function(res){res.success&&location.reload()}})}),"custom"==$('select[name="fee_order[method]"]').val()&&$(".wpbdp-admin-page-fees .wp-list-table .wpbdp-drag-handle").show(),$(".wpbdp-ajax-placeholder").each(function(i,v){wpbdp_load_placeholder($(v))}),$("input#doaction, input#doaction2").click(function(e){var action_name="doaction"==$(this).attr("id")?"action":"action2",$selected_option=$('select[name="'+action_name+'"] option:selected'),action_val=$selected_option.val();if("listing"==action_val.split("-")[0]){var action=action_val.split("-")[1];if("sep0"!=action&&"sep1"!=action&&"sep2"!=action){var $checked_posts=$('input[name="post[]"]:checked'),uri=$selected_option.attr("data-uri");return $checked_posts.each(function(i,v){uri+="&post[]="+$(v).val()}),window.location.href=uri,!1}}return!0}),$('.wpbdp-admin.wpbdp-page-formfields-preview form input[type="submit"]').click(function(e){e.preventDefault(),alert("This form is just a preview. It doesn't work.")}),$("#wpbdp-admin-debug-info-page a.nav-tab").click(function(e){e.preventDefault(),$("#wpbdp-admin-debug-info-page a.nav-tab").not(this).removeClass("nav-tab-active");var $selected_tab=$(this);$selected_tab.addClass("nav-tab-active"),$(".wpbdp-debug-section").hide(),$('.wpbdp-debug-section[data-id="'+$(this).attr("href")+'"]').show()}),$("#wpbdp-admin-debug-info-page a.nav-tab").length>0&&$("#wpbdp-admin-debug-info-page a.nav-tab").get(0).click(),$(".wpbdp-page-admin-transactions .column-actions a.details-link").click(function(e){e.preventDefault();var $tr=$(this).parents("tr"),$details=$tr.find("div.more-details"),$tr_details=$tr.next("tr.more-details-row");return $tr_details.length>0?($tr_details.remove(),void $(this).text($(this).text().replace("-","+"))):($(this).text($(this).text().replace("+","-")),void $tr.after('<tr class="more-details-row"><td colspan="7">'+$details.html()+"</td></tr>").show())})});var WPBDP_Admin={};WPBDP_Admin.payments={},WPBDP_Admin.ProgressBar=function($item,settings){$item.empty(),$item.html('<div class="wpbdp-progress-bar"><span class="progress-text">0%</span><div class="progress-bar"><div class="progress-bar-outer"><div class="progress-bar-inner" style="width: 0%;"></div></div></div>'),this.$item=$item,this.$text=$item.find(".progress-text"),this.$bar=$item.find(".progress-bar"),this.set=function(completed,total){var pcg=Math.round(100*parseInt(completed)/parseInt(total));this.$text.text(pcg+"%"),this.$bar.find(".progress-bar-inner").attr("style","width: "+pcg+"%;")}},function($){WPBDP_Admin.dialog={};WPBDP_Admin.dialog}(jQuery),function($){var payments=WPBDP_Admin.payments;payments._initialize=function(){$("#BusinessDirectory_listinginfo a.payment-details-link").click(function(e){e.preventDefault(),payments.viewPaymentDetails($(this).attr("data-id"))}),0==$("#wpbdp-modal-dialog").length&&$("body").append($('<div id="wpbdp-modal-dialog"></div>'))},payments.viewPaymentDetails=function(id){$.get(ajaxurl,{action:"wpbdp-payment-details",id:id},function(res){res&&res.success&&(0==$("#wpbdp-modal-dialog").length&&$("body").append($('<div id="wpbdp-modal-dialog"></div>')),$("#wpbdp-modal-dialog").html(res.data.html),tb_show("","#TB_inline?inlineId=wpbdp-modal-dialog"),$("#TB_window").width($("#TB_ajaxContent").outerWidth()),$("#TB_window").height()>$("#TB_ajaxContent").outerHeight()&&$("#TB_ajaxContent").height($("#TB_window").height()),$("#wpbdp-modal-dialog").remove())},"json")},$(document).ready(function(){payments._initialize()})}(jQuery),function($){var s=WPBDP_Admin.settings={init:function(){$("#wpbdp-settings-quick-search-fields").on("change",":checkbox",function(){var $container=$("#wpbdp-settings-quick-search-fields"),text_fields=$container.data("text-fields"),selected=$container.find(":checkbox:checked").map(function(){return parseInt($(this).val())}).get(),show_warning=!1;if(selected.length>0&&text_fields.length>0)for(var i=0;i<text_fields.length;i++)if($.inArray(text_fields[i],selected)>-1){show_warning=!0;break}show_warning?$("#wpbdp-settings-quick-search-fields .text-fields-warning").fadeIn("fast"):$("#wpbdp-settings-quick-search-fields .text-fields-warning").fadeOut("fast")})}};$(document).ready(function(){$("#wpbdp-admin-page-settings").length>0&&s.init()})}(jQuery),function($){var u=WPBDP_Admin.uninstall={init:function(){$('form#wpbdp-uninstall-capture-form input[name="uninstall[reason_id]"]').change(function(e){var val=$(this).val();"0"==val?$('form#wpbdp-uninstall-capture-form textarea[name="uninstall[reason_text]"]').fadeIn():$('form#wpbdp-uninstall-capture-form textarea[name="uninstall[reason_text]"]').fadeOut("fast",function(){$(this).val("")})})}};$(document).ready(function(){$(".wpbdp-page-admin-uninstall").length>0&&u.init()})}(jQuery),function($){$(document).ready(function(){0!=$("body.wp-admin.widgets-php").length&&$("body.wp-admin.widgets-php").on("change","input.wpbdp-toggle-images",function(){var checked=$(this).is(":checked");checked?$(this).parents(".widget").find(".thumbnail-width-config, .thumbnail-height-config").fadeIn("fast"):$(this).parents(".widget").find(".thumbnail-width-config, .thumbnail-height-config").fadeOut("fast")})})}(jQuery),function($){$(document).ready(function(){$("a.wpbdp-create-main-page-button").click(function(e){e.preventDefault();var $msg=$(this).parents("div.error");$.ajax({url:ajaxurl,data:{action:"wpbdp-create-main-page",_wpnonce:$(this).attr("data-nonce")},dataType:"json",success:function(res){res.success&&$msg.fadeOut("fast",function(){$(this).html("<p>"+res.message+"</p>"),$(this).removeClass("error"),$(this).addClass("updated"),$(this).fadeIn("fast")})}})})})}(jQuery),function($){$(function(){$(".wpbdp-notice.dismissible > .notice-dismiss").click(function(e){e.preventDefault();var $notice=$(this).parent(".wpbdp-notice"),dismissible_id=$(this).data("dismissible-id"),nonce=$(this).data("nonce");$.post(ajaxurl,{action:"wpbdp_dismiss_notification",id:dismissible_id,nonce:nonce},function(){$notice.fadeOut("fast",function(){$notice.remove()})})})})}(jQuery),jQuery(function($){$(".wpbdp-js-toggle").change(function(){var name=$(this).attr("name"),value=$(this).val(),is_checkbox=$(this).is(":checkbox"),is_radio=$(this).is(":radio"),is_select=$(this).is("select"),toggles=$(this).attr("data-toggles");if(is_select){var $option=$(this).find(":selected"),toggles=$option.attr("data-toggles");toggles&&"undefined"!=typeof toggles||(toggles="")}if(toggles){var $dest=$(toggles.startsWith("#")||toggles.startsWith("-")?toggles:"#"+toggles+", ."+toggles);if(0==$dest.length||!is_radio&&!is_checkbox&&!is_select)return;if(is_checkbox&&$(this).is(":checked"))return void $dest.toggleClass("hidden")}if(is_select)var other_opts=$(this).find("option").not('[value="'+value+'"]');else var other_opts=$('input[name="'+name+'"]').not('[value="'+value+'"]');other_opts.each(function(){var toggles_i=$(this).attr("data-toggles");if(toggles_i){var $dest_i=$(toggles_i.startsWith("#")||toggles_i.startsWith("-")?toggles_i:"#"+toggles_i+", ."+toggles_i);$dest_i.addClass("hidden")}}),toggles&&$dest.toggleClass("hidden")})}),jQuery(function($){$(".wpbdp-admin-tab-nav a").click(function(e){e.preventDefault();var $others=$(this).parents("ul").find("li a"),$selected=$others.filter(".current");$others.removeClass("current"),$(this).addClass("current");var href=$(this).attr("href"),$content=$(href);$selected.length>0&&$($selected.attr("href")).hide(),$content.show().focus()}),$(".wpbdp-admin-tab-nav").each(function(i,v){$(this).find("a:first").click()})}),jQuery(function($){$(document).on("click",".wpbdp-admin-confirm",function(e){var message=$(this).data("confirm");message&&"undefined"!=typeof message||(message="Are you sure you want to do this?");var confirm=window.confirm(message);return!!confirm||(e.stopImmediatePropagation(),!1)})});
assets/js/checkout.js ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($) {
2
+ var wpbdp_checkout = {
3
+ init: function() {
4
+ var $form = $( 'form#wpbdp-checkout-form' );
5
+
6
+ if ( 0 == $form.length )
7
+ return;
8
+
9
+ var self = this;
10
+ this.$form = $form;
11
+ this.$container = this.$form.find( '#wpbdp-checkout-form-fields' );
12
+
13
+ this.payment_key = this.$form.find( 'input[name="payment"]' ).val();
14
+ this.nonce = this.$form.find( 'input[name="_wpnonce"]' ).val();
15
+
16
+ this.working = false;
17
+
18
+ // Gateway changes.
19
+ this.$form.find( 'input[name="gateway"]' ).change(function() {
20
+ if ( self.working )
21
+ return;
22
+
23
+ var gateway = self.$form.find( 'input[name="gateway"]:checked' ).val();
24
+
25
+ if ( ! gateway )
26
+ return;
27
+
28
+ self.load_gateway( gateway );
29
+ });
30
+ },
31
+
32
+ load_gateway: function( gateway_id ) {
33
+ var self = this;
34
+ self.$container.html('');
35
+ self.working = true;
36
+
37
+ var url = wpbdp_global.ajaxurl;
38
+ url += url.indexOf( '?' ) > 0 ? '&' : '?';
39
+ url += 'payment=' + self.payment_key + '&'
40
+ url += 'gateway=' + gateway_id;
41
+
42
+ $.post( url, { action: 'wpbdp_ajax', handler: 'checkout__load_gateway', _wpnonce: self.nonce }, function( res ) {
43
+ self.$container.removeClass().addClass( 'wpbdp-payment-gateway-' + gateway_id + '-form-fields' );
44
+ self.$container.html( res );
45
+ self.working = false;
46
+ } );
47
+ }
48
+ };
49
+
50
+ wpbdp_checkout.init();
51
+
52
+
53
+ // Payment receipt print.
54
+ $( '.wpbdp-payment-receipt-print' ).click(function(e) {
55
+ e.preventDefault();
56
+ window.print();
57
+ });
58
+ });
59
+
assets/js/checkout.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(function($){var wpbdp_checkout={init:function(){var $form=$("form#wpbdp-checkout-form");if(0!=$form.length){var self=this;this.$form=$form,this.$container=this.$form.find("#wpbdp-checkout-form-fields"),this.payment_key=this.$form.find('input[name="payment"]').val(),this.nonce=this.$form.find('input[name="_wpnonce"]').val(),this.working=!1,this.$form.find('input[name="gateway"]').change(function(){if(!self.working){var gateway=self.$form.find('input[name="gateway"]:checked').val();gateway&&self.load_gateway(gateway)}})}},load_gateway:function(gateway_id){var self=this;self.$container.html(""),self.working=!0;var url=wpbdp_global.ajaxurl;url+=url.indexOf("?")>0?"&":"?",url+="payment="+self.payment_key+"&",url+="gateway="+gateway_id,$.post(url,{action:"wpbdp_ajax",handler:"checkout__load_gateway",_wpnonce:self.nonce},function(res){self.$container.removeClass().addClass("wpbdp-payment-gateway-"+gateway_id+"-form-fields"),self.$container.html(res),self.working=!1})}};wpbdp_checkout.init(),$(".wpbdp-payment-receipt-print").click(function(e){e.preventDefault(),window.print()})});
assets/js/submit-listing.js CHANGED
@@ -1,13 +1,459 @@
1
- jQuery(function( $ ) {
2
- $( '#wpbdp-submit-page.step-images #wpbdp-uploaded-images' ).sortable({
3
- placeholder: 'wpbdp-image-draggable-highlight',
4
- update: function( event, ui ) {
5
- var sorted = $( '#wpbdp-uploaded-images' ).sortable( 'toArray', { attribute: "data-imageid" } );
6
- var no_images = sorted.length;
7
 
8
- $.each( sorted, function( i, v ) {
9
- $( 'input[name="images_meta[' + v + '][order]"]' ).val( no_images - i );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  } );
11
  }
12
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  });
1
+ jQuery(function($) {
 
 
 
 
 
2
 
3
+ var wpbdp = window.wpbdp || {};
4
+ wpbdp.submit_listing = wpbdp.submit_listing || {};
5
+
6
+ // Fee_Selection_Helper {{
7
+ wpbdp.submit_listing.Fee_Selection_Helper = function( $submit, editing ) {
8
+ this.editing = ( 'undefined' === typeof(editing) || ! editing ) ? false : true;
9
+ this.reset();
10
+ };
11
+ $.extend( wpbdp.submit_listing.Fee_Selection_Helper.prototype, {
12
+ reset: function() {
13
+ this.field_wrapper = $( '.wpbdp-form-field-association-category' );
14
+ this.field_type = '';
15
+
16
+ if ( $( '.wpbdp-js-select2', this.field_wrapper ).length > 0 ) {
17
+ this.field_type = 'select2';
18
+ } else if ( this.field_wrapper.hasClass( 'wpbdp-form-field-type-checkbox' ) ) {
19
+ this.field_type = 'checkbox';
20
+ } else if ( this.field_wrapper.hasClass( 'wpbdp-form-field-type-radio' ) ) {
21
+ this.field_type = 'radio';
22
+ }
23
+
24
+ this.field = this.field_wrapper.find( 'select, input[type="checkbox"], input[type="radio"]' );
25
+
26
+ if ( ! this.field_type ) {
27
+ // This shouldn't happen.
28
+ return;
29
+ }
30
+
31
+ // First mark categories that were disabled since the beginning via HTML.
32
+ if ( 'select2' == this.field_type ) {
33
+ this.field.find( 'option[disabled="disabled"]' ).data( 'keep_disabled', true );
34
+ }
35
+
36
+ if ( this.editing ) {
37
+ return;
38
+ }
39
+
40
+ this.$plans_container = $( '.wpbdp-plan-selection-wrapper' );
41
+ this.$plan_selection = this.$plans_container.find( '.wpbdp-plan-selection' );
42
+ this.plans = this.$plan_selection.find( '.wpbdp-plan' );
43
+
44
+ this.$plan_selection.hide();
45
+
46
+ this.selected_categories = [];
47
+ this.available_plans = this.plans.map(function() {
48
+ return $(this).data('id');
49
+ }).get();
50
+
51
+ this.field.change( $.proxy( this.categories_changed, this ) );
52
+ this.maybe_limit_category_options();
53
+ this.field.first().trigger('change');
54
+
55
+ // this.field.select2();
56
+ },
57
+
58
+ categories_changed: function() {
59
+ this.selected_categories = [];
60
+
61
+ if ( 'select2' == this.field_type ) {
62
+ this.selected_categories = this.field.val();
63
+ } else if ( 'checkbox' == this.field_type ) {
64
+ this.selected_categories = this.field.filter( ':checked' ).map(function() {
65
+ return $( this ).val();
66
+ }).get();
67
+ } else if ( 'radio' == this.field_type ) {
68
+ this.selected_categories = this.field.val();
69
+ }
70
+
71
+ if ( ! this.selected_categories ) {
72
+ this.selected_categories = [];
73
+ }
74
+
75
+ if ( ! $.isArray( this.selected_categories ) )
76
+ this.selected_categories = [this.selected_categories];
77
+
78
+ if ( ! this.selected_categories ) {
79
+ this.selected_categories = [];
80
+ }
81
+
82
+ this.selected_categories = $.map( this.selected_categories, function(x) { return parseInt( x ); } );
83
+
84
+ this.update_plan_list();
85
+ this.update_plan_prices();
86
+ this.maybe_limit_category_options();
87
+
88
+ if ( 0 == this.selected_categories.length ) {
89
+ this.plans.find( 'input[name="listing_plan"]' ).prop( {
90
+ 'disabled': 0 == this.selected_categories.length,
91
+ 'checked': false
92
+ } );
93
+ } else {
94
+ this.plans.find( 'input[name="listing_plan"]' ).prop( 'disabled', false );
95
+ }
96
+
97
+ var self = this;
98
+ if ( this.selected_categories.length > 0 ) {
99
+ this.$plans_container.show();
100
+ Reusables.Breakpoints.evaluate();
101
+
102
+ this.$plan_selection.fadeIn( 'fast' );
103
+ } else {
104
+ this.$plans_container.fadeOut( 'fast', function() {
105
+ self.$plan_selection.hide();
106
+ } );
107
+ }
108
+
109
+ // Workaround for https://github.com/select2/select2/issues/3992.
110
+ if ( 'select2' == this.field_type ) {
111
+ var self = this;
112
+ setTimeout(function() {
113
+ self.field.select2({placeholder: wpbdpSubmitListingL10n.categoriesPlaceholderTxt});
114
+ });
115
+ }
116
+ },
117
+
118
+ _enable_categories: function( categories ) {
119
+ if ( 'none' != categories && 'all' != categories ) {
120
+ this._enable_categories( 'none' );
121
+ }
122
+
123
+ if ( 'none' == categories || 'all' == categories ) {
124
+ if ( 'select2' == this.field_type ) {
125
+ this.field.find( 'option' ).each(function(i, v) {
126
+ if ( true === $( this ).data( 'keep_disabled' ) ) {
127
+ // $( this ).prop( 'disabled', true );
128
+ } else {
129
+ $( this ).prop( 'disabled', ( 'all' == categories ) ? false : true );
130
+ }
131
+ });
132
+ } else {
133
+ this.field.prop( 'disabled', ( 'all' == categories ) ? false : true );
134
+
135
+ if ( 'all' == categories ) {
136
+ this.field_wrapper.find( '.wpbdp-form-field-checkbox-item, .wpbdp-form-field-radio-item' ).removeClass( 'disabled' );
137
+ } else {
138
+ this.field_wrapper.find( '.wpbdp-form-field-checkbox-item, .wpbdp-form-field-radio-item' ).addClass( 'disabled' );
139
+ }
140
+ }
141
+
142
+ return;
143
+ }
144
+
145
+ if ( 'select2' == this.field_type ) {
146
+ this.field.find( 'option' ).each(function(i, v) {
147
+ if ( true === $( this ).data( 'keep_disabled' ) ) {
148
+ } else {
149
+ $( this ).prop( 'disabled', -1 == $.inArray( parseInt( $( this ).val() ), categories ) );
150
+ }
151
+ });
152
+ } else {
153
+ this.field.each(function(i, v) {
154
+ if ( -1 != $.inArray( parseInt( $( this ).val() ), categories ) ) {
155
+ $( this ).prop( 'disabled', false );
156
+ $( this ).parents().filter( '.wpbdp-form-field-checkbox-item, .wpbdp-form-field-radio-item' ).removeClass( 'disabled' );
157
+ }
158
+ });
159
+ }
160
+
161
+ },
162
+
163
+ maybe_limit_category_options: function() {
164
+ var all_cats = false;
165
+ var cats = [];
166
+ var self = this;
167
+
168
+ $.each(this.available_plans, function(i, v) {
169
+ if ( all_cats )
170
+ return;
171
+
172
+ var plan_cats = self.plans.filter('[data-id="' + v + '"]').data('categories');
173
+
174
+ if ( 'all' == plan_cats ) {
175
+ all_cats = true;
176
+ } else {
177
+ cats = $.unique( cats.concat( plan_cats.toString().split( ',' ) ) );
178
+ cats = $.map( cats, function(x) { return parseInt( x ); } );
179
+ }
180
+ });
181
+
182
+ if ( all_cats ) {
183
+ this._enable_categories( 'all' );
184
+ } else {
185
+ this._enable_categories( cats );
186
+ }
187
+ },
188
+
189
+ update_plan_list: function() {
190
+ var self = this;
191
+ var plans = [];
192
+
193
+ // Recompute available plans depending on category selection.
194
+ $.each( this.plans, function( i, v ) {
195
+ var $plan = $( v );
196
+ var plan_cats = $plan.data('categories').toString();
197
+ var plan_supports_selection = true;
198
+
199
+ if ( 'all' != plan_cats && self.selected_categories ) {
200
+ plan_cats = $.map( plan_cats.split(','), function( x ) { return parseInt(x); } );
201
+
202
+ $.each( self.selected_categories, function( j, c ) {
203
+ if ( ! plan_supports_selection )
204
+ return;
205
+
206
+ if ( -1 == $.inArray( c, plan_cats ) ) {
207
+ plan_supports_selection = false;
208
+ }
209
+ } );
210
+ }
211
+
212
+ if ( plan_supports_selection ) {
213
+ plans.push( $plan.data('id') );
214
+ $plan.show();
215
+ } else {
216
+ $plan.hide();
217
+ }
218
+ } );
219
+
220
+ self.available_plans = plans;
221
+ },
222
+
223
+ update_plan_prices: function() {
224
+ var self = this;
225
+
226
+ $.each( self.available_plans, function( i, plan_id ) {
227
+ var $plan = self.plans.filter('[data-id="' + plan_id + '"]');
228
+ var pricing = $plan.data('pricing-details');
229
+ var price = null;
230
+
231
+ switch ( $plan.data( 'pricing-model' ) ) {
232
+ case 'variable':
233
+ price = 0.0;
234
+
235
+ $.each( self.selected_categories, function( j, cat_id ) {
236
+ price += parseFloat(pricing[cat_id]);
237
+ } );
238
+ break;
239
+ case 'extra':
240
+ price = parseFloat( $plan.data( 'amount' ) ) + ( parseFloat( pricing.extra ) * self.selected_categories.length );
241
+ break;
242
+ case 'flat':
243
+ default:
244
+ price = parseFloat( $plan.data( 'amount' ) );
245
+ break;
246
+ }
247
+
248
+ $plan.find( '.wpbdp-plan-price-amount' ).text( price ? $plan.data( 'amount-format' ).replace( '[amount]', price.toFixed(2) ) : $plan.data( 'free-text' ) );
249
  } );
250
  }
251
  });
252
+ // }}
253
+
254
+ wpbdp.submit_listing.Handler = function( $submit ) {
255
+ this.$submit = $submit;
256
+ this.$form = this.$submit.find( 'form' );
257
+ this.editing = ( this.$form.find( 'input[name="editing"]' ).val() == '1' );
258
+ this.$sections = this.$submit.find( '.wpbdp-submit-listing-section' );
259
+
260
+ this.listing_id = this.$form.find( 'input[name="listing_id"]' ).val();
261
+ this.ajax_url = this.$form.attr( 'data-ajax-url' );
262
+ this.doing_ajax = false;
263
+
264
+ this.setup_section_headers();
265
+ this.plan_handling();
266
+
267
+ var self = this;
268
+ this.$form.on( 'click', ':reset', function( e ) {
269
+ e.preventDefault();
270
+ self.$form.find('input[name="save_listing"]').val( '' );
271
+ self.$form.find('input[name="reset"]').val( 'reset' );
272
+ self.$form.submit();
273
+ } );
274
+
275
+ $( window ).on( 'wpbdp_submit_refresh', function( event, submit, section_id ) {
276
+ self.fee_helper.reset();
277
+ } );
278
+
279
+ // Create account form.
280
+ $( '#wpbdp-submit-listing' ).on( 'change', '#wpbdp-submit-listing-create_account', function( e ) {
281
+ $( '#wpbdp-submit-listing-account-details' ).toggle();
282
+ } );
283
+
284
+ $( '#wpbdp-submit-listing' ).on( 'keyup', '#wpbdp-submit-listing-account-details input[type="password"]', function( e ) {
285
+ self.check_password_strength( $( this) );
286
+ } );
287
+ };
288
+ $.extend( wpbdp.submit_listing.Handler.prototype, {
289
+ ajax: function( data, callback ) {
290
+ if ( this.doing_ajax ) {
291
+ alert( 'Please wait a moment!' );
292
+ return;
293
+ }
294
+
295
+ this.doing_ajax = true;
296
+ var self = this;
297
+
298
+ $.post( this.ajax_url, data, function( res ) {
299
+ if ( ! res.success ) {
300
+ alert('Something went wrong!');
301
+ return;
302
+ }
303
+
304
+ self.doing_ajax = false;
305
+ callback.call( self, res.data );
306
+ }, 'json' );
307
+ },
308
+
309
+ setup_section_headers: function() {
310
+ this.$sections.find( '.wpbdp-submit-listing-section-header' ).click(function() {
311
+ var $section = $( this ).parent( '.wpbdp-submit-listing-section' );
312
+ $section.toggleClass( 'collapsed' );
313
+ });
314
+ },
315
+
316
+ plan_handling: function() {
317
+ this.fee_helper = new wpbdp.submit_listing.Fee_Selection_Helper( this.$submit, this.editing );
318
+
319
+ if ( this.editing ) {
320
+ var $plan = this.$form.find( '.wpbdp-current-plan .wpbdp-plan' );
321
+ var plan_cats = $plan.data( 'categories' ).toString();
322
+
323
+ if ( 'all' != plan_cats ) {
324
+ var supported_categories = $.map( $.unique( plan_cats.split( ',' ) ), function(x) { return parseInt(x); } );
325
+ this.fee_helper._enable_categories( supported_categories );
326
+ }
327
+
328
+ return;
329
+ }
330
+
331
+ var self = this;
332
+ this.$submit.on( 'change, click', 'input[name="listing_plan"]', function() {
333
+ if ( $( this ).parents( '.wpbdp-plan' ).attr( 'data-disabled' ) == 1 ) {
334
+ return false;
335
+ }
336
+
337
+ var data = self.$form.serialize();
338
+ data += '&action=wpbdp_ajax&handler=submit_listing__sections';
339
+
340
+ self.ajax( data, function( res ) {
341
+ self.refresh( res );
342
+ } );
343
+ } );
344
+
345
+ this.$submit.on( 'click', '#change-plan-link a', function(e) {
346
+ e.preventDefault();
347
+
348
+ var data = self.$form.serialize();
349
+ data += '&action=wpbdp_ajax&handler=submit_listing__reset_plan';
350
+
351
+ self.ajax( data, function( res ) {
352
+ self.refresh( res );
353
+ } );
354
+ }) ;
355
+ },
356
+
357
+ refresh: function(data) {
358
+ var sections = data.sections;
359
+ var messages = data.messages;
360
+
361
+ var current_sections = this.$form.find( '.wpbdp-submit-listing-section' );
362
+ var new_sections = sections;
363
+
364
+ var self = this;
365
+
366
+ // Update sections.
367
+ $.each( new_sections, function( section_id, section_details ) {
368
+ var $section = current_sections.filter( '[data-section-id="' + section_id + '"]' );
369
+ var $new_html = $( section_details.html );
370
+
371
+ $section.find( '.wpbdp-editor-area' ).each( function() {
372
+ wp.editor.remove( $( this ).attr( 'id' ) );
373
+ } );
374
+
375
+ $section.attr( 'class', $new_html.attr( 'class' ) );
376
+ $section.find( '.wpbdp-submit-listing-section-content' ).fadeOut( 'fast', function() {
377
+ var $new_content = $new_html.find( '.wpbdp-submit-listing-section-content' );
378
+
379
+ $( this ).replaceWith( $new_content );
380
+
381
+ // Refresh things.
382
+ Reusables.Breakpoints.scan( $new_content );
383
+
384
+ $section.find( '.wpbdp-editor-area' ).each( function() {
385
+ var id = $( this ).attr( 'id' );
386
+ wp.editor.initialize( id, WPBDPTinyMCESettings[ id ] );
387
+ } );
388
+
389
+ $( window ).trigger( 'wpbdp_submit_refresh', [self, section_id, $section] );
390
+ } );
391
+ } );
392
+ },
393
+
394
+ check_password_strength: function( $input ) {
395
+ var pass = $input.val();
396
+ var $result = $input.siblings( '.wpbdp-password-strength-meter' );
397
+
398
+ $result.removeClass( 'strength-0 strength-2 strength-3 strength-4' )
399
+ .html('');
400
+
401
+ if ( ! pass ) {
402
+ return;
403
+ }
404
+
405
+ var strength = wp.passwordStrength.meter( pass, wp.passwordStrength.userInputBlacklist(), '' );
406
+ var strength_msg = '';
407
+
408
+ switch ( strength ) {
409
+ case 2:
410
+ strength_msg = pwsL10n.bad;
411
+ break;
412
+ case 3:
413
+ strength_msg = pwsL10n.good;
414
+ break
415
+ case 4:
416
+ strength_msg = pwsL10n.strong;
417
+ break;
418
+ case 5:
419
+ strength_msg = pwsL10n.mismatch;
420
+ break;
421
+ default:
422
+ strength_msg = pwsL10n.short;
423
+ break;
424
+ }
425
+
426
+ $result.addClass( 'strength-' + ( ( strength < 5 && strength >= 2 ) ? strength : '0' ) );
427
+ $result.html( strength_msg );
428
+
429
+ }
430
+
431
+ // function checkPasswordStrength( $pass1,
432
+ // $pass2,
433
+ // $strengthResult,
434
+ // $submitButton,
435
+ // blacklistArray ) {
436
+ // var pass1 = $pass1.val();
437
+ // var pass2 = $pass2.val();
438
+ //
439
+ // // Reset the form & meter
440
+ // $submitButton.attr( 'disabled', 'disabled' );
441
+ // $strengthResult.removeClass( 'short bad good strong' );
442
+ //
443
+ // // Extend our blacklist array with those from the inputs & site data
444
+ // blacklistArray = blacklistArray.concat( wp.passwordStrength.userInputBlacklist() )
445
+ //
446
+ // // Get the password strength
447
+ // var strength = wp.passwordStrength.meter( pass1, blacklistArray, pass2 );
448
+ //
449
+ // // Add the strength meter results
450
+ // return strength;
451
+ // }
452
+
453
+ });
454
+
455
+ var $submit = $( '#wpbdp-submit-listing' );
456
+ if ( $submit.length > 0 )
457
+ var x = new wpbdp.submit_listing.Handler( $submit );
458
+
459
  });
assets/js/submit-listing.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function($){$("#wpbdp-submit-page.step-images #wpbdp-uploaded-images").sortable({placeholder:"wpbdp-image-draggable-highlight",update:function(event,ui){var sorted=$("#wpbdp-uploaded-images").sortable("toArray",{attribute:"data-imageid"}),no_images=sorted.length;$.each(sorted,function(i,v){$('input[name="images_meta['+v+'][order]"]').val(no_images-i)})}})});
1
+ jQuery(function($){var wpbdp=window.wpbdp||{};wpbdp.submit_listing=wpbdp.submit_listing||{},wpbdp.submit_listing.Fee_Selection_Helper=function($submit,editing){this.editing=!("undefined"==typeof editing||!editing),this.reset()},$.extend(wpbdp.submit_listing.Fee_Selection_Helper.prototype,{reset:function(){this.field_wrapper=$(".wpbdp-form-field-association-category"),this.field_type="",$(".wpbdp-js-select2",this.field_wrapper).length>0?this.field_type="select2":this.field_wrapper.hasClass("wpbdp-form-field-type-checkbox")?this.field_type="checkbox":this.field_wrapper.hasClass("wpbdp-form-field-type-radio")&&(this.field_type="radio"),this.field=this.field_wrapper.find('select, input[type="checkbox"], input[type="radio"]'),this.field_type&&("select2"==this.field_type&&this.field.find('option[disabled="disabled"]').data("keep_disabled",!0),this.editing||(this.$plans_container=$(".wpbdp-plan-selection-wrapper"),this.$plan_selection=this.$plans_container.find(".wpbdp-plan-selection"),this.plans=this.$plan_selection.find(".wpbdp-plan"),this.$plan_selection.hide(),this.selected_categories=[],this.available_plans=this.plans.map(function(){return $(this).data("id")}).get(),this.field.change($.proxy(this.categories_changed,this)),this.maybe_limit_category_options(),this.field.first().trigger("change")))},categories_changed:function(){this.selected_categories=[],"select2"==this.field_type?this.selected_categories=this.field.val():"checkbox"==this.field_type?this.selected_categories=this.field.filter(":checked").map(function(){return $(this).val()}).get():"radio"==this.field_type&&(this.selected_categories=this.field.val()),this.selected_categories||(this.selected_categories=[]),$.isArray(this.selected_categories)||(this.selected_categories=[this.selected_categories]),this.selected_categories||(this.selected_categories=[]),this.selected_categories=$.map(this.selected_categories,function(x){return parseInt(x)}),this.update_plan_list(),this.update_plan_prices(),this.maybe_limit_category_options(),0==this.selected_categories.length?this.plans.find('input[name="listing_plan"]').prop({disabled:0==this.selected_categories.length,checked:!1}):this.plans.find('input[name="listing_plan"]').prop("disabled",!1);var self=this;if(this.selected_categories.length>0?(this.$plans_container.show(),Reusables.Breakpoints.evaluate(),this.$plan_selection.fadeIn("fast")):this.$plans_container.fadeOut("fast",function(){self.$plan_selection.hide()}),"select2"==this.field_type){var self=this;setTimeout(function(){self.field.select2({placeholder:wpbdpSubmitListingL10n.categoriesPlaceholderTxt})})}},_enable_categories:function(categories){return"none"!=categories&&"all"!=categories&&this._enable_categories("none"),"none"==categories||"all"==categories?void("select2"==this.field_type?this.field.find("option").each(function(i,v){!0===$(this).data("keep_disabled")||$(this).prop("disabled","all"!=categories)}):(this.field.prop("disabled","all"!=categories),"all"==categories?this.field_wrapper.find(".wpbdp-form-field-checkbox-item, .wpbdp-form-field-radio-item").removeClass("disabled"):this.field_wrapper.find(".wpbdp-form-field-checkbox-item, .wpbdp-form-field-radio-item").addClass("disabled"))):void("select2"==this.field_type?this.field.find("option").each(function(i,v){!0===$(this).data("keep_disabled")||$(this).prop("disabled",-1==$.inArray(parseInt($(this).val()),categories))}):this.field.each(function(i,v){-1!=$.inArray(parseInt($(this).val()),categories)&&($(this).prop("disabled",!1),$(this).parents().filter(".wpbdp-form-field-checkbox-item, .wpbdp-form-field-radio-item").removeClass("disabled"))}))},maybe_limit_category_options:function(){var all_cats=!1,cats=[],self=this;$.each(this.available_plans,function(i,v){if(!all_cats){var plan_cats=self.plans.filter('[data-id="'+v+'"]').data("categories");"all"==plan_cats?all_cats=!0:(cats=$.unique(cats.concat(plan_cats.toString().split(","))),cats=$.map(cats,function(x){return parseInt(x)}))}}),all_cats?this._enable_categories("all"):this._enable_categories(cats)},update_plan_list:function(){var self=this,plans=[];$.each(this.plans,function(i,v){var $plan=$(v),plan_cats=$plan.data("categories").toString(),plan_supports_selection=!0;"all"!=plan_cats&&self.selected_categories&&(plan_cats=$.map(plan_cats.split(","),function(x){return parseInt(x)}),$.each(self.selected_categories,function(j,c){plan_supports_selection&&-1==$.inArray(c,plan_cats)&&(plan_supports_selection=!1)})),plan_supports_selection?(plans.push($plan.data("id")),$plan.show()):$plan.hide()}),self.available_plans=plans},update_plan_prices:function(){var self=this;$.each(self.available_plans,function(i,plan_id){var $plan=self.plans.filter('[data-id="'+plan_id+'"]'),pricing=$plan.data("pricing-details"),price=null;switch($plan.data("pricing-model")){case"variable":price=0,$.each(self.selected_categories,function(j,cat_id){price+=parseFloat(pricing[cat_id])});break;case"extra":price=parseFloat($plan.data("amount"))+parseFloat(pricing.extra)*self.selected_categories.length;break;case"flat":default:price=parseFloat($plan.data("amount"))}$plan.find(".wpbdp-plan-price-amount").text(price?$plan.data("amount-format").replace("[amount]",price.toFixed(2)):$plan.data("free-text"))})}}),wpbdp.submit_listing.Handler=function($submit){this.$submit=$submit,this.$form=this.$submit.find("form"),this.editing="1"==this.$form.find('input[name="editing"]').val(),this.$sections=this.$submit.find(".wpbdp-submit-listing-section"),this.listing_id=this.$form.find('input[name="listing_id"]').val(),this.ajax_url=this.$form.attr("data-ajax-url"),this.doing_ajax=!1,this.setup_section_headers(),this.plan_handling();var self=this;this.$form.on("click",":reset",function(e){e.preventDefault(),self.$form.find('input[name="save_listing"]').val(""),self.$form.find('input[name="reset"]').val("reset"),self.$form.submit()}),$(window).on("wpbdp_submit_refresh",function(event,submit,section_id){self.fee_helper.reset()}),$("#wpbdp-submit-listing").on("change","#wpbdp-submit-listing-create_account",function(e){$("#wpbdp-submit-listing-account-details").toggle()}),$("#wpbdp-submit-listing").on("keyup",'#wpbdp-submit-listing-account-details input[type="password"]',function(e){self.check_password_strength($(this))})},$.extend(wpbdp.submit_listing.Handler.prototype,{ajax:function(data,callback){if(this.doing_ajax)return void alert("Please wait a moment!");this.doing_ajax=!0;var self=this;$.post(this.ajax_url,data,function(res){return res.success?(self.doing_ajax=!1,void callback.call(self,res.data)):void alert("Something went wrong!")},"json")},setup_section_headers:function(){this.$sections.find(".wpbdp-submit-listing-section-header").click(function(){var $section=$(this).parent(".wpbdp-submit-listing-section");$section.toggleClass("collapsed")})},plan_handling:function(){if(this.fee_helper=new wpbdp.submit_listing.Fee_Selection_Helper(this.$submit,this.editing),this.editing){var $plan=this.$form.find(".wpbdp-current-plan .wpbdp-plan"),plan_cats=$plan.data("categories").toString();if("all"!=plan_cats){var supported_categories=$.map($.unique(plan_cats.split(",")),function(x){return parseInt(x)});this.fee_helper._enable_categories(supported_categories)}}else{var self=this;this.$submit.on("change, click",'input[name="listing_plan"]',function(){if(1==$(this).parents(".wpbdp-plan").attr("data-disabled"))return!1;var data=self.$form.serialize();data+="&action=wpbdp_ajax&handler=submit_listing__sections",self.ajax(data,function(res){self.refresh(res)})}),this.$submit.on("click","#change-plan-link a",function(e){e.preventDefault();var data=self.$form.serialize();data+="&action=wpbdp_ajax&handler=submit_listing__reset_plan",self.ajax(data,function(res){self.refresh(res)})})}},refresh:function(data){var sections=data.sections,current_sections=(data.messages,this.$form.find(".wpbdp-submit-listing-section")),new_sections=sections,self=this;$.each(new_sections,function(section_id,section_details){var $section=current_sections.filter('[data-section-id="'+section_id+'"]'),$new_html=$(section_details.html);$section.find(".wpbdp-editor-area").each(function(){wp.editor.remove($(this).attr("id"))}),$section.attr("class",$new_html.attr("class")),$section.find(".wpbdp-submit-listing-section-content").fadeOut("fast",function(){var $new_content=$new_html.find(".wpbdp-submit-listing-section-content");$(this).replaceWith($new_content),Reusables.Breakpoints.scan($new_content),$section.find(".wpbdp-editor-area").each(function(){var id=$(this).attr("id");wp.editor.initialize(id,WPBDPTinyMCESettings[id])}),$(window).trigger("wpbdp_submit_refresh",[self,section_id,$section])})})},check_password_strength:function($input){var pass=$input.val(),$result=$input.siblings(".wpbdp-password-strength-meter");if($result.removeClass("strength-0 strength-2 strength-3 strength-4").html(""),pass){var strength=wp.passwordStrength.meter(pass,wp.passwordStrength.userInputBlacklist(),""),strength_msg="";switch(strength){case 2:strength_msg=pwsL10n.bad;break;case 3:strength_msg=pwsL10n.good;break;case 4:strength_msg=pwsL10n.strong;break;case 5:strength_msg=pwsL10n.mismatch;break;default:strength_msg=pwsL10n["short"]}$result.addClass("strength-"+(strength<5&&strength>=2?strength:"0")),$result.html(strength_msg)}}});var $submit=$("#wpbdp-submit-listing");if($submit.length>0){new wpbdp.submit_listing.Handler($submit)}});
assets/js/wpbdp.js CHANGED
@@ -6,10 +6,19 @@ if (typeof(window.wpbdp) == 'undefined') {
6
  window.wpbdp = {};
7
  }
8
 
 
 
 
 
9
  jQuery(document).ready(function($){
 
 
 
 
 
10
  /**
11
  * Handles flex behavior for main box columns.
12
- * @since next-release
13
  */
14
  wpbdp.main_box = {
15
  init: function() {
@@ -89,7 +98,7 @@ jQuery(document).ready(function($){
89
  }
90
 
91
  $( '.wpbdp-listing-contact-form .send-message-button' ).click(function() {
92
- $( '.wpbdp-listing-contact-form .contact-form-wrapper' ).toggleClass( 'wpbdp-hide-on-mobile' );
93
  });
94
 
95
  $( '.wpbdp-listings-sort-options.wpbdp-show-on-mobile select' ).change(function(e) {
@@ -107,6 +116,14 @@ jQuery(function( $ ) {
107
  $( '.wpbdp-form-field-type-date' ).each(function(i, v) {
108
  t.configure_date_picker( $(v).find( 'input' ) );
109
  });
 
 
 
 
 
 
 
 
110
  },
111
 
112
  configure_date_picker: function( $e ) {
@@ -172,24 +189,12 @@ WPBDP.fileUpload = {
172
  ( function( $ ) {
173
  var sb = wpbdp.listingSubmit = {
174
  init: function() {
175
- if ( $( '.wpbdp-submit-page.step-fee-selection' ).length > 0 ) {
176
- $( '#wpbdp-listing-form-fees .fee-selection input' ).change(function( e ) {
177
- console.log(this);
178
- if ( 1 == $( this ).attr( 'data-canrecur' ) ) {
179
- if ( $( '.make-charges-recurring-option' ).not( ':visible' ) )
180
- $( '.make-charges-recurring-option' ).fadeIn( 'fast' );
181
- } else {
182
- $( '.make-charges-recurring-option' ).fadeOut( 'fast' );
183
- }
184
- }).filter( ':checked' ).trigger( 'change' );
185
- }
186
-
187
- if ( $( '.wpbdp-submit-page.step-images' ).length > 0 )
188
  sb.images.init();
189
  }
190
  };
191
 
192
- var sbImages = sb.images = wpbdp.listingSubmit.images = {
193
  _initialized: false,
194
  _admin_nonce: '',
195
  _slots: 0,
@@ -209,9 +214,9 @@ WPBDP.fileUpload = {
209
  }
210
 
211
  // Handle image deletes.
212
- $( '#wpbdp-uploaded-images' ).delegate( '.delete-image', 'click', function( e ) {
213
  e.preventDefault();
214
- var url = $( this ).attr('data-action');
215
 
216
  $.post( url, {}, function( res ) {
217
  if ( ! res.success )
@@ -238,6 +243,20 @@ WPBDP.fileUpload = {
238
  $( '#image-upload-dnd-area .dnd-area-inside-error' ).hide();
239
  }
240
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  } );
242
  }, 'json' );
243
  } );
@@ -257,7 +276,15 @@ WPBDP.fileUpload = {
257
  return true;
258
 
259
  $( this ).siblings( '.wpbdp-msg' ).remove();
260
- return ( t._slotsRemaining - data.files.length ) >= 0;
 
 
 
 
 
 
 
 
261
  },
262
  done: function( res ) {
263
  var uploadErrors = false;
@@ -293,6 +320,21 @@ WPBDP.fileUpload = {
293
  $( '#image-upload-dnd-area .dnd-area-inside-error' ).show();
294
  }
295
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
297
  } );
298
 
@@ -320,4 +362,4 @@ WPBDP.fileUpload = {
320
  } );
321
  } )( jQuery );
322
 
323
- // }}
6
  window.wpbdp = {};
7
  }
8
 
9
+ jQuery(function( $ ) {
10
+ $( '.wpbdp-no-js' ).hide();
11
+ });
12
+
13
  jQuery(document).ready(function($){
14
+ if ( $( '.wpbdp-js-select2' ).length > 0 ) {
15
+ $( '.wpbdp-js-select2' ).select2();
16
+ }
17
+
18
+
19
  /**
20
  * Handles flex behavior for main box columns.
21
+ * @since 5.0
22
  */
23
  wpbdp.main_box = {
24
  init: function() {
98
  }
99
 
100
  $( '.wpbdp-listing-contact-form .send-message-button' ).click(function() {
101
+ $( '.wpbdp-listing-contact-form .contact-form-wrapper' ).toggle();
102
  });
103
 
104
  $( '.wpbdp-listings-sort-options.wpbdp-show-on-mobile select' ).change(function(e) {
116
  $( '.wpbdp-form-field-type-date' ).each(function(i, v) {
117
  t.configure_date_picker( $(v).find( 'input' ) );
118
  });
119
+
120
+ $( window ).on( 'wpbdp_submit_refresh', function( event, submit, section_id ) {
121
+ if ( 'listing_fields' != section_id ) {
122
+ return;
123
+ }
124
+
125
+ t.init();
126
+ } );
127
  },
128
 
129
  configure_date_picker: function( $e ) {
189
  ( function( $ ) {
190
  var sb = wpbdp.listingSubmit = {
191
  init: function() {
192
+ if ( $( '.wpbdp-submit-listing-section-listing_images' ).length > 0 )
 
 
 
 
 
 
 
 
 
 
 
 
193
  sb.images.init();
194
  }
195
  };
196
 
197
+ var sbImages = sb.images = wpbdp.listingSubmit.images = {
198
  _initialized: false,
199
  _admin_nonce: '',
200
  _slots: 0,
214
  }
215
 
216
  // Handle image deletes.
217
+ $( '#wpbdp-uploaded-images' ).on( 'click', '.wpbdp-image-delete-link', 'click', function( e ) {
218
  e.preventDefault();
219
+ var url = $( this ).attr('href');
220
 
221
  $.post( url, {}, function( res ) {
222
  if ( ! res.success )
243
  $( '#image-upload-dnd-area .dnd-area-inside-error' ).hide();
244
  }
245
 
246
+ if ( $( '#wpbdp-listing-fields.postbox' ).length > 0 ) {
247
+ var $with_count = $( '.wpbdp-admin-tab-nav li a .with-image-count' );
248
+ var $no_count = $( '.wpbdp-admin-tab-nav li a .no-image-count' );
249
+ var n = $( '#wpbdp-uploaded-images .wpbdp-image' ).length;
250
+
251
+ if ( n ) {
252
+ $no_count.addClass( 'hidden' );
253
+ $with_count.removeClass( 'hidden' ).find( 'span' ).text( n );
254
+ } else {
255
+ $with_count.addClass( 'hidden' );
256
+ $no_count.removeClass( 'hidden' );
257
+ }
258
+ }
259
+
260
  } );
261
  }, 'json' );
262
  } );
276
  return true;
277
 
278
  $( this ).siblings( '.wpbdp-msg' ).remove();
279
+
280
+ // if ( t._slotsRemaining < data.files.length ) {
281
+ // var errorMsg = $( '<div>' ).addClass('wpbdp-msg error').html( 'Hi there' );
282
+ // $( '.area-and-conditions' ).prepend( errorMsg );
283
+ //
284
+ // return false;
285
+ // }
286
+
287
+ return true;
288
  },
289
  done: function( res ) {
290
  var uploadErrors = false;
320
  $( '#image-upload-dnd-area .dnd-area-inside-error' ).show();
321
  }
322
  }
323
+
324
+ // On admin, update image count.
325
+ if ( $( '#wpbdp-listing-fields.postbox' ).length > 0 ) {
326
+ var $with_count = $( '.wpbdp-admin-tab-nav li a .with-image-count' );
327
+ var $no_count = $( '.wpbdp-admin-tab-nav li a .no-image-count' );
328
+ var n = $( '#wpbdp-uploaded-images .wpbdp-image' ).length;
329
+
330
+ if ( n ) {
331
+ $no_count.addClass( 'hidden' );
332
+ $with_count.removeClass( 'hidden' ).find( 'span' ).text( n );
333
+ } else {
334
+ $with_count.addClass( 'hidden' );
335
+ $no_count.removeClass( 'hidden' );
336
+ }
337
+ }
338
  }
339
  } );
340
 
362
  } );
363
  } )( jQuery );
364
 
365
+ // }}
assets/js/wpbdp.min.js CHANGED
@@ -1 +1 @@
1
- "undefined"==typeof window.WPBDP&&(window.WPBDP={}),"undefined"==typeof window.wpbdp&&(window.wpbdp={}),jQuery(document).ready(function($){wpbdp.main_box={init:function(){return},sum_width:function($selector,prop){var prop="undefined"==typeof prop?"width":prop,sum=0;return $selector.each(function(){var w=0;w="initial"==prop?$(this).data("initial-width"):"outer"==prop?$(this).outerWidth():"inner"==prop?$(this).innerWidth():$(this).width(),sum+=parseInt(w)}),sum},min_width:function(){return this.sum_width(this.$cols_fixed,"initial")},should_resize:function(){return this.$box.find("form").width()>this.min_width()},resize:function(){if(this.should_resize()){var available_width=this.$box.find("form").innerWidth()-this.min_width(),flex_width=Math.floor(available_width/this.$cols_expanding.length)-2;this.$cols_expanding.each(function(){$(this).outerWidth(flex_width)})}}},$("#wpbdp-main-box").length>0&&wpbdp.main_box.init(),0==$(".wpbdp-bar").children().length&&""==$.trim($(".wpbdp-bar").text())&&$(".wpbdp-bar").remove(),$(".wpbdp-listing-contact-form .send-message-button").click(function(){$(".wpbdp-listing-contact-form .contact-form-wrapper").toggleClass("wpbdp-hide-on-mobile")}),$(".wpbdp-listings-sort-options.wpbdp-show-on-mobile select").change(function(e){var selected=$(this).val();location.href=selected})}),jQuery(function($){var form_fields={init:function(){var t=this;$(".wpbdp-form-field-type-date").each(function(i,v){t.configure_date_picker($(v).find("input"))})},configure_date_picker:function($e){$e.datepicker({dateFormat:$e.attr("data-date-format"),defaultDate:$e.val()})}};form_fields.init()}),WPBDP.fileUpload={resizeIFrame:function(field_id,height){var iframe=jQuery("#wpbdp-upload-iframe-"+field_id)[0],iframeWin=iframe.contentWindow||iframe.contentDocument.parentWindow;iframeWin.document.body&&(iframe.height=iframeWin.document.documentElement.scrollHeight||iframeWin.document.body.scrollHeight)},handleUpload:function(o){var $input=jQuery(o),$form=$input.parent("form");$form.submit()},finishUpload:function(field_id,upload_id){var $iframe=jQuery("#wpbdp-upload-iframe-"+field_id),$input=jQuery('input[name="listingfields['+field_id+']"]');$input.val(upload_id);var $preview=$input.siblings(".preview");$preview.find("img").remove(),$preview.prepend($iframe.contents().find(".preview").html()),$iframe.contents().find(".preview").remove(),$preview.find(".delete").show()},deleteUpload:function(field_id){var $input=jQuery('input[name="listingfields['+field_id+']"]'),$preview=$input.siblings(".preview");return $input.val(""),$preview.find("img").remove(),$preview.find(".delete").hide(),!1}},function($){var sb=wpbdp.listingSubmit={init:function(){$(".wpbdp-submit-page.step-fee-selection").length>0&&$("#wpbdp-listing-form-fees .fee-selection input").change(function(e){console.log(this),1==$(this).attr("data-canrecur")?$(".make-charges-recurring-option").not(":visible")&&$(".make-charges-recurring-option").fadeIn("fast"):$(".make-charges-recurring-option").fadeOut("fast")}).filter(":checked").trigger("change"),$(".wpbdp-submit-page.step-images").length>0&&sb.images.init()}};sb.images=wpbdp.listingSubmit.images={_initialized:!1,_admin_nonce:"",_slots:0,_slotsRemaining:0,_working:!1,init:function(){this._initialized=!0,this._admin_nonce=$("#image-upload-dnd-area").attr("data-admin-nonce");var t=this;this._admin_nonce||(sb.images._slots=parseInt($("#image-slots-total").text()),sb.images._slotsRemaining=parseInt($("#image-slots-remaining").text())),$("#wpbdp-uploaded-images").delegate(".delete-image","click",function(e){e.preventDefault();var url=$(this).attr("data-action");$.post(url,{},function(res){res.success&&$('#wpbdp-uploaded-images .wpbdp-image[data-imageid="'+res.data.imageId+'"]').fadeOut(function(){$(this).remove(),1==$("#wpbdp-uploaded-images .wpbdp-image").length&&$('#wpbdp-uploaded-images .wpbdp-image:first input[name="thumbnail_id"] ').attr("checked","checked"),t._admin_nonce||(t._slotsRemaining++,$("#image-slots-remaining").text(t._slotsRemaining)),(t._admin_nonce&&0==$("#wpbdp-uploaded-images .wpbdp-image").length||!t._admin_nonce&&t._slotsRemaining==t._slots)&&$("#no-images-message").show(),(t._admin_nonce||t._slotsRemaining>0)&&($("#image-upload-dnd-area .dnd-area-inside").show(),$("#noslots-message").hide(),$("#image-upload-dnd-area").removeClass("error"),$("#image-upload-dnd-area .dnd-area-inside-error").hide())})},"json")}),wpbdp.dnd.setup($("#image-upload-dnd-area"),{init:function(){t._admin_nonce||t._slotsRemaining>0||($("#image-upload-dnd-area .dnd-area-inside").hide(),$("#noslots-message").show(),$("#image-upload-dnd-area").addClass("error"),$("#image-upload-dnd-area .dnd-area-inside-error").show())},validate:function(data){return!!t._admin_nonce||($(this).siblings(".wpbdp-msg").remove(),t._slotsRemaining-data.files.length>=0)},done:function(res){var uploadErrors=!1;if(uploadErrors=res.success?"undefined"!=typeof res.data.uploadErrors&&res.data.uploadErrors:[res.error]){var errorMsg=$("<div>").addClass("wpbdp-msg error").html(uploadErrors);return void $(".area-and-conditions").prepend(errorMsg)}$("#no-images-message").hide(),$("#wpbdp-uploaded-images").append(res.data.html),1==$("#wpbdp-uploaded-images .wpbdp-image").length&&$('#wpbdp-uploaded-images .wpbdp-image:first input[name="thumbnail_id"] ').attr("checked","checked"),t._admin_nonce||(t._slotsRemaining-=res.data.attachmentIds.length,$("#image-slots-remaining").text(t._slotsRemaining),0==t._slotsRemaining&&($("#image-upload-dnd-area .dnd-area-inside").hide(),$("#noslots-message").show(),$("#image-upload-dnd-area").addClass("error"),$("#image-upload-dnd-area .dnd-area-inside").hide(),$("#image-upload-dnd-area .dnd-area-inside-error").show()))}}),$("#wpbdp-uploaded-images").sortable({axis:"y",cursor:"move",opacity:.9,update:function(ev,ui){var sorted=$(this).sortable("toArray",{attribute:"data-imageid"}),no_images=sorted.length;$.each(sorted,function(i,v){$('input[name="images_meta['+v+'][order]"]').val(no_images-i)})}})}};$(document).ready(function(){0!=$(".wpbdp-submit-page").length&&sb.init()})}(jQuery);
1
+ "undefined"==typeof window.WPBDP&&(window.WPBDP={}),"undefined"==typeof window.wpbdp&&(window.wpbdp={}),jQuery(function($){$(".wpbdp-no-js").hide()}),jQuery(document).ready(function($){$(".wpbdp-js-select2").length>0&&$(".wpbdp-js-select2").select2(),wpbdp.main_box={init:function(){return},sum_width:function($selector,prop){var prop="undefined"==typeof prop?"width":prop,sum=0;return $selector.each(function(){var w=0;w="initial"==prop?$(this).data("initial-width"):"outer"==prop?$(this).outerWidth():"inner"==prop?$(this).innerWidth():$(this).width(),sum+=parseInt(w)}),sum},min_width:function(){return this.sum_width(this.$cols_fixed,"initial")},should_resize:function(){return this.$box.find("form").width()>this.min_width()},resize:function(){if(this.should_resize()){var available_width=this.$box.find("form").innerWidth()-this.min_width(),flex_width=Math.floor(available_width/this.$cols_expanding.length)-2;this.$cols_expanding.each(function(){$(this).outerWidth(flex_width)})}}},$("#wpbdp-main-box").length>0&&wpbdp.main_box.init(),0==$(".wpbdp-bar").children().length&&""==$.trim($(".wpbdp-bar").text())&&$(".wpbdp-bar").remove(),$(".wpbdp-listing-contact-form .send-message-button").click(function(){$(".wpbdp-listing-contact-form .contact-form-wrapper").toggle()}),$(".wpbdp-listings-sort-options.wpbdp-show-on-mobile select").change(function(e){var selected=$(this).val();location.href=selected})}),jQuery(function($){var form_fields={init:function(){var t=this;$(".wpbdp-form-field-type-date").each(function(i,v){t.configure_date_picker($(v).find("input"))}),$(window).on("wpbdp_submit_refresh",function(event,submit,section_id){"listing_fields"==section_id&&t.init()})},configure_date_picker:function($e){$e.datepicker({dateFormat:$e.attr("data-date-format"),defaultDate:$e.val()})}};form_fields.init()}),WPBDP.fileUpload={resizeIFrame:function(field_id,height){var iframe=jQuery("#wpbdp-upload-iframe-"+field_id)[0],iframeWin=iframe.contentWindow||iframe.contentDocument.parentWindow;iframeWin.document.body&&(iframe.height=iframeWin.document.documentElement.scrollHeight||iframeWin.document.body.scrollHeight)},handleUpload:function(o){var $input=jQuery(o),$form=$input.parent("form");$form.submit()},finishUpload:function(field_id,upload_id){var $iframe=jQuery("#wpbdp-upload-iframe-"+field_id),$input=jQuery('input[name="listingfields['+field_id+']"]');$input.val(upload_id);var $preview=$input.siblings(".preview");$preview.find("img").remove(),$preview.prepend($iframe.contents().find(".preview").html()),$iframe.contents().find(".preview").remove(),$preview.find(".delete").show()},deleteUpload:function(field_id){var $input=jQuery('input[name="listingfields['+field_id+']"]'),$preview=$input.siblings(".preview");return $input.val(""),$preview.find("img").remove(),$preview.find(".delete").hide(),!1}},function($){var sb=wpbdp.listingSubmit={init:function(){$(".wpbdp-submit-listing-section-listing_images").length>0&&sb.images.init()}};sb.images=wpbdp.listingSubmit.images={_initialized:!1,_admin_nonce:"",_slots:0,_slotsRemaining:0,_working:!1,init:function(){this._initialized=!0,this._admin_nonce=$("#image-upload-dnd-area").attr("data-admin-nonce");var t=this;this._admin_nonce||(sb.images._slots=parseInt($("#image-slots-total").text()),sb.images._slotsRemaining=parseInt($("#image-slots-remaining").text())),$("#wpbdp-uploaded-images").on("click",".wpbdp-image-delete-link","click",function(e){e.preventDefault();var url=$(this).attr("href");$.post(url,{},function(res){res.success&&$('#wpbdp-uploaded-images .wpbdp-image[data-imageid="'+res.data.imageId+'"]').fadeOut(function(){if($(this).remove(),1==$("#wpbdp-uploaded-images .wpbdp-image").length&&$('#wpbdp-uploaded-images .wpbdp-image:first input[name="thumbnail_id"] ').attr("checked","checked"),t._admin_nonce||(t._slotsRemaining++,$("#image-slots-remaining").text(t._slotsRemaining)),(t._admin_nonce&&0==$("#wpbdp-uploaded-images .wpbdp-image").length||!t._admin_nonce&&t._slotsRemaining==t._slots)&&$("#no-images-message").show(),(t._admin_nonce||t._slotsRemaining>0)&&($("#image-upload-dnd-area .dnd-area-inside").show(),$("#noslots-message").hide(),$("#image-upload-dnd-area").removeClass("error"),$("#image-upload-dnd-area .dnd-area-inside-error").hide()),$("#wpbdp-listing-fields.postbox").length>0){var $with_count=$(".wpbdp-admin-tab-nav li a .with-image-count"),$no_count=$(".wpbdp-admin-tab-nav li a .no-image-count"),n=$("#wpbdp-uploaded-images .wpbdp-image").length;n?($no_count.addClass("hidden"),$with_count.removeClass("hidden").find("span").text(n)):($with_count.addClass("hidden"),$no_count.removeClass("hidden"))}})},"json")}),wpbdp.dnd.setup($("#image-upload-dnd-area"),{init:function(){t._admin_nonce||t._slotsRemaining>0||($("#image-upload-dnd-area .dnd-area-inside").hide(),$("#noslots-message").show(),$("#image-upload-dnd-area").addClass("error"),$("#image-upload-dnd-area .dnd-area-inside-error").show())},validate:function(data){return!!t._admin_nonce||($(this).siblings(".wpbdp-msg").remove(),!0)},done:function(res){var uploadErrors=!1;if(uploadErrors=res.success?"undefined"!=typeof res.data.uploadErrors&&res.data.uploadErrors:[res.error]){var errorMsg=$("<div>").addClass("wpbdp-msg error").html(uploadErrors);return void $(".area-and-conditions").prepend(errorMsg)}if($("#no-images-message").hide(),$("#wpbdp-uploaded-images").append(res.data.html),1==$("#wpbdp-uploaded-images .wpbdp-image").length&&$('#wpbdp-uploaded-images .wpbdp-image:first input[name="thumbnail_id"] ').attr("checked","checked"),t._admin_nonce||(t._slotsRemaining-=res.data.attachmentIds.length,$("#image-slots-remaining").text(t._slotsRemaining),0==t._slotsRemaining&&($("#image-upload-dnd-area .dnd-area-inside").hide(),$("#noslots-message").show(),$("#image-upload-dnd-area").addClass("error"),$("#image-upload-dnd-area .dnd-area-inside").hide(),$("#image-upload-dnd-area .dnd-area-inside-error").show())),$("#wpbdp-listing-fields.postbox").length>0){var $with_count=$(".wpbdp-admin-tab-nav li a .with-image-count"),$no_count=$(".wpbdp-admin-tab-nav li a .no-image-count"),n=$("#wpbdp-uploaded-images .wpbdp-image").length;n?($no_count.addClass("hidden"),$with_count.removeClass("hidden").find("span").text(n)):($with_count.addClass("hidden"),$no_count.removeClass("hidden"))}}}),$("#wpbdp-uploaded-images").sortable({axis:"y",cursor:"move",opacity:.9,update:function(ev,ui){var sorted=$(this).sortable("toArray",{attribute:"data-imageid"}),no_images=sorted.length;$.each(sorted,function(i,v){$('input[name="images_meta['+v+'][order]"]').val(no_images-i)})}})}};$(document).ready(function(){0!=$(".wpbdp-submit-page").length&&sb.init()})}(jQuery);
business-directory-plugin.php CHANGED
@@ -3,1665 +3,57 @@
3
  * Plugin Name: Business Directory Plugin
4
  * Plugin URI: http://www.businessdirectoryplugin.com
5
  * Description: Provides the ability to maintain a free or paid business directory on your WordPress powered site.
6
- * Version: 4.1.15
7
  * Author: D. Rodenbaugh
8
- * Author URI: http://businessdirectoryplugin.com
9
  * Text Domain: WPBDM
10
  * Domain Path: /languages/
11
  * License: GPLv2 or any later version
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  */
13
 
14
- /* Copyright 2009-2016, Skyline Consulting and D. Rodenbaugh
15
-
16
- This program is free software; you can redistribute it and/or modify
17
- it under the terms of the GNU General Public License, version 2 or later, as
18
- published by the Free Software Foundation.
19
-
20
- This program is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU General Public License for more details.
24
-
25
- You should have received a copy of the GNU General Public License
26
- along with this program; if not, write to the Free Software
27
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
- */
29
-
30
- // Do not allow direct loading of this file.
31
- if( preg_match( '#' . basename( __FILE__ ) . '#', $_SERVER['PHP_SELF'] ) )
32
- exit();
33
-
34
- define( 'WPBDP_VERSION', '4.1.15' );
35
-
36
- define( 'WPBDP_PATH', wp_normalize_path( plugin_dir_path( __FILE__ ) ) );
37
- define( 'WPBDP_INC', trailingslashit( WPBDP_PATH . 'includes' ) );
38
- define( 'WPBDP_URL', trailingslashit( plugins_url( '/', __FILE__ ) ) );
39
- define( 'WPBDP_TEMPLATES_PATH', WPBDP_PATH . 'templates' );
40
-
41
- define( 'WPBDP_POST_TYPE', 'wpbdp_listing' );
42
- define( 'WPBDP_CATEGORY_TAX', 'wpbdp_category' );
43
- define( 'WPBDP_TAGS_TAX', 'wpbdp_tag' );
44
-
45
- require_once( WPBDP_INC . 'class-wpbdp.php' );
46
- require_once( WPBDP_INC . 'api.php' );
47
- require_once( WPBDP_INC . 'compatibility/class-compat.php' );
48
- require_once( WPBDP_INC . 'utils.php' );
49
- require_once( WPBDP_INC . 'admin/tracking.php' );
50
- require_once( WPBDP_INC . 'admin/class-admin.php' );
51
- require_once( WPBDP_INC . 'admin/settings/class-settings.php' );
52
- require_once( WPBDP_INC . 'form-fields.php' );
53
- require_once( WPBDP_INC . 'payment.php' );
54
- require_once( WPBDP_INC . 'listings.php' );
55
- require_once( WPBDP_INC . 'templates-generic.php' );
56
- require_once( WPBDP_INC . 'templates-listings.php' );
57
- require_once( WPBDP_INC . 'templates-ui.php' );
58
- require_once( WPBDP_INC . 'installer.php' );
59
- require_once( WPBDP_INC . 'licensing.php' );
60
- require_once( WPBDP_INC . 'seo.php' );
61
- require_once( WPBDP_INC . 'class-shortcodes.php' );
62
- require_once( WPBDP_INC . 'class-recaptcha.php' );
63
- require_once( WPBDP_INC . 'themes.php' );
64
- require_once( WPBDP_INC . 'template-sections.php' );
65
-
66
 
67
- global $wpbdp;
 
 
68
 
 
 
 
69
 
70
  /**
71
- * The main plugin class.
 
72
  */
73
- class WPBDP_Plugin {
74
-
75
- var $_query_stack = array();
76
-
77
-
78
- public function __construct() {
79
- register_activation_hook( __FILE__, array( &$this, 'plugin_activation' ) );
80
- register_deactivation_hook( __FILE__, array( &$this, 'plugin_deactivation' ) );
81
-
82
- // Enable debugging if needed.
83
- if ( ( defined( 'WPBDP_DEBUG' ) && true == WPBDP_DEBUG ) || wpbdp_experimental( 'debug_on' ) )
84
- $this->debug_on();
85
-
86
- // Load dummy objects in case plugins try to do something at an early stage.
87
- $noop = new WPBDP_NoopObject();
88
- $this->settings = $noop;
89
- $this->controller = $noop;
90
- $this->formfields = $noop;
91
- $this->admin = $noop;
92
- $this->fees = $noop;
93
- $this->payments = $noop;
94
- $this->listings = $noop;
95
-
96
- $this->themes = new WPBDP_Themes();
97
-
98
- $this->licensing = new WPBDP_Licensing();
99
-
100
- add_action( 'plugins_loaded', array( &$this, 'load_i18n' ) );
101
-
102
- add_action( 'plugins_loaded', array( $this, 'register_cache_groups' ) );
103
- add_action( 'switch_blog', array( $this, 'register_cache_groups' ) );
104
-
105
- if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
106
- add_action( 'init', array( &$this, 'init' ), 9 );
107
- } else {
108
- add_action( 'init', array( &$this, 'init' ) );
109
- }
110
-
111
- add_action( 'widgets_init', array( &$this, '_register_widgets' ) );
112
-
113
- // For testing the expiration routine only.
114
- // add_action('init', create_function('', 'do_action("wpbdp_listings_expiration_check");'), 20);
115
- }
116
-
117
- function load_i18n() {
118
- $plugin_dir = basename( dirname( __FILE__ ) );
119
- $languages_dir = trailingslashit( $plugin_dir . '/languages' );
120
- load_plugin_textdomain( 'WPBDM', false, $languages_dir );
121
- }
122
-
123
- function init() {
124
- // Register some basic JS resources.
125
- add_action( 'wp_enqueue_scripts', array( &$this, 'register_common_scripts' ) );
126
- add_action( 'admin_enqueue_scripts', array( &$this, 'register_common_scripts' ) );
127
-
128
- // Initialize settings API.
129
- $this->settings = new WPBDP_Settings();
130
- $this->formfields = WPBDP_FormFields::instance();
131
-
132
- // Install plugin.
133
- $this->settings->register_settings();
134
-
135
- // WPBDP is intended to replace this whole class in the near future.
136
- $bd = new WPBDP();
137
- $bd->init();
138
-
139
- $this->dispatcher = $bd->dispatcher;
140
- $this->installer = new WPBDP_Installer();
141
-
142
- try {
143
- $this->installer->install();
144
- } catch ( Exception $e ) {
145
- $this->installer->show_installation_error( $e );
146
- return;
147
- }
148
-
149
- if ( $manual_upgrade = get_option( 'wpbdp-manual-upgrade-pending', false ) ) {
150
- $this->installer->setup_manual_upgrade();
151
-
152
- add_shortcode( 'businessdirectory', array( $this, 'frontend_manual_upgrade_msg' ) );
153
- add_shortcode( 'business-directory', array( $this, 'frontend_manual_upgrade_msg' ) );
154
-
155
- return;
156
- }
157
-
158
- // Display "Settings" link on Plugins page.
159
- $plugin_filename = plugin_basename( __FILE__ );
160
- add_filter( 'plugin_action_links_' . $plugin_filename, array( &$this, 'plugin_action_links' ) );
161
-
162
- // Initialize APIs.
163
- $this->admin = is_admin() ? new WPBDP_Admin() : null;
164
- $this->fees = new WPBDP_Fees_API();
165
- $this->payments = new WPBDP_PaymentsAPI();
166
- $this->listings = new WPBDP_Listings_API();
167
- $this->shortcodes = new WPBDP__Shortcodes();
168
- $this->compat = new WPBDP_Compat();
169
-
170
- $this->_register_image_sizes();
171
-
172
- add_filter('rewrite_rules_array', array( &$this, '_rewrite_rules'));
173
- add_filter('query_vars', array( &$this, '_query_vars'));
174
- add_filter( 'redirect_canonical', array( &$this, '_redirect_canonical' ), 10, 2 );
175
- add_action('template_redirect', array( &$this, '_template_redirect'));
176
- add_action('wp_loaded', array( &$this, '_wp_loaded'));
177
-
178
- add_action( 'save_post_page', array( &$this, '_invalidate_pages_cache' ) );
179
-
180
- add_filter('comments_template', array( &$this, '_comments_template'));
181
- add_filter('taxonomy_template', array( &$this, '_category_template'));
182
- add_filter('single_template', array( &$this, '_single_template'));
183
-
184
- add_action( 'wp', array( &$this, '_meta_setup' ) );
185
- add_action( 'wp', array( &$this, '_jetpack_compat' ), 11, 1 );
186
- add_filter( 'wp_title', array( &$this, '_meta_title' ), 10, 3 );
187
- add_filter( 'pre_get_document_title', array( &$this, '_meta_title' ), 10, 3 );
188
- add_action( 'wp_head', array( &$this, '_rss_feed' ), 2 );
189
- add_filter( 'feed_links_show_posts_feed', array( $this, 'should_show_posts_feed_links' ) );
190
- add_filter( 'feed_links_show_comments_feed', array( $this, 'should_show_posts_feed_links' ) );
191
-
192
- if ( ! wpbdp_get_option( 'disable-cpt' ) ) {
193
- remove_filter('comments_template', array( &$this, '_comments_template'));
194
- remove_filter('taxonomy_template', array( &$this, '_category_template'));
195
- remove_filter('single_template', array( &$this, '_single_template'));
196
-
197
- remove_action( 'wp', array( &$this, '_meta_setup' ) );
198
- remove_action( 'wp', array( &$this, '_jetpack_compat' ), 11, 1 );
199
-
200
- remove_filter( 'wp_title', array( &$this, '_meta_title' ), 10, 3 );
201
- remove_filter( 'pre_get_document_title', array( &$this, '_meta_title' ), 10, 3 );
202
-
203
- add_filter( 'document_title_parts', array( &$this, 'set_view_title' ), 10 );
204
- }
205
-
206
- add_action( 'wp_head', array( &$this, '_handle_broken_plugin_filters' ), 0 );
207
-
208
- do_action( 'wpbdp_loaded' );
209
-
210
-
211
- // Expiration hook.
212
- add_action( 'wpbdp_listings_expiration_check', array( &$this, '_notify_expiring_listings' ), 0 );
213
-
214
- // Scripts & styles.
215
- add_action('wp_enqueue_scripts', array($this, '_enqueue_scripts'));
216
- add_action( 'wp_enqueue_scripts', array( &$this, 'enqueue_css_override' ), 9999, 0 );
217
-
218
- // Plugin modules initialization.
219
- $this->_init_modules();
220
-
221
- // AJAX actions.
222
- add_action( 'wp_ajax_wpbdp-file-field-upload', array( &$this, 'ajax_file_field_upload' ) );
223
- add_action( 'wp_ajax_nopriv_wpbdp-file-field-upload', array( &$this, 'ajax_file_field_upload' ) );
224
- add_action( 'wp_ajax_wpbdp-listing-submit-image-upload', array( &$this, 'ajax_listing_submit_image_upload' ) );
225
- add_action( 'wp_ajax_nopriv_wpbdp-listing-submit-image-upload', array( &$this, 'ajax_listing_submit_image_upload' ) );
226
- add_action( 'wp_ajax_wpbdp-listing-submit-image-delete', array( &$this, 'ajax_listing_submit_image_delete' ) );
227
- add_action( 'wp_ajax_nopriv_wpbdp-listing-submit-image-delete', array( &$this, 'ajax_listing_submit_image_delete' ) );
228
-
229
- // Core sorting options.
230
- add_filter( 'wpbdp_listing_sort_options', array( &$this, 'sortbar_sort_options' ) );
231
- add_filter( 'wpbdp_query_fields', array( &$this, 'sortbar_query_fields' ) );
232
- add_filter( 'wpbdp_query_orderby', array( &$this, 'sortbar_orderby' ) );
233
-
234
- $this->recaptcha = new WPBDP_reCAPTCHA();
235
-
236
- // Register shortcodes.
237
- $this->shortcodes->register();
238
- }
239
-
240
- public function register_cache_groups() {
241
- if ( ! function_exists( 'wp_cache_add_non_persistent_groups' ) ) {
242
- return;
243
- }
244
-
245
- wp_cache_add_non_persistent_groups( array( 'wpbdp pages', 'wpbdp formfields', 'wpbdp fees', 'wpbdp submit state', 'wpbdp' ) );
246
- }
247
-
248
-
249
- // {{{ Premium modules.
250
-
251
- /**
252
- * Return information about known premium modules.
253
- * @return array An array in the form $module_id => $module_information where $module_information contains the keys
254
- * 'installed' (True or False),
255
- * 'version' (if installed, NULL otherwise),
256
- * 'required' (required module version as known to current core version).
257
- * @since 3.4
258
- */
259
- public function get_premium_modules_data() {
260
- static $modules = array(
261
- '2checkout' => array( 'WPBDP_2Checkout_Module', '3.4' ),
262
- 'attachments' => array( 'WPBDP_ListingAttachmentsModule', '3.4' ),
263
- 'categories' => array( 'WPBDP_CategoriesModule', '3.4' ),
264
- 'featured-levels' => array( 'WPBDP_FeaturedLevelsModule', '3.4' ),
265
- 'googlemaps' => array( 'BusinessDirectory_GoogleMapsPlugin', '3.4' ),
266
- 'payfast' => array( 'WPBDP_Gateways_PayFast', '3.4' ),
267
- 'paypal' => array( 'WPBDP_PayPal_Module', '3.4' ),
268
- 'ratings' => array( 'BusinessDirectory_RatingsModule', '3.4' ),
269
- 'regions' => array( 'WPBDP_RegionsPlugin', '3.4' ),
270
- 'stripe' => array( 'WPBDP_Stripe_Module', '1.0' ),
271
- 'zipcodesearch' => array( 'WPBDP_ZIPCodeSearchModule', '3.4' )
272
- );
273
-
274
- static $data = null;
275
-
276
- if ( null !== $data )
277
- return $data;
278
-
279
- $data = array();
280
-
281
- foreach ( $modules as $module_id => $module_ ) {
282
- $module_class = $module_[0];
283
- $data[ $module_id ] = array( 'installed' => false,
284
- 'version' => null,
285
- 'required' => $module_[1] );
286
-
287
- if ( class_exists( $module_class ) ) {
288
- $data[ $module_id ]['installed'] = true;
289
-
290
- if ( defined( $module_class . '::VERSION' ) ) {
291
- $data[ $module_id ]['version'] = constant( $module_class . '::VERSION' );
292
- }
293
- }
294
- }
295
-
296
- return $data;
297
- }
298
-
299
- // }}}
300
-
301
- public function _invalidate_pages_cache( $arg0 = false ) {
302
- delete_transient( 'wpbdp-page-ids' );
303
- }
304
-
305
- private function get_rewrite_rules() {
306
- global $wpdb;
307
- global $wp_rewrite;
308
-
309
- $rules = array();
310
-
311
- // TODO: move this to WPML Compat.
312
- if ( $page_ids = wpbdp_get_page_ids( 'main' ) ) {
313
- foreach ( $page_ids as $page_id ) {
314
- $page_link = _get_page_link( $page_id );
315
- $page_link = preg_replace( '/\?.*/', '', $page_link ); // Remove querystring from page link.
316
-
317
- $home_url = home_url();
318
- $home_url = preg_replace( '/\?.*/', '', $home_url ); // Remove querystring from home URL.
319
-
320
- $rewrite_base = str_replace( 'index.php/', '', rtrim( str_replace( trailingslashit( $home_url ), '', $page_link ), '/' ) );
321
-
322
- $dir_slug = urlencode( wpbdp_get_option( 'permalinks-directory-slug' ) );
323
- $category_slug = urlencode( wpbdp_get_option( 'permalinks-category-slug' ) );
324
- $tags_slug = urlencode( wpbdp_get_option( 'permalinks-tags-slug' ) );
325
-
326
- $rules['(' . $rewrite_base . ')/' . $wp_rewrite->pagination_base . '/?([0-9]{1,})/?$'] = 'index.php?page_id=' . $page_id . '&paged=$matches[2]';
327
-
328
- $rules['(' . $rewrite_base . ')/' . $category_slug . '/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?' . WPBDP_CATEGORY_TAX . '=$matches[2]&feed=$matches[3]';
329
- $rules['(' . $rewrite_base . ')/' . $category_slug . '/(.+?)/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?' . WPBDP_CATEGORY_TAX . '=$matches[2]&feed=$matches[3]';
330
-
331
- if ( ! wpbdp_get_option( 'disable-cpt' ) ) {
332
- $rules['(' . $rewrite_base . ')/' . $category_slug . '/(.+?)/' . $wp_rewrite->pagination_base . '/?([0-9]{1,})/?$'] = 'index.php?' . WPBDP_CATEGORY_TAX . '=$matches[2]&paged=$matches[3]';
333
- $rules['(' . $rewrite_base . ')/' . $category_slug . '/(.+?)/?$'] = 'index.php?' . WPBDP_CATEGORY_TAX . '=$matches[2]';
334
- } else {
335
- $rules['(' . $rewrite_base . ')/' . $category_slug . '/(.+?)/' . $wp_rewrite->pagination_base . '/?([0-9]{1,})/?$'] = 'index.php?page_id=' . $page_id . '&_' . $category_slug . '=$matches[2]&paged=$matches[3]';
336
- $rules['(' . $rewrite_base . ')/' . $category_slug . '/(.+?)/?$'] = 'index.php?page_id=' . $page_id . '&_' . $category_slug . '=$matches[2]';
337
- }
338
-
339
- $rules['(' . $rewrite_base . ')/' . $tags_slug . '/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?' . WPBDP_TAGS_TAX . '=$matches[2]&feed=$matches[3]';
340
- $rules['(' . $rewrite_base . ')/' . $tags_slug . '/(.+?)/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?' . WPBDP_TAGS_TAX . '=$matches[2]&feed=$matches[3]';
341
-
342
- if ( ! wpbdp_get_option( 'disable-cpt') ) {
343
- $rules['(' . $rewrite_base . ')/' . $tags_slug . '/(.+?)/' . $wp_rewrite->pagination_base . '/?([0-9]{1,})/?$'] = 'index.php?' . WPBDP_TAGS_TAX . '=$matches[2]&paged=$matches[3]';
344
- $rules['(' . $rewrite_base . ')/' . $tags_slug . '/(.+?)$'] = 'index.php?' . WPBDP_TAGS_TAX . '=$matches[2]';
345
- } else {
346
- $rules['(' . $rewrite_base . ')/' . $tags_slug . '/(.+?)/' . $wp_rewrite->pagination_base . '/?([0-9]{1,})/?$'] = 'index.php?page_id=' .$page_id .'&_' . $tags_slug . '=$matches[2]&paged=$matches[3]';
347
- $rules['(' . $rewrite_base . ')/' . $tags_slug . '/(.+?)$'] = 'index.php?page_id=' . $page_id . '&_' . $tags_slug . '=$matches[2]';
348
- }
349
-
350
- if ( wpbdp_get_option( 'permalinks-no-id' ) ) {
351
- if ( ! wpbdp_get_option( 'disable-cpt' ) ) {
352
- $rules['(' . $rewrite_base . ')/(.*)/?$'] = 'index.php?' . WPBDP_POST_TYPE . '=$matches[2]';
353
- } else {
354
- $rules['(' . $rewrite_base . ')/(.*)/?$'] = 'index.php?page_id=' . $page_id . '&_' . $dir_slug . '=$matches[2]';
355
- }
356
- } else {
357
- if ( ! wpbdp_get_option( 'disable-cpt' ) ) {
358
- $rules['(' . $rewrite_base . ')/([0-9]{1,})/?(.*)/?$'] = 'index.php?p=$matches[2]&post_type=' . WPBDP_POST_TYPE; // FIXME: post_type shouldn't be required. Fix Query_Integration too.
359
- } else {
360
- $rules['(' . $rewrite_base . ')/([0-9]{1,})/?(.*)/?$'] = 'index.php?page_id=' . $page_id . '&_' . $dir_slug . '=$matches[2]';
361
- }
362
- }
363
- }
364
- }
365
-
366
- $rules = apply_filters( 'wpbdp_rewrite_rules', $rules );
367
-
368
- // Create uppercase versions of rules involving octets (support for cyrillic characters).
369
- foreach ( $rules as $def => $redirect ) {
370
- $upper_r = preg_replace_callback( '/%[0-9a-zA-Z]{2}/',
371
- create_function( '$x', 'return strtoupper( $x[0] );' ),
372
- $def );
373
-
374
- if ( 0 !== strcmp( $def, $upper_r ) ) {
375
- $rules[ $upper_r ] = $redirect;
376
- }
377
- }
378
-
379
- return $rules;
380
- }
381
-
382
- public function _rewrite_rules($rules) {
383
- $newrules = $this->get_rewrite_rules();
384
- return $newrules + $rules;
385
- }
386
-
387
- /**
388
- * TODO: Why do we generate rewrite rules on every request?
389
- */
390
- public function _wp_loaded() {
391
- if ($rules = get_option( 'rewrite_rules' )) {
392
- foreach ($this->get_rewrite_rules() as $k => $v) {
393
- if (!isset($rules[$k]) || $rules[$k] != $v) {
394
- global $wp_rewrite;
395
- $wp_rewrite->flush_rules();
396
- return;
397
- }
398
- }
399
- }
400
- }
401
-
402
- public function _query_vars($vars) {
403
- array_push($vars, 'id');
404
- array_push($vars, 'listing');
405
- array_push($vars, 'category_id'); // TODO: are we really using this var?
406
- array_push($vars, 'category');
407
- array_push($vars, 'action'); // TODO: are we really using this var?
408
- array_push( $vars, 'wpbdpx' );
409
- array_push( $vars, 'region' );
410
- array_push( $vars, 'wpbdp_view' );
411
-
412
- if ( wpbdp_get_option( 'disable-cpt' ) ) {
413
- array_push( $vars, '_' . wpbdp_get_option( 'permalinks-directory-slug' ) );
414
- array_push( $vars, '_' . wpbdp_get_option( 'permalinks-category-slug' ) );
415
- array_push( $vars, '_' . wpbdp_get_option( 'permalinks-tags-slug' ) );
416
- }
417
-
418
- return $vars;
419
- }
420
-
421
- /**
422
- * Workaround for issue WP bug #16373.
423
- * See http://wordpress.stackexchange.com/questions/51530/rewrite-rules-problem-when-rule-includes-homepage-slug.
424
- */
425
- public function _redirect_canonical( $redirect_url, $requested_url ) {
426
- global $wp_query;
427
-
428
- if ( $main_page_id = wpbdp_get_page_id( 'main' ) ) {
429
- if ( is_page() && !is_feed() && isset( $wp_query->queried_object ) &&
430
- get_option( 'show_on_front' ) == 'page' &&
431
- get_option( 'page_on_front' ) == $wp_query->queried_object->ID ) {
432
- return $requested_url;
433
- }
434
- }
435
-
436
- return $redirect_url;
437
- }
438
-
439
- public function _template_redirect() {
440
- global $wp_query;
441
-
442
- if ( $wp_query->get( 'wpbdpx' ) ) {
443
- // Handle some special wpbdpx actions.
444
- $wpbdpx = $wp_query->get( 'wpbdpx' );
445
-
446
- if ( isset( $this->{$wpbdpx} ) && method_exists( $this->{$wpbdpx}, 'process_request' ) ) {
447
- $this->{$wpbdpx}->process_request();
448
- exit();
449
- }
450
- }
451
-
452
- if ( is_feed() )
453
- return;
454
-
455
- // FIXME for themes-release
456
- // handle some deprecated stuff
457
- // if ( is_search() && isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] == WPBDP_POST_TYPE ) {
458
- // $url = esc_url_raw( add_query_arg( array( 'action' => 'search',
459
- // 'dosrch' => 1,
460
- // 'q' => wpbdp_getv( $_REQUEST, 's', '' ) ), wpbdp_get_page_link( 'main' ) ) );
461
- // wp_redirect( $url ); exit;
462
- // }
463
- //
464
- // if ( wpbdp_experimental( 'typeintegration') && (get_query_var('taxonomy') == WPBDP_CATEGORY_TAX) && (_wpbdp_template_mode('category') == 'page') ) {
465
- // return;
466
- // }
467
- //
468
- // if ( (get_query_var('taxonomy') == WPBDP_CATEGORY_TAX) && (_wpbdp_template_mode('category') == 'page') ) {
469
- // wp_redirect( esc_url_raw( add_query_arg('category', get_query_var('term'), wpbdp_get_page_link('main')) ) ); // XXX
470
- // exit;
471
- // }
472
- //
473
- // if ( (get_query_var('taxonomy') == WPBDP_TAGS_TAX) && (_wpbdp_template_mode('category') == 'page') ) {
474
- // wp_redirect( esc_url_raw( add_query_arg('tag', get_query_var('term'), wpbdp_get_page_link('main')) ) ); // XXX
475
- // exit;
476
- // }
477
- //
478
- // if ( wpbdp_experimental( 'typeintegration' ) && is_single() && (get_query_var('post_type') == WPBDP_POST_TYPE) && (_wpbdp_template_mode('single') == 'page') ) {
479
- // return;
480
- // }
481
- //
482
- // if ( is_single() && (get_query_var('post_type') == WPBDP_POST_TYPE) && (_wpbdp_template_mode('single') == 'page') ) {
483
- // $url = wpbdp_get_page_link( 'main' );
484
- //
485
- // if (get_query_var('name')) {
486
- // wp_redirect( esc_url_raw( add_query_arg('listing', get_query_var('name'), $url) ) ); // XXX
487
- // } else {
488
- // wp_redirect( esc_url_raw( add_query_arg('id', get_query_var('p'), $url) ) ); // XXX
489
- // }
490
- //
491
- // exit;
492
- // }
493
- //
494
-
495
- // Redirect some old views.
496
- if ( 'main' == wpbdp_current_view() && ! empty( $_GET['action'] ) ) {
497
- switch ( $_GET['action'] ) {
498
- case 'submitlisting':
499
- $newview = 'submit_listing';
500
- break;
501
- case 'search':
502
- $newview = 'search';
503
- break;
504
- default:
505
- $newview = '';
506
- break;
507
- }
508
-
509
- wp_redirect( add_query_arg( 'wpbdp_view', $newview, remove_query_arg( 'action' ) ) );
510
- exit();
511
- }
512
-
513
- // Handle login URL for some views.
514
- if ( in_array( wpbdp_current_view(), array( 'edit_listing', 'submit_listing', 'delete_listing', 'renew_listing' ), true )
515
- && wpbdp_get_option( 'require-login' )
516
- && ! is_user_logged_in() ) {
517
-
518
- $login_url = trim( wpbdp_get_option( 'login-url' ) );
519
-
520
- if ( ! $login_url )
521
- return;
522
-
523
- $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
524
- $url = add_query_arg( 'redirect_to', urlencode( $current_url ), $login_url );
525
- wp_redirect( esc_url_raw( $url ) );
526
- exit();
527
- }
528
- }
529
-
530
- public function plugin_activation() {
531
- add_action('init', array($this, 'flush_rules'), 11);
532
-
533
- $this->_invalidate_pages_cache();
534
- }
535
-
536
- public function plugin_deactivation() {
537
- wp_clear_scheduled_hook('wpbdp_listings_expiration_check');
538
- }
539
-
540
- public function flush_rules() {
541
- if (function_exists('flush_rewrite_rules'))
542
- flush_rewrite_rules(false);
543
- }
544
-
545
 
546
- // TODO: better validation.
547
- public function ajax_listing_submit_image_upload() {
548
- $res = new WPBDP_Ajax_Response();
549
-
550
- $listing_id = ! empty( $_REQUEST['listing_id'] ) ? intval( $_REQUEST['listing_id'] ) : 0;
551
- $listing = null;
552
- $state_id = ! empty( $_REQUEST['state_id'] ) ? trim( $_REQUEST['state_id'] ) : '';
553
- $state = null;
554
-
555
- if ( $state_id ) {
556
- require_once( WPBDP_INC . 'views/view-submit-listing.php' );
557
- $state = WPBDP_Listing_Submit_State::get( $state_id );
558
- } elseif ( $listing_id ) {
559
- $listing = WPBDP_Listing::get( $listing_id );
560
- }
561
-
562
- if ( ! $listing && ! $state )
563
- return $res->send_error();
564
-
565
- if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'listing-' . ( $state ? $state->id : $listing->get_id() ) . '-image-upload' ) )
566
- return $res->send_error();
567
-
568
- $content_range = null;
569
- $size = null;
570
-
571
- if ( isset( $_SERVER['HTTP_CONTENT_RANGE'] ) ) {
572
- $content_range = preg_split('/[^0-9]+/', $_SERVER['HTTP_CONTENT_RANGE']);
573
- $size = $content_range ? $content_range[3] : null;
574
- }
575
-
576
- $attachments = array();
577
- $files = wpbdp_flatten_files_array( isset( $_FILES['images'] ) ? $_FILES['images'] : array() );
578
- $errors = array();
579
-
580
- $image_slots = 0;
581
- $slots_available = 0;
582
- if ( wpbdp_get_option( 'allow-images' ) ) {
583
- if ( $state ) {
584
- foreach ( $state->categories as $cat_id => $fee_id ) {
585
- $image_slots += wpbdp_get_fee( $fee_id )->images;
586
- }
587
-
588
- $slots_available = $image_slots - count( $state->images ) - count( $files );
589
- $images_meta = $state->images_meta;
590
- } else {
591
- $categories = $listing->get_categories( 'all' );
592
-
593
- foreach ( $categories as $cat ) {
594
- $fee = wpbdp_get_fee( $cat->fee_id );
595
- $image_slots += $fee->images;
596
- }
597
-
598
- $slots_available = $image_slots - count( $listing->get_images() ) - count( $files );
599
- }
600
- }
601
-
602
- if ( ! current_user_can( 'administrator' ) && $slots_available < 0 ) {
603
- return $res->send_error( _x( 'Can not upload any more images for this listing.', 'listing image upload', 'WPBDM' ) );
604
- }
605
-
606
- foreach ( $files as $i => $file ) {
607
- $image_error = '';
608
- $attachment_id = wpbdp_media_upload( $file,
609
- true,
610
- true,
611
- array( 'image' => true,
612
- 'min-size' => intval( wpbdp_get_option( 'image-min-filesize' ) ) * 1024,
613
- 'max-size' => intval( wpbdp_get_option( 'image-max-filesize' ) ) * 1024,
614
- 'min-width' => wpbdp_get_option( 'image-min-width' ),
615
- 'min-height' => wpbdp_get_option( 'image-min-height' )
616
- ),
617
- $image_error ); // TODO: handle errors.
618
-
619
- if ( $image_error )
620
- $errors[ $file['name'] ] = $image_error;
621
- else
622
- $attachments[] = $attachment_id;
623
- }
624
-
625
-
626
- $html = '';
627
- foreach ( $attachments as $attachment_id ) {
628
- if ( $state )
629
- $state->images[] = $attachment_id;
630
-
631
- $html .= wpbdp_render( 'submit-listing/images-single',
632
- array( 'image_id' => $attachment_id, 'state_id' => $state ? $state->id : '', 'listing_id' => $listing ? $listing->get_id() : 0 ),
633
- false );
634
- }
635
-
636
- if ( $state ) {
637
- $state->save();
638
- } else {
639
- $listing->set_images( $attachments, true );
640
- }
641
-
642
- if ( $errors ) {
643
- $error_msg = '';
644
-
645
- foreach ( $errors as $fname => $error )
646
- $error_msg .= sprintf( '&#149; %s: %s', $fname, $error ) . '<br />';
647
-
648
- $res->add( 'uploadErrors', $error_msg );
649
- }
650
-
651
- $res->add( 'attachmentIds', $attachments );
652
- $res->add( 'html', $html );
653
- $res->send();
654
- }
655
-
656
- public function ajax_listing_submit_image_delete() {
657
- $res = new WPBDP_Ajax_Response();
658
-
659
- $image_id = intval( $_REQUEST['image_id'] );
660
- $listing_id = isset( $_REQUEST['listing_id'] ) ? absint( $_REQUEST['listing_id'] ) : 0;
661
- $state_id = isset( $_REQUEST['state_id'] ) ? trim( $_REQUEST['state_id'] ) : '';
662
-
663
- $nonce = $_REQUEST['_wpnonce'];
664
-
665
- if ( ! $image_id || ( ! $listing_id && ! $state_id ) )
666
- $res->send_error();
667
-
668
- if ( ! wp_verify_nonce( $nonce, 'delete-listing-' . ( $listing_id ? $listing_id : $state_id ) . '-image-' . $image_id ) )
669
- $res->send_error();
670
-
671
- if ( $state_id ) {
672
- require_once( WPBDP_INC . 'views/view-submit-listing.php' );
673
-
674
- $state = WPBDP_Listing_Submit_State::get( $state_id );
675
-
676
- if ( ! $state || ! in_array( $image_id, $state->images ) )
677
- $res->send_error();
678
-
679
- wpbdp_array_remove_value( $state->images, $image_id );
680
- $state->save();
681
- } else {
682
- $parent_id = (int) wp_get_post_parent_id( $image_id );
683
- if ( $parent_id != $listing_id )
684
- $res->send_error();
685
- }
686
-
687
- wp_delete_attachment( $image_id, true );
688
-
689
- $res->add( 'imageId', $image_id );
690
- $res->send();
691
- }
692
-
693
- public function _init_modules() {
694
- do_action('wpbdp_modules_loaded');
695
- do_action_ref_array( 'wpbdp_register_settings', array( &$this->settings ) );
696
- do_action('wpbdp_register_fields', $this->formfields);
697
- do_action('wpbdp_modules_init');
698
-
699
- if ( wpbdp_get_option( 'tracking-on', false ) ) {
700
- $this->site_tracking = new WPBDP_SiteTracking();
701
- }
702
- }
703
-
704
- public function get_post_type() {
705
- return WPBDP_POST_TYPE;
706
- }
707
-
708
- public function get_post_type_category() {
709
- return WPBDP_CATEGORY_TAX;
710
- }
711
-
712
- public function get_post_type_tags() {
713
- return WPBDP_TAGS_TAX;
714
- }
715
-
716
- public function plugin_action_links( $links ) {
717
- $links['settings'] = '<a href="' . admin_url( 'admin.php?page=wpbdp_admin_settings' ) . '">' . _x( 'Settings', 'admin plugins', 'WPBDM' ) . '</a>';
718
- return $links;
719
- }
720
-
721
- public function _register_image_sizes() {
722
- $thumbnail_width = absint( wpbdp_get_option( 'thumbnail-width' ) );
723
- $thumbnail_height = absint( wpbdp_get_option( 'thumbnail-height' ) );
724
-
725
- $max_width = absint( wpbdp_get_option('image-max-width') );
726
- $max_height = absint( wpbdp_get_option('image-max-height') );
727
-
728
- $crop = (bool) wpbdp_get_option( 'thumbnail-crop' );
729
-
730
- // thumbnail size
731
- add_image_size( 'wpbdp-thumb', $thumbnail_width, $crop ? $thumbnail_height : 9999, $crop );
732
- // add_image_size( 'wpbdp-thumb', $thumbnail_width, $thumbnail_height, true );
733
- add_image_size( 'wpbdp-large', $max_width, $max_height, false );
734
- }
735
-
736
- public function is_debug_on() {
737
- return WPBDP_Debugging::is_debug_on();
738
- }
739
-
740
- public function debug_on() {
741
- global $wpdb;
742
-
743
- // Set MySQL strict mode.
744
- //$wpdb->show_errors();
745
- //$wpdb->query( "SET @@sql_mode = 'TRADITIONAL'" );
746
-
747
- // Enable BD debugging.
748
- WPBDP_Debugging::debug_on();
749
- }
750
-
751
- public function debug_off() {
752
- WPBDP_Debugging::debug_off();
753
- }
754
-
755
- public function has_module($name) {
756
- switch (strtolower($name)) {
757
- case 'payfast':
758
- case 'payfast-payment-module':
759
- return class_exists( 'WPBDP_Gateways_PayFast' );
760
- break;
761
- case 'paypal':
762
- case 'paypal-gateway-module':
763
- return class_exists( 'WPBDP_Paypal_Module' );
764
- break;
765
- case '2checkout':
766
- case 'twocheckout':
767
- case '2checkout-gateway-module':
768
- return class_exists( 'WPBDP_2Checkout_Module' );
769
- break;
770
- case 'googlecheckout':
771
- return wpbdp_payments_api()->has_gateway('googlecheckout');
772
- break;
773
- case 'google-maps-module':
774
- case 'googlemaps':
775
- return class_exists('BusinessDirectory_GoogleMapsPlugin');
776
- break;
777
- case 'ratings-module':
778
- case 'ratings':
779
- return class_exists('BusinessDirectory_RatingsModule');
780
- break;
781
- case 'regions-module':
782
- case 'regions':
783
- return class_exists('WPBDP_RegionsPlugin');
784
- break;
785
- case 'file-attachments-module':
786
- case 'attachments':
787
- return class_exists( 'WPBDP_ListingAttachmentsModule' );
788
- break;
789
- case 'zip-search-module':
790
- case 'zipcodesearch':
791
- return class_exists( 'WPBDP_ZIPCodeSearchModule' );
792
- break;
793
- case 'featured-levels-module':
794
- case 'featuredlevels':
795
- return class_exists( 'WPBDP_FeaturedLevelsModule' );
796
- break;
797
- case 'stripe-payment-module':
798
- case 'stripe':
799
- return class_exists( 'WPBDP_Stripe_Module' );
800
- break;
801
- case 'categories':
802
- return class_exists( 'WPBDP_CategoriesModule' );
803
- break;
804
- case 'claim-listings-module':
805
- return class_exists( 'WPBDP_Claim_Listings_Module' );
806
- break;
807
- case 'discount-codes-module':
808
- return class_exists( 'WPBDP_Coupons_Module' );
809
- break;
810
- default:
811
- break;
812
- }
813
-
814
- return false;
815
- }
816
-
817
- public function _rss_feed() {
818
- $current_view = wpbdp_current_view();
819
-
820
- if ( ! $current_view ) {
821
- return;
822
- }
823
-
824
- if ( ! in_array( $current_view, array( 'main', 'show_category', 'all_listings' ), true ) ) {
825
- return;
826
- }
827
-
828
- $main_page_title = get_the_title( wpbdp_get_page_id() );
829
- $link_template = '<link rel="alternate" type="application/rss+xml" title="%s" href="%s" />' . PHP_EOL;
830
- $feed_links = array();
831
-
832
- if ( 'main' === $current_view || 'all_listings' === $current_view ) {
833
- $feed_title = sprintf( _x( '%s Feed', 'rss feed', 'WPBDM'), $main_page_title );
834
- $feed_url = esc_url( add_query_arg( 'post_type', WPBDP_POST_TYPE, get_bloginfo( 'rss2_url' ) ) );
835
-
836
- $feed_links[] = sprintf( $link_template, $feed_title, $feed_url );
837
- }
838
-
839
- if ( 'show_category' === $current_view ) {
840
- $term = _wpbpd_current_category();
841
-
842
- if ( $term ) {
843
- $taxonomy = get_taxonomy( $term->taxonomy );
844
- $feed_title = sprintf( '%s &raquo; %s %s Feed', $main_page_title, $term->name, $taxonomy->labels->singular_name );
845
- $query_args = array( 'post_type' => WPBDP_POST_TYPE, WPBDP_CATEGORY_TAX => $term->slug );
846
- $feed_url = esc_url( add_query_arg( $query_args, get_bloginfo( 'rss2_url' ) ) );
847
-
848
- $feed_links[] = sprintf( $link_template, $feed_title, $feed_url );
849
-
850
- // Add dummy action to prevent https://core.trac.wordpress.org/ticket/40906
851
- add_action( 'wp_head', '__return_null', 3 );
852
- // Avoid two RSS URLs in Category pages.
853
- remove_action( 'wp_head', 'feed_links_extra', 3 );
854
- }
855
- }
856
-
857
- if ( $feed_links ) {
858
- echo '<!-- Business Directory RSS feed -->' . PHP_EOL;
859
- echo implode( '', $feed_links );
860
- echo '<!-- /Business Directory RSS feed -->' . PHP_EOL;
861
- }
862
- }
863
-
864
- public function should_show_posts_feed_links( $should ) {
865
- $current_view = wpbdp_current_view();
866
-
867
- if ( ! $current_view ) {
868
- return $should;
869
- }
870
-
871
- if ( ! in_array( $current_view, array( 'main', 'show_category', 'all_listings' ), true ) ) {
872
- return $should;
873
- }
874
-
875
- return false;
876
- }
877
-
878
- public function _register_widgets() {
879
- include_once ( WPBDP_INC . 'widgets/widget-featured-listings.php' );
880
- include_once ( WPBDP_INC . 'widgets/widget-latest-listings.php' );
881
- include_once ( WPBDP_INC . 'widgets/widget-random-listings.php' );
882
- include_once ( WPBDP_INC . 'widgets/widget-search.php' );
883
-
884
- register_widget('WPBDP_FeaturedListingsWidget');
885
- register_widget('WPBDP_LatestListingsWidget');
886
- register_widget('WPBDP_RandomListingsWidget');
887
- register_widget('WPBDP_SearchWidget');
888
- }
889
-
890
- /* theme filters */
891
- public function _comments_template($template) {
892
- $is_single_listing = is_single() && get_post_type() == WPBDP_POST_TYPE;
893
- $is_main_page = get_post_type() == 'page' && get_the_ID() == wpbdp_get_page_id( 'main' );
894
-
895
- $comments_allowed = in_array(
896
- $this->settings->get( 'allow-comments-in-listings' ),
897
- array( 'allow-comments', 'allow-comments-and-insert-template' )
898
- );
899
-
900
- // disable comments in WPBDP pages or if comments are disabled for listings
901
- if ( ( $is_single_listing && ! $comments_allowed ) || $is_main_page ) {
902
- return WPBDP_TEMPLATES_PATH . '/empty-template.php';
903
- }
904
-
905
- return $template;
906
- }
907
-
908
- public function _category_template($template) {
909
- if (get_query_var(WPBDP_CATEGORY_TAX) && taxonomy_exists(WPBDP_CATEGORY_TAX)) {
910
- return wpbdp_locate_template(array('businessdirectory-category', 'wpbusdirman-category'));
911
- }
912
-
913
- return $template;
914
- }
915
-
916
- public function _single_template($template) {
917
- if (is_single() && get_post_type() == WPBDP_POST_TYPE) {
918
- return wpbdp_locate_template(array('businessdirectory-single', 'wpbusdirman-single'));
919
- }
920
-
921
- return $template;
922
- }
923
-
924
- /* scripts & styles */
925
-
926
- /**
927
- * Registers scripts and styles that can be used either by frontend or backend code.
928
- * The scripts are just registered, not enqueued.
929
- *
930
- * @since 3.4
931
- */
932
- public function register_common_scripts() {
933
- // jQuery-FileUpload.
934
- // wp_register_script( 'jquery-fileupload-ui-widget',
935
- // WPBDP_URL . 'vendors/jQuery-File-Upload-9.5.7/js/vendor/jquery.ui.widget' . ( ! $this->is_debug_on() ? '.min' : '' ) . '.js' );
936
- wp_register_script( 'jquery-file-upload-iframe-transport',
937
- WPBDP_URL . 'vendors/jQuery-File-Upload-9.5.7/js/jquery.iframe-transport' . ( ! $this->is_debug_on() ? '.min' : '' ) . '.js' );
938
- wp_register_script( 'jquery-file-upload',
939
- WPBDP_URL . 'vendors/jQuery-File-Upload-9.5.7/js/jquery.fileupload' . ( ! $this->is_debug_on() ? '.min' : '' ) . '.js',
940
- array( 'jquery',
941
- 'jquery-ui-widget',
942
- 'jquery-file-upload-iframe-transport' ) );
943
-
944
- wp_register_script(
945
- 'jquery-breakpoints',
946
- WPBDP_URL . 'vendors/jquery-breakpoints' . ( ! $this->is_debug_on() ? '.min' : '' ) . '.js',
947
- array( 'jquery' ),
948
- null,
949
- true
950
- );
951
-
952
- // Drag & Drop.
953
- wp_register_style( 'wpbdp-dnd-upload', WPBDP_URL . 'assets/css/dnd-upload.min.css' );
954
- wp_register_script( 'wpbdp-dnd-upload', WPBDP_URL . 'assets/js/dnd-upload.min.js',
955
- array( 'jquery-file-upload' ) );
956
-
957
- wp_register_style( 'wpbdp-base-css', WPBDP_URL . 'assets/css/wpbdp.min.css' );
958
-
959
- wp_register_script(
960
- 'wpbdp-js',
961
- WPBDP_URL . 'assets/js/wpbdp.min.js',
962
- array( 'jquery', 'jquery-breakpoints', 'jquery-ui-sortable' )
963
- );
964
- }
965
-
966
- public function is_plugin_page() {
967
- if ( wpbdp_current_view() ) {
968
- return true;
969
- }
970
-
971
- global $wp_query;
972
-
973
- if ( ! empty( $wp_query->wpbdp_our_query ) || ! empty( $wp_query->wpbdp_view ) )
974
- return true;
975
-
976
- global $post;
977
-
978
- if ( $post && ( 'page' == $post->post_type || 'post' == $post->post_type ) ) {
979
- foreach ( array_keys( $this->shortcodes->get_shortcodes() ) as $shortcode ) {
980
- if ( wpbdp_has_shortcode( $post->post_content, $shortcode ) ) {
981
- return true;
982
- break;
983
- }
984
- }
985
- }
986
-
987
- if ( $post && WPBDP_POST_TYPE == $post->post_type )
988
- return true;
989
-
990
- return false;
991
- }
992
-
993
- public function _enqueue_scripts() {
994
- $only_in_plugin_pages = true;
995
- $enqueue_scripts_and_styles = apply_filters( 'wpbdp_should_enqueue_scripts_and_styles', $this->is_plugin_page() );
996
-
997
- wp_enqueue_style( 'wpbdp-widgets', WPBDP_URL . 'assets/css/widgets.min.css' );
998
-
999
- if ( $only_in_plugin_pages && ! $enqueue_scripts_and_styles )
1000
- return;
1001
-
1002
- wp_enqueue_style( 'wpbdp-dnd-upload' );
1003
- wp_enqueue_script( 'wpbdp-dnd-upload' );
1004
-
1005
- if ( wpbdp_get_option( 'use-thickbox' ) ) {
1006
- add_thickbox();
1007
- }
1008
-
1009
- wp_enqueue_style( 'wpbdp-base-css' );
1010
- wp_enqueue_script( 'wpbdp-js' );
1011
-
1012
- do_action( 'wpbdp_enqueue_scripts' );
1013
-
1014
- // enable legacy css (should be removed in a future release) XXX
1015
- if (_wpbdp_template_mode('single') == 'template' || _wpbdp_template_mode('category') == 'template' )
1016
- wp_enqueue_style('wpbdp-legacy-css', WPBDP_URL . 'assets/css/wpbdp-legacy.min.css');
1017
- }
1018
-
1019
- /**
1020
- * @since 3.5.3
1021
- */
1022
- public function enqueue_css_override() {
1023
- $stylesheet_dir = trailingslashit( get_stylesheet_directory() );
1024
- $stylesheet_dir_uri = trailingslashit( get_stylesheet_directory_uri() );
1025
- $template_dir = trailingslashit( get_template_directory() );
1026
- $template_dir_uri = trailingslashit( get_template_directory_uri() );
1027
-
1028
- $folders_uris = array(
1029
- array( trailingslashit( WP_PLUGIN_DIR ), trailingslashit( WP_PLUGIN_URL ) ),
1030
- array( $stylesheet_dir, $stylesheet_dir_uri ),
1031
- array( $stylesheet_dir . 'css/', $stylesheet_dir_uri . 'css/' )
1032
- );
1033
-
1034
- if ( $template_dir != $stylesheet_dir ) {
1035
- $folders_uris[] = array( $template_dir, $template_dir_uri );
1036
- $folders_uris[] = array( $template_dir . 'css/', $template_dir_uri . 'css/' );
1037
- }
1038
-
1039
- $filenames = array( 'wpbdp.css',
1040
- 'wpbusdirman.css',
1041
- 'wpbdp_custom_style.css',
1042
- 'wpbdp_custom_styles.css',
1043
- 'wpbdm_custom_style.css',
1044
- 'wpbdm_custom_styles.css' );
1045
-
1046
- $n = 0;
1047
- foreach ( $folders_uris as $folder_uri ) {
1048
- list( $dir, $uri ) = $folder_uri;
1049
-
1050
- foreach ( $filenames as $f ) {
1051
- if ( file_exists( $dir . $f ) ) {
1052
- wp_enqueue_style( 'wpbdp-custom-' . $n, $uri . $f );
1053
- $n++;
1054
- }
1055
- }
1056
- }
1057
- }
1058
-
1059
- /*
1060
- * Page metadata
1061
- */
1062
- public function _meta_setup() {
1063
- $action = wpbdp_current_view();
1064
-
1065
- $plugin_views_with_meta = array(
1066
- 'show_listing', 'show_category', 'show_tag',
1067
- 'all_listings', 'submit_listing', 'search'
1068
- );
1069
-
1070
- if ( ! in_array( $action, $plugin_views_with_meta ) ) {
1071
- return;
1072
- }
1073
-
1074
- require_once( WPBDP_INC . 'class-page-meta.php' );
1075
- $this->page_meta = new WPBDP_Page_Meta( $action );
1076
-
1077
- $this->_do_wpseo = defined( 'WPSEO_VERSION' ) ? true : false;
1078
-
1079
- if ( $this->_do_wpseo ) {
1080
- $wpseo_front = $this->_get_wpseo_frontend();
1081
-
1082
- remove_filter( 'wp_title', array( $this, '_meta_title' ), 10, 3 );
1083
- add_filter( 'wp_title', array( $this, '_meta_title' ), 16, 3 );
1084
- add_filter( 'pre_get_document_title', array( $this, '_meta_title' ), 16 );
1085
-
1086
- if ( is_object( $wpseo_front ) ) {
1087
- remove_filter( 'pre_get_document_title', array( &$wpseo_front, 'title' ), 15 );
1088
- remove_filter( 'wp_title', array( &$wpseo_front, 'title' ), 15, 3 );
1089
- remove_action( 'wp_head', array( &$wpseo_front, 'head' ), 1, 1 );
1090
- }
1091
-
1092
- add_action( 'wp_head', array( $this, '_meta_keywords' ) );
1093
- }
1094
-
1095
- remove_filter( 'wp_head', 'rel_canonical' );
1096
- add_filter( 'wp_head', array( $this, '_meta_rel_canonical' ) );
1097
-
1098
- if ( 'show_listing' == $action && wpbdp_rewrite_on() ) {
1099
- add_action( 'wp_head', array( &$this, 'listing_opentags' ) );
1100
- }
1101
- }
1102
-
1103
- private function _get_wpseo_frontend() {
1104
- if ( isset( $GLOBALS['wpseo_front'] ) ) {
1105
- return $GLOBALS['wpseo_front'];
1106
- } elseif ( class_exists( 'WPSEO_Frontend' ) && method_exists( 'WPSEO_Frontend', 'get_instance' ) ) {
1107
- return WPSEO_Frontend::get_instance();
1108
- }
1109
- }
1110
-
1111
- /*
1112
- * Fix issues with Jetpack.
1113
- */
1114
- public function _jetpack_compat( &$wp ) {
1115
- static $incompatible_actions = array( 'submitlisting', 'editlisting', 'upgradetostickylisting' );
1116
-
1117
- // TODO: fix before themes-release
1118
- $action = '';
1119
-
1120
- if ( !$action )
1121
- return;
1122
-
1123
- if ( defined( 'JETPACK__VERSION' ) && in_array( $action, $incompatible_actions ) ) {
1124
- add_filter( 'jetpack_enable_opengraph', '__return_false', 99 );
1125
- remove_action( 'wp_head', 'jetpack_og_tags' );
1126
- }
1127
- }
1128
-
1129
- public function _handle_broken_plugin_filters() {
1130
- // TODO: fix before themes-release
1131
- $action = '';
1132
-
1133
- if ( !$action )
1134
- return;
1135
-
1136
- // Relevanssi
1137
- if ( in_array( $action, array( 'submitlisting', 'editlisting' ), true ) && function_exists( 'relevanssi_insert_edit' ) ) {
1138
- remove_action( 'wp_insert_post', 'relevanssi_insert_edit', 99, 1 );
1139
- remove_action( 'delete_attachment', 'relevanssi_delete' );
1140
- remove_action( 'add_attachment', 'relevanssi_publish' );
1141
- remove_action( 'edit_attachment', 'relevanssi_edit' );
1142
- }
1143
-
1144
- $bad_filters = array( 'get_the_excerpt' => array(), 'the_excerpt' => array(), 'the_content' => array() );
1145
-
1146
- // AddThis Social Bookmarking Widget - http://www.addthis.com/
1147
- if ( defined( 'ADDTHIS_PLUGIN_VERSION' ) ) {
1148
- $bad_filters['get_the_excerpt'][] = array( 'addthis_display_social_widget_excerpt', 11);
1149
- $bad_filters['get_the_excerpt'][] = array( 'addthis_display_social_widget', 15 );
1150
- $bad_filters['the_content'][] = array( 'addthis_display_social_widget', 15 );
1151
- }
1152
-
1153
- // Jamie Social Icons - http://wordpress.org/extend/plugins/jamie-social-icons/
1154
- if ( function_exists( 'jamiesocial' ) ) {
1155
- $bad_filters['the_content'][] = 'add_post_topbot_content';
1156
- $bad_filters['the_content'][] = 'add_post_bot_content';
1157
- $bad_filters['the_content'][] = 'add_page_topbot_content';
1158
- $bad_filters['the_content'][] = 'add_page_top_content';
1159
- $bad_filters['the_content'][] = 'add_page_bot_content';
1160
- }
1161
-
1162
- // TF Social Share - http://www.searchtechword.com/2011/06/wordpress-plugin-add-twitter-facebook-google-plus-one-share
1163
- if ( function_exists( 'kc_twitter_facebook_excerpt' ) ) {
1164
- $bad_filters['the_excerpt'][] = 'kc_twitter_facebook_excerpt';
1165
- $bad_filters['the_content'][] = 'kc_twitter_facebook_contents';
1166
- }
1167
-
1168
- // Shareaholic - https://shareaholic.com/publishers/
1169
- if ( defined( 'SHRSB_vNum' ) ) {
1170
- $bad_filters['the_content'][] = 'shrsb_position_menu';
1171
- $bad_filters['the_content'][] = 'shrsb_get_recommendations';
1172
- $bad_filters['the_content'][] = 'shrsb_get_cb';
1173
- }
1174
-
1175
- // Simple Facebook Connect (#481)
1176
- if ( function_exists( 'sfc_version' ) ) {
1177
- remove_action( 'wp_head', 'sfc_base_meta' );
1178
- }
1179
-
1180
- // Quick AdSense - http://quicksense.net/
1181
- global $QData;
1182
- if ( isset( $QData ) ) {
1183
- $bad_filters['the_content'][] = 'process_content';
1184
- }
1185
-
1186
- foreach ( $bad_filters as $filter => &$callbacks ) {
1187
- foreach ( $callbacks as &$callback_info ) {
1188
- if ( has_filter( $filter, is_array( $callback_info ) ? $callback_info[0] : $callback_info ) ) {
1189
- remove_filter( $filter, is_array( $callback_info ) ? $callback_info[0] : $callback_info, is_array( $callback_info ) ? $callback_info[1] : 10 );
1190
- }
1191
- }
1192
- }
1193
-
1194
- }
1195
-
1196
- public function set_view_title( $title ) {
1197
- global $wp_query;
1198
-
1199
- if ( empty( $wp_query->wpbdp_view ) || ! is_array( $title ) )
1200
- return $title;
1201
-
1202
- $current_view = $this->dispatcher->current_view_object();
1203
-
1204
- if ( ! $current_view )
1205
- return $title;
1206
-
1207
- if ( $view_title = $current_view->get_title() )
1208
- $title['title'] = $view_title;
1209
-
1210
- return $title;
1211
- }
1212
-
1213
- // TODO: it'd be nice to move workarounds outside this class.
1214
- public function _meta_title( $title = '', $sep = '»', $seplocation = 'right' ) {
1215
- $wpseo_front = $this->_get_wpseo_frontend();
1216
-
1217
- $current_view = wpbdp_current_view();
1218
-
1219
- switch ( $current_view ) {
1220
- case 'submit_listing':
1221
- $view_title = _x( 'Submit A Listing', 'views', 'WPBDM' );
1222
- return $this->_maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation );
1223
- break;
1224
-
1225
- case 'search':
1226
- $view_title = _x( 'Find a Listing', 'title', 'WPBDM' );
1227
- return $this->_maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation );
1228
- break;
1229
-
1230
- case 'all_listings':
1231
- $view_title = _x( 'View All Listings', 'title', 'WPBDM' );
1232
- return $this->_maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation );
1233
- break;
1234
-
1235
- case 'show_tag':
1236
- $term = get_term_by(
1237
- 'slug',
1238
- get_query_var( '_' . wpbdp_get_option( 'permalinks-tags-slug' ) ),
1239
- WPBDP_TAGS_TAX
1240
- );
1241
-
1242
- if ( ! $term ) {
1243
- return $title;
1244
- }
1245
-
1246
- if ( $this->_do_wpseo ) {
1247
- if ( method_exists( 'WPSEO_Taxonomy_Meta', 'get_term_meta' ) ) {
1248
- $title = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'title' );
1249
- } else {
1250
- $title = trim( wpseo_get_term_meta( $term, $term->taxonomy, 'title' ) );
1251
- }
1252
-
1253
- if ( !empty( $title ) )
1254
- return wpseo_replace_vars( $title, (array) $term );
1255
-
1256
- if ( is_object( $wpseo_front ) )
1257
- return $wpseo_front->get_title_from_options( 'title-tax-' . $term->taxonomy, $term );
1258
- }
1259
-
1260
- return sprintf( _x( 'Listings tagged: %s', 'title', 'WPBDM' ), $term->name ) . ' ' . $sep . ' ' . $title;
1261
-
1262
- break;
1263
-
1264
- case 'show_category':
1265
- $term = get_term_by(
1266
- 'slug',
1267
- get_query_var( '_' . wpbdp_get_option( 'permalinks-category-slug' ) ),
1268
- WPBDP_CATEGORY_TAX
1269
- );
1270
-
1271
- if ( ! $term && get_query_var( 'category_id' ) ) {
1272
- $term = get_term_by( 'id', get_query_var( 'category_id' ), WPBDP_CATEGORY_TAX );
1273
- }
1274
-
1275
- if ( ! $term ) {
1276
- return $title;
1277
- }
1278
-
1279
- if ( $this->_do_wpseo ) {
1280
- if ( method_exists( 'WPSEO_Taxonomy_Meta', 'get_term_meta' ) ) {
1281
- $title = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'title' );
1282
- } else {
1283
- $title = trim( wpseo_get_term_meta( $term, $term->taxonomy, 'title' ) );
1284
- }
1285
-
1286
- if ( !empty( $title ) )
1287
- return wpseo_replace_vars( $title, (array) $term );
1288
-
1289
- if ( is_object( $wpseo_front ) )
1290
- return $wpseo_front->get_title_from_options( 'title-tax-' . $term->taxonomy, $term );
1291
- }
1292
-
1293
- return $term->name . ' ' . $sep . ' ' . $title;
1294
-
1295
- break;
1296
-
1297
- case 'show_listing':
1298
- $listing_id = wpbdp_get_post_by_id_or_slug(
1299
- get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
1300
- 'id',
1301
- 'id'
1302
- );
1303
-
1304
- if ( $this->_do_wpseo ) {
1305
- $title = $wpseo_front->get_content_title( get_post( $listing_id ) );
1306
- $title = esc_html( strip_tags( stripslashes( apply_filters( 'wpseo_title', $title ) ) ) );
1307
-
1308
- return $title;
1309
- break;
1310
- } else {
1311
- $post_title = get_the_title($listing_id);
1312
- }
1313
-
1314
- return $post_title . ' '. $sep . ' ' . $title;
1315
- break;
1316
-
1317
- case 'main':
1318
- break;
1319
-
1320
- default:
1321
- break;
1322
- }
1323
-
1324
- return $title;
1325
- }
1326
-
1327
- private function _maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation ) {
1328
- $wpseo_front = $this->_get_wpseo_frontend();
1329
-
1330
- if ( $this->_do_wpseo && is_object( $wpseo_front ) ) {
1331
- return $wpseo_front->get_title_from_options( 'title-page', array( 'post_title' => $view_title ) );
1332
- }
1333
-
1334
- if ( 'left' == $seplocation ) {
1335
- return $title . ' ' . $sep . ' ' . $view_title;
1336
- } else {
1337
- return $view_title . ' ' . $sep . ' ' . $title;
1338
- }
1339
- }
1340
-
1341
- public function _meta_keywords() {
1342
- $wpseo_front = $this->_get_wpseo_frontend();
1343
-
1344
- $current_view = wpbdp_current_view();
1345
-
1346
- switch ( $current_view ){
1347
- case 'show_listing':
1348
- global $post;
1349
-
1350
- $listing_id = wpbdp_get_post_by_id_or_slug(
1351
- get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
1352
- 'id',
1353
- 'id'
1354
- );
1355
-
1356
- $prev_post = $post;
1357
- $post = get_post( $listing_id );
1358
-
1359
- if ( is_object( $wpseo_front ) ) {
1360
- $wpseo_front->metadesc();
1361
- $wpseo_front->metakeywords();
1362
- $wpseo_front->webmaster_tools_authentication();
1363
- }
1364
-
1365
- $post = $prev_post;
1366
-
1367
- break;
1368
- case 'show_category':
1369
- case 'show_tag':
1370
- if ( $current_view == 'show_tag' ) {
1371
- $term = get_term_by(
1372
- 'slug',
1373
- get_query_var( '_' . wpbdp_get_option( 'permalinks-tags-slug' ) ),
1374
- WPBDP_TAGS_TAX
1375
- );
1376
- } else {
1377
- $term = get_term_by(
1378
- 'slug',
1379
- get_query_var( '_' . wpbdp_get_option( 'permalinks-category-slug' ) ),
1380
- WPBDP_CATEGORY_TAX
1381
- );
1382
-
1383
- if ( ! $term && get_query_var( 'category_id' ) ) {
1384
- $term = get_term_by( 'id', get_query_var( 'category_id' ), WPBDP_CATEGORY_TAX );
1385
- }
1386
- }
1387
-
1388
- if ( $term ) {
1389
- $metadesc = method_exists( 'WPSEO_Taxonomy_Meta', 'get_term_meta' ) ?
1390
- WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'desc' ) :
1391
- wpseo_get_term_meta( $term, $term->taxonomy, 'desc' );
1392
-
1393
- if ( !$metadesc && is_object( $wpseo_front ) && isset( $wpseo_front->options['metadesc-tax-' . $term->taxonomy] ) )
1394
- $metadesc = wpseo_replace_vars( $wpseo_front->options['metadesc-tax-' . $term->taxonomy], (array) $term );
1395
-
1396
- if ( $metadesc )
1397
- echo '<meta name="description" content="' . esc_attr( strip_tags( stripslashes( $metadesc ) ) ) . '"/>' . "\n";
1398
- }
1399
-
1400
- break;
1401
-
1402
- case 'main':
1403
- if ( is_object( $wpseo_front ) ) {
1404
- $wpseo_front->metadesc();
1405
- $wpseo_front->metakeywords();
1406
- $wpseo_front->webmaster_tools_authentication();
1407
- }
1408
-
1409
- break;
1410
-
1411
- default:
1412
- break;
1413
- }
1414
-
1415
- }
1416
-
1417
- public function _meta_rel_canonical() {
1418
- $action = wpbdp_current_view();
1419
-
1420
- if ( !$action )
1421
- return rel_canonical();
1422
-
1423
- $not_supported_views = array(
1424
- 'edit_listing', 'submit_listing', 'delete_listing', 'renew_listing',
1425
- 'listing_contact', 'upgradetostickylisting',
1426
- );
1427
-
1428
- if ( in_array( $action, $not_supported_views ) )
1429
- return;
1430
-
1431
- if ( $action == 'show_listing' ) {
1432
- $listing_id = wpbdp_get_post_by_id_or_slug(
1433
- get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
1434
- 'id',
1435
- 'id'
1436
- );
1437
- $url = get_permalink( $listing_id );
1438
- } else {
1439
- $url = site_url( $_SERVER['REQUEST_URI'] );
1440
- }
1441
-
1442
- echo sprintf( '<link rel="canonical" href="%s" />', esc_url( user_trailingslashit( $url ) ) );
1443
- }
1444
-
1445
- function listing_opentags() {
1446
- $listing_id = wpbdp_get_post_by_id_or_slug(
1447
- get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
1448
- 'id',
1449
- 'id'
1450
- );
1451
-
1452
- $listing = WPBDP_Listing::get( $listing_id );
1453
-
1454
- if ( ! $listing )
1455
- return;
1456
-
1457
- echo '<meta property="og:type" content="website" />';
1458
- echo '<meta property="og:title" content="' . esc_attr( WPBDP_SEO::listing_title( $listing_id ) ) . '" />';
1459
- echo '<meta property="og:url" content="' . esc_url( user_trailingslashit( $listing->get_permalink() ) ) . '" />';
1460
- echo '<meta property="og:description" content="' . esc_attr( WPBDP_SEO::listing_og_description( $listing_id ) ) . '" />';
1461
-
1462
- if ( $thumbnail_id = $listing->get_thumbnail_id() ) {
1463
- if ( $img = wp_get_attachment_image_src( $thumbnail_id, 'wpbdp-large' ) )
1464
- echo '<meta property="og:image" content="' . $img[0] . '" />';
1465
- } else {
1466
- $image_url = WPBDP_URL . 'assets/images/default-image-big.gif';
1467
- echo '<meta property="og:image" content="' . $image_url . '" />';
1468
- }
1469
- }
1470
-
1471
- public function ajax_file_field_upload() {
1472
- $field_id = ! empty( $_REQUEST['field_id'] ) ? absint( $_REQUEST['field_id'] ) : 0;
1473
- $nonce = ! empty( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '';
1474
- $listing_id = ! empty( $_REQUEST['listing_id'] ) ? absint( $_REQUEST['listing_id'] ) : 0;
1475
- $state_id = ! empty( $_REQUEST['state_id'] ) ? $_REQUEST['state_id'] : '';
1476
-
1477
- if ( ! $field_id || ! $nonce || ( ! $listing_id && ! $state_id ) ) {
1478
- die;
1479
- }
1480
-
1481
- $state_challenge = $listing_id ? ( 'listing_id-' . $listing_id ) : ( 'state_id-' . $state_id );
1482
- if ( ! wp_verify_nonce( $nonce, 'wpbdp-file-field-upload-' . $field_id . '-' . $state_challenge ) ) {
1483
- die;
1484
- }
1485
-
1486
- $field = wpbdp_get_form_field( $field_id );
1487
- if ( ! $field || 'image' != $field->get_field_type_id() ) {
1488
- die;
1489
- }
1490
-
1491
- echo '<form action="" method="POST" enctype="multipart/form-data">';
1492
- echo '<input type="file" name="file" class="file-upload" onchange="return window.parent.WPBDP.fileUpload.handleUpload(this);"/>';
1493
- echo '</form>';
1494
-
1495
- if ( isset($_FILES['file']) && $_FILES['file']['error'] == 0 ) {
1496
- // TODO: we support only images for now but we could use this for anything later
1497
- if ( $media_id = wpbdp_media_upload( $_FILES['file'],
1498
- true,
1499
- true,
1500
- array( 'image' => true,
1501
- 'min-size' => intval( wpbdp_get_option( 'image-min-filesize' ) ) * 1024,
1502
- 'max-size' => intval( wpbdp_get_option( 'image-max-filesize' ) ) * 1024,
1503
- 'min-width' => wpbdp_get_option( 'image-min-width' ),
1504
- 'min-height' => wpbdp_get_option( 'image-min-height' )
1505
- ),
1506
- $errors ) ) {
1507
- echo '<div class="preview" style="display: none;">';
1508
- echo wp_get_attachment_image( $media_id, 'thumb', false );
1509
- echo '</div>';
1510
-
1511
- echo '<script type="text/javascript">';
1512
- echo sprintf( 'window.parent.WPBDP.fileUpload.finishUpload(%d, %d);', $field_id, $media_id );
1513
- echo '</script>';
1514
- } else {
1515
- print $errors;
1516
- }
1517
- }
1518
-
1519
- echo sprintf( '<script type="text/javascript">window.parent.WPBDP.fileUpload.resizeIFrame(%d);</script>', $field_id );
1520
-
1521
- exit;
1522
- }
1523
-
1524
- /* Listing expiration. */
1525
- public function _notify_expiring_listings() {
1526
- if ( wpbdp_get_option( 'payment-abandonment' ) )
1527
- $this->payments->notify_abandoned_payments();
1528
-
1529
- wpbdp_log('Running expirations hook.');
1530
-
1531
- $now = current_time( 'timestamp' );
1532
-
1533
- $api = wpbdp_listings_api();
1534
- $api->notify_expiring_listings( 0, $now ); // notify already expired listings first
1535
-
1536
- if ( ! wpbdp_get_option( 'listing-renewal' ) )
1537
- return;
1538
-
1539
- $api->notify_expiring_listings( wpbdp_get_option( 'renewal-email-threshold', 5 ), $now ); // notify listings expiring soon
1540
-
1541
- if ( wpbdp_get_option( 'renewal-reminder' ) ) {
1542
- $threshold = -max( 1, intval( wpbdp_get_option( 'renewal-reminder-threshold' ) ) );
1543
- $api->notify_expiring_listings( $threshold, $now );
1544
- }
1545
- }
1546
-
1547
- // {{ Sorting options.
1548
- public function sortbar_sort_options( $options ) {
1549
- $sortbar_fields = $this->settings->sortbar_fields_cb();
1550
- $sortbar = wpbdp_get_option( 'listings-sortbar-fields' );
1551
-
1552
- foreach ( $sortbar as $field_id ) {
1553
- if ( ! array_key_exists( $field_id, $sortbar_fields ) )
1554
- continue;
1555
- $options[ 'field-' . $field_id ] = array( $sortbar_fields[ $field_id ], '', 'ASC' );
1556
- }
1557
-
1558
- return $options;
1559
- }
1560
-
1561
- public function sortbar_query_fields( $fields ) {
1562
- global $wpdb;
1563
-
1564
- $sort = wpbdp_get_current_sort_option();
1565
-
1566
- if ( ! $sort || ! in_array( str_replace( 'field-', '', $sort->option ), wpbdp_get_option( 'listings-sortbar-fields' ) ) )
1567
- return $fields;
1568
-
1569
- $sname = str_replace( 'field-', '', $sort->option );
1570
- $q = '';
1571
-
1572
- switch ( $sname ) {
1573
- case 'user_login':
1574
- $q = "(SELECT user_login FROM {$wpdb->users} WHERE {$wpdb->users}.ID = {$wpdb->posts}.post_author) AS user_login";
1575
- break;
1576
- case 'user_registered':
1577
- $q = "(SELECT user_registered FROM {$wpdb->users} WHERE {$wpdb->users}.ID = {$wpdb->posts}.post_author) AS user_registered";
1578
- break;
1579
- case 'date':
1580
- case 'modified':
1581
- break;
1582
- default:
1583
- $field = wpbdp_get_form_field( $sname );
1584
-
1585
- if ( ! $field || 'meta' != $field->get_association() )
1586
- break;
1587
-
1588
- $q = $wpdb->prepare( "(SELECT {$wpdb->postmeta}.meta_value FROM {$wpdb->postmeta} WHERE {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID AND {$wpdb->postmeta}.meta_key = %s) AS field_{$sname}", '_wpbdp[fields][' . $field->get_id() . ']' );
1589
- break;
1590
- }
1591
-
1592
- if ( $q )
1593
- return $fields . ', ' . $q;
1594
- else
1595
- return $fields;
1596
- }
1597
-
1598
- public function sortbar_orderby( $orderby ) {
1599
- global $wpdb;
1600
-
1601
- $sort = wpbdp_get_current_sort_option();
1602
-
1603
- if ( ! $sort || ! in_array( str_replace( 'field-', '', $sort->option ), wpbdp_get_option( 'listings-sortbar-fields' ) ) )
1604
- return $orderby;
1605
-
1606
- $sname = str_replace( 'field-', '', $sort->option );
1607
- $qn = '';
1608
-
1609
- switch ( $sname ) {
1610
- case 'user_login':
1611
- case 'user_registered':
1612
- $qn = $sname;
1613
- break;
1614
- case 'date':
1615
- case 'modified':
1616
- $qn = "{$wpdb->posts}.post_{$sname}";
1617
- break;
1618
- default:
1619
- $field = wpbdp_get_form_field( $sname );
1620
-
1621
- if ( ! $field )
1622
- break;
1623
-
1624
- switch ( $field->get_association() ) {
1625
- case 'title':
1626
- case 'excerpt':
1627
- case 'content':
1628
- $qn = "{$wpdb->posts}.post_" . $field->get_association();
1629
- break;
1630
- case 'meta':
1631
- $qn = "field_{$sname}";
1632
- break;
1633
- }
1634
-
1635
- break;
1636
- }
1637
-
1638
- if ( $qn )
1639
- return $orderby . ', ' . $qn . ' ' . $sort->order;
1640
- else
1641
- return $orderby;
1642
- }
1643
- // }}
1644
-
1645
- public function frontend_manual_upgrade_msg() {
1646
- wp_enqueue_style( 'wpbdp-base-css' );
1647
-
1648
- if ( current_user_can( 'administrator' ) ) {
1649
- return wpbdp_render_msg(
1650
- str_replace(
1651
- '<a>',
1652
- '<a href="' . admin_url( 'admin.php?page=wpbdp-upgrade-page' ) . '">',
1653
- __( 'The directory features are disabled at this time because a <a>manual upgrade</a> is pending.', 'WPBDM' )
1654
- ),
1655
- 'error'
1656
- );
1657
- }
1658
-
1659
- return wpbdp_render_msg(
1660
- __( 'The directory is not available at this time. Please try again in a few minutes or contact the administrator if the problem persists.', 'WPBDM' ),
1661
- 'error'
1662
- );
1663
  }
1664
 
 
1665
  }
1666
 
1667
- $wpbdp = new WPBDP_Plugin();
 
 
3
  * Plugin Name: Business Directory Plugin
4
  * Plugin URI: http://www.businessdirectoryplugin.com
5
  * Description: Provides the ability to maintain a free or paid business directory on your WordPress powered site.
6
+ * Version: 5.0
7
  * Author: D. Rodenbaugh
8
+ * Author URI: https://businessdirectoryplugin.com
9
  * Text Domain: WPBDM
10
  * Domain Path: /languages/
11
  * License: GPLv2 or any later version
12
+ *
13
+ *
14
+ * Copyright 2009-2016, Skyline Consulting and D. Rodenbaugh
15
+ *
16
+ * This program is free software; you can redistribute it and/or modify
17
+ * it under the terms of the GNU General Public License, version 2 or later, as
18
+ * published by the Free Software Foundation.
19
+ *
20
+ * This program is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License
26
+ * along with this program; if not, write to the Free Software
27
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
  */
29
 
30
+ // Do not allow direct access to this file.
31
+ if ( ! defined( 'ABSPATH' ) ) {
32
+ exit;
33
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
+ if ( ! defined( 'WPBDP_PLUGIN_FILE' ) ) {
36
+ define( 'WPBDP_PLUGIN_FILE', __FILE__ );
37
+ }
38
 
39
+ if ( ! class_exists( 'WPBDP' ) ) {
40
+ require_once( dirname( WPBDP_PLUGIN_FILE ) . '/includes/class-wpbdp.php' );
41
+ }
42
 
43
  /**
44
+ * Returns the main instance of Business Directory.
45
+ * @return WPBDP
46
  */
47
+ function wpbdp() {
48
+ static $instance = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ if ( is_null( $instance ) ) {
51
+ $instance = new WPBDP();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
+ return $instance;
55
  }
56
 
57
+
58
+ // For backwards compatibility.
59
+ $GLOBALS['wpbdp'] = wpbdp();
includes/admin/admin-pages.php CHANGED
@@ -1,19 +1,77 @@
1
  <?php
2
  function wpbdp_admin_sidebar() {
3
- return wpbdp_render_page(WPBDP_PATH . 'templates/admin/sidebar.tpl.php');
4
  }
5
 
6
- function wpbdp_admin_header($title_ = null, $id = null, $h2items =array(), $sidebar = true) {
7
- global $title;
 
 
8
 
9
- if (!$title_) $title_ = $title;
10
- return wpbdp_render_page( WPBDP_PATH . 'templates/admin/header.tpl.php', array( 'page_title' => $title_, 'page_id' => $id, 'h2items' => $h2items, 'sidebar' => $sidebar ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
12
 
13
 
14
- function wpbdp_admin_footer()
15
- {
16
- $html = '<!--</div>--></div><br class="clear" /></div>';
17
- return $html;
 
 
18
  }
19
 
1
  <?php
2
  function wpbdp_admin_sidebar() {
3
+ return wpbdp_render_page( WPBDP_PATH . 'templates/admin/sidebar.tpl.php' );
4
  }
5
 
6
+ function wpbdp_admin_header( $args_or_title = null, $id = null, $h2items = array(), $sidebar = null ) {
7
+ // For backwards compatibility.
8
+ if ( empty( $args_or_title ) || is_string( $args_or_title ) ) {
9
+ $buttons = array();
10
 
11
+ if ( $h2items ) {
12
+ foreach ( $h2items as $item ) {
13
+ $buttons[ $item[0] ] = $item[1];
14
+ }
15
+ }
16
+
17
+ $args_or_title = array(
18
+ 'title' => $args_or_title,
19
+ 'id' => $id,
20
+ 'buttons' => $buttons,
21
+ 'sidebar' => $sidebar
22
+ );
23
+
24
+ if ( empty( $args_or_title['title'] ) ) {
25
+ unset( $args_or_title['title'] );
26
+ }
27
+
28
+ if ( empty( $args_or_title['id'] ) ) {
29
+ unset( $args_or_title['id'] );
30
+ }
31
+
32
+ if ( is_null( $args_or_title['sidebar'] ) ) {
33
+ unset( $args_or_title['sidebar'] );
34
+ }
35
+ }
36
+
37
+ $defaults = array(
38
+ 'title' => ! empty( $GLOBALS['title'] ) ? $GLOBALS['title'] : '',
39
+ 'id' => ! empty( $_GET['page'] ) ? $_GET['page'] : '',
40
+ 'buttons' => array(),
41
+ 'sidebar' => true
42
+ );
43
+
44
+ $args = wp_parse_args( $args_or_title, $defaults);
45
+ extract( $args );
46
+
47
+ $id = str_replace( array( 'wpbdp_', 'wpbdp-' ), '', $id );
48
+ $id = str_replace( array( 'admin-', 'admin_' ), '', $id );
49
+
50
+ ob_start();
51
+ ?>
52
+ <div class="wrap wpbdp-admin wpbdp-admin-page wpbdp-admin-page-<?php echo $id; ?>" id="wpbdp-admin-page-<?php echo $id; ?>">
53
+ <div id="icon-edit-pages" class="icon32"></div>
54
+ <h1>
55
+ <?php echo $title; ?>
56
+
57
+ <?php foreach ( $buttons as $label => $url ): ?>
58
+ <a href="<?php echo $url; ?>" class="add-new-h2"><?php echo $label; ?></a>
59
+ <?php endforeach; ?>
60
+ </h1>
61
+
62
+ <?php echo $sidebar = $sidebar ? wpbdp_admin_sidebar() : ''; ?>
63
+
64
+ <div class="wpbdp-admin-content <?php echo ! empty( $sidebar ) ? 'with-sidebar' : 'without-sidebar'; ?>">
65
+ <?php
66
+ return ob_get_clean();
67
  }
68
 
69
 
70
+ function wpbdp_admin_footer() {
71
+ ob_start();
72
+ ?>
73
+ </div><br class="clear" /></div>
74
+ <?php
75
+ return ob_get_clean();
76
  }
77
 
includes/admin/class-admin-controller.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Admin__Controller {
6
+
7
+ protected $controller_id = '';
8
+ protected $wpbdp;
9
+ protected $current_view = '';
10
+
11
+
12
+ function __construct() {
13
+ $this->wpbdp = $GLOBALS['wpbdp'];
14
+ $this->controller_id = str_replace( 'wpbdp__admin__', '', WPBDP_Utils::normalize( get_class( $this ) ) );
15
+ }
16
+
17
+ function _enqueue_scripts() {
18
+ if ( file_exists( WPBDP_PATH . 'assets/js/admin-' . $this->controller_id . '.js' ) )
19
+ wp_enqueue_script( 'wpbdp-' . $this->controller_id . '-js', WPBDP_URL . 'assets/js/admin-' . $this->controller_id . '.js', array( 'wpbdp-admin-js' ) );
20
+ }
21
+
22
+ function _ajax_dispatch() {
23
+ $handler = ! empty( $_REQUEST['handler'] ) ? trim( $_REQUEST['handler'] ) : '';
24
+ $parts = explode( '__', $handler );
25
+ $controller_id = $parts[0];
26
+ $function = isset( $parts[1] ) ? $parts[1] : '';
27
+
28
+ if ( method_exists( $this, 'ajax_' . $function ) )
29
+ return call_user_func( array( $this, 'ajax_' . $function ) );
30
+ }
31
+
32
+ function _dispatch() {
33
+ if ( empty( $this->current_view ) )
34
+ $this->current_view = isset( $_GET['wpbdp-view'] ) ? $_GET['wpbdp-view'] : 'index';
35
+
36
+ $this->current_view = WPBDP_Utils::normalize( $this->current_view );
37
+
38
+ $result = false;
39
+ $output = '';
40
+
41
+ $callback = ( false !== strpos( $this->current_view, '-' ) ? str_replace( '-', '_', $this->current_view ) : $this->current_view );
42
+
43
+ // Remove query args.
44
+ $orig_uri = $_SERVER['REQUEST_URI'];
45
+ $_SERVER['REQUEST_URI'] = remove_query_arg( array( 'wpbdp-view', 'id' ), $_SERVER['REQUEST_URI'] );
46
+
47
+ if ( method_exists( $this, $callback ) )
48
+ $result = call_user_func( array( $this, $callback ) );
49
+
50
+ if ( is_array( $result ) ) {
51
+ $template = WPBDP_PATH . 'templates/admin/' . $this->controller_id . '-' . $this->current_view . '.tpl.php';
52
+
53
+ if ( ! file_exists( $template ) )
54
+ $output = json_encode( $result );
55
+ else
56
+ $output = wpbdp_render_page( $template, $result );
57
+ } else {
58
+ $output = $result;
59
+ }
60
+
61
+ $_SERVER['REQUEST_URI'] = $orig_uri;
62
+
63
+ echo $output;
64
+ }
65
+
66
+ function _redirect( $view_or_url ) {
67
+ $this->current_view = $view_or_url;
68
+ return $this->_dispatch();
69
+ }
70
+
71
+ function _confirm_action( $args = array() ) {
72
+ $defaults = array(
73
+ 'title' => _x( 'Are you sure you want to do this?', 'admin confirm', 'WPBDM' ),
74
+ 'cancel_url' => '',
75
+ 'cancel_text' => _x( 'No, go back', 'admin confirm', 'WPBDM' ),
76
+ 'submit_text' => _x( 'Yes, I\'m sure', 'admin confirm', 'WPBDM' ),
77
+ 'explanation' => ''
78
+ );
79
+ $args = wp_parse_args( $args, $defaults );
80
+ $nonce = ! empty( $_POST['_wpnonce'] ) ? $_POST['_wpnonce'] : '';
81
+
82
+ if ( $nonce && wp_verify_nonce( $nonce, 'confirm ' . md5( $args['title'] ) ) )
83
+ return array( true, '' );
84
+
85
+ return array( false, wpbdp_render_page( WPBDP_PATH . 'templates/admin/confirm-page.tpl.php', $args ) );
86
+ }
87
+
88
+ }
includes/admin/class-admin-csv.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Admin__Csv extends WPBDP__Admin__Controller {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+
8
+ require_once( WPBDP_INC . 'admin/csv-import.php' );
9
+ $this->csv_import = new WPBDP_CSVImportAdmin();
10
+
11
+ require_once( WPBDP_INC . 'admin/csv-export.php' );
12
+ $this->csv_export = new WPBDP_Admin_CSVExport();
13
+ }
14
+
15
+ public function _dispatch() {
16
+ $tabs = array( 'csv_import', 'csv_export' );
17
+
18
+ if ( ! empty( $_GET['tab'] ) ) {
19
+ $current_tab = $_GET['tab'];
20
+ } else {
21
+ $current_tab = 'csv_import';
22
+ }
23
+
24
+ if ( ! in_array( $current_tab, $tabs ) ) {
25
+ wp_die();
26
+ }
27
+
28
+ ob_start();
29
+ call_user_func( array( $this->{$current_tab}, 'dispatch' ) );
30
+ $output = ob_get_clean();
31
+
32
+ echo wpbdp_admin_header();
33
+ echo wpbdp_admin_notices();
34
+ ?>
35
+
36
+ <?php if ( 'csv_import' == $current_tab ): ?>
37
+ <div class="wpbdp-csv-import-top-buttons">
38
+ <a href="<?php echo esc_url(add_query_arg('action', 'example-csv')); ?>" class="button"><?php _ex('See an example CSV import file', 'admin csv-import', 'WPBDM'); ?></a>
39
+ <a href="#help" class="button"><?php _ex('Help', 'admin csv-import', 'WPBDM'); ?></a>
40
+ </div>
41
+ <?php endif; ?>
42
+
43
+
44
+ <h2 class="nav-tab-wrapper">
45
+ <a class="nav-tab <?php echo 'csv_import' == $current_tab ? 'nav-tab-active' : ''; ?>" href="<?php echo esc_url( add_query_arg( 'tab', 'csv_import' ) ); ?>"><span class="dashicons dashicons-upload"></span> <?php _ex( 'Import', 'admin csv', 'WPBDM' ); ?></a>
46
+ <a class="nav-tab <?php echo 'csv_export' == $current_tab ? 'nav-tab-active' : ''; ?>" href="<?php echo esc_url( add_query_arg( 'tab', 'csv_export' ) ); ?>"><span class="dashicons dashicons-download"></span> <?php _ex( 'Export', 'admin csv', 'WPBDM' ); ?></a>
47
+ </h2>
48
+ <?php
49
+ echo $output;
50
+ echo wpbdp_admin_footer();
51
+ }
52
+
53
+ }
54
+
includes/admin/class-admin-listings.php CHANGED
@@ -4,21 +4,23 @@ class WPBDP_Admin_Listings {
4
 
5
  function __construct() {
6
  add_action('admin_init', array($this, 'add_metaboxes'));
7
- add_action( 'wpbdp_admin_notices', array( $this, 'no_category_edit_notice' ) );
8
 
9
- add_action( 'manage_' . WPBDP_POST_TYPE . '_posts_columns', array( &$this, 'add_columns' ) );
10
  add_action( 'manage_' . WPBDP_POST_TYPE . '_posts_custom_column', array( &$this, 'listing_column' ), 10, 2 );
 
11
 
12
  add_filter( 'views_edit-' . WPBDP_POST_TYPE, array( &$this, 'listing_views' ) );
13
  add_filter( 'posts_clauses', array( &$this, 'listings_admin_filters' ) );
14
 
15
  add_filter( 'post_row_actions', array( &$this, 'row_actions' ), 10, 2 );
16
 
17
- add_action( 'save_post', array( &$this, 'save_post' ), 10, 2 );
18
-
19
  add_action('admin_footer', array($this, '_add_bulk_actions'));
20
  add_action('admin_footer', array($this, '_fix_new_links'));
21
 
 
 
 
22
  // Filter by category.
23
  add_action( 'restrict_manage_posts', array( &$this, '_add_category_filter' ) );
24
  add_action( 'parse_query', array( &$this, '_apply_category_filter' ) );
@@ -110,7 +112,7 @@ class WPBDP_Admin_Listings {
110
  return $pieces;
111
  }
112
 
113
- function no_category_edit_notice() {
114
  if ( ! function_exists( 'get_current_screen' ) )
115
  return;
116
 
@@ -129,46 +131,75 @@ class WPBDP_Admin_Listings {
129
  if ( ! $listing )
130
  return;
131
 
132
- if( ! $listing->get_categories( 'all' ) )
133
- wpbdp_admin_message( _x( 'This listing doesn\'t have any category assigned. At least one category (and its respective fee) is required in order to determine the features available to this listing, as well as handling renewals.', 'admin listings', 'WPBDM' ), 'error' );
134
  }
135
 
136
  function add_metaboxes() {
137
- add_meta_box( 'BusinessDirectory_listinginfo',
138
  __( 'Listing Information', 'WPBDM' ),
139
- array( 'WPBDP_Admin_Listing_Metabox', 'metabox_callback' ),
 
 
 
 
 
 
140
  WPBDP_POST_TYPE,
141
  'side',
142
  'core' );
143
-
144
  add_meta_box( 'wpbdp-listing-fields',
145
- _x( 'Listing Fields / Images', 'admin', 'WPBDM' ),
146
  array( 'WPBDP_Admin_Listing_Fields_Metabox', 'metabox_callback' ),
147
  WPBDP_POST_TYPE,
148
  'normal',
149
  'core' );
150
  }
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  // {{{ Custom columns.
153
 
154
- function add_columns( $columns_ ) {
155
- $custom_columns = array();
156
- $custom_columns['category'] = _x( 'Categories', 'admin', 'WPBDM' );
157
- $custom_columns['payment_status'] = __( 'Payment Status', 'WPBDM' );
158
- $custom_columns['sticky_status'] = __( 'Featured (Sticky) Status', 'WPBDM' );
159
 
160
- $columns = array();
161
 
162
- foreach ( $columns_ as $k => $v ) {
163
- $columns[ $k ] = $v;
 
 
 
 
 
 
164
 
165
- if ( 'title' == $k )
166
- $columns = array_merge( $columns, $custom_columns );
167
  }
168
 
169
- return apply_filters( 'wpbdp_admin_directory_columns', $columns );
 
 
 
 
170
  }
171
 
 
 
 
 
172
 
173
  function listing_column( $column, $post_id ) {
174
  if ( ! method_exists( $this, 'listing_column_' . $column ) )
@@ -178,168 +209,152 @@ class WPBDP_Admin_Listings {
178
  }
179
 
180
  function listing_column_category( $post_id ) {
181
- $listing = WPBDP_Listing::get( $post_id );
182
- $categories = $listing->get_categories( 'all' );
183
-
184
- $i = 0;
185
- foreach ( $categories as &$category ) {
186
- print $category->expired ? '<s>' : '';
187
- printf( '<a href="%s" title="%s">%s</a>',
188
- get_term_link( $category->id, WPBDP_CATEGORY_TAX ),
189
- $category->expired ? _x( '(Listing expired in this category)', 'admin', 'WPBDM' ) : '',
190
- $category->name );
191
- print $category->expired ? '</s>' : '';
192
- print ( ( $i + 1 ) != count( $categories ) ? ', ' : '' );
193
-
194
- $i++;
195
  }
196
  }
197
 
198
- function listing_column_payment_status( $post_id ) {
199
- $listing = WPBDP_Listing::get( $post_id );
200
- $paid_status = $listing->get_payment_status();
201
 
202
- $status_links = '';
 
 
203
 
204
- if ( $paid_status != 'ok' )
205
- $status_links .= sprintf('<span><a href="%s">%s</a></span>',
206
- esc_url( add_query_arg( array( 'wpbdmaction' => 'setaspaid', 'post' => $post_id ) ) ),
207
- __('Paid', 'WPBDM'));
 
208
 
209
- printf( '<span class="tag paymentstatus %s">%s</span>', $paid_status, strtoupper( $paid_status ) );
 
 
210
 
211
- if ( $status_links && current_user_can( 'administrator' ) )
212
- printf( '<div class="row-actions"><b>%s:</b> %s</div>', __( 'Mark as', 'WPBDM' ), $status_links );
 
 
213
  }
214
 
215
- function listing_column_sticky_status( $post_id ) {
216
- $upgrades_api = wpbdp_listing_upgrades_api();
217
- $sticky_info = $upgrades_api->get_info( $post_id );
218
 
219
- echo sprintf('<span class="tag status %s">%s</span><br />',
220
- str_replace(' ', '', $sticky_info->status),
221
- $sticky_info->pending ? __('Pending Upgrade', 'WPBDM') : esc_attr($sticky_info->level->name) );
222
 
223
- echo '<div class="row-actions">';
 
 
224
 
225
- if ( current_user_can('administrator') ) {
226
- if ( $sticky_info->upgradeable ) {
227
- echo sprintf('<span><a href="%s">%s</a></span>',
228
- esc_url( add_query_arg(array('wpbdmaction' => 'changesticky', 'u' => $sticky_info->upgrade->id, 'post' => $post_id)) ),
229
- '<b>↑</b> ' . sprintf(__('Upgrade to %s', 'WPBDM'), esc_attr($sticky_info->upgrade->name)) );
230
- echo '<br />';
231
- }
232
 
233
- if ( $sticky_info->downgradeable ) {
234
- echo sprintf('<span><a href="%s">%s</a></span>',
235
- esc_url( add_query_arg(array('wpbdmaction' => 'changesticky', 'u' => $sticky_info->downgrade->id, 'post' => $post_id)) ),
236
- '<b>↓</b> ' . sprintf(__('Downgrade to %s', 'WPBDM'), esc_attr($sticky_info->downgrade->name)) );
237
- }
238
- } elseif ( current_user_can('contributor') && wpbdp_user_can( 'upgrade-to-sticky', $post_id ) ) {
239
- echo sprintf('<span><a href="%s"><b>↑</b> %s</a></span>', wpbdp_get_page_link('upgradetostickylisting', $post_id), _x('Upgrade to Featured', 'admin actions', 'WPBDM'));
 
 
 
 
 
 
240
  }
241
 
242
- echo '</div>';
243
 
 
 
244
  }
245
 
 
246
  // }}}
247
 
248
  // {{{ List views.
249
 
250
- function listing_views( $views ) {
251
  global $wpdb;
252
 
253
  if ( ! current_user_can( 'administrator' ) && ! current_user_can( 'editor' ) ) {
254
- if ( current_user_can( 'contributor' ) && isset( $views['mine'] ) )
255
- return array( $views['mine'] );
256
 
257
  return array();
258
  }
259
 
260
  $post_statuses = '\'' . join('\',\'', isset($_GET['post_status']) ? array($_GET['post_status']) : array('publish', 'draft', 'pending')) . '\'';
261
 
262
- // $unpaid = $wpdb->get_var( $wpdb->prepare(
263
- // "SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->posts} p LEFT JOIN {$wpdb->prefix}wpbdp_payments ps ON p.ID = ps.listing_id
264
- // WHERE p.post_type = %s AND p.post_status IN ({$post_statuses}) AND ps.status = %s",
265
- // WPBDP_POST_TYPE,
266
- // 'pending'
267
- // ) );
268
- $unpaid = $wpdb->get_var( $wpdb->prepare(
269
- "SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->posts} p LEFT JOIN {$wpdb->prefix}wpbdp_payments ps
270
- ON (ps.listing_id = p.ID AND ps.status = %s) WHERE p.post_type = %s
271
- AND p.post_status IN ({$post_statuses}) AND ps.status IS NOT NULL",
272
- 'pending',
273
- WPBDP_POST_TYPE ) );
274
-
275
- $paid = intval( $wpdb->get_var( $wpdb->prepare(
276
- "SELECT COUNT(*) FROM {$wpdb->posts} p WHERE p.post_type = %s AND p.post_status IN ({$post_statuses})",
277
- WPBDP_POST_TYPE ) ) ) - $unpaid;
278
-
279
- $pending_upgrade = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm ON (p.ID = pm.post_id)
280
- WHERE p.post_type = %s AND p.post_status IN ({$post_statuses}) AND ( (pm.meta_key = %s AND pm.meta_value = %s) )",
281
- WPBDP_POST_TYPE,
282
- '_wpbdp[sticky]',
283
- 'pending') );
284
- $expired = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->posts} p INNER JOIN {$wpdb->prefix}wpbdp_listing_fees lf ON lf.listing_id = p.ID WHERE lf.expires_on < %s",
285
- current_time( 'mysql' ) ) );
286
-
287
- $views['paid'] = sprintf('<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
288
- esc_url( add_query_arg('wpbdmfilter', 'paid', remove_query_arg('post')) ),
289
- wpbdp_getv($_REQUEST, 'wpbdmfilter') == 'paid' ? 'current' : '',
290
- __('Paid', 'WPBDM'),
291
- number_format_i18n($paid));
292
- $views['unpaid'] = sprintf('<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
293
- esc_url( add_query_arg('wpbdmfilter', 'unpaid', remove_query_arg('post')) ),
294
- wpbdp_getv($_REQUEST, 'wpbdmfilter') == 'unpaid' ? 'current' : '',
295
- __('Unpaid', 'WPBDM'),
296
- number_format_i18n($unpaid));
297
- $views['featured'] = sprintf('<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
298
- esc_url( add_query_arg('wpbdmfilter', 'pendingupgrade', remove_query_arg('post')) ),
299
- wpbdp_getv($_REQUEST, 'wpbdmfilter') == 'pendingupgrade' ? 'current' : '',
300
- __('Pending Upgrade', 'WPBDM'),
301
- number_format_i18n($pending_upgrade));
302
- $views['expired'] = sprintf( '<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
303
- esc_url( add_query_arg( 'wpbdmfilter', 'expired', remove_query_arg( 'post' ) ) ),
304
- wpbdp_getv( $_REQUEST, 'wpbdmfilter' ) == 'expired' ? 'current' : '' ,
305
- _x( 'Expired', 'admin', 'WPBDM' ),
306
- number_format_i18n( $expired )
307
- );
308
 
309
  $views = apply_filters( 'wpbdp_admin_directory_views', $views, $post_statuses );
 
 
 
 
 
310
 
311
  return $views;
312
  }
313
 
314
- function listings_admin_filters( $pieces ) {
315
  global $wpdb;
316
 
317
- if ( ! is_admin() || ! isset( $_REQUEST['wpbdmfilter'] ) || ! function_exists( 'get_current_screen' ) || ! get_current_screen() || 'edit-' . WPBDP_POST_TYPE != get_current_screen()->id )
318
  return $pieces;
319
 
320
- switch ( $_REQUEST['wpbdmfilter'] ) {
321
- case 'expired':
322
- $pieces['join'] = " LEFT JOIN {$wpdb->prefix}wpbdp_listing_fees ON {$wpdb->prefix}wpbdp_listing_fees.listing_id = {$wpdb->posts}.ID ";
323
- $pieces['where'] = $wpdb->prepare( " AND {$wpdb->prefix}wpbdp_listing_fees.expires_on IS NOT NULL AND {$wpdb->prefix}wpbdp_listing_fees.expires_on < %s ", current_time( 'mysql' ) );
324
- $pieces['groupby'] = " {$wpdb->posts}.ID ";
325
- break;
326
- case 'pendingupgrade':
327
- $pieces['join'] = " LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = {$wpdb->posts}.ID ";
328
- $pieces['where'] = $wpdb->prepare( " AND pm.meta_key = %s AND pm.meta_value = %s ", '_wpbdp[sticky]', 'pending' );
329
- break;
330
- case 'paid':
331
- $pieces['where'] .= $wpdb->prepare( " AND NOT EXISTS ( SELECT 1 FROM {$wpdb->prefix}wpbdp_payments WHERE {$wpdb->posts}.ID = {$wpdb->prefix}wpbdp_payments.listing_id AND ( {$wpdb->prefix}wpbdp_payments.status IS NULL OR {$wpdb->prefix}wpbdp_payments.status != %s ) )", 'completed' );
332
- break;
333
- case 'unpaid':
334
- $pieces['join'] .= " LEFT JOIN {$wpdb->prefix}wpbdp_payments ON {$wpdb->posts}.ID = {$wpdb->prefix}wpbdp_payments.listing_id ";
335
- $pieces['where'] .= $wpdb->prepare( " AND {$wpdb->prefix}wpbdp_payments.status = %s ", 'pending' );
336
- $pieces['groupby'] .= " {$wpdb->posts}.ID ";
337
- break;
338
- default:
339
- $pieces = apply_filters( 'wpbdp_admin_directory_filter', $pieces, $_REQUEST['wpbdmfilter'] );
340
- break;
341
  }
342
 
 
 
 
343
  return $pieces;
344
  }
345
 
@@ -347,7 +362,10 @@ class WPBDP_Admin_Listings {
347
 
348
 
349
  public function row_actions($actions, $post) {
350
- if ($post->post_type == WPBDP_POST_TYPE && current_user_can('contributor') && ! current_user_can( 'administrator' ) ) {
 
 
 
351
  if (wpbdp_user_can('edit', $post->ID))
352
  $actions['edit'] = sprintf('<a href="%s">%s</a>',
353
  wpbdp_url( 'edit_listing', $post->ID ),
@@ -357,51 +375,116 @@ class WPBDP_Admin_Listings {
357
  $actions['delete'] = sprintf( '<a href="%s">%s</a>', wpbdp_url( 'delete_listing', $post->ID ), _x( 'Delete Listing', 'admin actions', 'WPBDM' ) );
358
  }
359
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  return $actions;
361
  }
362
 
363
- public function save_post( $post_id, $post) {
364
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
 
 
 
365
  return;
366
 
367
- // Handle listings saved admin-side.
368
- if ( is_admin() && isset( $_REQUEST['post_type'] ) && $_REQUEST['post_type'] == WPBDP_POST_TYPE ) {
369
- $listing = WPBDP_Listing::get( $post_id );
370
 
371
- if ( ! $listing )
372
- return;
373
 
374
- $listing->fix_categories( true );
 
 
 
 
 
 
 
 
375
 
376
- // Save custom fields.
377
- $nonce = isset( $_POST['wpbdp-admin-listing-fields-nonce'] ) ? $_POST['wpbdp-admin-listing-fields-nonce'] : '';
378
 
379
- if ( $nonce && wp_verify_nonce( $nonce, 'save listing fields' ) && ! empty( $_POST['listingfields'] ) ) {
380
- $fields = wpbdp_get_form_fields( array( 'association' => 'meta' ) );
 
381
 
382
- foreach ( $fields as $field ) {
383
- if ( isset( $_POST['listingfields'][ $field->get_id() ] ) ) {
384
- $value = $field->convert_input( $_POST['listingfields'][ $field->get_id() ] );
385
- $field->store_value( $post_id, $value );
386
- } else {
387
- $field->store_value( $post_id, $field->convert_input( null ) );
388
- }
389
- }
390
 
391
- if ( isset( $_POST['thumbnail_id'] ) )
392
- $listing->set_thumbnail_id( $_POST['thumbnail_id'] );
 
 
 
 
393
 
394
- // Images info.
395
- if ( isset( $_POST['images_meta'] ) ) {
396
- $meta = $_POST['images_meta'];
 
 
 
397
 
398
- foreach ( $meta as $img_id => $img_meta ) {
399
- update_post_meta( $img_id, '_wpbdp_image_weight', absint( $img_meta[ 'order' ] ) );
400
- update_post_meta( $img_id, '_wpbdp_image_caption', strval( $img_meta[ 'caption' ] ) );
401
- }
402
- }
403
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  }
406
  }
407
 
@@ -418,8 +501,6 @@ class WPBDP_Admin_Listings {
418
  'upgradefeatured' => _x('Upgrade to Featured', 'admin actions', 'WPBDM'),
419
  'cancelfeatured' => _x('Downgrade to Normal', 'admin actions', 'WPBDM'),
420
  'sep2' => '--',
421
- 'setaspaid' => _x('Mark as Paid', 'admin actions', 'WPBDM'),
422
- 'sep3' => '--',
423
  'renewlisting' => _x( 'Renew Listing', 'admin actions', 'WPBDM' )
424
  );
425
  $bulk_actions = apply_filters( 'wpbdp_admin_directory_bulk_actions', $bulk_actions );
4
 
5
  function __construct() {
6
  add_action('admin_init', array($this, 'add_metaboxes'));
7
+ add_action( 'wpbdp_admin_notices', array( $this, 'no_plan_edit_notice' ) );
8
 
9
+ add_action( 'manage_' . WPBDP_POST_TYPE . '_posts_columns', array( &$this, 'modify_columns' ) );
10
  add_action( 'manage_' . WPBDP_POST_TYPE . '_posts_custom_column', array( &$this, 'listing_column' ), 10, 2 );
11
+ add_filter( 'manage_edit-' . WPBDP_POST_TYPE . '_sortable_columns', array( &$this, 'sortable_columns' ) );
12
 
13
  add_filter( 'views_edit-' . WPBDP_POST_TYPE, array( &$this, 'listing_views' ) );
14
  add_filter( 'posts_clauses', array( &$this, 'listings_admin_filters' ) );
15
 
16
  add_filter( 'post_row_actions', array( &$this, 'row_actions' ), 10, 2 );
17
 
 
 
18
  add_action('admin_footer', array($this, '_add_bulk_actions'));
19
  add_action('admin_footer', array($this, '_fix_new_links'));
20
 
21
+ add_action( 'wpbdp_save_listing', array( $this, 'maybe_save_fields' ) );
22
+ add_action( 'wpbdp_save_listing', array( $this, 'maybe_update_plan' ) );
23
+
24
  // Filter by category.
25
  add_action( 'restrict_manage_posts', array( &$this, '_add_category_filter' ) );
26
  add_action( 'parse_query', array( &$this, '_apply_category_filter' ) );
112
  return $pieces;
113
  }
114
 
115
+ function no_plan_edit_notice() {
116
  if ( ! function_exists( 'get_current_screen' ) )
117
  return;
118
 
131
  if ( ! $listing )
132
  return;
133
 
134
+ if( ! $listing->has_fee_plan() )
135
+ wpbdp_admin_message( _x( 'This listing doesn\'t have a fee plan assigned. This is required in order to determine the features available to this listing, as well as handling renewals.', 'admin listings', 'WPBDM' ), 'error' );
136
  }
137
 
138
  function add_metaboxes() {
139
+ add_meta_box( 'wpbdp-listing-plan',
140
  __( 'Listing Information', 'WPBDM' ),
141
+ array( $this, '_metabox_listing_info' ),
142
+ WPBDP_POST_TYPE,
143
+ 'side',
144
+ 'core' );
145
+ add_meta_box( 'wpbdp-listing-timeline',
146
+ __( 'Listing Timeline', 'WPBDM' ),
147
+ array( $this, '_metabox_listing_timeline' ),
148
  WPBDP_POST_TYPE,
149
  'side',
150
  'core' );
 
151
  add_meta_box( 'wpbdp-listing-fields',
152
+ _x( 'Directory Listing Fields / Images', 'admin', 'WPBDM' ),
153
  array( 'WPBDP_Admin_Listing_Fields_Metabox', 'metabox_callback' ),
154
  WPBDP_POST_TYPE,
155
  'normal',
156
  'core' );
157
  }
158
 
159
+ public function _metabox_listing_info( $post ) {
160
+ require_once( WPBDP_PATH . 'includes/admin/helpers/class-listing-information-metabox.php' );
161
+ $metabox = new WPBDP__Admin__Metaboxes__Listing_Information( $post->ID );
162
+ echo $metabox->render();
163
+ }
164
+
165
+ public function _metabox_listing_timeline( $post ) {
166
+ require_once( WPBDP_PATH . 'includes/admin/helpers/class-listing-timeline.php' );
167
+ $timeline = new WPBDP__Listing_Timeline( $post->ID );
168
+
169
+ echo $timeline->render();
170
+ }
171
+
172
  // {{{ Custom columns.
173
 
174
+ function modify_columns( $columns ) {
175
+ // Hide comments and author column.
176
+ unset( $columns['author'], $columns['comments'] );
 
 
177
 
178
+ $new_columns = array();
179
 
180
+ foreach ( $columns as $c_key => $c_label ) {
181
+ // Insert category and expiration date after title.
182
+ if ( 'title' == $c_key ) {
183
+ $new_columns['title_'] = $c_label;
184
+ $new_columns['category'] = _x( 'Categories', 'admin', 'WPBDM' );
185
+ $new_columns['expiration_date'] = __( 'Expires on', 'WPBDM' );
186
+ continue;
187
+ }
188
 
189
+ $new_columns[ $c_key ] = $c_label;
 
190
  }
191
 
192
+ // Attributes goes last.
193
+ $new_columns['attributes'] = __( 'Attributes', 'WPBDM' );
194
+
195
+ $new_columns = apply_filters( 'wpbdp_admin_directory_columns', $new_columns );
196
+ return $new_columns;
197
  }
198
 
199
+ function sortable_columns( $columns ) {
200
+ $columns['title_'] = 'title';
201
+ return $columns;
202
+ }
203
 
204
  function listing_column( $column, $post_id ) {
205
  if ( ! method_exists( $this, 'listing_column_' . $column ) )
209
  }
210
 
211
  function listing_column_category( $post_id ) {
212
+ $terms = wp_get_post_terms( $post_id, WPBDP_CATEGORY_TAX );
213
+ foreach ( $terms as $i => $term ) {
214
+ printf( '<a href="%s">%s</a>', get_term_link( $term->term_id, WPBDP_CATEGORY_TAX ), $term->name );
215
+
216
+ if ( ( $i + 1 ) != count( $terms ) )
217
+ echo ', ';
 
 
 
 
 
 
 
 
218
  }
219
  }
220
 
221
+ function listing_column_title_( $post_id ) {
222
+ $table = _get_list_table( 'WP_Posts_List_Table' );
223
+ ob_start(); $table->column_title( get_post( $post_id ) ); $out = ob_get_clean();
224
 
225
+ $listing = wpbdp_get_listing( $post_id );
226
+ $status = apply_filters( 'wpbdp_admin_listing_display_status', array( $listing->get_status(), $listing->get_status_label() ), $listing );
227
+ $status_label = $status[1];
228
 
229
+ $html = " &mdash; <span class='post-state wpbdp-listing-status-{$status[0]}'>{$status_label}</span>";
230
+ $out = preg_replace( '/\s+&mdash;\s+(<span class=[\'"]post-state[\'"]>)(.*)(<\/span>)/uiUm', '', $out );
231
+ $out = preg_replace('/(<a.*class=[\'"]row-title[\'"].*>.*<\/a>)/uiUm', "$1 {$html}", $out );
232
+ echo $out;
233
+ }
234
 
235
+ public function listing_column_expiration_date( $post_id ) {
236
+ $listing = WPBDP_Listing::get( $post_id );
237
+ $exp_date = $listing->get_expiration_date();
238
 
239
+ if ( $exp_date )
240
+ echo date_i18n( get_option( 'date_format' ), strtotime( $exp_date ) );
241
+ else
242
+ echo _x( 'Never', 'admin listings', 'WPBDM' );
243
  }
244
 
245
+ public function listing_column_attributes( $post_id ) {
246
+ $listing = WPBDP_Listing::get( $post_id );
247
+ $plan = $listing->get_fee_plan();
248
 
249
+ $attributes = array();
 
 
250
 
251
+ foreach ( $listing->get_flags() as $f ) {
252
+ $attributes[ $f ] = '<span class="wpbdp-tag wpbdp-listing-attr-' . $f . '">' . ucwords( str_replace( '-', ' ', $f ) ) . '</span>';
253
+ }
254
 
255
+ if ( $plan ) {
256
+ if ( $plan->is_sticky )
257
+ $attributes['featured'] = '<span class="wpbdp-tag wpbdp-listing-attr-featured">' . _x( 'Featured', 'admin listings', 'WPBDM' ) . '</span>';
 
 
 
 
258
 
259
+ if ( $plan->is_recurring )
260
+ $attributes['recurring'] = '<span class="wpbdp-tag wpbdp-listing-attr-recurring">' . _x( 'Recurring', 'admin listings', 'WPBDM' ) . '</span>';
261
+
262
+ if ( 0.0 == $plan->fee_price )
263
+ $attributes['free'] = '<span class="wpbdp-tag wpbdp-listing-attr-free">' . _x( 'Free', 'admin listings', 'WPBDM' ) . '</span>';
264
+ elseif ( 'pending_payment' != $listing->get_status() )
265
+ $attributes['paid'] = '<span class="wpbdp-tag wpbdp-listing-attr-paid">' . _x( 'Paid', 'admin listings', 'WPBDM' ) . '</span>';
266
+ }
267
+
268
+ $post_status = get_post_status( $post_id );
269
+ if ( in_array( $post_status, array( 'draft', 'pending' ), true ) ) {
270
+ $post_status_trans = array( 'draft' => _x( 'Draft', 'admin listings', 'WPBDM' ), 'pending' => _x( 'Pending Review', 'admin listings', 'WPBDM' ) );
271
+ $attributes['post-status'] = '<span class="wpbdp-tag wpbdp-listing-attr-post-status-' . $post_status . '">' . $post_status_trans[ $post_status ] . '</span>';
272
  }
273
 
274
+ $attributes = apply_filters( 'wpbdp_admin_directory_listing_attributes', $attributes, $listing );
275
 
276
+ foreach ( $attributes as $attr )
277
+ echo $attr;
278
  }
279
 
280
+
281
  // }}}
282
 
283
  // {{{ List views.
284
 
285
+ function listing_views( $views_ ) {
286
  global $wpdb;
287
 
288
  if ( ! current_user_can( 'administrator' ) && ! current_user_can( 'editor' ) ) {
289
+ if ( current_user_can( 'contributor' ) && isset( $views_['mine'] ) )
290
+ return array( $views_['mine'] );
291
 
292
  return array();
293
  }
294
 
295
  $post_statuses = '\'' . join('\',\'', isset($_GET['post_status']) ? array($_GET['post_status']) : array('publish', 'draft', 'pending')) . '\'';
296
 
297
+ $stati = WPBDP_Listing::get_stati();
298
+ unset( $stati['unknown'], $stati['legacy'], $stati['incomplete'] );
299
+
300
+ // TODO: what are we going to do with regular post statuses?
301
+ $views = array();
302
+
303
+ $count = absint( $wpdb->get_var( $wpdb->prepare(
304
+ "SELECT COUNT(p.ID) FROM {$wpdb->posts} p WHERE p.post_type = %s AND p.post_status IN ({$post_statuses})",
305
+ WPBDP_POST_TYPE
306
+ ) ) );
307
+ $views['all'] = sprintf( '<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
308
+ esc_url( remove_query_arg( array( 'listing_status', 'post_status' ) ) ),
309
+ wpbdp_getv( $_REQUEST, 'listing_status', 'all' ) == 'all' ? 'current' : '',
310
+ _x( 'All', 'admin listings', 'WPBDM' ),
311
+ number_format_i18n( $count ) );
312
+
313
+ foreach ( $stati as $status_id => $status_label ) {
314
+ $count = absint( $wpdb->get_var( $wpdb->prepare(
315
+ "SELECT COUNT(p.ID) FROM {$wpdb->posts} p INNER JOIN {$wpdb->prefix}wpbdp_listings ls ON p.ID = ls.listing_id WHERE p.post_type = %s AND p.post_status IN ({$post_statuses}) AND ls.listing_status = %s",
316
+ WPBDP_POST_TYPE,
317
+ $status_id
318
+ ) ) );
319
+
320
+ if ( ! $count )
321
+ continue;
322
+
323
+ $views[ $status_id ] = sprintf( '<a href="%s" class="%s">%s <span class="count">(%s)</span></a>',
324
+ esc_url( add_query_arg( 'listing_status', $status_id ) ),
325
+ wpbdp_getv( $_REQUEST, 'listing_status' ) == $status_id ? 'current' : '',
326
+ $status_label,
327
+ number_format_i18n( $count ) );
328
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
 
330
  $views = apply_filters( 'wpbdp_admin_directory_views', $views, $post_statuses );
331
+ if ( isset( $views_['trash'] ) || ( ! empty( $_GET['post_status'] ) && 'trash' == $_GET['post_status'] ) ) {
332
+ $stati = get_post_stati( array(), 'objects' );
333
+ $label = $stati['trash']->label;
334
+ $views['trash'] = isset( $views_['trash'] ) ? $views_['trash'] : $label . ' <span class="count">(0)</span>';
335
+ }
336
 
337
  return $views;
338
  }
339
 
340
+ function listings_admin_filters( $pieces ) {
341
  global $wpdb;
342
 
343
+ if ( ! is_admin() || ( ! isset( $_REQUEST['listing_status'] ) && ! isset( $_REQUEST['wpbdmfilter'] ) ) || ! function_exists( 'get_current_screen' ) || ! get_current_screen() || 'edit-' . WPBDP_POST_TYPE != get_current_screen()->id )
344
  return $pieces;
345
 
346
+
347
+ $status_filter = wpbdp_getv( $_REQUEST, 'listing_status', 'all' );
348
+ $other_filter = wpbdp_getv( $_REQUEST, 'wpbdmfilter', '' );
349
+
350
+ if ( in_array( $status_filter, array_keys( WPBDP_Listing::get_stati() ), true ) ) {
351
+ $pieces['join'] .= " LEFT JOIN {$wpdb->prefix}wpbdp_listings ls ON ls.listing_id = {$wpdb->posts}.ID ";
352
+ $pieces['where'] .= $wpdb->prepare( "AND ls.listing_status = %s", $status_filter );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  }
354
 
355
+ if ( $other_filter )
356
+ $pieces = apply_filters( 'wpbdp_admin_directory_filter', $pieces, $other_filter );
357
+
358
  return $pieces;
359
  }
360
 
362
 
363
 
364
  public function row_actions($actions, $post) {
365
+ if ( WPBDP_POST_TYPE != $post->post_type )
366
+ return $actions;
367
+
368
+ if (current_user_can('contributor') && ! current_user_can( 'administrator' ) ) {
369
  if (wpbdp_user_can('edit', $post->ID))
370
  $actions['edit'] = sprintf('<a href="%s">%s</a>',
371
  wpbdp_url( 'edit_listing', $post->ID ),
375
  $actions['delete'] = sprintf( '<a href="%s">%s</a>', wpbdp_url( 'delete_listing', $post->ID ), _x( 'Delete Listing', 'admin actions', 'WPBDM' ) );
376
  }
377
 
378
+ if ( ! current_user_can( 'administrator' ) )
379
+ return $actions;
380
+
381
+ $listing = wpbdp_get_listing( $post->ID );
382
+ $payments = $listing->get_payments();
383
+ if ( $payments->count() > 1 ) {
384
+ $actions['view-payments'] = '<a href="' . esc_url( admin_url( 'admin.php?page=wpbdp_admin_payments&listing=' . $listing->get_id() ) ) . '">' . _x( 'View Payments', 'admin actions', 'WPBDM' ) . '</a>';
385
+ } else {
386
+ $payment = $payments->get();
387
+
388
+ if ( $payment )
389
+ $actions['view-payments'] = '<a href="' . esc_url( $payment->get_admin_url() ) . '">' . _x( 'View Payment', 'admin actions', 'WPBDM' ) . '</a>';
390
+ }
391
+
392
+ $listing = wpbdp_get_listing( $post->ID );
393
+ $actions = apply_filters( 'wpbdp_admin_directory_row_actions', $actions, $listing );
394
+
395
  return $actions;
396
  }
397
 
398
+ /**
399
+ * @since 5.0
400
+ */
401
+ public function maybe_save_fields( $post_id ) {
402
+ if ( ! is_admin() )
403
  return;
404
 
405
+ $nonce = isset( $_POST['wpbdp-admin-listing-fields-nonce'] ) ? $_POST['wpbdp-admin-listing-fields-nonce'] : '';
 
 
406
 
407
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'save listing fields' ) || empty( $_POST['listingfields'] ) )
408
+ return;
409
 
410
+ $fields = wpbdp_get_form_fields( array( 'association' => 'meta' ) );
411
+ foreach ( $fields as $field ) {
412
+ if ( isset( $_POST['listingfields'][ $field->get_id() ] ) ) {
413
+ $value = $field->convert_input( $_POST['listingfields'][ $field->get_id() ] );
414
+ $field->store_value( $post_id, $value );
415
+ } else {
416
+ $field->store_value( $post_id, $field->convert_input( null ) );
417
+ }
418
+ }
419
 
420
+ $listing = wpbdp_get_listing( $post_id );
 
421
 
422
+ // Update image information.
423
+ if ( ! empty ( $_POST['thumbnail_id'] ) )
424
+ $listing->set_thumbnail_id( $_POST['thumbnail_id'] );
425
 
426
+ // Images info.
427
+ if ( ! empty( $_POST['images_meta'] ) ) {
428
+ $meta = $_POST['images_meta'];
 
 
 
 
 
429
 
430
+ foreach ( $meta as $img_id => $img_meta ) {
431
+ update_post_meta( $img_id, '_wpbdp_image_weight', absint( $img_meta[ 'order' ] ) );
432
+ update_post_meta( $img_id, '_wpbdp_image_caption', strval( $img_meta[ 'caption' ] ) );
433
+ }
434
+ }
435
+ }
436
 
437
+ /**
438
+ * @since 5.0
439
+ */
440
+ public function maybe_update_plan( $post_id ) {
441
+ if ( ! is_admin() )
442
+ return;
443
 
444
+ $nonce = isset( $_POST['wpbdp-admin-listing-plan-nonce'] ) ? $_POST['wpbdp-admin-listing-plan-nonce'] : '';
445
+
446
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'update listing plan' ) )
447
+ return;
448
+
449
+ global $wpdb;
450
+
451
+ $listing = wpbdp_get_listing( $post_id );
452
+ $new_plan = ! empty( $_POST['listing_plan' ] ) ? $_POST['listing_plan'] : array();
453
+ $current_plan = $listing->get_fee_plan();
454
+
455
+ if ( ! $current_plan && empty( $new_plan['fee_id'] ) ) {
456
+ // Choose the free fee. (This shouldn't happen)
457
+ $free = wpbdp_get_fee_plan( 'free' );
458
+ $new_plan['fee_id'] = $new_plan->id;
459
+ $new_plan['expiration_date'] = $free->calculate_expiration_time();
460
+ $new_plan['fee_images'] = $free->images;
461
+ $new_plan['is_sticky'] = $free->sticky;
462
+ }
463
 
464
+ if ( ! $current_plan || (int) $current_plan->fee_id != (int) $new_plan['fee_id'] ) {
465
+ $payment = $listing->set_fee_plan_with_payment( $new_plan['fee_id'] );
466
+
467
+ if ( $payment )
468
+ $payment->process_as_admin();
469
+ }
470
+
471
+ if ( ! $current_plan ) {
472
+ $listing->set_flag( 'admin-posted' );
473
+ }
474
+
475
+ // Update plan attributes.
476
+ $row = array();
477
+ $row['expiration_date'] = '' == $new_plan['expiration_date'] ? null : $new_plan['expiration_date'];
478
+ $row['fee_images'] = absint( $new_plan['fee_images'] );
479
+ $row['is_sticky'] = ! empty( $new_plan['is_sticky'] ) ? 1 : 0;
480
+
481
+ $wpdb->update( $wpdb->prefix . 'wpbdp_listings', $row, array( 'listing_id' => $post_id ) );
482
+
483
+ // Check if the status needs to be changed.
484
+ if ( 'expired' == $listing->get_status() ) {
485
+ if ( null === $row['expiration_date'] || strtotime( $new_plan['expiration_date'] ) > current_time( 'timestamp' ) ) {
486
+ $listing->get_status( true, true );
487
+ }
488
  }
489
  }
490
 
501
  'upgradefeatured' => _x('Upgrade to Featured', 'admin actions', 'WPBDM'),
502
  'cancelfeatured' => _x('Downgrade to Normal', 'admin actions', 'WPBDM'),
503
  'sep2' => '--',
 
 
504
  'renewlisting' => _x( 'Renew Listing', 'admin actions', 'WPBDM' )
505
  );
506
  $bulk_actions = apply_filters( 'wpbdp_admin_directory_bulk_actions', $bulk_actions );
includes/admin/class-admin.php CHANGED
@@ -1,39 +1,43 @@
1
  <?php
2
- require_once( WPBDP_INC . 'admin/admin-pages.php' );
3
- require_once( WPBDP_INC . 'admin/class-admin-listings.php' );
4
- require_once( WPBDP_INC . 'admin/fees.php' );
5
- require_once( WPBDP_INC . 'admin/form-fields.php' );
6
- require_once( WPBDP_INC . 'admin/payments.php' );
7
- require_once( WPBDP_INC . 'admin/csv-import.php' );
8
- require_once( WPBDP_INC . 'admin/csv-export.php' );
9
- require_once( WPBDP_INC . 'admin/helpers/listing-metabox.php' );
10
- require_once( WPBDP_INC . 'admin/class-listing-fields-metabox.php' );
11
- require_once( WPBDP_INC . 'admin/page-debug.php' );
12
 
13
  if ( ! class_exists( 'WPBDP_Admin' ) ) {
14
 
15
  class WPBDP_Admin {
16
 
 
 
 
 
17
  private $dropdown_users_args_stack = array();
18
 
19
  public $messages = array();
20
 
21
- function __construct() {
 
22
  add_action('admin_init', array($this, 'handle_actions'));
23
 
24
- add_action('admin_init', array($this, 'register_settings'));
25
- add_action('admin_init', array($this, 'check_for_required_fields'));
26
  add_action('admin_init', array($this, 'check_for_required_pages'));
27
- add_action('admin_init', array($this, 'check_payments_possible'));
28
 
29
  add_action( 'admin_init', array( &$this, 'process_admin_action' ), 999 );
30
 
31
  add_action('admin_notices', array($this, 'admin_notices'));
32
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 20 );
33
 
34
- // Admin menu.
35
  add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
 
 
36
  add_filter( 'custom_menu_order', '__return_true' );
 
 
37
  add_filter( 'menu_order', array( &$this, 'admin_menu_reorder' ) );
38
 
39
  add_filter( 'wp_dropdown_users_args', array( $this, '_dropdown_users_args' ), 10, 2 );
@@ -49,10 +53,6 @@ class WPBDP_Admin {
49
  add_action( 'wp_ajax_wpbdp-admin-fees-set-order', array( &$this, 'ajax_fees_set_order' ) );
50
  add_action( 'wp_ajax_wpbdp-admin-fees-reorder', array( &$this, 'ajax_fees_reorder' ) );
51
 
52
- add_action( 'wp_ajax_wpbdp-listing_set_expiration', array( &$this, 'ajax_listing_set_expiration' ) );
53
- add_action( 'wp_ajax_wpbdp-listing_remove_category', array( &$this, 'ajax_listing_remove_category' ) );
54
- add_action( 'wp_ajax_wpbdp-listing_change_fee', array( &$this, 'ajax_listing_change_fee' ) );
55
-
56
  add_action( 'wp_ajax_wpbdp-renderfieldsettings', array( 'WPBDP_FormFieldsAdmin', '_render_field_settings' ) );
57
 
58
  add_action( 'wp_ajax_wpbdp-create-main-page', array( &$this, 'ajax_create_main_page' ) );
@@ -62,25 +62,40 @@ class WPBDP_Admin {
62
  // Reset settings action.
63
  add_action( 'wpbdp_action_reset-default-settings', array( &$this, 'settings_reset_defaults' ) );
64
 
 
 
 
65
  $this->listings = new WPBDP_Admin_Listings();
66
  $this->csv_import = new WPBDP_CSVImportAdmin();
67
  $this->csv_export = new WPBDP_Admin_CSVExport();
68
- $this->payments = new WPBDP_Admin_Payments();
69
  $this->debug_page = new WPBDP_Admin_Debug_Page();
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
 
72
  function enqueue_scripts() {
73
  global $wpbdp;
74
  global $pagenow;
75
 
76
- $debug_on = $wpbdp->is_debug_on();
77
-
78
  wp_enqueue_style( 'wpbdp-admin',
79
  WPBDP_URL . 'assets/css/admin.min.css');
80
  wp_enqueue_style( 'thickbox' );
81
 
82
  wp_enqueue_style( 'wpbdp-frontend-css', WPBDP_URL . 'assets/css/wpbdp.min.css' );
83
- wp_enqueue_script( 'wpbdp-js' );
 
 
84
  wp_enqueue_script( 'wpbdp-admin-js',
85
  WPBDP_URL . 'assets/js/admin.min.js',
86
  array( 'jquery', 'thickbox', 'jquery-ui-sortable' ) );
@@ -88,8 +103,8 @@ class WPBDP_Admin {
88
  if ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) {
89
  wpbdp_enqueue_jquery_ui_style();
90
 
91
- wp_enqueue_script( 'jquery-ui-datepicker' );
92
  wp_enqueue_style( 'wpbdp-listing-admin-metabox', WPBDP_URL . 'assets/css/admin-listing-metabox.min.css' );
 
93
 
94
  wp_enqueue_style( 'wpbdp-dnd-upload' );
95
  wp_enqueue_script(
@@ -97,6 +112,18 @@ class WPBDP_Admin {
97
  WPBDP_URL . 'assets/js/admin-listing.min.js',
98
  array( 'wpbdp-admin-js', 'wpbdp-dnd-upload', 'jquery-ui-tooltip' )
99
  );
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  wp_localize_script( 'wpbdp-admin-listing', 'WPBDP_admin_listings_config', array(
102
  'messages' => array(
@@ -234,112 +261,240 @@ to how WordPress stores the data.", 'WPBDM' )
234
  'wpbdp_admin',
235
  array( &$this, 'main_menu' ),
236
  WPBDP_URL . 'assets/images/menuico.png' );
237
- add_submenu_page('wpbdp_admin',
238
- _x('Add New Listing', 'admin menu', 'WPBDM'),
239
- _x('Add New Listing', 'admin menu', 'WPBDM'),
240
- 'administrator',
241
- 'wpbdp_add_listing',
242
- '__return_null');
243
- add_submenu_page('wpbdp_admin',
244
- _x('Manage Options', 'admin menu', 'WPBDM'),
245
- _x('Manage Options', 'admin menu', 'WPBDM'),
246
- 'administrator',
247
- 'wpbdp_admin_settings',
248
- array($this, 'admin_settings'));
249
- add_submenu_page('wpbdp_admin',
250
- _x('Manage Fees', 'admin menu', 'WPBDM'),
251
- _x('Manage Fees', 'admin menu', 'WPBDM'),
252
- 'administrator',
253
- 'wpbdp_admin_fees',
254
- array('WPBDP_FeesAdmin', 'admin_menu_cb'));
255
- add_submenu_page('wpbdp_admin',
256
- _x('Manage Form Fields', 'admin menu', 'WPBDM'),
257
- _x('Manage Form Fields', 'admin menu', 'WPBDM'),
258
- 'administrator',
259
- 'wpbdp_admin_formfields',
260
- array('WPBDP_FormFieldsAdmin', 'admin_menu_cb'));
261
- add_submenu_page('wpbdp_admin',
262
- _x('Listings', 'admin menu', 'WPBDM'),
263
- _x('Listings', 'admin menu', 'WPBDM'),
264
- 'administrator',
265
- 'wpbdp_all_listings',
266
- '__return_false');
267
- // if ( wpbdp_payments_api()->payments_possible() ) {
268
- // add_submenu_page( 'wpbdp_admin',
269
- // _x( 'Transactions', 'admin menu', 'WPBDM' ),
270
- // _x( 'Transactions', 'admin menu', 'WPBDM' ),
271
- // 'administrator',
272
- // 'wpbdp_manage_transactions',
273
- // array( 'WPBDP_TransactionsAdmin', 'admin_menu_cb' )
274
- // );
275
- // }
276
- add_submenu_page( 'wpbdp_admin',
277
- _x( 'CSV Import', 'admin menu', 'WPBDM' ),
278
- _x( 'CSV Import', 'admin menu', 'WPBDM' ),
279
- 'administrator',
280
- 'wpbdp-csv-import',
281
- array( &$this->csv_import, 'dispatch' ) );
282
- add_submenu_page( 'wpbdp_admin',
283
- _x( 'CSV Export', 'admin menu', 'WPBDM' ),
284
- _x( 'CSV Export', 'admin menu', 'WPBDM' ),
285
- 'administrator',
286
- 'wpbdp-csv-export',
287
- array( &$this->csv_export, 'dispatch' ) );
288
- add_submenu_page( 'wpbdp_admin',
289
- _x( 'Debug', 'admin menu', 'WPBDM' ),
290
- _x( 'Debug', 'admin menu', 'WPBDM' ),
291
  'administrator',
292
- 'wpbdp-debug-info',
293
- array( &$this->debug_page, 'dispatch' ) );
294
-
295
- global $submenu;
296
-
297
- if (current_user_can('administrator')) {
298
- $submenu['wpbdp_admin'][1][2] = admin_url(sprintf('post-new.php?post_type=%s', WPBDP_POST_TYPE));
299
- $submenu['wpbdp_admin'][0][0] = _x('Main Menu', 'admin menu', 'WPBDM');
300
- $submenu['wpbdp_admin'][5][2] = admin_url( 'edit.php?post_type=' . WPBDP_POST_TYPE );
301
- } elseif (current_user_can('contributor')) {
302
- $m = $submenu['edit.php?post_type=' . WPBDP_POST_TYPE];
303
- $keys = array_keys($m);
304
- $m[$keys[1]][2] = wpbdp_get_page_link('add-listing');
 
 
 
 
 
 
 
305
  }
306
-
307
  do_action('wpbdp_admin_menu', 'wpbdp_admin');
308
 
309
- add_submenu_page('wpbdp_admin',
310
- _x('Uninstall Business Directory Plugin', 'admin menu', 'WPBDM'),
311
- _x('Uninstall', 'admin menu', 'WPBDM'),
312
- 'administrator',
313
- 'wpbdp_uninstall',
314
- array($this, 'uninstall_plugin'));
 
 
 
 
 
 
 
315
 
316
- if ( isset( $submenu['wpbdp_admin'] ) )
317
- $submenu['wpbdp_admin'] = apply_filters( 'wpbdp_admin_menu_reorder', $submenu['wpbdp_admin'] );
318
  }
319
 
320
- function admin_menu_reorder( $menu_order ) {
321
- $admin_index = array_search( 'wpbdp_admin', $menu_order, true );
322
- $dir_index = array_search( 'edit.php?post_type=' . WPBDP_POST_TYPE, $menu_order, true );
 
 
323
 
324
- if ( false === $admin_index || false === $dir_index )
325
- return $menu_order;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
- $min_key = min( $admin_index, $dir_index );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
 
329
- $res = array();
330
- foreach ( $menu_order as $i => $v ) {
331
- if ( $i == $min_key ) {
332
- $res[] = $menu_order[ $dir_index ];
333
- $res[] = $menu_order[ $admin_index ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  continue;
335
- } elseif ( $admin_index == $i || $dir_index == $i ) {
 
 
 
 
336
  continue;
337
- }
338
 
339
- $res[] = $v;
 
340
  }
341
 
342
- return $res;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
344
 
345
  public function _checklist_args($args) {
@@ -391,11 +546,11 @@ to how WordPress stores the data.", 'WPBDM' )
391
  if ( ! $order )
392
  $response->send_error();
393
 
394
- $wpdb->update( $wpdb->prefix . 'wpbdp_fees', array( 'weight' => 0 ) );
395
 
396
  $weight = count( $order ) - 1;
397
  foreach( $order as $fee_id ) {
398
- $wpdb->update( $wpdb->prefix . 'wpbdp_fees', array( 'weight' => $weight ), array( 'id' => $fee_id ) );
399
  $weight--;
400
  }
401
 
@@ -405,65 +560,6 @@ to how WordPress stores the data.", 'WPBDM' )
405
  /*
406
  * AJAX listing actions.
407
  */
408
- public function ajax_listing_set_expiration() {
409
- $response = new WPBDP_Ajax_Response();
410
-
411
- $renewal_id = intval( isset( $_POST['renewal_id'] ) ? $_POST['renewal_id'] : 0 );
412
- $expiration_time = isset( $_POST['expiration_date'] ) ? ( 'never' == $_POST['expiration_date'] ? 'never' : date( 'Y-m-d 00:00:00', strtotime( trim( $_POST['expiration_date'] ) ) ) ) : '';
413
-
414
- if ( ! $renewal_id || ! $expiration_time || ! current_user_can( 'administrator' ) )
415
- $response->send_error();
416
-
417
- global $wpdb;
418
-
419
- if ( 'never' == $expiration_time ) {
420
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listing_fees SET expires_on = NULL, email_sent = %d WHERE id = %d", 0, $renewal_id ) );
421
- } else {
422
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listing_fees SET expires_on = %s, email_sent = %d WHERE id = %d", $expiration_time, 0, $renewal_id ) );
423
- }
424
-
425
- $response->add( 'formattedExpirationDate', 'never' == $expiration_time ? _x( 'never', 'admin infometabox', 'WPBDM' ) : date_i18n( get_option( 'date_format' ), strtotime( $expiration_time ) ) );
426
- $response->send();
427
- }
428
-
429
- public function ajax_listing_remove_category() {
430
- $response = new WPBDP_Ajax_Response();
431
-
432
- $listing = WPBDP_Listing::get( intval( isset( $_POST['listing'] ) ? $_POST['listing'] : 0 ) );
433
- $category = intval( isset( $_POST['category'] ) ? $_POST['category'] : 0 );
434
- if ( ! $listing || ! $category )
435
- $response->send_error();
436
-
437
- $listing->remove_category( $category );
438
- $response->send();
439
- }
440
-
441
- public function ajax_listing_change_fee() {
442
- global $wpdb;
443
-
444
- $response = new WPBDP_Ajax_Response();
445
-
446
- if ( ! current_user_can( 'administrator' ) )
447
- $response->send_error();
448
-
449
- $fee_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d", isset( $_POST['renewal'] ) ? $_POST['renewal'] : 0 ) );
450
-
451
- if ( ! $fee_info )
452
- $response->send_error();
453
-
454
- $listing = WPBDP_Listing::get( $fee_info->listing_id );
455
- $category = $listing->get_category_info( $fee_info->category_id );
456
-
457
- if ( ! $listing || ! $category || 'pending' == $category->status )
458
- $response->send_error();
459
-
460
- $response->add( 'html', wpbdp_render_page( WPBDP_PATH . 'templates/admin/listing-change-fee.tpl.php',
461
- array( 'category' => $category,
462
- 'listing' => $listing,
463
- 'fees' => wpbdp_get_fees_for_category( $fee_info->category_id ) ) ) );
464
- $response->send();
465
- }
466
-
467
  function ajax_dismiss_notification() {
468
  $id = isset( $_POST['id'] ) ? $_POST['id'] : '';
469
  $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
@@ -485,9 +581,9 @@ to how WordPress stores the data.", 'WPBDM' )
485
  if ( ! isset( $this->displayed_warnings ) )
486
  $this->displayed_warnings = array();
487
 
488
- $this->check_compatibility();
489
  $this->check_setup();
490
  $this->check_ajax_compat_mode();
 
491
 
492
  do_action( 'wpbdp_admin_notices' );
493
 
@@ -533,7 +629,6 @@ to how WordPress stores the data.", 'WPBDM' )
533
  $posts = is_array($_REQUEST['post']) ? $_REQUEST['post'] : array($_REQUEST['post']);
534
 
535
  $listings_api = wpbdp_listings_api();
536
- $upgrades_api = wpbdp_listing_upgrades_api();
537
 
538
  if (!current_user_can('administrator'))
539
  exit;
@@ -551,116 +646,33 @@ to how WordPress stores the data.", 'WPBDM' )
551
  'WPBDM');
552
  break;
553
 
554
- case 'setaspaid':
555
- $ok = true;
556
-
557
- foreach ($posts as $post_id) {
558
- $listing = WPBDP_Listing::get( $post_id );
559
-
560
- if ( ! $listing->mark_as_paid() )
561
- $ok = false;
562
- }
563
-
564
- if ( $ok ) {
565
- $this->messages[] = _nx('The listing status has been set as paid.',
566
- 'The listings status has been set as paid.',
567
- count($posts),
568
- 'admin',
569
- 'WPBDM');
570
- } else {
571
- $msg = _nx( 'Only invoices containing non-recurring items were marked as paid. Please review the <a>Transactions</a> tab for the listing to manage recurring items or check the gateway\'s backend.',
572
- 'Only invoices containing non-recurring items were marked as paid. Recurring payments have to be managed through the gateway.',
573
- count( $posts ),
574
- 'admin',
575
- 'WPBDM' );
576
-
577
- if ( 1 == count( $posts ) )
578
- $msg = str_replace( '<a>', '<a href="' . admin_url( 'post.php?post=' . $posts[0] . '&action=edit#listing-metabox-transactions' ) . '">', $msg );
579
-
580
- $this->messages[] = array( $msg, 'error' );
581
- }
582
-
583
- break;
584
-
585
- case 'changesticky':
586
- foreach ( $posts as $post_id ):
587
- $upgrades_api->set_sticky( $post_id, wpbdp_getv($_GET, 'u') );
588
- endforeach;
589
-
590
- $this->messages[] = _nx('The listing has been modified.',
591
- 'The listings have been modified.',
592
- count($posts),
593
- 'admin',
594
- 'WPBDM');
595
-
596
- break;
597
-
598
- case 'upgradefeatured':
599
- foreach ( $posts as $post_id ):
600
- $upgrades_api->set_sticky( $post_id, 'sticky', true );
601
- endforeach;
602
-
603
- $this->messages[] = _nx('The listing has been upgraded.',
604
- 'The listings have been upgraded.',
605
- count($posts),
606
- 'admin',
607
- 'WPBDM');
608
- break;
609
-
610
- case 'cancelfeatured':
611
- foreach ($posts as $post_id ):
612
- $upgrades_api->set_sticky( $post_id, 'normal' );
613
- endforeach;
614
-
615
- $this->messages[] = _nx('The listing has been downgraded.',
616
- 'The listings have been downgraded.',
617
- count($posts),
618
- 'admin',
619
- 'WPBDM');
620
- break;
621
-
622
- case 'approvetransaction':
623
- $transaction = WPBDP_Payment::get( $_GET['transaction_id'] );
624
-
625
- if( $transaction->has_item_type( 'recurring_fee' ) ) {
626
- $this->messages[] = array( _x( 'The payment status was not changed. Recurring payments can\'t be manually approved. Please check your gateway\'s backend to see if the payment really went through.', 'admin payments', 'WPBDM' ), 'error' );
627
- } else {
628
- $transaction->set_status( WPBDP_Payment::STATUS_COMPLETED, 'admin' );
629
- $transaction->save();
630
-
631
- $this->messages[] = _x( 'The transaction has been approved.', 'admin', 'WPBDM' );
632
- }
633
-
634
- break;
635
-
636
- case 'rejecttransaction':
637
- $transaction = WPBDP_Payment::get( $_GET['transaction_id'] );
638
- $transaction->set_status( WPBDP_Payment::STATUS_REJECTED, 'admin' );
639
- $transaction->save();
640
-
641
- $this->messages[] = _x( 'The transaction has been rejected.', 'admin', 'WPBDM' );
642
- break;
643
-
644
  case 'assignfee':
645
  $listing = WPBDP_Listing::get( $posts[0] );
646
- $listing->add_category( $_GET['category_id'], $_GET['fee_id'] );
 
 
647
  $this->messages[] = _x('The fee was successfully assigned.', 'admin', 'WPBDM');
648
 
649
  break;
650
 
651
  case 'renewlisting':
652
  foreach ( $posts as $post_id ):
653
- $listings_api->auto_renew( $post_id );
 
654
  endforeach;
655
 
656
  $this->messages[] = _nx( 'Listing was renewed.', 'Listings were renewed.', count( $posts ), 'admin', 'WPBDM' );
657
  break;
658
 
659
  case 'send-renewal-email':
660
- $renewal_id = intval( $_GET['renewal_id'] );
 
 
 
 
661
 
662
- if ( $listings_api->send_renewal_email( $renewal_id ) )
663
- $this->messages[] = _x( 'Renewal email sent.', 'admin', 'WPBDM' );
664
 
665
  break;
666
 
@@ -734,45 +746,6 @@ to how WordPress stores the data.", 'WPBDM' )
734
  return $value;
735
  }
736
 
737
-
738
- /* Settings page */
739
- public function register_settings() {
740
- global $wpbdp;
741
- $wpbdp->settings->register_in_admin();
742
- }
743
-
744
- public function admin_settings() {
745
- global $wpbdp;
746
-
747
- flush_rewrite_rules(false);
748
-
749
- $_SERVER['REQUEST_URI'] = remove_query_arg( 'deletedb', $_SERVER['REQUEST_URI'] );
750
-
751
- $reset_defaults = ( isset( $_GET['action'] ) && 'reset' == $_GET['action'] );
752
- if ( $reset_defaults ) {
753
- echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/settings-reset.tpl.php' );
754
- return;
755
- }
756
-
757
- $_SERVER['REQUEST_URI'] = remove_query_arg( 'deletedb', $_SERVER['REQUEST_URI'] );
758
-
759
- wpbdp_render_page(WPBDP_PATH . 'templates/admin/settings.tpl.php',
760
- array('wpbdp_settings' => $wpbdp->settings),
761
- true);
762
- }
763
-
764
- public function settings_reset_defaults() {
765
- $do_reset = ( ! empty ( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'reset defaults' ) );
766
-
767
- if ( $do_reset ) {
768
- global $wpbdp;
769
- $wpbdp->settings->reset_defaults();
770
- }
771
-
772
- wp_redirect( admin_url( 'admin.php?page=wpbdp_admin_settings&settings-updated=1&groupid=general' ) );
773
- exit();
774
- }
775
-
776
  /* Uninstall. */
777
  public function uninstall_plugin() {
778
  global $wpdb;
@@ -800,7 +773,8 @@ to how WordPress stores the data.", 'WPBDM' )
800
  $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", 'wpbdp%' ) );
801
 
802
  // Clear scheduled hooks.
803
- wp_clear_scheduled_hook('wpbdp_listings_expiration_check');
 
804
 
805
  $tracking = new WPBDP_SiteTracking();
806
  $tracking->track_uninstall( isset( $_POST['uninstall'] ) ? $_POST['uninstall'] : null );
@@ -820,37 +794,6 @@ to how WordPress stores the data.", 'WPBDM' )
820
  }
821
  }
822
 
823
- /* Required fields check. */
824
- public function check_for_required_fields() {
825
- global $wpbdp;
826
-
827
- if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'wpbdp_admin_formfields' &&
828
- isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'createrequired' ) {
829
- // do not display the warning inside the page creating the required fields
830
- return;
831
- }
832
-
833
- if ( $missing = $wpbdp->formfields->get_missing_required_fields() ) {
834
- if (count($missing) > 1) {
835
- $message = sprintf(_x('<b>Business Directory Plugin</b> requires fields with the following associations in order to work correctly: <b>%s</b>.', 'admin', 'WPBDM'), join(', ', $missing));
836
- } else {
837
- $message = sprintf(_x('<b>Business Directory Plugin</b> requires a field with a <b>%s</b> association in order to work correctly.', 'admin', 'WPBDM'), array_pop( $missing ) );
838
- }
839
-
840
- $message .= '<br />';
841
- $message .= _x('You can create these custom fields by yourself inside "Manage Form Fields" or let Business Directory do this for you automatically.', 'admin', 'WPBDM');
842
- $message .= '<br /><br />';
843
- $message .= sprintf('<a href="%s">%s</a> | ',
844
- admin_url('admin.php?page=wpbdp_admin_formfields'),
845
- _x('Go to "Manage Form Fields"', 'admin', 'WPBDM'));
846
- $message .= sprintf('<a href="%s">%s</a>',
847
- admin_url('admin.php?page=wpbdp_admin_formfields&action=createrequired'),
848
- _x('Create these required fields for me', 'admin', 'WPBDM'));
849
-
850
- $this->messages[] = array($message, 'error');
851
- }
852
- }
853
-
854
  /* Required pages check. */
855
  public function check_for_required_pages() {
856
  if ( ! wpbdp_get_page_id( 'main' ) && current_user_can( 'administrator' ) ) {
@@ -867,18 +810,6 @@ to how WordPress stores the data.", 'WPBDM' )
867
  }
868
  }
869
 
870
- /* Check if payments are enabled but no gateway available. */
871
- public function check_payments_possible() {
872
- // show messages only in directory admin pages
873
- if ( (isset($_GET['post_type']) && $_GET['post_type'] == WPBDP_POST_TYPE) ||
874
- (isset($_GET['page']) && stripos($_GET['page'], 'wpbdp_') !== FALSE) ) {
875
-
876
- if ($errors = wpbdp_payments_api()->check_config()) {
877
- foreach ($errors as $error) $this->messages[] = array($error, 'error');
878
- }
879
- }
880
- }
881
-
882
  /**
883
  * @since 3.6.10
884
  */
@@ -889,47 +820,10 @@ to how WordPress stores the data.", 'WPBDM' )
889
  }
890
  }
891
 
892
- private function check_compatibility() {
893
- global $wpbdp;
894
-
895
- $modules_msg = '';
896
- $modules = $wpbdp->get_premium_modules_data();
897
-
898
- foreach ( $modules as $module_id => &$module_info ) {
899
- if ( $module_info['installed'] && version_compare( $module_info['version'], $module_info['required'], '<' ) ) {
900
- $modules_msg .= '<li class="module-info">';
901
- $modules_msg .= 'business-directory-<b>' . $module_id . '</b><br />';
902
- $modules_msg .= '<span class="module-version">';
903
- $modules_msg .= sprintf( _x( 'Installed: %s', 'admin compat', 'WPBDM' ), '<b>' . ( null === $module_info['version'] ? _x( 'N/A', 'admin compat', 'WPBDM' ) : $module_info['version'] ) . '</b>' );
904
- $modules_msg .= '</span> -- ';
905
- $modules_msg .= '<span class="module-required">';
906
- $modules_msg .= sprintf( _x( 'Required: %s', 'admin compat', 'WPBDM' ), '<b>' . $module_info['required'] . '</b>' );
907
- $modules_msg .= '</span>';
908
- $modules_msg .= '</li>';
909
-
910
- /* $modules_msg .= sprintf( _x( '&#149; %s (installed: %s, required: %s).', 'admin compat', 'WPBDM' ),
911
- '<span class="module-name">business-directory-<b>' . $module_id . '</b></span>',
912
- '<span class="module-version">' . ( null === $module_info['version'] ? _x( 'N/A', 'admin compat', 'WPBDM' ) : $module_info['version'] ) . $module_info['required'] . '</span>' );*/
913
- }
914
- }
915
-
916
- if ( $modules_msg ) {
917
- $message = '';
918
- $message .= _x( 'Business Directory has detected some incompatible premium module versions installed.', 'admin compat', 'WPBDM' );
919
- $message .= '<br />';
920
- $message .= _x( 'Please upgrade to the required versions indicated below to make sure everything functions properly.', 'admin compat', 'WPBDM' );
921
- $message .= '<ul class="wpbdp-module-compat-check">';
922
- $message .= $modules_msg;
923
- $message .= '</ul>';
924
-
925
- $this->messages[] = array( $message, 'error' );
926
- }
927
- }
928
-
929
  public function check_setup() {
930
  global $pagenow;
931
 
932
- if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp_admin_settings' != $_GET['page'] )
933
  return;
934
 
935
  // Registration disabled message.
@@ -947,7 +841,7 @@ to how WordPress stores the data.", 'WPBDM' )
947
  public function check_ajax_compat_mode() {
948
  global $pagenow;
949
 
950
- if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp_admin_settings' != $_GET['page'] )
951
  return;
952
 
953
  $notice = get_option( 'wpbdp-ajax-compat-mode-notice' );
@@ -959,6 +853,16 @@ to how WordPress stores the data.", 'WPBDM' )
959
  delete_option( 'wpbdp-ajax-compat-mode-notice' );
960
  }
961
 
 
 
 
 
 
 
 
 
 
 
962
  public function main_menu() {
963
  echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/home.tpl.php' );
964
  }
1
  <?php
2
+ require_once( WPBDP_PATH . 'includes/admin/admin-pages.php' );
3
+ require_once( WPBDP_PATH . 'includes/admin/class-admin-listings.php' );
4
+ require_once( WPBDP_PATH . 'includes/admin/form-fields.php' );
5
+ require_once( WPBDP_PATH . 'includes/admin/csv-import.php' );
6
+ require_once( WPBDP_PATH . 'includes/admin/csv-export.php' );
7
+ require_once( WPBDP_PATH . 'includes/admin/class-listing-fields-metabox.php' );
8
+ require_once( WPBDP_PATH . 'includes/admin/page-debug.php' );
9
+ require_once( WPBDP_PATH . 'includes/admin/class-admin-controller.php' );
 
 
10
 
11
  if ( ! class_exists( 'WPBDP_Admin' ) ) {
12
 
13
  class WPBDP_Admin {
14
 
15
+ private $menu = array();
16
+ private $current_controller = null;
17
+ private $current_controller_output = '';
18
+
19
  private $dropdown_users_args_stack = array();
20
 
21
  public $messages = array();
22
 
23
+
24
+ public function __construct() {
25
  add_action('admin_init', array($this, 'handle_actions'));
26
 
 
 
27
  add_action('admin_init', array($this, 'check_for_required_pages'));
 
28
 
29
  add_action( 'admin_init', array( &$this, 'process_admin_action' ), 999 );
30
 
31
  add_action('admin_notices', array($this, 'admin_notices'));
32
+ add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
33
 
34
+ // Adds admin menus.
35
  add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
36
+
37
+ // Enables reordering of admin menus.
38
  add_filter( 'custom_menu_order', '__return_true' );
39
+
40
+ // Puts the "Directory" and "Directory Admin" next to each other.
41
  add_filter( 'menu_order', array( &$this, 'admin_menu_reorder' ) );
42
 
43
  add_filter( 'wp_dropdown_users_args', array( $this, '_dropdown_users_args' ), 10, 2 );
53
  add_action( 'wp_ajax_wpbdp-admin-fees-set-order', array( &$this, 'ajax_fees_set_order' ) );
54
  add_action( 'wp_ajax_wpbdp-admin-fees-reorder', array( &$this, 'ajax_fees_reorder' ) );
55
 
 
 
 
 
56
  add_action( 'wp_ajax_wpbdp-renderfieldsettings', array( 'WPBDP_FormFieldsAdmin', '_render_field_settings' ) );
57
 
58
  add_action( 'wp_ajax_wpbdp-create-main-page', array( &$this, 'ajax_create_main_page' ) );
62
  // Reset settings action.
63
  add_action( 'wpbdp_action_reset-default-settings', array( &$this, 'settings_reset_defaults' ) );
64
 
65
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_view_dispatch' ), 9999 );
66
+ add_action( 'wp_ajax_wpbdp_admin_ajax', array( $this, 'admin_ajax_dispatch' ), 9999 );
67
+
68
  $this->listings = new WPBDP_Admin_Listings();
69
  $this->csv_import = new WPBDP_CSVImportAdmin();
70
  $this->csv_export = new WPBDP_Admin_CSVExport();
 
71
  $this->debug_page = new WPBDP_Admin_Debug_Page();
72
+
73
+ // Post-install migrations.
74
+ if ( get_option( 'wpbdp-migrate-18_0-featured-pending', false ) ) {
75
+ require_once( WPBDP_PATH . 'includes/admin/upgrades/migrations/manual-upgrade-18_0-featured-levels.php' );
76
+ $this->post_install_migration = new WPBDP__Manual_Upgrade__18_0__Featured_Levels();
77
+ }
78
+
79
+ require_once( WPBDP_INC . 'admin/settings/class-settings-admin.php' );
80
+ $this->settings_admin = new WPBDP__Settings_Admin();
81
+
82
+ if ( wpbdp_get_option( 'tracking-on' ) ) {
83
+ $this->site_tracking = new WPBDP_SiteTracking();
84
+ }
85
  }
86
 
87
  function enqueue_scripts() {
88
  global $wpbdp;
89
  global $pagenow;
90
 
 
 
91
  wp_enqueue_style( 'wpbdp-admin',
92
  WPBDP_URL . 'assets/css/admin.min.css');
93
  wp_enqueue_style( 'thickbox' );
94
 
95
  wp_enqueue_style( 'wpbdp-frontend-css', WPBDP_URL . 'assets/css/wpbdp.min.css' );
96
+ wp_enqueue_script( 'wpbdp-frontend-js',
97
+ WPBDP_URL . 'assets/js/wpbdp.min.js',
98
+ array( 'jquery' ) );
99
  wp_enqueue_script( 'wpbdp-admin-js',
100
  WPBDP_URL . 'assets/js/admin.min.js',
101
  array( 'jquery', 'thickbox', 'jquery-ui-sortable' ) );
103
  if ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) {
104
  wpbdp_enqueue_jquery_ui_style();
105
 
 
106
  wp_enqueue_style( 'wpbdp-listing-admin-metabox', WPBDP_URL . 'assets/css/admin-listing-metabox.min.css' );
107
+ wp_enqueue_style( 'wpbdp-listing-admin-timeline', WPBDP_URL . 'assets/css/admin-listing-timeline.min.css' );
108
 
109
  wp_enqueue_style( 'wpbdp-dnd-upload' );
110
  wp_enqueue_script(
112
  WPBDP_URL . 'assets/js/admin-listing.min.js',
113
  array( 'wpbdp-admin-js', 'wpbdp-dnd-upload', 'jquery-ui-tooltip' )
114
  );
115
+ wp_enqueue_script(
116
+ 'wpbdp-admin-listing-metabox',
117
+ WPBDP_URL . 'assets/js/admin-listing-metabox.min.js',
118
+ array( 'wpbdp-admin-js', 'jquery-ui-datepicker' )
119
+ );
120
+
121
+ wp_localize_script( 'wpbdp-admin-listing-metabox', 'wpbdpListingMetaboxL10n', array(
122
+ 'planDisplayFormat' => sprintf( '<a href="%s">%s</a>', admin_url( 'admin.php?page=wpbdp-admin-fees&wpbdp_view=edit-fee&id={{plan_id}}' ), '{{plan_label}}' ),
123
+ 'noExpiration' => _x( 'Never', 'listing metabox', 'WPBDM' ),
124
+ 'yes' => _x( 'Yes', 'listing metabox', 'WPBDM' ),
125
+ 'no' => _x( 'No', 'listing metabox', 'WPBDM' )
126
+ ) );
127
 
128
  wp_localize_script( 'wpbdp-admin-listing', 'WPBDP_admin_listings_config', array(
129
  'messages' => array(
261
  'wpbdp_admin',
262
  array( &$this, 'main_menu' ),
263
  WPBDP_URL . 'assets/images/menuico.png' );
264
+
265
+ $menu['wpbdp-admin-add-listing'] = array(
266
+ 'title' => _x('Add New Listing', 'admin menu', 'WPBDM'),
267
+ 'url' => admin_url( sprintf( 'post-new.php?post_type=%s', WPBDP_POST_TYPE ) )
268
+ );
269
+ // $menu['wpbdp_admin_settings'] = array(
270
+ // 'title' => _x('Manage Options', 'admin menu', 'WPBDM'),
271
+ // 'callback' => array( $this, 'admin_settings' )
272
+ // );
273
+ $menu['wpbdp-admin-fees'] = array(
274
+ 'title' => _x( 'Manage Fees', 'admin menu', 'WPBDM' )
275
+ );
276
+ $menu['wpbdp_all_listings'] = array(
277
+ 'title' => _x('Listings', 'admin menu', 'WPBDM'),
278
+ 'url' => admin_url( 'edit.php?post_type=' . WPBDP_POST_TYPE )
279
+ );
280
+ $menu['wpbdp_admin_formfields'] = array(
281
+ 'title' => _x('Manage Form Fields', 'admin menu', 'WPBDM'),
282
+ 'callback' => array('WPBDP_FormFieldsAdmin', 'admin_menu_cb')
283
+ );
284
+ $menu['wpbdp_admin_payments'] = array(
285
+ 'title' => _x( 'Payment History', 'admin menu', 'WPBDM' )
286
+ );
287
+ $menu['wpbdp_admin_csv'] = array(
288
+ 'title' => _x( 'CSV Import & Export', 'admin menu', 'WPBDM' )
289
+ );
290
+ // $menu['wpbdp-csv-import'] = array(
291
+ // 'title' => _x( 'CSV Import', 'admin menu', 'WPBDM' ),
292
+ // 'callback' => array( &$this->csv_import, 'dispatch' )
293
+ // );
294
+ // $menu['wpbdp-csv-export'] = array(
295
+ // 'title' => _x( 'CSV Export', 'admin menu', 'WPBDM' ),
296
+ // 'callback' => array( &$this->csv_export, 'dispatch' )
297
+ // );
298
+ $menu['wpbdp-debug-info'] = array(
299
+ 'title' => _x( 'Debug', 'admin menu', 'WPBDM' ),
300
+ 'callback' => array( &$this->debug_page, 'dispatch' )
301
+ );
302
+
303
+ add_submenu_page( null,
304
+ __( 'Uninstall Business Directory Plugin', 'WPBDM' ),
305
+ __( 'Uninstall Business Directory Plugin', 'WPBDM' ),
 
 
 
 
 
 
 
 
 
 
 
 
306
  'administrator',
307
+ 'wpbdp_uninstall',
308
+ array( $this, 'uninstall_plugin' ) );
309
+
310
+
311
+ // FIXME: before next-release
312
+ // if (current_user_can('administrator')) {
313
+ // $submenu['wpbdp_admin'][0][0] = _x('Main Menu', 'admin menu', 'WPBDM');
314
+ // $submenu['wpbdp_admin'] = apply_filters( 'wpbdp_admin_menu_reorder', $submenu['wpbdp_admin'] );
315
+
316
+ $this->menu = apply_filters( 'wpbdp_admin_menu_items', $menu );
317
+ $this->prepare_menu( $this->menu );
318
+
319
+ // Register menu items.
320
+ foreach ( $this->menu as $item_slug => &$item_data ) {
321
+ $item_data['hook'] = add_submenu_page( 'wpbdp_admin',
322
+ $item_data['title'],
323
+ $item_data['label'],
324
+ 'administrator',
325
+ $item_slug,
326
+ array( $this, 'menu_dispatch' ) );
327
  }
328
+ // $item_data = null;
329
  do_action('wpbdp_admin_menu', 'wpbdp_admin');
330
 
331
+ if ( ! current_user_can( 'administrator' ) )
332
+ return;
333
+
334
+ // Handle some special menu items.
335
+ foreach ( $GLOBALS['submenu']['wpbdp_admin'] as &$menu_item ) {
336
+ if ( ! isset( $this->menu[ $menu_item[2] ] ) )
337
+ continue;
338
+
339
+ $menu_item_data = $this->menu[ $menu_item[2] ];
340
+
341
+ if ( ! empty( $menu_item_data['url'] ) )
342
+ $menu_item[2] = $menu_item_data['url'];
343
+ }
344
 
 
 
345
  }
346
 
347
+ /**
348
+ * @since 5.0
349
+ */
350
+ private function prepare_menu( &$menu ) {
351
+ $n = 1;
352
 
353
+ foreach ( $menu as &$item ) {
354
+ if ( ! isset( $item['priority'] ) )
355
+ $item['priority'] = $n++;
356
+
357
+ if ( ! isset( $item['title'] ) )
358
+ $item['title'] = _x( 'Untitled Menu', 'admin', 'WPBDM' );
359
+
360
+ if ( ! isset( $item['label'] ) )
361
+ $item['label'] = $item['title'];
362
+
363
+ if ( ! isset( $item['file'] ) )
364
+ $item['file'] = '';
365
+
366
+ if ( ! isset( $item['callback'] ) )
367
+ $item['callback'] = '';
368
+
369
+ if ( ! isset( $item['url'] ) )
370
+ $item['url'] = '';
371
+ }
372
+
373
+ WPBDP_Utils::sort_by_property( $menu, 'priority' );
374
+ }
375
+
376
+ /**
377
+ * @since 5.0
378
+ */
379
+ function admin_view_dispatch() {
380
+ global $plugin_page;
381
 
382
+ if ( ! isset( $plugin_page ) || ! isset( $this->menu[ $plugin_page ] ) )
383
+ return;
384
+
385
+ $item = $this->menu[ $plugin_page ];
386
+ $slug = $plugin_page;
387
+ $callback = $item['callback'];
388
+
389
+
390
+ // Simple callback view are not processed here.
391
+ if ( $callback && is_callable( $callback ) )
392
+ return;
393
+
394
+ $id = str_replace( array( 'wpbdp-admin-', 'wpbdp_admin_' ), '', $slug );
395
+
396
+ $candidates = array( $item['file'],
397
+ WPBDP_INC . 'admin/class-admin-' . $id . '.php',
398
+ WPBDP_INC . 'admin/' . $id . '.php' );
399
+ foreach ( $candidates as $c ) {
400
+ if ( $c && file_exists( $c ) )
401
+ require_once( $c );
402
+ }
403
+
404
+ // Maybe loading one of the candidate files made the callback available.
405
+ if ( $callback && is_callable( $callback ) ) {
406
+ ob_start();
407
+ call_user_func( $callback );
408
+ $this->current_controller_output = ob_get_contents();
409
+ ob_end_clean();
410
+ return;
411
+ }
412
+
413
+ $classname = 'WPBDP__Admin__' . ucfirst( $id );
414
+
415
+ if ( ! class_exists( $classname ) )
416
+ return;
417
 
418
+ $this->current_controller = new $classname;
419
+
420
+ ob_start();
421
+ $this->current_controller->_dispatch();
422
+ $this->current_controller_output = ob_get_contents();
423
+ ob_end_clean();
424
+
425
+ $this->current_controller->_enqueue_scripts();
426
+ }
427
+
428
+ /**
429
+ * @since 5.0
430
+ */
431
+ function admin_ajax_dispatch() {
432
+ if ( empty( $_REQUEST['handler'] ) )
433
+ return;
434
+
435
+ $handler = trim( $_REQUEST['handler'] );
436
+ $handler = WPBDP__Utils::normalize( $handler );
437
+
438
+ $parts = explode( '__', $handler );
439
+ $controller_id = $parts[0];
440
+ $function = isset( $parts[1] ) ? $parts[1] : '';
441
+
442
+ $candidates = array( WPBDP_INC . 'admin/class-admin-' . $controller_id . '.php',
443
+ WPBDP_INC . 'admin/' . $controller_id . '.php' );
444
+ foreach ( $candidates as $c ) {
445
+ if ( ! file_exists( $c ) )
446
  continue;
447
+
448
+ require_once( $c );
449
+ $classname = 'WPBDP__Admin__' . ucfirst( $controller_id );
450
+
451
+ if ( ! class_exists( $classname ) )
452
  continue;
 
453
 
454
+ $controller = new $classname;
455
+ return $controller->_ajax_dispatch();
456
  }
457
 
458
+ exit;
459
+ }
460
+
461
+ /**
462
+ * @since 5.0
463
+ */
464
+ function menu_dispatch() {
465
+ $output = $this->current_controller_output;
466
+
467
+ if ( $output )
468
+ return print( $output );
469
+
470
+ global $plugin_page;
471
+ if ( ! isset( $plugin_page ) || ! isset( $this->menu[ $plugin_page ] ) )
472
+ return;
473
+
474
+ $item = $this->menu[ $plugin_page ];
475
+ $slug = $plugin_page;
476
+ $callback = $item['callback'];
477
+
478
+ call_user_func( $callback );
479
+ }
480
+
481
+ /**
482
+ * Makes sure that both the "Directory" and "Directory Admin" menus are next to each other.
483
+ */
484
+ function admin_menu_reorder( $menu_order ) {
485
+ $index1 = array_search( 'wpbdp_admin', $menu_order, true );
486
+ $index2 = array_search( 'edit.php?post_type=' . WPBDP_POST_TYPE, $menu_order, true );
487
+
488
+ if ( false === $index1 || false === $index2 )
489
+ return $menu_order;
490
+
491
+ $min = min( $index1, $index2 );
492
+ $max = max( $index1, $index2 );
493
+
494
+ return array_merge( array_slice( $menu_order, 0, $min ),
495
+ array( $menu_order[ $min ], $menu_order[ $max ] ),
496
+ array_slice( $menu_order, $min + 1, $max - $min - 1 ),
497
+ array_slice( $menu_order, $max + 1 ) );
498
  }
499
 
500
  public function _checklist_args($args) {
546
  if ( ! $order )
547
  $response->send_error();
548
 
549
+ $wpdb->query( "UPDATE {$wpdb->prefix}wpbdp_plans SET weight = 0" );
550
 
551
  $weight = count( $order ) - 1;
552
  foreach( $order as $fee_id ) {
553
+ $wpdb->update( $wpdb->prefix . 'wpbdp_plans', array( 'weight' => $weight ), array( 'id' => $fee_id ) );
554
  $weight--;
555
  }
556
 
560
  /*
561
  * AJAX listing actions.
562
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  function ajax_dismiss_notification() {
564
  $id = isset( $_POST['id'] ) ? $_POST['id'] : '';
565
  $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
581
  if ( ! isset( $this->displayed_warnings ) )
582
  $this->displayed_warnings = array();
583
 
 
584
  $this->check_setup();
585
  $this->check_ajax_compat_mode();
586
+ $this->check_deprecation_warnings();
587
 
588
  do_action( 'wpbdp_admin_notices' );
589
 
629
  $posts = is_array($_REQUEST['post']) ? $_REQUEST['post'] : array($_REQUEST['post']);
630
 
631
  $listings_api = wpbdp_listings_api();
 
632
 
633
  if (!current_user_can('administrator'))
634
  exit;
646
  'WPBDM');
647
  break;
648
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649
  case 'assignfee':
650
  $listing = WPBDP_Listing::get( $posts[0] );
651
+ $fee_id = (int) $_GET['fee_id'];
652
+ $listing->set_fee_plan( $fee_id );
653
+
654
  $this->messages[] = _x('The fee was successfully assigned.', 'admin', 'WPBDM');
655
 
656
  break;
657
 
658
  case 'renewlisting':
659
  foreach ( $posts as $post_id ):
660
+ $listing = WPBDP_Listing::get( $post_id );
661
+ $listing->renew();
662
  endforeach;
663
 
664
  $this->messages[] = _nx( 'Listing was renewed.', 'Listings were renewed.', count( $posts ), 'admin', 'WPBDM' );
665
  break;
666
 
667
  case 'send-renewal-email':
668
+ $listing_id = intval( $_GET['listing_id'] );
669
+ $listing = WPBDP_Listing::get( $listing_id );
670
+
671
+ if ( ! $listing )
672
+ break;
673
 
674
+ wpbdp()->listing_email_notification->send_notices( 'expiration', '0 days', $listing_id, true );
675
+ $this->messages[] = _x( 'Renewal email sent.', 'admin', 'WPBDM' );
676
 
677
  break;
678
 
746
  return $value;
747
  }
748
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
749
  /* Uninstall. */
750
  public function uninstall_plugin() {
751
  global $wpdb;
773
  $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", 'wpbdp%' ) );
774
 
775
  // Clear scheduled hooks.
776
+ wp_clear_scheduled_hook('wpbdp_hourly_events');
777
+ wp_clear_scheduled_hook('wpbdp_daily_events');
778
 
779
  $tracking = new WPBDP_SiteTracking();
780
  $tracking->track_uninstall( isset( $_POST['uninstall'] ) ? $_POST['uninstall'] : null );
794
  }
795
  }
796
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
797
  /* Required pages check. */
798
  public function check_for_required_pages() {
799
  if ( ! wpbdp_get_page_id( 'main' ) && current_user_can( 'administrator' ) ) {
810
  }
811
  }
812
 
 
 
 
 
 
 
 
 
 
 
 
 
813
  /**
814
  * @since 3.6.10
815
  */
820
  }
821
  }
822
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
823
  public function check_setup() {
824
  global $pagenow;
825
 
826
+ if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp_settings' != $_GET['page'] )
827
  return;
828
 
829
  // Registration disabled message.
841
  public function check_ajax_compat_mode() {
842
  global $pagenow;
843
 
844
+ if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp_settings' != $_GET['page'] )
845
  return;
846
 
847
  $notice = get_option( 'wpbdp-ajax-compat-mode-notice' );
853
  delete_option( 'wpbdp-ajax-compat-mode-notice' );
854
  }
855
 
856
+ private function check_deprecation_warnings() {
857
+ global $wpbdp_deprecation_warnings;
858
+
859
+ if ( ! empty( $wpbdp_deprecation_warnings ) ) {
860
+ foreach ( $wpbdp_deprecation_warnings as $warning ) {
861
+ $this->messages[] = $warning;
862
+ }
863
+ }
864
+ }
865
+
866
  public function main_menu() {
867
  echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/home.tpl.php' );
868
  }
includes/admin/class-csv-exporter.php CHANGED
@@ -58,9 +58,6 @@ class WPBDP_CSVExporter {
58
  if ( $this->settings['include-users'] )
59
  $this->columns['username'] = 'username';
60
 
61
- if ( $this->settings['include-sticky-status'] )
62
- $this->columns['featured_level'] = 'featured_level';
63
-
64
  if ( $this->settings['include-expiration-date'] )
65
  $this->columns['expires_on'] = 'expires_on';
66
 
@@ -121,7 +118,7 @@ class WPBDP_CSVExporter {
121
  $shortnames = wpbdp_formfields_api()->get_short_names();
122
 
123
  foreach ( $state['columns'] as $fshortname ) {
124
- if ( in_array( $fshortname, array( 'images', 'username', 'featured_level', 'expires_on', 'sequence_id' ) ) ) {
125
  $export->columns[ $fshortname ] = $fshortname;
126
  continue;
127
  }
@@ -274,110 +271,84 @@ class WPBDP_CSVExporter {
274
  }
275
 
276
  private function extract_data( $post_id ) {
277
- global $wpdb;
278
 
279
- $post = get_post( $post_id );
280
-
281
- if ( !$post || $post->post_type != WPBDP_POST_TYPE )
282
  return false;
283
-
284
- $listings_api = wpbdp_listings_api();
285
- $upgrades_api = wpbdp_listing_upgrades_api();
286
 
287
  $data = array();
288
 
289
- foreach ( $this->columns as $colname => &$col ) {
290
- $association = is_object( $col ) ? $col->get_association() : $col;
291
  $value = '';
292
 
293
- switch( $association ) {
294
- case 'sequence_id':
295
- $value = $listings_api->calculate_sequence_id( $post->ID );
296
- break;
297
-
298
- /* Special columns. */
299
- case 'images':
 
 
 
 
300
  $upload_dir = wp_upload_dir();
301
- $listing_images = array();
302
 
303
- if ( $images = $listings_api->get_images( $post->ID ) ) {
304
- foreach ( $images as &$img ) {
305
- $img_metadata = wp_get_attachment_metadata( $img->ID );
306
 
307
- if ( !isset( $img_metadata['file'] ) )
308
- continue;
 
309
 
310
- $img_path = realpath( $upload_dir['basedir'] . DIRECTORY_SEPARATOR . $img_metadata['file'] );
311
 
312
- if ( !is_readable( $img_path ) )
313
- continue;
 
314
 
315
- $this->images_archive = !isset( $this->images_archive ) ? new PclZip( $this->workingdir . 'images.zip' ) : $this->images_archive;
316
- if ( $res = $this->images_archive->add( $img_path, PCLZIP_OPT_REMOVE_ALL_PATH ) )
317
- $listing_images[] = basename( $img_path );
318
  }
319
  }
 
320
 
321
- if ( $listing_images )
322
- $value = implode( $this->settings['images-separator'], $listing_images );
323
-
324
- break;
325
-
326
- case 'username':
327
- $value = get_the_author_meta( 'user_login', $post->post_author );
328
- break;
329
-
330
- case 'featured_level':
331
- $listing_level = $upgrades_api->get_listing_level( $post->ID );
332
- $value = $listing_level->id;
333
- break;
334
-
335
- case 'expires_on':
336
- $value = '';
337
- $terms = wp_get_post_terms( $post->ID,
338
- WPBDP_CATEGORY_TAX,
339
- 'fields=ids' );
340
- $expiresdata = $wpdb->get_results( $wpdb->prepare( "SELECT category_id, expires_on FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d", $post->ID ) );
341
- $expiresdata = wp_list_pluck( $expiresdata, 'expires_on', 'category_id' );
342
- $expiration_dates = array();
343
-
344
- foreach ( $terms as $term_id ) {
345
- if ( isset( $expiresdata[ $term_id ] ) )
346
- $expiration_dates[] = $expiresdata[ $term_id ];
347
- else
348
- $expiration_dates[] = '';
349
  }
350
- $value = implode( '/', $expiration_dates );
351
-
352
- break;
353
-
354
- /* Standard associations. */
355
- case 'category':
356
- case 'tags':
357
- $terms = wp_get_post_terms( $post->ID,
358
- $col->get_association() == 'tags' ? WPBDP_TAGS_TAX : WPBDP_CATEGORY_TAX,
359
- 'fields=names' );
360
- $terms = array_map( 'html_entity_decode', $terms );
361
-
362
- if ( $terms )
363
- $value = implode( $this->settings['category-separator'], $terms );
364
- break;
365
- case 'meta':
366
- default:
367
- $value = $col->csv_value( $post->ID );
368
 
369
- break;
370
  }
371
 
372
- if ( ! is_string( $value ) ) {
373
- if ( is_array( $value ) ) {
374
- $value = '';
375
- } else {
376
- $value = strval( $value );
377
- }
378
  }
379
 
380
- $data[ $colname ] = '"' . str_replace( '"', '""', $value ) . '"';
381
  }
382
 
383
  return $data;
58
  if ( $this->settings['include-users'] )
59
  $this->columns['username'] = 'username';
60
 
 
 
 
61
  if ( $this->settings['include-expiration-date'] )
62
  $this->columns['expires_on'] = 'expires_on';
63
 
118
  $shortnames = wpbdp_formfields_api()->get_short_names();
119
 
120
  foreach ( $state['columns'] as $fshortname ) {
121
+ if ( in_array( $fshortname, array( 'images', 'username', 'expires_on', 'sequence_id' ) ) ) {
122
  $export->columns[ $fshortname ] = $fshortname;
123
  continue;
124
  }
271
  }
272
 
273
  private function extract_data( $post_id ) {
274
+ $listing = wpbdp_get_listing( $post_id );
275
 
276
+ if ( ! $listing ) {
 
 
277
  return false;
278
+ }
 
 
279
 
280
  $data = array();
281
 
282
+ foreach ( $this->columns as $column_name => $column_obj ) {
 
283
  $value = '';
284
 
285
+ switch ( $column_name ) {
286
+ case 'sequence_id':
287
+ $value = $listing->get_sequence_id();
288
+ break;
289
+ case 'username':
290
+ $value = $listing->get_author_meta( 'login' );
291
+ break;
292
+ case 'images':
293
+ $images = array();
294
+
295
+ if ( $image_ids = $listing->get_images( 'ids' ) ) {
296
  $upload_dir = wp_upload_dir();
 
297
 
298
+ foreach ( $image_ids as $image_id ) {
299
+ $img_meta = wp_get_attachment_metadata( $image_id );
 
300
 
301
+ if ( empty( $img_meta['file'] ) ) {
302
+ continue;
303
+ }
304
 
305
+ $img_path = realpath( $upload_dir['basedir'] . DIRECTORY_SEPARATOR . $img_meta['file'] );
306
 
307
+ if ( ! is_readable( $img_path ) ) {
308
+ continue;
309
+ }
310
 
311
+ $this->images_archive = ( ! isset( $this->images_archive ) ) ? $this->get_pclzip_instance( $this->workingdir . 'images.zip' ) : $this->images_archive;
312
+ if ( $success = $this->images_archive->add( $img_path, PCLZIP_OPT_REMOVE_ALL_PATH ) ) {
313
+ $images[] = basename( $img_path );
314
  }
315
  }
316
+ }
317
 
318
+ $value = implode( $this->settings['images-separator'], $images );
319
+ break;
320
+ case 'expires_on':
321
+ case 'expiration_date':
322
+ if ( $plan = $listing->get_fee_plan() ) {
323
+ $value = $plan->expiration_date;
324
+ }
325
+ break;
326
+ default:
327
+ if ( is_object( $column_obj ) ) {
328
+ $field = $column_obj;
329
+
330
+ switch ( $field->get_association() ) {
331
+ case 'category':
332
+ case 'tags':
333
+ $value = wp_get_post_terms( $listing->get_id(), ( 'tags' == $field->get_association() ? WPBDP_TAGS_TAX : WPBDP_CATEGORY_TAX ), 'fields=names' );
334
+ $value = array_map( 'html_entity_decode', $value );
335
+ $value = implode( $this->settings['category-separator'], $value );
336
+ break;
337
+ case 'meta':
338
+ default:
339
+ $value = $field->csv_value( $listing->get_id() );
340
+ break;
 
 
 
 
 
341
  }
342
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
+ break;
345
  }
346
 
347
+ if ( ! is_string( $value ) && ! is_array( $value ) ) {
348
+ $value = strval( $value );
 
 
 
 
349
  }
350
 
351
+ $data[ $column_name ] = '"' . str_replace( '"', '""', $value ) . '"';
352
  }
353
 
354
  return $data;
includes/admin/class-csv-import.php CHANGED
@@ -245,10 +245,6 @@ class WPBDP_CSV_Import {
245
  }
246
 
247
  public function cleanup() {
248
- global $wpdb;
249
-
250
- $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'wpbdp-slug-%'" );
251
-
252
  wpbdp_rrmdir( $this->working_dir );
253
  }
254
 
@@ -260,7 +256,7 @@ class WPBDP_CSV_Import {
260
 
261
  $csv_imports_dir = rtrim( $upload_dir['basedir'], DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . 'wpbdp-csv-imports' . DIRECTORY_SEPARATOR . $state_id;
262
 
263
- // TODO: validate $state_id is really an uniqid() string and does not contain other chars (maybe someone is
264
  // trying to access parts that it shouldn't in the FS).
265
  if ( ! is_dir( $csv_imports_dir ) )
266
  throw new Exception( 'Invalid state ID' );
@@ -429,8 +425,9 @@ class WPBDP_CSV_Import {
429
  global $wpdb;
430
  global $wpbdp;
431
 
432
- if ( $this->settings['test-import'] )
433
  return;
 
434
 
435
  extract( $data );
436
 
@@ -480,26 +477,19 @@ class WPBDP_CSV_Import {
480
  }
481
 
482
  // Handle fields.
483
- $post_data_associations = array( 'title', 'excerpt', 'content' );
484
- foreach ( array_keys( $fields ) as $field_id ) {
485
  $f = wpbdp_get_form_field( $field_id );
486
 
487
- $field_data = $fields[ $field_id ];
488
- $association = $f->get_association();
489
 
490
- if ( 'image' == $f->get_field_type_id() ) {
491
- $img = trim( $field_data );
492
 
493
- if ( ! $img ) {
494
- continue;
495
- }
496
 
497
- $media_id = $this->upload_image( $img );
498
- $fields[ $field_id ] = $media_id ? $media_id : '';
499
- } elseif ( in_array( $association, $post_data_associations, true ) ) {
500
- $state->{$association} = $field_data;
501
- unset( $fields[ $field_id ] );
502
- }
503
  }
504
 
505
  $state->fields = $fields;
@@ -510,55 +500,24 @@ class WPBDP_CSV_Import {
510
  $state->images[] = $img_id;
511
  }
512
 
513
- if ( isset( $state->title ) ) {
514
- $state->post_name = $this->get_unique_post_name( sanitize_title( $state->title ) );
 
 
 
 
 
515
  }
516
 
517
- // Set username.
518
  if ( $u = get_user_by( 'login', $meta['username'] ) ) {
519
- $state->post_author = $u->ID;
520
  }
521
 
522
- // Insert or update listing.
523
- if ( $listing_id ) {
524
- $state->post_status = wpbdp_get_option( 'edit-post-status' );
525
-
526
- $listing = WPBDP_Listing::get( $listing_id );
527
- $listing->update( $state, array( 'append-images' => $this->settings['append-images'] ) );
528
- } else {
529
- $state->post_status = $this->settings['post-status'];
530
-
531
- $listing = WPBDP_Listing::create( $state );
532
- $listing->set_field_values( $state->fields, true );
533
- $listing->set_images( $state->images );
534
- $listing->set_categories( $state->categories, 'nofix' );
535
- $listing->save();
536
- }
537
-
538
- // Set featured level.
539
- if ( $meta['featured_level'] ) {
540
- if ( $l = $wpbdp->listings->upgrades->get( $meta['featured_level'] ) )
541
- $wpbdp->listings->upgrades->set_sticky( $listing->get_id(), $l->id );
542
  }
543
 
544
- // Update expiration dates.
545
- foreach ( $categories as $c ) {
546
- if ( ! $c['expires_on'] )
547
- continue;
548
-
549
- if( strtotime( $c['expires_on'] ) <= 0 )
550
- continue;
551
-
552
- $wpdb->update( $wpdb->prefix . 'wpbdp_listing_fees',
553
- array( 'expires_on' => $c['expires_on'] ),
554
- array( 'category_id' => $c['term_id'],
555
- 'listing_id' => $listing->get_id() ) );
556
- }
557
-
558
- // Update sequence_id.
559
- if ( $meta['sequence_id'] )
560
- update_post_meta( $listing->get_id(), '_wpbdp[import_sequence_id]', $meta['sequence_id'] );
561
-
562
  if ( $errors ) {
563
  $error = new WP_Error();
564
 
@@ -579,12 +538,11 @@ class WPBDP_CSV_Import {
579
  $categories = array();
580
  $fields = array();
581
  $images = array();
582
- $expires_on = array();
583
 
584
  $meta = array();
585
  $meta['sequence_id'] = 0;
586
  $meta['username'] = '';
587
- $meta['featured_level'] = '';
588
 
589
  if ( $this->settings['assign-listings-to-user'] && $this->settings['default-user'] ) {
590
  if ( $u = get_user_by( 'id', $this->settings['default-user'] ) )
@@ -621,17 +579,9 @@ class WPBDP_CSV_Import {
621
 
622
  break;
623
 
624
- case 'featured_level':
625
- $meta['featured_level'] = $value;
626
-
627
- break;
628
-
629
  case 'expires_on':
630
  $dates = explode( '/', $value );
631
-
632
- foreach ( $dates as $d )
633
- $expires_on[] = $d;
634
-
635
  break;
636
 
637
  case 'sequence_id':
@@ -663,7 +613,7 @@ class WPBDP_CSV_Import {
663
  continue;
664
 
665
  if ( $term = term_exists( $csv_category, WPBDP_CATEGORY_TAX ) ) {
666
- $categories[] = array( 'name' => $csv_category, 'term_id' => $term['term_id'], 'expires_on' => '' );
667
  } else {
668
  if ( ! $this->settings['create-missing-categories'] ) {
669
  $errors[] = sprintf( _x( 'Listing category "%s" does not exist', 'admin csv-import', 'WPBDM' ), $csv_category );
@@ -673,7 +623,7 @@ class WPBDP_CSV_Import {
673
  if ( $this->settings['test-import'] )
674
  continue;
675
 
676
- $categories[] = array( 'name' => $csv_category, 'term_id' => 0, 'expires_on' => '' );
677
  }
678
  }
679
  }/* else if ( 'tags' == $field->get_association() ) {
@@ -687,14 +637,7 @@ class WPBDP_CSV_Import {
687
  }
688
  }
689
 
690
- if ( $categories && $expires_on ) {
691
- foreach ( $categories as $i => &$category_data ) {
692
- if ( ! empty( $expires_on[ $i ] ) )
693
- $category_data['expires_on'] = $expires_on[ $i ];
694
- }
695
- }
696
-
697
- return array( compact( 'categories', 'fields', 'images', 'meta' ), $errors );
698
  }
699
 
700
  private function get_header() {
@@ -713,22 +656,4 @@ class WPBDP_CSV_Import {
713
 
714
  return $media_id;
715
  }
716
-
717
- private function get_unique_post_name( $post_name ) {
718
- global $wpdb;
719
-
720
- $post_name_hash = 'wpbdp-slug-' . sha1( $post_name );
721
-
722
- $sql = "SELECT option_value FROM $wpdb->options WHERE option_name = '%s'";
723
- $slug_prefix = $wpdb->get_var( $wpdb->prepare( $sql, $post_name_hash ) );
724
-
725
- if ( ! is_null( $slug_prefix ) && function_exists( '_truncate_post_slug' ) ) {
726
- $slug_prefix = intval( $slug_prefix ) + 1;
727
- $post_name = _truncate_post_slug( $post_name, 200 - strlen( $slug_prefix ) - 1 ) . '-' . $slug_prefix;
728
- $sql = "UPDATE $wpdb->options SET option_value = '%s' WHERE option_name = '%s'";
729
- $wpdb->query( $wpdb->prepare( $sql, $slug_prefix, $post_name_hash ) );
730
- }
731
-
732
- return $post_name;
733
- }
734
  }
245
  }
246
 
247
  public function cleanup() {
 
 
 
 
248
  wpbdp_rrmdir( $this->working_dir );
249
  }
250
 
256
 
257
  $csv_imports_dir = rtrim( $upload_dir['basedir'], DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . 'wpbdp-csv-imports' . DIRECTORY_SEPARATOR . $state_id;
258
 
259
+ // TODO: validate $state_id is really an uniqid() string and does not contain other chars (maybe someone is
260
  // trying to access parts that it shouldn't in the FS).
261
  if ( ! is_dir( $csv_imports_dir ) )
262
  throw new Exception( 'Invalid state ID' );
425
  global $wpdb;
426
  global $wpbdp;
427
 
428
+ if ( $this->settings['test-import'] ) {
429
  return;
430
+ }
431
 
432
  extract( $data );
433
 
477
  }
478
 
479
  // Handle fields.
480
+ foreach ( $fields as $field_id => $field_data ) {
 
481
  $f = wpbdp_get_form_field( $field_id );
482
 
483
+ if ( 'image' != $f->get_field_type_id() )
484
+ continue;
485
 
486
+ $img = trim( $field_data );
 
487
 
488
+ if ( ! $img )
489
+ continue;
 
490
 
491
+ $media_id = $this->upload_image( $img );
492
+ $fields[ $field_id ] = $media_id ? $media_id : '';
 
 
 
 
493
  }
494
 
495
  $state->fields = $fields;
500
  $state->images[] = $img_id;
501
  }
502
 
503
+ // Insert or update listing.
504
+ $listing_data = (array) $state;
505
+ $listing_data['listing_id'] = $listing_id;
506
+ $listing_data['append_images'] = $this->settings['append-images'];
507
+ $listing_data['post_status'] = $listing_id ? wpbdp_get_option( 'edit-post-status' ) : $this->settings['post-status'];
508
+ if ( $meta['sequence_id'] ) {
509
+ $listing_data['sequence_id'] = $meta['sequence_id'];
510
  }
511
 
 
512
  if ( $u = get_user_by( 'login', $meta['username'] ) ) {
513
+ $listing_data['user_id'] = $u->ID;
514
  }
515
 
516
+ $listing = wpbdp_save_listing( $listing_data, true, 'csv-import' );
517
+ if ( is_wp_error( $listing ) ) {
518
+ $errors = array_merge( $errors, $listing->get_error_messages() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  }
520
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  if ( $errors ) {
522
  $error = new WP_Error();
523
 
538
  $categories = array();
539
  $fields = array();
540
  $images = array();
541
+ $expires_on = '';
542
 
543
  $meta = array();
544
  $meta['sequence_id'] = 0;
545
  $meta['username'] = '';
 
546
 
547
  if ( $this->settings['assign-listings-to-user'] && $this->settings['default-user'] ) {
548
  if ( $u = get_user_by( 'id', $this->settings['default-user'] ) )
579
 
580
  break;
581
 
 
 
 
 
 
582
  case 'expires_on':
583
  $dates = explode( '/', $value );
584
+ $expires_on = $dates[0];
 
 
 
585
  break;
586
 
587
  case 'sequence_id':
613
  continue;
614
 
615
  if ( $term = term_exists( $csv_category, WPBDP_CATEGORY_TAX ) ) {
616
+ $categories[] = array( 'name' => $csv_category, 'term_id' => $term['term_id'] );
617
  } else {
618
  if ( ! $this->settings['create-missing-categories'] ) {
619
  $errors[] = sprintf( _x( 'Listing category "%s" does not exist', 'admin csv-import', 'WPBDM' ), $csv_category );
623
  if ( $this->settings['test-import'] )
624
  continue;
625
 
626
+ $categories[] = array( 'name' => $csv_category, 'term_id' => 0 );
627
  }
628
  }
629
  }/* else if ( 'tags' == $field->get_association() ) {
637
  }
638
  }
639
 
640
+ return array( compact( 'categories', 'fields', 'images', 'meta', 'expires_on' ), $errors );
 
 
 
 
 
 
 
641
  }
642
 
643
  private function get_header() {
656
 
657
  return $media_id;
658
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
  }
includes/admin/class-listing-fields-metabox.php CHANGED
@@ -7,9 +7,19 @@ class WPBDP_Admin_Listing_Fields_Metabox {
7
  }
8
 
9
  public function render() {
 
 
10
  echo '<div id="wpbdp-submit-listing">';
11
 
12
- echo '<div id="wpbdp-listing-fields-fields" class="wpbdp-admin-tab-content" tabindex="1">';
 
 
 
 
 
 
 
 
13
  $this->listing_fields();
14
  echo '</div>';
15
 
@@ -38,13 +48,15 @@ class WPBDP_Admin_Listing_Fields_Metabox {
38
  return;
39
 
40
  $images = $this->listing->get_images( 'all', true );
 
41
 
42
- echo '<div class="wpbdp-submit-page step-images">';
43
- echo wpbdp_render( 'submit-listing/images',
44
  array(
45
- 'admin' => true,
46
- 'listing' => $this->listing,
47
- 'images' => $images ) );
 
48
  echo '</div>';
49
  }
50
 
@@ -58,3 +70,4 @@ class WPBDP_Admin_Listing_Fields_Metabox {
58
  return $instance->render();
59
  }
60
  }
 
7
  }
8
 
9
  public function render() {
10
+ $image_count = count( $this->listing->get_images( 'ids' ) );
11
+
12
  echo '<div id="wpbdp-submit-listing">';
13
 
14
+ echo '<ul class="wpbdp-admin-tab-nav subsubsub">';
15
+ echo '<li><a href="#wpbdp-listing-fields-fields">' . _x( 'Fields', 'admin', 'WPBDM' ) . '</a> | </li>';
16
+ echo '<li><a href="#wpbdp-listing-fields-images">';
17
+ echo '<span class="with-image-count ' . ( $image_count > 0 ? '' : ' hidden' ) . '">' . sprintf( _x( 'Images (%s)', 'admin', 'WPBDM' ), '<span>' . $image_count . '</span>' ) . '</span>';
18
+ echo '<span class="no-image-count' . ( $image_count > 0 ? ' hidden' : '' ) . '">' . _x( 'Images', 'admin', 'WPBDM' ) . '</span>';
19
+ echo '</a></li>';
20
+ echo '</ul>';
21
+
22
+ echo '<div id="wpbdp-listing-fields-fields" class="wpbdp-admin-tab-content" tabindex="1">';
23
  $this->listing_fields();
24
  echo '</div>';
25
 
48
  return;
49
 
50
  $images = $this->listing->get_images( 'all', true );
51
+ $thumbnail_id = $this->listing->get_thumbnail_id();
52
 
53
+ echo '<div class="wpbdp-submit-listing-section-listing_images">';
54
+ echo wpbdp_render( 'submit-listing-images',
55
  array(
56
+ 'admin' => true,
57
+ 'thumbnail_id' => $thumbnail_id,
58
+ 'listing' => $this->listing,
59
+ 'images' => $images ) );
60
  echo '</div>';
61
  }
62
 
70
  return $instance->render();
71
  }
72
  }
73
+
includes/admin/class-themes-admin.php CHANGED
@@ -5,25 +5,22 @@
5
  class WPBDP_Themes_Admin {
6
 
7
  private $api;
8
- private $updater;
9
 
10
 
11
- function __construct( &$api ) {
12
  $this->api = $api;
 
13
 
14
- require_once( WPBDP_INC . 'admin/upgrades/class-themes-updater.php' );
15
- $this->updater = new WPBDP_Themes_Updater( $this->api );
 
16
 
17
- add_action( 'wp_ajax_wpbdp-themes-activate-license', array( &$this, 'ajax_activate_license' ) );
18
- add_action( 'wp_ajax_wpbdp-themes-deactivate-license', array( &$this, 'ajax_deactivate_license' ) );
19
-
20
-
21
- add_filter( 'wpbdp_admin_menu_badge_number', array( &$this, 'admin_menu_badge_count' ) );
22
  add_action( 'wpbdp_admin_menu', array( &$this, 'admin_menu' ) );
23
  add_filter( 'wpbdp_admin_menu_reorder', array( &$this, 'admin_menu_move_themes_up' ) );
24
 
25
  add_action( 'wpbdp_admin_notices', array( &$this, 'pre_themes_templates_warning' ) );
26
- add_action( 'wpbdp_admin_notices', array( &$this, 'warn_about_licenses' ) );
27
 
28
  add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
29
 
@@ -32,11 +29,12 @@ class WPBDP_Themes_Admin {
32
  add_action( 'wpbdp_action_upload-theme', array( &$this, 'upload_theme' ) );
33
  add_action( 'wpbdp_action_create-theme-suggested-fields', array( &$this, 'create_suggested_fields' ) );
34
 
35
- add_action( 'wpbdp-admin-themes-extra', array( &$this, 'enter_license_key_row' ) );
36
  }
37
 
38
  function admin_menu( $slug ) {
39
- $count = $this->updater->get_updates_count();
 
40
 
41
  if ( $count )
42
  $count_html = '<span class="update-plugins"><span class="plugin-count">' . number_format_i18n( $count ) . '</span></span>';
@@ -105,33 +103,6 @@ class WPBDP_Themes_Admin {
105
  wpbdp_admin_message( $msg, 'error' );
106
  }
107
 
108
- function warn_about_licenses() {
109
- global $pagenow;
110
-
111
- if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp-themes' != $_GET['page'] )
112
- return;
113
-
114
- $themes = $this->api->get_installed_themes();
115
- $licenses_needed = false;
116
-
117
- foreach ( $themes as $t ) {
118
- if ( ! $t->can_be_activated ) {
119
- $licenses_needed = true;
120
- break;
121
- }
122
- }
123
-
124
- if ( ! $licenses_needed )
125
- return;
126
-
127
- $msg = _x( 'You need to <a>activate your theme\'s license key</a> before you can activate the theme. <a>Click here</a> to do that.',
128
- 'admin themes',
129
- 'WPBDM' );
130
- $msg = str_replace( '<a>', '<a href="' . esc_url( admin_url( 'admin.php?page=wpbdp-themes&v=licenses' ) ) . '">', $msg );
131
-
132
- wpbdp_admin_message( $msg, 'error' );
133
- }
134
-
135
  function enqueue_scripts( $hook ) {
136
  global $wpbdp;
137
  global $pagenow;
@@ -139,8 +110,6 @@ class WPBDP_Themes_Admin {
139
  if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp-themes' != $_GET['page'] )
140
  return;
141
 
142
- $debug_on = $wpbdp->is_debug_on();
143
-
144
  wp_enqueue_style( 'wpbdp-admin-themes',
145
  WPBDP_URL . 'assets/css/admin-themes.min.css' );
146
  wp_enqueue_script( 'wpbdp-admin-themes',
@@ -186,9 +155,6 @@ class WPBDP_Themes_Admin {
186
  case 'delete-theme':
187
  return $this->theme_delete_confirm();
188
  break;
189
- case 'licenses':
190
- return $this->theme_licenses();
191
- break;
192
  case 'theme-selection':
193
  default:
194
  return $this->theme_selection();
@@ -235,7 +201,7 @@ class WPBDP_Themes_Admin {
235
  break;
236
  }
237
 
238
- $themes = $this->api->get_installed_themes();
239
  $active_theme = $this->api->get_active_theme();
240
 
241
  // Make sure the current theme is always first.
@@ -248,6 +214,26 @@ class WPBDP_Themes_Admin {
248
  'active_theme' => $active_theme ) );
249
  }
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  function upload_theme() {
252
  if ( ! current_user_can( 'administrator' ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'upload theme zip' ) )
253
  wp_die();
@@ -332,132 +318,6 @@ class WPBDP_Themes_Admin {
332
  exit;
333
  }
334
 
335
- function ajax_activate_license() {
336
- if ( ! current_user_can( 'administrator' ) )
337
- die();
338
-
339
- $nonce = $_POST['nonce'];
340
- $theme = $_POST['theme'];
341
- $license = trim( $_POST['license'] );
342
-
343
- if ( ! wp_verify_nonce( $nonce, 'activate ' . $theme ) )
344
- die();
345
-
346
- // Try to activate license.
347
- $info = $this->api->get_theme( $theme );
348
- if ( ! $info )
349
- die();
350
-
351
- $edd_name = ! empty ( $info->edd_name ) ? $info->edd_name : $info->name;
352
- if ( ! $edd_name )
353
- die();
354
-
355
- // Try to activate theme.
356
- $error = false;
357
- $request_vars = array(
358
- 'edd_action' => 'activate_license',
359
- 'license' => $license,
360
- 'item_name' => urlencode( $edd_name ),
361
- 'url' => home_url()
362
- );
363
- $request = wp_remote_get( add_query_arg( $request_vars, 'http://businessdirectoryplugin.com/' ), array( 'timeout' => 15, 'sslverify' => false ) );
364
-
365
- if ( is_wp_error( $request ) )
366
- $error = _x( 'Could not contact licensing server', 'licensing', 'WPBDM' );
367
-
368
- if ( ! $error ) {
369
- $request_result = json_decode( wp_remote_retrieve_body( $request ) );
370
-
371
- if ( ! is_object( $request_result ) || ! $request_result || ! isset( $request_result->license ) || 'valid' !== $request_result->license )
372
- $error = _x( 'License key is invalid', 'licensing', 'WPBDM' );
373
- }
374
-
375
- $response = new WPBDP_Ajax_Response();
376
- if ( $error )
377
- return $response->send_error( sprintf( _x( 'Could not activate license: %s.', 'licensing', 'WPBDM' ), $error ) );
378
-
379
- // Store license details.
380
- $theme_licenses = get_option( 'wpbdp-themes-licenses', array() );
381
- if ( ! is_array( $theme_licenses ) )
382
- $theme_licenses = array();
383
-
384
- $theme_licenses[ $theme ] = array( 'license' => $license,
385
- 'status' => 'valid',
386
- 'updated' => time() );
387
-
388
- update_option( 'wpbdp-themes-licenses', $theme_licenses );
389
-
390
- $response->set_message( _x( 'License activated', 'licensing', 'WPBDM' ) );
391
- $response->send();
392
- }
393
-
394
- function ajax_deactivate_license() {
395
- if ( ! current_user_can( 'administrator' ) )
396
- die();
397
-
398
- $nonce = $_POST['nonce'];
399
- $theme = $_POST['theme'];
400
-
401
- if ( ! wp_verify_nonce( $nonce, 'deactivate ' . $theme ) )
402
- die();
403
-
404
- // Try to activate license.
405
- $info = $this->api->get_theme( $theme );
406
- if ( ! $info )
407
- die();
408
-
409
- $edd_name = ! empty ( $info->edd_name ) ? $info->edd_name : $info->name;
410
- if ( ! $edd_name )
411
- die();
412
-
413
- if ( empty( $info->license_key ) )
414
- die();
415
-
416
- // Try to deactivate the key.
417
- $error = false;
418
- $request_vars = array(
419
- 'edd_action' => 'deactivate_license',
420
- 'license' => $info->license_key,
421
- 'item_name' => urlencode( $edd_name ),
422
- 'url' => home_url()
423
- );
424
- $request = wp_remote_get( add_query_arg( $request_vars, 'http://businessdirectoryplugin.com/' ), array( 'timeout' => 15, 'sslverify' => false ) );
425
-
426
- if ( is_wp_error( $request ) )
427
- $error = _x( 'Could not contact licensing server', 'licensing', 'WPBDM' );
428
-
429
- if ( ! $error ) {
430
- $request_result = json_decode( wp_remote_retrieve_body( $request ) );
431
-
432
- if ( ! is_object( $request_result ) || ! $request_result || ! isset( $request_result->success ) || ! $request_result->success )
433
- $error = _x( 'Invalid response from server', 'licensing', 'WPBDM' );
434
- }
435
-
436
- $response = new WPBDP_Ajax_Response();
437
- // if ( $error )
438
- // return $response->send_error( sprintf( _x( 'Could not deactivate license: %s.', 'licensing', 'WPBDM' ), $error ) );
439
-
440
- // Store license details.
441
- $theme_licenses = get_option( 'wpbdp-themes-licenses', array() );
442
- if ( ! is_array( $theme_licenses ) )
443
- $theme_licenses = array();
444
-
445
- if ( isset( $theme_licenses[ $theme ] ) )
446
- unset( $theme_licenses[ $theme ] );
447
-
448
- update_option( 'wpbdp-themes-licenses', $theme_licenses );
449
-
450
- $response->set_message( _x( 'License deactivated', 'licensing', 'WPBDM' ) );
451
- $response->send();
452
- }
453
-
454
- function theme_licenses() {
455
- $themes = $this->api->get_installed_themes();
456
-
457
- echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/themes-licenses.tpl.php',
458
- array( 'themes' => $themes ) );
459
- }
460
-
461
  function enter_license_key_row( $theme ) {
462
  if ( $theme->can_be_activated )
463
  return;
5
  class WPBDP_Themes_Admin {
6
 
7
  private $api;
8
+ private $licensing;
9
 
10
 
11
+ function __construct( &$api, $licensing ) {
12
  $this->api = $api;
13
+ $this->licensing = $licensing;
14
 
15
+ // return;
16
+ // require_once( WPBDP_PATH . 'includes/admin/upgrades/class-themes-updater.php' );
17
+ // $this->updater = new WPBDP_Themes_Updater( $this->api );
18
 
19
+ // add_filter( 'wpbdp_admin_menu_badge_number', array( &$this, 'admin_menu_badge_count' ) );
 
 
 
 
20
  add_action( 'wpbdp_admin_menu', array( &$this, 'admin_menu' ) );
21
  add_filter( 'wpbdp_admin_menu_reorder', array( &$this, 'admin_menu_move_themes_up' ) );
22
 
23
  add_action( 'wpbdp_admin_notices', array( &$this, 'pre_themes_templates_warning' ) );
 
24
 
25
  add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
26
 
29
  add_action( 'wpbdp_action_upload-theme', array( &$this, 'upload_theme' ) );
30
  add_action( 'wpbdp_action_create-theme-suggested-fields', array( &$this, 'create_suggested_fields' ) );
31
 
32
+ // add_action( 'wpbdp-admin-themes-extra', array( &$this, 'enter_license_key_row' ) );
33
  }
34
 
35
  function admin_menu( $slug ) {
36
+ // $count = $this->updater->get_updates_count();
37
+ $count = 0;
38
 
39
  if ( $count )
40
  $count_html = '<span class="update-plugins"><span class="plugin-count">' . number_format_i18n( $count ) . '</span></span>';
103
  wpbdp_admin_message( $msg, 'error' );
104
  }
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  function enqueue_scripts( $hook ) {
107
  global $wpbdp;
108
  global $pagenow;
110
  if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) || 'wpbdp-themes' != $_GET['page'] )
111
  return;
112
 
 
 
113
  wp_enqueue_style( 'wpbdp-admin-themes',
114
  WPBDP_URL . 'assets/css/admin-themes.min.css' );
115
  wp_enqueue_script( 'wpbdp-admin-themes',
155
  case 'delete-theme':
156
  return $this->theme_delete_confirm();
157
  break;
 
 
 
158
  case 'theme-selection':
159
  default:
160
  return $this->theme_selection();
201
  break;
202
  }
203
 
204
+ $themes = $this->get_installed_themes();
205
  $active_theme = $this->api->get_active_theme();
206
 
207
  // Make sure the current theme is always first.
214
  'active_theme' => $active_theme ) );
215
  }
216
 
217
+ private function get_installed_themes() {
218
+ $themes = $this->api->get_installed_themes();
219
+
220
+ foreach( $themes as &$theme ) {
221
+ if ( $theme->is_core_theme ) {
222
+ $license_status = 'valid';
223
+ } else {
224
+ $license_status = $this->licensing->get_license_status( null, $theme->id, 'theme' );
225
+ }
226
+
227
+ if ( 'valid' === $license_status ) {
228
+ $theme->can_be_activated = true;
229
+ } else {
230
+ $theme->can_be_activated = false;
231
+ }
232
+ }
233
+
234
+ return $themes;
235
+ }
236
+
237
  function upload_theme() {
238
  if ( ! current_user_can( 'administrator' ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'upload theme zip' ) )
239
  wp_die();
318
  exit;
319
  }
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  function enter_license_key_row( $theme ) {
322
  if ( $theme->can_be_activated )
323
  return;
includes/admin/csv-export.php CHANGED
@@ -14,13 +14,8 @@ class WPBDP_Admin_CSVExport {
14
  }
15
 
16
  public function enqueue_scripts() {
17
- global $plugin_page;
18
-
19
- if ( 'wpbdp-csv-export' != $plugin_page )
20
- return;
21
-
22
- wp_enqueue_script( 'wpbdp-admin-export-js', WPBDP_URL . 'assets/js/admin-export.js', array( 'wpbdp-admin-js', 'jquery-ui-dialog' ) );
23
- wp_enqueue_style( 'wpbdp-admin-export-css', WPBDP_URL . 'assets/css/admin-export.min.css', array( 'wp-jquery-ui-dialog' ) );
24
  }
25
 
26
  public function dispatch() {
14
  }
15
 
16
  public function enqueue_scripts() {
17
+ wp_enqueue_script( 'wpbdp-admin-export-js', WPBDP_URL . 'assets/js/admin-export.min.js', array( 'wpbdp-admin-js' ) );
18
+ wp_enqueue_style( 'wpbdp-admin-export-css', WPBDP_URL . 'assets/css/admin-export.min.css' );
 
 
 
 
 
19
  }
20
 
21
  public function dispatch() {
includes/admin/csv-import.php CHANGED
@@ -17,11 +17,6 @@ class WPBDP_CSVImportAdmin {
17
  }
18
 
19
  function enqueue_scripts() {
20
- global $plugin_page;
21
-
22
- if ( 'wpbdp-csv-import' != $plugin_page )
23
- return;
24
-
25
  wp_enqueue_script( 'wpbdp-admin-import-js', WPBDP_URL . 'assets/js/admin-csv-import.min.js', array( 'wpbdp-admin-js', 'jquery-ui-autocomplete' ) );
26
  wp_enqueue_style( 'wpbdp-admin-import-css', WPBDP_URL . 'assets/css/admin-csv-import.min.css' );
27
  }
@@ -56,9 +51,7 @@ class WPBDP_CSVImportAdmin {
56
  $wpbdp->_importing_csv_no_email = (bool) $import->get_setting( 'disable-email-notifications' );
57
 
58
  wp_defer_term_counting( true );
59
- add_filter( 'wp_unique_post_slug', array( $this, 'cache_unique_slug_prefix' ), 10, 6 );
60
  $import->do_work();
61
- remove_filter( 'wp_unique_post_slug', array( $this, 'cache_unique_slug_prefix' ), 10, 6 );
62
  wp_defer_term_counting( false );
63
 
64
  unset( $wpbdp->_importing_csv ); unset( $wpbdp->_importing_csv_no_email );
@@ -77,26 +70,6 @@ class WPBDP_CSVImportAdmin {
77
  $res->send();
78
  }
79
 
80
- public function cache_unique_slug_prefix( $slug, $post_id, $post_status, $post_type, $post_parent, $original_slug ) {
81
- global $wpdb;
82
-
83
- if ( $slug == $original_slug ) {
84
- return $slug;
85
- }
86
-
87
- if ( ! preg_match( '/-(\d+)$/', $slug, $matches ) ) {
88
- return $slug;
89
- }
90
-
91
- $wpdb->insert( $wpdb->options, array(
92
- 'option_name' => 'wpbdp-slug-' . sha1( $original_slug ),
93
- 'option_value' => intval( $matches[1] ),
94
- 'autoload' => 'no',
95
- ) );
96
-
97
- return $slug;
98
- }
99
-
100
  public function ajax_autocomplete_user() {
101
  $users = get_users( array( 'search' => "*{$_REQUEST['term']}*" ) );
102
 
@@ -175,7 +148,7 @@ class WPBDP_CSVImportAdmin {
175
  private function example_csv() {
176
  echo wpbdp_admin_header(_x('Example CSV Import File', 'admin csv-import', 'WPBDM'), null, array(
177
  array(_x('← Return to "CSV Import"', 'admin csv-import', 'WPBDM'), esc_url(remove_query_arg('action')))
178
- ));
179
 
180
  $posts = get_posts(array(
181
  'post_type' => WPBDP_POST_TYPE,
@@ -369,3 +342,6 @@ class WPBDP_CSVImportAdmin {
369
  }
370
 
371
  }
 
 
 
17
  }
18
 
19
  function enqueue_scripts() {
 
 
 
 
 
20
  wp_enqueue_script( 'wpbdp-admin-import-js', WPBDP_URL . 'assets/js/admin-csv-import.min.js', array( 'wpbdp-admin-js', 'jquery-ui-autocomplete' ) );
21
  wp_enqueue_style( 'wpbdp-admin-import-css', WPBDP_URL . 'assets/css/admin-csv-import.min.css' );
22
  }
51
  $wpbdp->_importing_csv_no_email = (bool) $import->get_setting( 'disable-email-notifications' );
52
 
53
  wp_defer_term_counting( true );
 
54
  $import->do_work();
 
55
  wp_defer_term_counting( false );
56
 
57
  unset( $wpbdp->_importing_csv ); unset( $wpbdp->_importing_csv_no_email );
70
  $res->send();
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  public function ajax_autocomplete_user() {
74
  $users = get_users( array( 'search' => "*{$_REQUEST['term']}*" ) );
75
 
148
  private function example_csv() {
149
  echo wpbdp_admin_header(_x('Example CSV Import File', 'admin csv-import', 'WPBDM'), null, array(
150
  array(_x('← Return to "CSV Import"', 'admin csv-import', 'WPBDM'), esc_url(remove_query_arg('action')))
151
+ ), false);
152
 
153
  $posts = get_posts(array(
154
  'post_type' => WPBDP_POST_TYPE,
342
  }
343
 
344
  }
345
+
346
+
347
+
includes/admin/fees.php CHANGED
@@ -1,56 +1,38 @@
1
  <?php
2
-
3
- class WPBDP_FeesAdmin {
4
-
5
- public function __construct() {
6
- $this->admin = wpbdp()->admin;
7
- $this->api = wpbdp()->fees;
 
 
8
  }
9
 
10
- public function dispatch() {
11
- $action = wpbdp_getv($_REQUEST, 'action');
12
- $_SERVER['REQUEST_URI'] = remove_query_arg(array('action', 'id'), $_SERVER['REQUEST_URI']);
13
-
14
- switch ($action) {
15
- case 'addfee':
16
- case 'editfee':
17
- $this->processFieldForm();
18
- break;
19
- case 'enablefee':
20
- $fee = WPBDP_Fee_Plan::find( $_REQUEST['id'] );
21
- if ( $fee && $fee->update( array( 'enabled' => 1 ) ) )
22
- wpbdp_admin_message( _x( 'Fee enabled.', 'fees admin', 'WPBDM' ) );
23
-
24
- return $this->feesTable();
25
-
26
- break;
27
- case 'disablefee':
28
- $fee = WPBDP_Fee_Plan::find( $_REQUEST['id'] );
29
- if ( $fee && $fee->update( array( 'enabled' => 0 ) ) )
30
- wpbdp_admin_message( _x( 'Fee disabled.', 'fees admin', 'WPBDM' ) );
31
-
32
- return $this->feesTable();
33
-
34
- break;
35
- case 'deletefee':
36
- $this->delete_fee();
37
- break;
38
- default:
39
- $this->feesTable();
40
- break;
41
  }
42
- }
43
 
44
- public static function admin_menu_cb() {
45
- $instance = new WPBDP_FeesAdmin();
46
- $instance->dispatch();
47
  }
48
 
49
- /* field list */
50
- private function feesTable() {
51
- require_once( WPBDP_INC . 'admin/helpers/class-fees-table.php' );
52
 
53
- $table = new WPBDP_FeesTable();
54
  $table->prepare_items();
55
 
56
  $order_options = array();
@@ -62,60 +44,90 @@ class WPBDP_FeesAdmin {
62
  $order_options[ $k ] = $l;
63
  }
64
 
65
- wpbdp_render_page(WPBDP_PATH . 'templates/admin/fees.tpl.php',
66
- array( 'table' => $table,
67
- 'order_options' => $order_options,
68
- 'current_order' => wpbdp_get_option( 'fee-order' ) ),
69
- true);
 
 
 
 
70
  }
71
 
72
- private function processFieldForm() {
73
- $fee_id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0;
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- if ( $fee_id ) {
76
- $fee = WPBDP_Fee_Plan::find( $fee_id );
77
  } else {
78
- $fee = new WPBDP_Fee_Plan( array( 'categories' => array( 'categories' => array( 0 ) ) ) );
79
  }
80
 
81
- if ( isset( $_POST['fee'] ) ) {
82
- if ( ! isset( $_POST['fee']['sticky'] ) )
83
- $_POST['fee']['sticky'] = 0;
 
 
84
 
85
- if ( $fee->update( stripslashes_deep( $_POST['fee'] ) ) ) {
86
- $this->admin->messages[] = _x('Fee updated.', 'fees admin', 'WPBDM');
87
- return $this->feesTable();
 
 
88
  }
89
 
90
- $this->admin->messages[] = array( $fee->errors->html() , 'error' );
 
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
 
93
- wpbdp_render_page( WPBDP_PATH . 'templates/admin/fees-addoredit.tpl.php',
94
- array(
95
- 'fee' => $fee,
96
- 'fee_extra_settings' => wpbdp_capture_action_array( 'wpbdp_admin_fee_form_extra_settings', array( &$fee ) )
97
- ),
98
- true );
99
  }
100
 
101
- private function delete_fee() {
102
- global $wpdb;
 
 
 
 
103
 
104
- $fee = WPBDP_Fee_Plan::find( $_REQUEST['id'] );
 
 
 
105
 
106
- if ( ! $fee )
107
- die();
108
 
109
- if (isset($_POST['doit'])) {
110
- if ( $fee->destroy() )
111
- $this->admin->messages[] = _x('Fee deleted.', 'fees admin', 'WPBDM');
 
112
 
113
- return $this->feesTable();
114
- } else {
115
- wpbdp_render_page(WPBDP_PATH . 'templates/admin/fees-confirm-delete.tpl.php',
116
- array('fee' => $fee),
117
- true);
118
- }
119
  }
120
 
121
  }
1
  <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Admin__Fees extends WPBDP__Admin__Controller {
6
+
7
+ function __construct() {
8
+ parent::__construct();
9
+ $this->api = $this->wpbdp->fees;
10
  }
11
 
12
+ /**
13
+ * @override
14
+ */
15
+ function _enqueue_scripts() {
16
+ switch ( $this->current_view ) {
17
+ case 'add-fee':
18
+ case 'edit-fee':
19
+ wp_enqueue_style( 'wp-color-picker' );
20
+ wp_enqueue_style( 'wpbdp-js-select2-css' );
21
+ wp_enqueue_script( 'wpbdp-admin-fees-js', WPBDP_URL . 'assets/js/admin-fees.min.js', array( 'wp-color-picker', 'wpbdp-js-select2' ) );
22
+
23
+ break;
24
+ default:
25
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
 
27
 
28
+ if ( ! in_array( $this->current_view, array( 'add-fee', 'edit-fee' ), true ) )
29
+ return;
 
30
  }
31
 
32
+ function index() {
33
+ require_once( WPBDP_PATH . 'includes/admin/helpers/class-fees-table.php' );
 
34
 
35
+ $table = new WPBDP__Admin__Fees_Table();
36
  $table->prepare_items();
37
 
38
  $order_options = array();
44
  $order_options[ $k ] = $l;
45
  }
46
 
47
+ return array(
48
+ 'table' => $table,
49
+ 'order_options' => $order_options,
50
+ 'current_order' => wpbdp_get_option( 'fee-order' )
51
+ );
52
+ }
53
+
54
+ function add_fee() {
55
+ return $this->insert_or_update_fee( 'insert' );
56
  }
57
 
58
+ function edit_fee() {
59
+ return $this->insert_or_update_fee( 'update' );
60
+ }
61
+
62
+ private function insert_or_update_fee( $mode ) {
63
+ if ( ! empty( $_POST['fee'] ) ) {
64
+ $posted_values = stripslashes_deep( $_POST['fee'] );
65
+
66
+ if ( ! isset( $_POST['limit_categories'] ) || 0 == $_POST['limit_categories'] )
67
+ $posted_values['supported_categories'] = 'all';
68
+
69
+ if ( ! isset( $posted_values['sticky'] ) )
70
+ $posted_values['sticky'] = 0;
71
 
72
+ if ( ! isset( $posted_values['recurring'] ) )
73
+ $posted_values['recurring'] = 0;
74
  } else {
75
+ $posted_values = array();
76
  }
77
 
78
+ if ( 'insert' == $mode ) {
79
+ $fee = new WPBDP__Fee_Plan( $posted_values );
80
+ } else {
81
+ $fee = wpbdp_get_fee_plan( $_GET['id'] ) or die();
82
+ }
83
 
84
+ if ( $posted_values ) {
85
+ if ( $fee->exists() ) {
86
+ $result = $fee->update( $posted_values );
87
+ } else {
88
+ $result = $fee->save();
89
  }
90
 
91
+ if ( ! is_wp_error( $result ) ) {
92
+ if ( 'insert' == $mode ) {
93
+ wpbdp_admin_message( _x( 'Fee plan added.', 'fees admin', 'WPBDM' ) );
94
+ } else {
95
+ wpbdp_admin_message( _x( 'Fee plan updated.', 'fees admin', 'WPBDM' ) );
96
+ }
97
+
98
+ return $this->_redirect( 'index' );
99
+ } else {
100
+ foreach ( $result->get_error_messages() as $msg ) {
101
+ wpbdp_admin_message( $msg, 'error' );
102
+ }
103
+ }
104
  }
105
 
106
+ return array( 'fee' => $fee );
 
 
 
 
 
107
  }
108
 
109
+ function delete_fee() {
110
+ $fee = wpbdp_get_fee_plan( $_GET['id'] ) or die();
111
+
112
+ list( $do, $html ) = $this->_confirm_action( array(
113
+ 'cancel_url' => remove_query_arg( array( 'wpbdp-view', 'id' ) ),
114
+ ) );
115
 
116
+ if ( $do && $fee->delete() ) {
117
+ wpbdp_admin_message( sprintf( _x( 'Fee "%s" deleted.', 'fees admin', 'WPBDM' ), $fee->label ) );
118
+ return $this->_redirect( 'index' );
119
+ }
120
 
121
+ return $html;
122
+ }
123
 
124
+ function toggle_fee() {
125
+ $fee = wpbdp_get_fee_plan( $_GET['id'] ) or die();
126
+ $fee->enabled = ! $fee->enabled;
127
+ $fee->save();
128
 
129
+ wpbdp_admin_message( _x( 'Fee disabled.', 'fees admin', 'WPBDM' ) );
130
+ return $this->_redirect( 'index' );
 
 
 
 
131
  }
132
 
133
  }
includes/admin/form-fields.php CHANGED
@@ -97,6 +97,39 @@ class WPBDP_FormFieldsAdmin {
97
  public function __construct() {
98
  $this->api = wpbdp_formfields_api();
99
  $this->admin = wpbdp()->admin;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  }
101
 
102
  public function dispatch() {
@@ -168,16 +201,21 @@ class WPBDP_FormFieldsAdmin {
168
 
169
  /* preview form */
170
  private function previewForm() {
171
- require_once( WPBDP_INC . 'views/view-submit-listing.php' );
172
- $controller = new WPBDP_Submit_Listing_Page( 0, true );
173
 
174
- $html = '';
175
  $html .= wpbdp_admin_header(_x('Form Preview', 'form-fields admin', 'WPBDM'), 'formfields-preview', array(
176
  array(_x('← Return to "Manage Form Fields"', 'form-fields admin', 'WPBDM'), esc_url(remove_query_arg('action')))
177
  ));
178
  $html .= wpbdp_admin_notices();
179
  $html .= wpbdp_capture_action( 'wpbdp_admin_form_fields_before_preview' );
180
- $html .= $controller->preview_listing_fields_form();
 
 
 
 
 
 
181
  $html .= wpbdp_capture_action( 'wpbdp_admin_form_fields_after_preview' );
182
  $html .= wpbdp_admin_footer();
183
 
@@ -207,11 +245,11 @@ class WPBDP_FormFieldsAdmin {
207
  return $this->fieldsTable();
208
  } else {
209
  $errmsg = '';
210
-
211
  foreach ( $res->get_error_messages() as $err ) {
212
  $errmsg .= sprintf( '&#149; %s<br />', $err );
213
  }
214
-
215
  $this->admin->messages[] = array( $errmsg, 'error' );
216
  }
217
  } else {
@@ -223,7 +261,7 @@ class WPBDP_FormFieldsAdmin {
223
  'form-fields admin',
224
  'WPBDM' );
225
  $msg = str_replace( '<a>',
226
- '<a href="' . admin_url( 'admin.php?page=wpbdp_admin_settings&groupid=email' ) . '">',
227
  $msg );
228
  wpbdp_admin_message( $msg, 'error' );
229
  }
97
  public function __construct() {
98
  $this->api = wpbdp_formfields_api();
99
  $this->admin = wpbdp()->admin;
100
+
101
+ add_action('admin_init', array($this, 'check_for_required_fields'));
102
+ }
103
+
104
+ /* Required fields check. */
105
+ public function check_for_required_fields() {
106
+ global $wpbdp;
107
+
108
+ if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'wpbdp_admin_formfields' &&
109
+ isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'createrequired' ) {
110
+ // do not display the warning inside the page creating the required fields
111
+ return;
112
+ }
113
+
114
+ if ( $missing = $wpbdp->formfields->get_missing_required_fields() ) {
115
+ if (count($missing) > 1) {
116
+ $message = sprintf(_x('<b>Business Directory Plugin</b> requires fields with the following associations in order to work correctly: <b>%s</b>.', 'admin', 'WPBDM'), join(', ', $missing));
117
+ } else {
118
+ $message = sprintf(_x('<b>Business Directory Plugin</b> requires a field with a <b>%s</b> association in order to work correctly.', 'admin', 'WPBDM'), array_pop( $missing ) );
119
+ }
120
+
121
+ $message .= '<br />';
122
+ $message .= _x('You can create these custom fields by yourself inside "Manage Form Fields" or let Business Directory do this for you automatically.', 'admin', 'WPBDM');
123
+ $message .= '<br /><br />';
124
+ $message .= sprintf('<a href="%s">%s</a> | ',
125
+ admin_url('admin.php?page=wpbdp_admin_formfields'),
126
+ _x('Go to "Manage Form Fields"', 'admin', 'WPBDM'));
127
+ $message .= sprintf('<a href="%s">%s</a>',
128
+ admin_url('admin.php?page=wpbdp_admin_formfields&action=createrequired'),
129
+ _x('Create these required fields for me', 'admin', 'WPBDM'));
130
+
131
+ $this->messages[] = array($message, 'error');
132
+ }
133
  }
134
 
135
  public function dispatch() {
201
 
202
  /* preview form */
203
  private function previewForm() {
204
+ require_once( WPBDP_INC . 'views/submit_listing.php' );
 
205
 
206
+ $html = '';
207
  $html .= wpbdp_admin_header(_x('Form Preview', 'form-fields admin', 'WPBDM'), 'formfields-preview', array(
208
  array(_x('← Return to "Manage Form Fields"', 'form-fields admin', 'WPBDM'), esc_url(remove_query_arg('action')))
209
  ));
210
  $html .= wpbdp_admin_notices();
211
  $html .= wpbdp_capture_action( 'wpbdp_admin_form_fields_before_preview' );
212
+
213
+ require_once( WPBDP_INC . 'helpers/class-dummy-listing.php' );
214
+ $listing = new WPBDP__Dummy_Listing();
215
+ do_action( 'wpbdp_preview_form_setup_listing', $listing );
216
+
217
+ $html .= WPBDP__Views__Submit_Listing::preview_form( $listing );
218
+
219
  $html .= wpbdp_capture_action( 'wpbdp_admin_form_fields_after_preview' );
220
  $html .= wpbdp_admin_footer();
221
 
245
  return $this->fieldsTable();
246
  } else {
247
  $errmsg = '';
248
+
249
  foreach ( $res->get_error_messages() as $err ) {
250
  $errmsg .= sprintf( '&#149; %s<br />', $err );
251
  }
252
+
253
  $this->admin->messages[] = array( $errmsg, 'error' );
254
  }
255
  } else {
261
  'form-fields admin',
262
  'WPBDM' );
263
  $msg = str_replace( '<a>',
264
+ '<a href="' . admin_url( 'admin.php?page=wpbdp_settings&tab=email' ) . '">',
265
  $msg );
266
  wpbdp_admin_message( $msg, 'error' );
267
  }
includes/admin/helpers/class-fees-table.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
 
2
  if (!class_exists('WP_List_Table'))
3
  require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
4
 
5
- class WPBDP_FeesTable extends WP_List_Table {
6
 
7
  public function __construct() {
8
  parent::__construct(array(
@@ -15,7 +16,7 @@ class WPBDP_FeesTable extends WP_List_Table {
15
  public function no_items() {
16
  if ( 'all' == $this->get_current_view() ) {
17
  echo str_replace( '<a>',
18
- '<a href="' . admin_url( 'admin.php?page=wpbdp_admin_fees&action=addfee' ) . '">',
19
  _x( 'There are no fees right now. You can <a>create one</a>, if you want.', 'fees admin', 'WPBDM' ) );
20
  return;
21
  }
@@ -35,7 +36,7 @@ class WPBDP_FeesTable extends WP_List_Table {
35
  break;
36
  }
37
  printf( str_replace( '<a>',
38
- '<a href="' . admin_url( 'admin.php?page=wpbdp_admin_fees&action=addfee' ) . '">',
39
  _x( 'There are no "%s" fees right now. You can <a>create one</a>, if you want.', 'fees admin', 'WPBDM' ) ),
40
  $view_name );
41
  }
@@ -49,7 +50,7 @@ class WPBDP_FeesTable extends WP_List_Table {
49
 
50
  $views = array();
51
 
52
- $all = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_fees" ) );
53
  $views['all'] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
54
  esc_url( add_query_arg( 'fee_status', 'all' ) ),
55
  'all' == $this->get_current_view() ? 'current' : '',
@@ -60,7 +61,7 @@ class WPBDP_FeesTable extends WP_List_Table {
60
  if ( ! wpbdp_payments_possible() )
61
  $active = 1;
62
  else
63
- $active = absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_fees WHERE enabled = %d AND tag != %s", 1, 'free' ) ) );
64
 
65
  $views['active'] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
66
  esc_url( add_query_arg( 'fee_status', 'active' ) ),
@@ -69,7 +70,7 @@ class WPBDP_FeesTable extends WP_List_Table {
69
  number_format_i18n( $active ) );
70
 
71
 
72
- $disabled = absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_fees WHERE enabled = %d", 0 ) ) );
73
  $unavailable = $all - $active - $disabled;
74
 
75
  $views['unavailable'] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
@@ -95,42 +96,43 @@ class WPBDP_FeesTable extends WP_List_Table {
95
  'amount' => _x('Amount', 'fees admin', 'WPBDM'),
96
  'duration' => _x('Duration', 'fees admin', 'WPBDM'),
97
  'images' => _x('Images', 'fees admin', 'WPBDM'),
98
- 'sticky' => _x( 'Featured/Sticky', 'fees admin', 'WPBDM' )
99
  );
100
 
101
- if ( 'all' == $this->get_current_view() ) {
102
- $cols[ 'status' ] = _x( 'Status', 'fees admin', 'WPBDM' );
103
- }
104
-
105
  return $cols;
106
  }
107
 
108
  public function prepare_items() {
109
  $this->_column_headers = array($this->get_columns(), array(), $this->get_sortable_columns());
110
 
111
- switch ( $this->get_current_view() ) {
112
- case 'active':
113
- if ( wpbdp_payments_possible() )
114
- $this->items = WPBDP_Fee_Plan::find( array( 'enabled' => 1, '-tag' => 'free' ) );
115
- else
116
- $this->items = WPBDP_Fee_Plan::find( array( 'enabled' => 1, 'tag' => 'free' ) );
117
 
118
- break;
119
- case 'disabled':
120
- $this->items = WPBDP_Fee_Plan::find( array( 'enabled' => 0 ) );
121
- break;
122
- case 'unavailable':
123
- if ( wpbdp_payments_possible() )
124
- $this->items = WPBDP_Fee_Plan::find( array( 'tag' => 'free' ) );
125
- else
126
- $this->items = WPBDP_Fee_Plan::find( array( 'enabled' => 1, '-tag' => 'free' ) );
 
 
 
 
 
 
 
 
127
 
128
- break;
129
- case 'all':
130
- default:
131
- $this->items = WPBDP_Fee_Plan::find();
132
- break;
133
  }
 
 
134
  }
135
 
136
  /* Rows */
@@ -183,7 +185,7 @@ class WPBDP_FeesTable extends WP_List_Table {
183
  public function column_label($fee) {
184
  $actions = array();
185
  $actions['edit'] = sprintf('<a href="%s">%s</a>',
186
- esc_url(add_query_arg(array('action' => 'editfee', 'id' => $fee->id))),
187
  _x('Edit', 'fees admin', 'WPBDM'));
188
 
189
  if ( 'free' == $fee->tag ) {
@@ -193,15 +195,15 @@ class WPBDP_FeesTable extends WP_List_Table {
193
  } else {
194
  if ( $fee->enabled )
195
  $actions['disable'] = sprintf('<a href="%s">%s</a>',
196
- esc_url(add_query_arg(array('action' => 'disablefee', 'id' => $fee->id))),
197
  _x('Disable', 'fees admin', 'WPBDM'));
198
  else
199
  $actions['enable'] = sprintf('<a href="%s">%s</a>',
200
- esc_url(add_query_arg(array('action' => 'enablefee', 'id' => $fee->id))),
201
  _x('Enable', 'fees admin', 'WPBDM'));
202
 
203
  $actions['delete'] = sprintf('<a href="%s">%s</a>',
204
- esc_url(add_query_arg(array('action' => 'deletefee', 'id' => $fee->id))),
205
  _x('Delete', 'fees admin', 'WPBDM'));
206
  }
207
 
@@ -210,7 +212,7 @@ class WPBDP_FeesTable extends WP_List_Table {
210
  $fee->id );
211
 
212
  $html .= sprintf('<strong><a href="%s">%s</a></strong>',
213
- esc_url(add_query_arg(array('action' => 'editfee', 'id' => $fee->id))),
214
  esc_attr($fee->label));
215
  $html .= $this->row_actions($actions);
216
 
@@ -218,7 +220,16 @@ class WPBDP_FeesTable extends WP_List_Table {
218
  }
219
 
220
  public function column_amount($fee) {
221
- return $fee->amount;
 
 
 
 
 
 
 
 
 
222
  }
223
 
224
  public function column_duration($fee) {
@@ -246,19 +257,30 @@ class WPBDP_FeesTable extends WP_List_Table {
246
  return $names ? join($names, ', ') : '--';
247
  }
248
 
249
- public function column_sticky( $fee ) {
250
- return $fee->sticky ? _x( 'Yes', 'fees admin', 'WPBDM' ) : _x( 'No', 'fees admin', 'WPBDM' );
251
- }
252
 
253
- public function column_status( $fee ) {
254
- if ( ! $fee->enabled )
255
- return _x( 'Disabled', 'fees admin', 'WPBDM' );
 
 
 
 
 
 
 
 
 
 
256
 
257
- if ( ( ! wpbdp_payments_possible() && 'free' != $fee->tag ) || ( wpbdp_payments_possible() && 'free' == $fee->tag ) )
258
- return _x( 'Not Available', 'fees admin', 'WPBDM' );
259
 
260
- return _x( 'Active', 'fees admin', 'WPBDM' );
 
 
 
261
  }
262
 
263
  }
264
-
1
  <?php
2
+
3
  if (!class_exists('WP_List_Table'))
4
  require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
5
 
6
+ class WPBDP__Admin__Fees_Table extends WP_List_Table {
7
 
8
  public function __construct() {
9
  parent::__construct(array(
16
  public function no_items() {
17
  if ( 'all' == $this->get_current_view() ) {
18
  echo str_replace( '<a>',
19
+ '<a href="' . admin_url( 'admin.php?page=wpbdp-admin-fees&wpbdp-view=add-fee' ) . '">',
20
  _x( 'There are no fees right now. You can <a>create one</a>, if you want.', 'fees admin', 'WPBDM' ) );
21
  return;
22
  }
36
  break;
37
  }
38
  printf( str_replace( '<a>',
39
+ '<a href="' . admin_url( 'admin.php?page=wpbdp-admin-fees&wpbdp-view=add-fee' ) . '">',
40
  _x( 'There are no "%s" fees right now. You can <a>create one</a>, if you want.', 'fees admin', 'WPBDM' ) ),
41
  $view_name );
42
  }
50
 
51
  $views = array();
52
 
53
+ $all = absint( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_plans" ) );
54
  $views['all'] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
55
  esc_url( add_query_arg( 'fee_status', 'all' ) ),
56
  'all' == $this->get_current_view() ? 'current' : '',
61
  if ( ! wpbdp_payments_possible() )
62
  $active = 1;
63
  else
64
+ $active = absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_plans WHERE enabled = %d AND tag != %s", 1, 'free' ) ) );
65
 
66
  $views['active'] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
67
  esc_url( add_query_arg( 'fee_status', 'active' ) ),
70
  number_format_i18n( $active ) );
71
 
72
 
73
+ $disabled = absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_plans WHERE enabled = %d", 0 ) ) );
74
  $unavailable = $all - $active - $disabled;
75
 
76
  $views['unavailable'] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
96
  'amount' => _x('Amount', 'fees admin', 'WPBDM'),
97
  'duration' => _x('Duration', 'fees admin', 'WPBDM'),
98
  'images' => _x('Images', 'fees admin', 'WPBDM'),
99
+ 'attributes' => _x( 'Attributes', 'fees admin', 'WPBDM' )
100
  );
101
 
 
 
 
 
102
  return $cols;
103
  }
104
 
105
  public function prepare_items() {
106
  $this->_column_headers = array($this->get_columns(), array(), $this->get_sortable_columns());
107
 
108
+ $args = array();
 
 
 
 
 
109
 
110
+ switch ( $this->get_current_view() ) {
111
+ case 'active':
112
+ $args['enabled'] = 1;
113
+ $args['include_free'] = ! wpbdp_payments_possible();
114
+ break;
115
+ case 'disabled':
116
+ $args['enabled'] = 0;
117
+
118
+ break;
119
+ case 'unavailable':
120
+ if ( wpbdp_payments_possible() ) {
121
+ $args['enabled'] = 'all';
122
+ $args['tag'] = 'free';
123
+ } else {
124
+ $args['enabled'] = 1;
125
+ $args['include_free'] = false;
126
+ }
127
 
128
+ break;
129
+ case 'all':
130
+ default:
131
+ $args['include_free'] = true;
132
+ break;
133
  }
134
+
135
+ $this->items = wpbdp_get_fee_plans( $args );
136
  }
137
 
138
  /* Rows */
185
  public function column_label($fee) {
186
  $actions = array();
187
  $actions['edit'] = sprintf('<a href="%s">%s</a>',
188
+ esc_url(add_query_arg(array('wpbdp-view' => 'edit-fee', 'id' => $fee->id))),
189
  _x('Edit', 'fees admin', 'WPBDM'));
190
 
191
  if ( 'free' == $fee->tag ) {
195
  } else {
196
  if ( $fee->enabled )
197
  $actions['disable'] = sprintf('<a href="%s">%s</a>',
198
+ esc_url(add_query_arg(array('wpbdp-view' => 'toggle-fee', 'id' => $fee->id))),
199
  _x('Disable', 'fees admin', 'WPBDM'));
200
  else
201
  $actions['enable'] = sprintf('<a href="%s">%s</a>',
202
+ esc_url(add_query_arg(array('wpbdp-view' => 'toggle-fee', 'id' => $fee->id))),
203
  _x('Enable', 'fees admin', 'WPBDM'));
204
 
205
  $actions['delete'] = sprintf('<a href="%s">%s</a>',
206
+ esc_url(add_query_arg(array('wpbdp-view' => 'delete-fee', 'id' => $fee->id))),
207
  _x('Delete', 'fees admin', 'WPBDM'));
208
  }
209
 
212
  $fee->id );
213
 
214
  $html .= sprintf('<strong><a href="%s">%s</a></strong>',
215
+ esc_url(add_query_arg(array('wpbdp-view' => 'edit-fee', 'id' => $fee->id))),
216
  esc_attr($fee->label));
217
  $html .= $this->row_actions($actions);
218
 
220
  }
221
 
222
  public function column_amount($fee) {
223
+ if ( 'variable' == $fee->pricing_model ) {
224
+ return _x( 'Variable', 'fees admin', 'WPBDM' );
225
+ } else if ( 'extra' == $fee->pricing_model ) {
226
+ $amount = wpbdp_currency_format( $fee->amount );
227
+ $extra = wpbdp_currency_format( $fee->pricing_details['extra'] );
228
+
229
+ return sprintf( _x( '%s + %s per category', 'fees admin', 'WPBDM' ), $amount, $extra );
230
+ }
231
+
232
+ return wpbdp_currency_format( $fee->amount );
233
  }
234
 
235
  public function column_duration($fee) {
257
  return $names ? join($names, ', ') : '--';
258
  }
259
 
260
+ public function column_attributes( $fee ) {
261
+ $html = '';
 
262
 
263
+ if ( 'all' == $this->get_current_view() ) {
264
+ $html .= '<span class="wpbdp-tag">';
265
+
266
+ if ( ! $fee->enabled ) {
267
+ $html .= _x( 'Disabled', 'fees admin', 'WPBDM' );
268
+ } elseif ( ( ! wpbdp_payments_possible() && 'free' != $fee->tag ) || ( wpbdp_payments_possible() && 'free' == $fee->tag ) ) {
269
+ $html .= _x( 'Unavailable', 'fees admin', 'WPBDM' );
270
+ } else {
271
+ $html .= _x( 'Active', 'fees admin', 'WPBDM' );
272
+ }
273
+
274
+ $html .= '</span>';
275
+ }
276
 
277
+ if ( $fee->sticky )
278
+ $html .= '<span class="wpbdp-tag">' . _x( 'Sticky', 'fees admin', 'WPBDM' ) . '</span>';
279
 
280
+ if ( $fee->recurring )
281
+ $html .= '<span class="wpbdp-tag">' . _x( 'Recurring', 'fees admin', 'WPBDM' ) . '</span>';
282
+
283
+ return $html;
284
  }
285
 
286
  }
 
includes/admin/helpers/class-listing-information-metabox.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Admin__Metaboxes__Listing_Information {
6
+
7
+ public function __construct( $post_id ) {
8
+ $this->listing = WPBDP_Listing::get( $post_id );
9
+ }
10
+
11
+ public function render() {
12
+ $tabs = array();
13
+ $tabs[] = array(
14
+ 'id' => 'plan-info',
15
+ 'label' => _x( 'Listing', 'listing metabox', 'WPBDM' ),
16
+ 'content' => $this->plan_info_tab() );
17
+ $tabs[] = array(
18
+ 'id' => 'payments',
19
+ 'label' => _x( 'Recent Payments', 'listing metabox', 'WPBDM' ),
20
+ 'content' => $this->payments_tab() );
21
+ $tabs[] = array(
22
+ 'id' => 'other',
23
+ 'label' => _x( 'Access Key', 'listing metabox', 'WPBDM' ),
24
+ 'content' => $this->other_tab() );
25
+ $tabs = apply_filters( 'wpbdp_listing_metabox_tabs', $tabs, $this->listing );
26
+
27
+ return wpbdp_render_page( WPBDP_PATH . 'templates/admin/metaboxes-listing-information.tpl.php', array( 'tabs' => $tabs ) );
28
+ }
29
+
30
+ private function plan_info_tab() {
31
+ $vars = array(
32
+ 'plans' => wpbdp_get_fee_plans(),
33
+ 'listing' => $this->listing,
34
+ 'current_plan' => $this->listing->get_fee_plan()
35
+ );
36
+
37
+ return wpbdp_render_page( WPBDP_PATH . 'templates/admin/metaboxes-listing-information-plan.tpl.php', $vars );
38
+ }
39
+
40
+ private function payments_tab() {
41
+ $vars = array(
42
+ 'payments' => $this->listing->get_latest_payments(),
43
+ 'listing' => $this->listing
44
+ );
45
+ return wpbdp_render_page( WPBDP_PATH . 'templates/admin/metaboxes-listing-information-payments.tpl.php', $vars );
46
+ }
47
+
48
+ private function other_tab() {
49
+ $vars = array(
50
+ 'access_key' => $this->listing->get_access_key()
51
+ );
52
+ return wpbdp_render_page( WPBDP_PATH . 'templates/admin/metaboxes-listing-information-other.tpl.php', $vars );
53
+ }
54
+
55
+ }
includes/admin/helpers/class-listing-timeline.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+
6
+ class WPBDP__Listing_Timeline {
7
+
8
+ private $listing = null;
9
+
10
+
11
+ public function __construct( $listing_id ) {
12
+ $this->listing = wpbdp_get_listing( $listing_id );
13
+ }
14
+
15
+ public function get_items() {
16
+ $items = wpbdp_get_logs( array( 'object_type' => 'listing', 'object_id' => $this->listing->get_id(), 'order' => 'DESC' ) );
17
+
18
+ if ( ! $items ) {
19
+ $this->recreate_logs();
20
+ return $this->get_items();
21
+ }
22
+
23
+ return $items;
24
+ }
25
+
26
+ public function render() {
27
+ $items = $this->get_items();
28
+ $timeline = array();
29
+
30
+ foreach ( $items as $item ) {
31
+ $obj = clone $item;
32
+ $obj->html = '';
33
+ $obj->timestamp = strtotime( $obj->created_at );
34
+ $obj->extra = '';
35
+ $obj->actions = array();
36
+
37
+ $callback = 'process_' . str_replace( '.', '_', $obj->log_type );
38
+ if ( method_exists( $this, $callback ) )
39
+ $obj = call_user_func( array( $this, $callback ), $obj );
40
+
41
+ if ( ! $obj->html )
42
+ $obj->html = $obj->message ? $obj->message : $obj->log_type;
43
+
44
+ $timeline[] = $obj;
45
+ }
46
+
47
+ return wpbdp_render_page( WPBDP_PATH . 'templates/admin/metaboxes-listing-timeline.tpl.php', array( 'timeline' => $timeline ) );
48
+ }
49
+
50
+ private function recreate_logs() {
51
+ $post = get_post( $this->listing->get_id() );
52
+ $post_date = $post->post_date;
53
+
54
+ wpbdp_insert_log( array( 'log_type' => 'listing.created', 'object_id' => $post->ID, 'created_at' => $post_date ) );
55
+
56
+ // Insert logs for payments.
57
+ $payments = WPBDP_Payment::objects()->filter( array( 'listing_id' => $post->ID ) );
58
+ foreach ( $payments as $p ) {
59
+ wpbdp_insert_log( array( 'log_type' => 'listing.payment', 'object_id' => $post->ID, 'rel_object_id' => $p->id ) );
60
+ }
61
+ }
62
+
63
+ private function process_listing_created( $item ) {
64
+ $item->html = _x( 'Listing created', 'listing timeline', 'WPBDM' );
65
+ return $item;
66
+ }
67
+
68
+ private function process_listing_expired( $item ) {
69
+ $item->html = _x( 'Listing expired', 'listing timeline', 'WPBDM' );
70
+ return $item;
71
+ }
72
+
73
+ private function process_listing_renewal( $item ) {
74
+ $item->html = _x( 'Listing renewed', 'listing timeline', 'WPBDM' );
75
+ return $item;
76
+ }
77
+
78
+ private function process_listing_payment( $item ) {
79
+ $payment = WPBDP_Payment::objects()->get( $item->rel_object_id );
80
+
81
+ // switch ( $payment->payment_type ) {
82
+ // case 'initial':
83
+ // $item->html .= 'Initial Payment';
84
+ // break;
85
+ // default:
86
+ // $item->html .= 'Payment #' . $payment->id;
87
+ // break;
88
+ // }
89
+
90
+ $title = $payment->summary;
91
+
92
+ if ( 'initial' == $payment->payment_type ) {
93
+ if ( 'admin-submit' == $payment->context )
94
+ $title = 'Paid as admin';
95
+ else
96
+ $title = 'Initial Payment';
97
+ }
98
+
99
+ $item->html = '';
100
+ $item->html .= '<a href="' . esc_url( admin_url( 'admin.php?page=wpbdp_admin_payments&wpbdp-view=details&payment-id=' . $payment->id ) ) . '">';
101
+ $item->html .= $title;
102
+ $item->html .= '</a>';
103
+
104
+ if ( 'completed' != $payment->status )
105
+ $item->html .= '<span class="payment-status tag ' . $payment->status . '">' . $payment->status . '</span>';
106
+
107
+ $item->extra .= '<span class="payment-id">Payment #' . $payment->id . '</span>';
108
+ $item->extra .= '<span class="payment-amount">Amount: ' . wpbdp_currency_format( $payment->amount, 'force_numeric=1' ) . '</span>';
109
+
110
+ $item->actions = array(
111
+ 'details' => '<a href="' . esc_url( admin_url( 'admin.php?page=wpbdp_admin_payments&wpbdp-view=details&payment-id=' . $payment->id ) ) . '">Go to payment</a>'
112
+ );
113
+
114
+ return $item;
115
+ }
116
+
117
+ }
includes/admin/helpers/class-payments-table.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! class_exists( 'WP_List_Table' ) )
3
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
4
+
5
+ /**
6
+ * @since 5.0
7
+ */
8
+ class WPBDP__Admin__Payments_Table extends WP_List_Table {
9
+
10
+ public function __construct() {
11
+ parent::__construct( array(
12
+ 'singular' => _x( 'payment', 'payments admin', 'WPBDM' ),
13
+ 'plural' => _x( 'payments', 'payments admin', 'WPBDM' ),
14
+ 'ajax' => false
15
+ ) );
16
+ }
17
+
18
+ public function no_items() {
19
+ echo _x( 'No payments found.', 'payments admin', 'WPBDM' );
20
+ }
21
+
22
+ public function get_current_view() {
23
+ return wpbdp_getv( $_GET, 'status', 'all' );
24
+ }
25
+
26
+ public function get_views() {
27
+ global $wpdb;
28
+
29
+ $views_ = array();
30
+
31
+ $count = WPBDP_Payment::objects()->count();
32
+ $views_['all'] = array( _x( 'All', 'payments admin', 'WPBDM' ), $count );
33
+
34
+ foreach ( WPBDP_Payment::get_stati() as $status => $status_label ) {
35
+ $count = WPBDP_Payment::objects()->filter( array( 'status' => $status ) )->count();
36
+ $views_[ $status ] = array( $status_label, $count );
37
+ }
38
+
39
+ $views = array();
40
+ foreach ( $views_ as $view_id => $view_data ) {
41
+ $views[ $view_id ] = sprintf( '<a href="%s" class="%s">%s</a> <span class="count">(%s)</span></a>',
42
+ esc_url( add_query_arg( 'status', $view_id ) ),
43
+ $view_id == $this->get_current_view() ? 'current': '',
44
+ $view_data[0],
45
+ number_format_i18n( $view_data[1] ) );
46
+ }
47
+
48
+ return $views;
49
+ }
50
+
51
+ public function get_columns() {
52
+ $cols = array(
53
+ 'listing' => _x( 'Listing', 'fees admin', 'WPBDM' ),
54
+ 'payment_id' => _x( 'ID', 'fees admin', 'WPBDM' ),
55
+ 'date' => _x( 'Date', 'fees admin', 'WPBDM' ),
56
+ 'details' => _x( 'Payment History', 'fees admin', 'WPBDM' ),
57
+ 'amount' => _x( 'Amount', 'fees admin', 'WPBDM' ),
58
+ 'status' => _x( 'Status', 'fees admin', 'WPBDM' )
59
+ );
60
+
61
+ return $cols;
62
+ }
63
+
64
+ public function prepare_items() {
65
+ $this->_column_headers = array($this->get_columns(), array(), $this->get_sortable_columns());
66
+
67
+ $args = array();
68
+
69
+ if ( 'all' != $this->get_current_view() )
70
+ $args['status'] = $this->get_current_view();
71
+
72
+ if ( ! empty( $_GET['listing'] ) )
73
+ $args['listing_id'] = absint( $_GET['listing'] );
74
+
75
+ $this->items = WPBDP_Payment::objects()->filter( $args )->order_by( '-id' );
76
+
77
+ if ( ! empty( $_GET['s'] ) ) {
78
+ $s = trim( $_GET['s'] );
79
+
80
+ $this->items = $this->items->filter(
81
+ array(
82
+ 'payer_first_name__icontains' => $s,
83
+ 'payer_last_name__icontains' => $s,
84
+ 'payer_email__icontains' => $s,
85
+ 'gateway_tx_id' => $s
86
+ ),
87
+ false,
88
+ 'OR'
89
+ );
90
+
91
+ // wpbdp_debug_e( $s, $this->items );
92
+ }
93
+
94
+ $this->items = $this->items;
95
+ }
96
+
97
+ public function has_items() {
98
+ return $this->items->count() > 0;
99
+ }
100
+
101
+ public function column_payment_id( $payment ) {
102
+ return sprintf( '<a href="%s">%d</a>', add_query_arg( array( 'wpbdp-view' => 'details', 'payment-id' => $payment->id ) ), $payment->id );
103
+ }
104
+
105
+ public function column_date( $payment ) {
106
+ return date_i18n( get_option( 'date_format' ), strtotime( $payment->created_at ));
107
+ }
108
+
109
+ public function column_amount( $payment ) {
110
+ return wpbdp_currency_format( $payment->amount );
111
+ }
112
+
113
+ public function column_status( $payment ) {
114
+ return WPBDP_Payment::get_status_label( $payment->status );
115
+ }
116
+
117
+ public function column_details( $payment ) {
118
+ return '<a href="' . esc_url( add_query_arg( array( 'wpbdp-view' => 'details', 'payment-id' => $payment->id ) ) ) . '">' . _x( 'View Payment History', 'payments admin', 'WPBDM' ) . '</a>';
119
+ }
120
+
121
+ public function column_listing( $payment ) {
122
+ $listing = $payment->listing;
123
+
124
+ if ( ! $listing )
125
+ return '';
126
+
127
+ return '<a href="' . esc_url( $listing->get_admin_edit_link() ) . '">' . esc_html( $listing->get_title() ) . '</a>';
128
+ }
129
+
130
+ // public function column_label($fee) {
131
+ // $actions = array();
132
+ // $actions['edit'] = sprintf('<a href="%s">%s</a>',
133
+ // esc_url(add_query_arg(array('wpbdp-view' => 'edit-fee', 'id' => $fee->id))),
134
+ // _x('Edit', 'fees admin', 'WPBDM'));
135
+ //
136
+ // if ( 'free' == $fee->tag ) {
137
+ // // $actions['delete'] = sprintf('<a href="%s">%s</a>',
138
+ // // esc_url(add_query_arg(array('action' => 'deletefee', 'id' => $fee->id))),
139
+ // // _x('Disable', 'fees admin', 'WPBDM'));
140
+ // } else {
141
+ // if ( $fee->enabled )
142
+ // $actions['disable'] = sprintf('<a href="%s">%s</a>',
143
+ // esc_url(add_query_arg(array('wpbdp-view' => 'toggle-fee', 'id' => $fee->id))),
144
+ // _x('Disable', 'fees admin', 'WPBDM'));
145
+ // else
146
+ // $actions['enable'] = sprintf('<a href="%s">%s</a>',
147
+ // esc_url(add_query_arg(array('wpbdp-view' => 'toggle-fee', 'id' => $fee->id))),
148
+ // _x('Enable', 'fees admin', 'WPBDM'));
149
+ //
150
+ // $actions['delete'] = sprintf('<a href="%s">%s</a>',
151
+ // esc_url(add_query_arg(array('wpbdp-view' => 'delete-fee', 'id' => $fee->id))),
152
+ // _x('Delete', 'fees admin', 'WPBDM'));
153
+ // }
154
+ //
155
+ // $html = '';
156
+ // $html .= sprintf( '<span class="wpbdp-drag-handle" data-fee-id="%s"></span></a>',
157
+ // $fee->id );
158
+ //
159
+ // $html .= sprintf('<strong><a href="%s">%s</a></strong>',
160
+ // esc_url(add_query_arg(array('wpbdp-view' => 'edit-fee', 'id' => $fee->id))),
161
+ // esc_attr($fee->label));
162
+ // $html .= $this->row_actions($actions);
163
+ //
164
+ // return $html;
165
+ // }
166
+
167
+ }
includes/admin/helpers/class-variable-pricing-configurator.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once ( WPBDP_PATH . 'includes/helpers/class-wp-taxonomy-term-list.php' );
3
+
4
+ /**
5
+ * @since 5.0
6
+ */
7
+ class WPBDP__Admin__Variable_Pricing_Configurator extends WPBDP__WP_Taxonomy_Term_List {
8
+
9
+ private $categories = array();
10
+ private $prices = array();
11
+
12
+
13
+ function __construct( $args ) {
14
+ parent::__construct( $args );
15
+
16
+ if ( ! isset( $args['fee'] ) )
17
+ return;
18
+
19
+ $fee = $args['fee'];
20
+
21
+ $this->pricing_model = $fee->pricing_model;
22
+ $this->categories = $fee->supported_categories;
23
+
24
+ if ( 'variable' != $this->pricing_model )
25
+ return;
26
+
27
+ $this->prices = $fee->pricing_details;
28
+ }
29
+
30
+ protected function element_before( $term, $depth ) {
31
+ return '<tr class="wpbdp-variable-pricing-configurator-row ' . ( 'all' != $this->categories && ! in_array( $term->term_id, $this->categories ) ? 'hidden' : '' ) . '" data-term-id="' . $term->term_id . '"><td class="category-name-col">';
32
+ }
33
+
34
+ protected function element( $term, $depth ) {
35
+ $res = parent::element( $term, $depth );
36
+ return str_replace( array( '<br>', '<br />' ), '', $res );
37
+ }
38
+
39
+ protected function element_after( $term, $depth ) {
40
+ $res = '';
41
+ $res .= sprintf( '</td><td class="category-price-col"><input type="text" name="fee[pricing_details][%d]" class="category-price" value="%s" /></td>',
42
+ $term->term_id,
43
+ isset( $this->prices[ $term->term_id ] ) ? $this->prices[ $term->term_id ] : '0.0' );
44
+ $res .= '</tr>';
45
+
46
+ return $res;
47
+ }
48
+
49
+ }
includes/admin/helpers/listing-metabox.php DELETED
@@ -1,119 +0,0 @@
1
- <?php
2
- class WPBDP_Admin_Listing_Metabox {
3
-
4
- private $listing = null;
5
-
6
- public function __construct( $listing_id ) {
7
- $this->listing = WPBDP_Listing::get( $listing_id );
8
- }
9
-
10
- public function render() {
11
- $tabs = array( 'generalinfo' => _x('General', 'admin', 'WPBDM'),
12
- 'fees' => _x('Fee Details', 'admin', 'WPBDM'),
13
- 'transactions' => _x('Transactions', 'admin', 'WPBDM') );
14
-
15
- // Determine selected tab.
16
- $selected_tab = 'generalinfo';
17
- if ( isset( $_GET['wpbdmaction'] ) && in_array( $_GET['wpbdmaction'], array( 'removecategory', 'assignfee', 'change_expiration' ), true ) )
18
- $selected_tab = 'fees';
19
- $selected_tab = 'fees';
20
-
21
- echo '<div class="misc-pub-section">';
22
-
23
- echo '<ul class="listing-metabox-tabs">';
24
- foreach ( $tabs as $tab_id => $tab_label ) {
25
- echo '<li class="tabs ' . ( $selected_tab === $tab_id ? 'selected' : '' ) . '"><a href="#listing-metabox-' . $tab_id . '">' . $tab_label .'</a></li>';
26
- }
27
- echo '</ul>';
28
-
29
- foreach ( array_keys( $tabs ) as $tab_id ) {
30
- echo '<div id="listing-metabox-' . $tab_id . '" class="listing-metabox-tab">';
31
- call_user_func( array( &$this, 'tab_' . $tab_id ) );
32
- echo '</div>';
33
- }
34
-
35
- echo '</div>';
36
- echo '<div class="clear"></div>';
37
- }
38
-
39
- private function tab_generalinfo() {
40
- $upgrades_api = wpbdp_listing_upgrades_api();
41
-
42
- echo '<strong>' . _x('General Info', 'admin infometabox', 'WPBDM') . '</strong>';
43
- echo '<dl>';
44
- echo '<dt>' . _x( 'Access Key', 'admin infometabox', 'WPBDM' ) . '</dt>';
45
- echo '<dd><input type="text" value="' . esc_attr( $this->listing->get_access_key() ) . '" /></dd>';
46
- echo '<dt>'. _x('Total Listing Cost', 'admin infometabox', 'WPBDM') . '</dt>';
47
- echo '<dd>' . wpbdp_currency_format( $this->listing->get_total_cost() ) . '</dd>';
48
- echo '<dt>'. _x('Payment Status', 'admin infometabox', 'WPBDM') . '</dt>';
49
- echo '<dd>';
50
- echo sprintf('<span class="tag paymentstatus %1$s">%1$s</span>', $this->listing->get_payment_status() );
51
- echo '</dd>';
52
- echo '<dt>' . _x('Featured (Sticky) Status', 'admin infometabox', 'WPBDM') . '</dt>';
53
- echo '<dd>';
54
-
55
- // sticky information
56
- $sticky_info = $upgrades_api->get_info( $this->listing->get_id() );
57
-
58
- echo '<span><b>';
59
- if ($sticky_info->pending) {
60
- echo _x('Pending Upgrade', 'admin metabox', 'WPBDM');
61
- } else {
62
- echo esc_attr( $sticky_info->level->name );
63
- }
64
- echo '</b> </span><br />';
65
-
66
- if (current_user_can('administrator')) {
67
- if ( $sticky_info->upgradeable ) {
68
- echo sprintf('<span><a href="%s">%s</a></span>',
69
- esc_url( add_query_arg(array('wpbdmaction' => 'changesticky', 'u' => $sticky_info->upgrade->id, 'post' => $this->listing->get_id())) ),
70
- '<b>↑</b> ' . sprintf(__('Upgrade to %s', 'WPBDM'), esc_attr($sticky_info->upgrade->name)) );
71
- }
72
-
73
- if ( $sticky_info->downgradeable ) {
74
- echo '<br />';
75
- echo sprintf('<span><a href="%s">%s</a></span>',
76
- esc_url( add_query_arg(array('wpbdmaction' => 'changesticky', 'u' => $sticky_info->downgrade->id, 'post' => $this->listing->get_id())) ),
77
- '<b>↓</b> ' . sprintf(__('Downgrade to %s', 'WPBDM'), esc_attr($sticky_info->downgrade->name)) );
78
- }
79
- }
80
-
81
- $import_id = get_post_meta( $this->listing->get_id(), '_wpbdp[import_sequence_id]', true );
82
- if ( current_user_can( 'administrator' ) && $import_id ) {
83
- echo '<dt>' . _x( 'CSV Import Sequence ID', 'admin infometabox', 'WPBDM' ) . '</dt>';
84
- echo '<dd>' . $import_id . '</dd>';
85
- }
86
-
87
- echo '</dd>';
88
- do_action( 'wpbdp_admin_metabox_generalinfo_list', $this->listing->get_id() );
89
- echo '</dl>';
90
-
91
- if ( current_user_can( 'administrator' ) && 'ok' != $this->listing->get_payment_status() ) {
92
- echo sprintf( '<a href="%s" class="button button-primary">%s</a> ',
93
- esc_url( add_query_arg('wpbdmaction', 'setaspaid' ) ),
94
- _x( 'Mark listing as Paid', 'admin infometabox', 'WPBDM' ) );
95
- }
96
-
97
- echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/listing-metabox-feesummary.tpl.php', array(
98
- 'categories' => $this->listing->get_categories( 'all' ),
99
- 'listing' => $this->listing
100
- ) );
101
- }
102
-
103
- private function tab_fees() {
104
- echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/listing-metabox-fees.tpl.php', array(
105
- 'categories' => $this->listing->get_categories( 'all' ),
106
- 'listing' => $this->listing
107
- ) );
108
- }
109
-
110
- private function tab_transactions() {
111
- echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/listing-metabox-transactions.tpl.php',
112
- array( 'payments' => $this->listing->get_latest_payments() ) );
113
- }
114
-
115
- public static function metabox_callback( $post ) {
116
- $instance = new self( $post->ID );
117
- return $instance->render();
118
- }
119
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/admin/index.php CHANGED
@@ -1 +1,2 @@
1
- <?php
 
1
+ <?php
2
+ // Silence is golden.
includes/admin/page-debug.php CHANGED
@@ -20,7 +20,7 @@ class WPBDP_Admin_Debug_Page {
20
 
21
  // Premium modules.
22
  $mod_versions = array();
23
- foreach ( $wpbdp->licensing->modules as $m ) {
24
  $mod_versions[] = str_replace( ' Module', '', $m['name'] ) . ' - ' . $m['version'];
25
  }
26
  if ( class_exists( 'WPBDP_CategoriesModule' ) ) {
@@ -32,8 +32,7 @@ class WPBDP_Admin_Debug_Page {
32
  'html' => implode( '<br />', $mod_versions )
33
  );
34
 
35
-
36
- $tables = apply_filters( 'wpbdp_debug_info_tables_check', array( 'wpbdp_form_fields', 'wpbdp_fees', 'wpbdp_payments', 'wpbdp_listing_fees' ) );
37
  $missing_tables = array();
38
  foreach ( $tables as &$t ) {
39
  if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->prefix . $t) ) == '' )
@@ -52,12 +51,21 @@ class WPBDP_Admin_Debug_Page {
52
  $debug_info['options']['_title'] = _x( 'BD Options', 'debug-info', 'WPBDM' );
53
 
54
  $settings_api = wpbdp_settings_api();
55
- foreach ( $settings_api->settings as &$s ) {
56
- if ( $s->type == 'core' || in_array( $s->name, $blacklisted ) )
57
  continue;
58
 
59
- $value = wpbdp_get_option( $s->name );
60
- $debug_info['options'][ $s->name ] = is_array( $value ) ? implode( ',', $value ) : $value;
 
 
 
 
 
 
 
 
 
61
  }
62
  $debug_info['options'] = apply_filters( 'wpbdp_debug_info_section', $debug_info['options'], 'options' );
63
 
20
 
21
  // Premium modules.
22
  $mod_versions = array();
23
+ foreach ( $wpbdp->licensing->get_items() as $m ) {
24
  $mod_versions[] = str_replace( ' Module', '', $m['name'] ) . ' - ' . $m['version'];
25
  }
26
  if ( class_exists( 'WPBDP_CategoriesModule' ) ) {
32
  'html' => implode( '<br />', $mod_versions )
33
  );
34
 
35
+ $tables = apply_filters( 'wpbdp_debug_info_tables_check', array( 'wpbdp_form_fields', 'wpbdp_plans', 'wpbdp_payments', 'wpbdp_listings' ) );
 
36
  $missing_tables = array();
37
  foreach ( $tables as &$t ) {
38
  if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->prefix . $t) ) == '' )
51
  $debug_info['options']['_title'] = _x( 'BD Options', 'debug-info', 'WPBDM' );
52
 
53
  $settings_api = wpbdp_settings_api();
54
+ foreach ( $settings_api->get_registered_settings() as &$s ) {
55
+ if ( in_array( $s['id'], $blacklisted ) )
56
  continue;
57
 
58
+ $value = wpbdp_get_option( $s['id'] );
59
+
60
+ if ( is_array( $value ) ) {
61
+ if ( empty( $value ) ) {
62
+ $value = '';
63
+ } else {
64
+ $value = print_r( $value, 1 );
65
+ }
66
+ }
67
+
68
+ $debug_info['options'][ $s['id'] ] = $value;
69
  }
70
  $debug_info['options'] = apply_filters( 'wpbdp_debug_info_section', $debug_info['options'], 'options' );
71
 
includes/admin/payments.php CHANGED
@@ -1,32 +1,105 @@
1
  <?php
2
- require_once( WPBDP_INC . 'class-payment.php' );
3
 
4
  /**
5
- * Payments admin page and AJAX actions.
6
- * @since 3.4
7
  */
8
- class WPBDP_Admin_Payments {
9
 
10
- public function __construct() {
11
- add_action( 'wp_ajax_wpbdp-payment-details', array( &$this, 'ajax_payment_details' ) );
 
 
12
  }
13
 
14
- public function ajax_payment_details() {
15
- if ( ! current_user_can( 'administrator' ) )
16
- exit();
17
 
18
- global $wpbdp;
 
19
 
20
- $response = new WPBDP_AJAX_Response();
21
 
22
- $payment = WPBDP_Payment::get( intval( $_REQUEST['id'] ) );
23
- if ( ! $payment )
24
- $response->send_error();
25
 
26
- $response->add( 'html', wpbdp_render_page( WPBDP_PATH . 'templates/admin/payment-details.tpl.php',
27
- array( 'payment' => $payment,
28
- 'invoice' => $wpbdp->payments->render_invoice( $payment ) ) ) );
29
- $response->send();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
31
 
32
  }
 
1
  <?php
2
+ require_once( WPBDP_PATH . 'includes/class-payment.php' );
3
 
4
  /**
5
+ * @since 5.0
 
6
  */
7
+ class WPBDP__Admin__Payments extends WPBDP__Admin__Controller {
8
 
9
+ function _enqueue_scripts() {
10
+ wp_enqueue_script( 'jquery-ui-datepicker' );
11
+ wpbdp_enqueue_jquery_ui_style();
12
+ parent::_enqueue_scripts();
13
  }
14
 
15
+ function index() {
16
+ $_SERVER['REQUEST_URI'] = remove_query_arg( 'listing' );
 
17
 
18
+ if ( ! empty( $_GET['message'] ) && 'payment_delete' == $_GET['message'] )
19
+ wpbdp_admin_message( _x( 'Payment deleted.', 'payments admin', 'WPBDM' ) );
20
 
 
21
 
22
+ require_once( WPBDP_INC . 'admin/helpers/class-payments-table.php' );
 
 
23
 
24
+ $table = new WPBDP__Admin__Payments_Table();
25
+ $table->prepare_items();
26
+
27
+ if ( ! empty( $_GET['listing'] ) ) {
28
+ $listing = WPBDP_Listing::get( $_GET['listing'] );
29
+
30
+ if ( $listing )
31
+ wpbdp_admin_message(
32
+ str_replace( '<a>',
33
+ '<a href="' . remove_query_arg( 'listing' ) . '">',
34
+ sprintf( _x( 'You\'re seeing payments related to listing: "%s" (ID #%d). <a>Click here</a> to see all payments.', 'payments admin', 'WPBDM' ),
35
+ esc_html( $listing->get_title() ),
36
+ $listing->get_id() ) )
37
+ );
38
+ }
39
+
40
+ return compact( 'table' );
41
+ }
42
+
43
+ function details() {
44
+ if ( ! empty( $_GET['message'] ) && 1 == $_GET['message'] )
45
+ wpbdp_admin_message( _x( 'Payment details updated.', 'payments admin', 'WPBDM' ) );
46
+
47
+ $payment = WPBDP_Payment::objects()->get( $_GET['payment-id'] );
48
+ return compact( 'payment' );
49
+ }
50
+
51
+ function payment_update() {
52
+ $data = $_POST['payment'];
53
+ $payment = WPBDP_Payment::objects()->get( $data['id'] );
54
+ $payment->update( $data );
55
+ $payment->save();
56
+
57
+ wp_redirect( admin_url( 'admin.php?page=wpbdp_admin_payments&wpbdp-view=details&payment-id=' . $payment->id . '&message=1' ) );
58
+ exit;
59
+ }
60
+
61
+ function payment_delete() {
62
+ $payment = WPBDP_Payment::objects()->get( (int) $_REQUEST['payment-id'] );
63
+ $payment->delete();
64
+
65
+ wp_redirect( admin_url( 'admin.php?page=wpbdp_admin_payments&message=payment_delete' ) );
66
+ exit;
67
+ }
68
+
69
+ function ajax_add_note() {
70
+ $payment_id = absint( $_POST['payment_id'] );
71
+ $payment = WPBDP_Payment::objects()->get( $payment_id );
72
+ $text = trim( $_POST['note'] );
73
+
74
+ $res = new WPBDP_Ajax_Response();
75
+
76
+ if ( ! $payment || ! $text )
77
+ $res->send_error();
78
+
79
+ $note = wpbdp_insert_log( array( 'log_type' => 'payment.note', 'message' => $text, 'actor' => 'user:' . get_current_user_id(), 'object_id' => $payment_id ) );
80
+ if ( ! $note )
81
+ $res->send_error();
82
+
83
+ $res->add( 'note', $note );
84
+ $res->add( 'html', wpbdp_render_page( WPBDP_PATH . 'templates/admin/payments-note.tpl.php', compact( 'note', 'payment_id' ) ) );
85
+ $res->send();
86
+ }
87
+
88
+ function ajax_delete_note() {
89
+ $payment_id = absint( $_GET['payment_id'] );
90
+ $note_key = trim( $_GET['note'] );
91
+
92
+ $res = new WPBDP_Ajax_Response();
93
+
94
+ $note = wpbdp_get_log( $note_key );
95
+ if ( 'payment.note' != $note->log_type || $payment_id != $note->object_id )
96
+ $res->send_error();
97
+
98
+ wpbdp_delete_log( $note_key );
99
+
100
+ $res->add( 'note', $note );
101
+ $res->send();
102
  }
103
 
104
  }
105
+
includes/admin/settings/class-settings-admin.php ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Settings_Admin {
3
+
4
+ /**
5
+ * Used to lookup sections by ID during the section callback execution.
6
+ */
7
+ private $sections_by_id = array();
8
+
9
+
10
+ public function __construct() {
11
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
12
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
13
+ add_filter( 'wpbdp_admin_menu_items', array( $this, 'menu_item' ) );
14
+ }
15
+
16
+ public function enqueue_scripts( $hook ) {
17
+ if ( 'directory-admin_page_wpbdp_settings' == $hook ) {
18
+ wp_enqueue_script( 'wpbdp-admin-settings', WPBDP_URL . 'assets/js/admin-settings.js' );
19
+ }
20
+ }
21
+
22
+ public function menu_item( $menu ) {
23
+ $menu['wpbdp_settings'] = array(
24
+ 'title' => _x( 'Manage Options', 'admin menu', 'WPBDM' ),
25
+ 'callback' => array( $this, 'settings_page' ),
26
+ 'priority' => 2
27
+ );
28
+ return $menu;
29
+ }
30
+
31
+ public function register_settings() {
32
+ $all_groups = wpbdp()->settings->get_registered_groups();
33
+ $non_tabs = wp_list_filter( $all_groups, array( 'type' => 'tab' ), 'NOT' );
34
+
35
+ foreach ( $non_tabs as $group_id => $group ) {
36
+ switch ( $group['type'] ) {
37
+ case 'subtab':
38
+ add_settings_section(
39
+ 'wpbdp_settings_subtab_' . $group_id,
40
+ '',
41
+ '__return_false',
42
+ 'wpbdp_settings_subtab_' . $group_id
43
+ );
44
+ break;
45
+ case 'section':
46
+ add_settings_section(
47
+ 'wpbdp_settings_subtab_' . $group['parent'] . '_' . $group_id,
48
+ $group['title'],
49
+ array( $this, 'section_header_callback' ),
50
+ 'wpbdp_settings_subtab_' . $group['parent']
51
+ );
52
+ break;
53
+ default:
54
+ break;
55
+ }
56
+ }
57
+
58
+ foreach ( wpbdp()->settings->get_registered_settings() as $setting_id => $setting ) {
59
+ $args = array_merge(
60
+ array(
61
+ 'label_for' => $setting['id'],
62
+ 'class' => '',
63
+ 'desc' => '',
64
+ 'tooltip' => ''
65
+ ),
66
+ $setting
67
+ );
68
+
69
+ if ( 'silent' == $setting['type'] ) {
70
+ continue;
71
+ }
72
+
73
+ if ( isset( $all_groups[ $args['group'] ] ) ) {
74
+ switch ( $all_groups[ $args['group'] ]['type'] ) {
75
+ case 'subtab':
76
+ $subtab_group = 'wpbdp_settings_subtab_' . $args['group'];
77
+ $section_group = $subtab_group;
78
+ break;
79
+ case 'section':
80
+ $subtab_group = 'wpbdp_settings_subtab_' . $all_groups[ $args['group'] ]['parent'];
81
+ $section_group = $subtab_group . '_' . $args['group'];
82
+ break;
83
+ }
84
+ } else {
85
+ wpbdp_debug_e( 'group not found: ', $args );
86
+ }
87
+
88
+ add_settings_field(
89
+ 'wpbdp_settings[' . $args['id'] . ']',
90
+ $args['name'],
91
+ array( $this, 'setting_callback' ),
92
+ $subtab_group,
93
+ $section_group,
94
+ $args
95
+ );
96
+ }
97
+ }
98
+
99
+ public function section_header_callback( $wp_section ) {
100
+ return;
101
+
102
+ if ( ! empty( $section['desc'] ) ) {
103
+ echo '<p class="wpbdp-setting-description wpbdp-settings-section-description">';
104
+ echo $section['desc'];
105
+ echo '</p>';
106
+ }
107
+ }
108
+
109
+ public function setting_callback( $setting ) {
110
+ if ( 'callback' == $setting['type'] ) {
111
+ if ( ! empty( $setting['callback'] ) && is_callable( $setting['callback'] ) ) {
112
+ $callback_html = call_user_func( $setting['callback'], $setting );
113
+ } else {
114
+ $callback_html = 'Missing callback';
115
+ }
116
+ } else {
117
+ $value = wpbdp()->settings->get_option( $setting['id'] );
118
+
119
+ ob_start();
120
+
121
+ if ( method_exists( $this, 'setting_' . $setting['type'] . '_callback' ) ) {
122
+ call_user_func( array( $this, 'setting_' . $setting['type'] . '_callback' ), $setting, $value );
123
+ } else {
124
+ $this->setting_missing_callback( $setting, $value );
125
+ }
126
+
127
+ $callback_html = ob_get_clean();
128
+ }
129
+
130
+ if ( ! empty( $setting['attrs'] ) ) {
131
+ $attrs = wpbdp_html_attributes( $setting['attrs'], array( 'id', 'class' ) );
132
+ } else {
133
+ $attrs = '';
134
+ }
135
+
136
+ $attrs .= ' data-setting-id="' . esc_attr( $setting['id'] ) . '" ';
137
+
138
+ if ( ! empty( $setting['requirements'] ) ) {
139
+ $reqs_info = array();
140
+
141
+ foreach ( $setting['requirements'] as $r ) {
142
+ $reqs_info[] = array( $r, (bool) wpbdp_get_option( str_replace( '!', '', $r ) ) );
143
+ }
144
+
145
+ $attrs .= ' data-requirements="' . esc_attr( json_encode( $reqs_info ) ) . '"';
146
+ }
147
+
148
+ $html = '';
149
+ $html .= '<div id="wpbdp-settings-' . $setting['id'] . '" class="wpbdp-settings-setting wpbdp-settings-type-' . $setting['type'] . '" ' . $attrs . '>';
150
+ $html .= $callback_html;
151
+ $html .= '<a name="' . $setting['id'] . '"></a>';
152
+ $html .= '</div>';
153
+
154
+ echo $html;
155
+ }
156
+
157
+ public function setting_tooltip( $tooltip = '' ) {
158
+ if ( ! $tooltip ) {
159
+ return;
160
+ }
161
+
162
+ return '<span class="wpbdp-setting-tooltip wpbdp-tooltip dashicons dashicons-editor-help" title="' . esc_attr( $tooltip ) . '"></span>';
163
+ }
164
+
165
+ public function setting_missing_callback( $setting, $value ) {
166
+ if ( has_filter( 'wpbdp_setting_type_' . $setting['type'] ) ) {
167
+ echo apply_filters( 'wpbdp_setting_type_' . $setting['type'], $setting, $value );
168
+ } else {
169
+ echo 'Callback Missing';
170
+ }
171
+ }
172
+
173
+ public function setting_text_callback( $setting, $value ) {
174
+ echo '<input type="text" id="' . $setting['id'] . '" name="wpbdp_settings[' . $setting['id'] . ']" value="' . esc_attr( $value ) . '" placeholder="' . ( ! empty( $setting['placeholder'] ) ? esc_attr( $setting['placeholder'] ) : '' ) . '" />';
175
+
176
+ if ( ! empty( $setting['desc'] ) ) {
177
+ echo '<span class="wpbdp-setting-description">' . wp_kses_post( $setting['desc'] ) . '</span>';
178
+ }
179
+ }
180
+
181
+ public function setting_number_callback( $setting, $value ) {
182
+ echo '<input type="number" id="' . $setting['id'] . '" name="wpbdp_settings[' . $setting['id'] . ']" value="' . esc_attr( $value ) . '"';
183
+
184
+ if ( isset( $setting['min'] ) ) {
185
+ echo 'min="' . $setting['min'] . '"';
186
+ }
187
+
188
+ if ( isset( $setting['step'] ) ) {
189
+ echo 'step="' . $setting['step'] . '"';
190
+ }
191
+ echo '/>';
192
+
193
+ if ( ! empty( $setting['desc'] ) ) {
194
+ echo '<span class="wpbdp-setting-description">' . wp_kses_post( $setting['desc'] ) . '</span>';
195
+ }
196
+ }
197
+
198
+ public function setting_textarea_callback( $setting, $value ) {
199
+ echo '<textarea id="' . $setting['id'] . '" name="wpbdp_settings[' . $setting['id'] . ']" placeholder="' . ( ! empty( $setting['placeholder'] ) ? esc_attr( $setting['placeholder'] ) : '' ) . '">';
200
+ echo esc_textarea( $value );
201
+ echo '</textarea>';
202
+
203
+ if ( ! empty( $setting['desc'] ) ) {
204
+ echo '<span class="wpbdp-setting-description">' . $setting['desc'] . '</span>';
205
+ }
206
+ }
207
+
208
+ public function setting_checkbox_callback( $setting, $value ) {
209
+ $value = (boolean) $value;
210
+
211
+ echo '<input type="hidden" name="wpbdp_settings[' . $setting['id'] . ']" value="-1" />';
212
+ echo '<input type="checkbox" id="' . $setting['id'] . '" name="wpbdp_settings[' . $setting['id'] . ']" value="1" ' . checked( $value, 1, false ) . ' />';
213
+
214
+ if ( ! empty( $setting['desc'] ) ) {
215
+ echo '<label for="' . $setting['id'] . '">' . $setting['desc'] . '</label>';
216
+ }
217
+
218
+ if ( ! empty( $setting['tooltip'] ) ) {
219
+ echo '<span class="wpbdp-setting-description">' . $setting['tooltip'] . '</span>';
220
+ }
221
+ }
222
+
223
+ public function setting_radio_callback( $setting, $value ) {
224
+ if ( empty( $setting['options'] ) ) {
225
+ return;
226
+ }
227
+
228
+ echo '<div class="wpbdp-settings-radio-options">';
229
+ foreach ( $setting['options'] as $option_value => $option_label ) {
230
+ echo '<div class="wpbdp-settings-radio-option">';
231
+ echo '<input type="radio" name="wpbdp_settings[' . $setting['id'] . ']" value="' . esc_attr( $option_value ) . '" ' . checked( $option_value, $value, false ) . ' id="wpbdp-settings-' . $setting['id'] . '-radio-' . $option_value . '" />';
232
+ echo '<label>';
233
+ echo $option_label;
234
+ echo '</label>';
235
+ echo '</div>';
236
+ }
237
+ echo '</div>';
238
+
239
+ if ( ! empty( $setting['desc'] ) ) {
240
+ echo '<span class="wpbdp-setting-description">' . $setting['desc'] . '</span>';
241
+ }
242
+ }
243
+
244
+ public function setting_multicheck_callback( $setting, $value ) {
245
+ if ( empty( $setting['options'] ) ) {
246
+ return;
247
+ }
248
+
249
+ $value = (array) $value;
250
+
251
+ echo '<input type="hidden" name="wpbdp_settings[' . $setting['id'] . ']" value="-1" />';
252
+
253
+ echo '<div class="wpbdp-settings-multicheck-options">';
254
+ $n = 0;
255
+ foreach ( $setting['options'] as $option_value => $option_label ) {
256
+ echo '<div class="wpbdp-settings-multicheck-option wpbdp-settings-multicheck-option-no-' . $n . '">';
257
+ echo '<input type="checkbox" name="wpbdp_settings[' . $setting['id'] . '][]" id="wpbdp-' . $setting['id'] . '-checkbox-no-' . $n . '" value="' . esc_attr( $option_value ) . '" ' . checked( in_array( $option_value, $value ), true, false ) . ' />';
258
+ echo '<label for="wpbdp-' . $setting['id'] . '-checkbox-no-' . $n . '">';
259
+ echo $option_label;
260
+ echo '</label>';
261
+ echo '</div>';
262
+
263
+ $n++;
264
+ }
265
+
266
+ echo '</div>';
267
+
268
+ if ( ! empty( $setting['desc'] ) ) {
269
+ echo '<span class="wpbdp-setting-description">' . $setting['desc'] . '</span>';
270
+ }
271
+ }
272
+
273
+ public function setting_select_callback( $setting, $value ) {
274
+ if ( empty( $setting['options'] ) ) {
275
+ return;
276
+ }
277
+
278
+ $multiple = ! empty( $setting['multiple'] ) && $setting['multiple'];
279
+
280
+ echo '<select id="' . $setting['id'] . '" name="wpbdp_settings[' . $setting['id'] . ']' . ( $multiple ? '[]' : '' ) . '" ' . ( $multiple ? 'multiple="multiple"' : '' ) . '>';
281
+ foreach ( $setting['options'] as $option_value => $option_label ) {
282
+ if ( $multiple ) {
283
+ $selected = in_array( $option_value, $value );
284
+ } else {
285
+ $selected = ( $option_value == $value );
286
+ }
287
+
288
+ echo '<option value="' . $option_value . '" ' . selected( $selected, true, false ) . '>' . $option_label . '</option>';
289
+ }
290
+ echo '</select>';
291
+
292
+ if ( ! empty( $setting['desc'] ) ) {
293
+ echo '<span class="wpbdp-setting-description">' . $setting['desc'] . '</span>';
294
+ }
295
+ }
296
+
297
+ public function setting_email_template_callback( $setting, $value ) {
298
+ if ( ! is_array( $value ) ) {
299
+ $value = array(
300
+ 'subject' => $setting['default']['subject'],
301
+ 'body' => $value
302
+ );
303
+ }
304
+
305
+ $args = array(
306
+ 'setting_name' => 'wpbdp_settings[' . $setting['id'] . ']',
307
+ 'email_subject' => $value['subject'],
308
+ 'email_body' => $value['body'],
309
+ 'placeholders' => ! empty( $setting['placeholders'] ) ? $setting['placeholders'] : array()
310
+ );
311
+
312
+ if ( ! empty( $setting['desc'] ) ) {
313
+ echo '<span class="wpbdp-setting-description">' . $setting['desc'] . '</span>';
314
+ }
315
+
316
+ echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/settings-email.tpl.php', $args );
317
+ }
318
+
319
+ public function setting_expiration_notices_callback( $setting, $value ) {
320
+ ?>
321
+ <div class="wpbdp-settings-expiration-notices">
322
+ <button id="wpbdp-settings-expiration-notices-add-btn" class="button"><?php _ex( 'Add notice', 'expiration notices', 'WPBDM' ); ?></button>
323
+
324
+ <div id="wpbdp-settings-expiration-notices-add">
325
+ <?php
326
+ $n = max( array_keys( $value ) ) + 1;
327
+ echo wpbdp_render_page(
328
+ WPBDP_PATH . 'templates/admin/settings-email.tpl.php',
329
+ array(
330
+ 'setting_name' => 'new_notice[' . $n . ']',
331
+ 'uid' => '',
332
+ 'container_class' => 'wpbdp-expiration-notice-email',
333
+ 'extra_fields' => $this->setting_expiration_notices_email_extra_fields( 'new_notice[' . $n . ']', '', null ),
334
+ 'editor_only' => true
335
+ )
336
+ );
337
+ ?>
338
+ </div>
339
+
340
+ <?php if ( ! $value ): ?>
341
+ <p class="wpbdp-no-items"><?php _ex( 'No notices configured.', 'expiration notices', 'WPBDM' ); ?></p>
342
+ <?php endif; ?>
343
+
344
+ <?php
345
+ foreach ( $value as $i => $notice ) {
346
+ $uid = uniqid( 'wpbdp-settings-email-' );
347
+ $vars = array(
348
+ 'setting_name' => 'wpbdp_settings[' . $setting['id'] . '][' . $i . ']',
349
+ 'uid' => $uid,
350
+ 'container_class' => 'wpbdp-expiration-notice-email',
351
+ 'email_subject' => $notice['subject'],
352
+ 'email_body' => $notice['body'],
353
+ 'extra_fields' => $this->setting_expiration_notices_email_extra_fields( 'wpbdp_settings[' . $setting['id'] . '][' . $i . ']', $uid, $notice ),
354
+ 'after_container' => $this->setting_expiration_notices_email_summary( $notice ),
355
+ 'before_buttons' => '<a href="#" class="delete">' . _x( 'Delete', 'expiration notices', 'WPBDM' ) . '</a>'
356
+ );
357
+
358
+ echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/settings-email.tpl.php', $vars );
359
+ }
360
+ ?>
361
+ </div>
362
+ <?php
363
+ }
364
+
365
+ private function setting_expiration_notices_email_summary( $notice ) {
366
+ $event = $notice['event'];
367
+ $listings = $notice['listings'];
368
+ $relative_time = ! empty( $notice['relative_time'] ) ? $notice['relative_time'] : '';
369
+
370
+ if ( 'both' == $listings ) {
371
+ $recurring_modifier = _x( 'recurring and non-recurring', 'expiration notices', 'WPBDM' );
372
+ } elseif ( 'recurring' == $listings ) {
373
+ $recurring_modifier = _x( 'recurring only', 'expiration notices', 'WPBDM' );
374
+ } else {
375
+ $recurring_modifier = _x( 'non-recurring only', 'expiration notices', 'WPBDM' );
376
+ }
377
+
378
+ if ( 'renewal' == $event ) {
379
+ $summary = sprintf( _x( 'Sent when a listing (%s) is renewed.', 'expiration notices', 'WPBDM' ), $recurring_modifier );
380
+ }
381
+
382
+ if ( 'expiration' == $event ) {
383
+ if ( '0 days' == $relative_time ) {
384
+ $summary = sprintf( _x( 'Sent when a listing (%s) expires.', 'expiration notices', 'WPBDM' ), $recurring_modifier );
385
+ } else {
386
+ $relative_time_parts = explode( ' ', $relative_time );
387
+ $relative_time_number = trim( str_replace( array( '+', '-' ), '', $relative_time_parts[0] ) );
388
+ $relative_time_units = $relative_time_parts[1];
389
+
390
+ switch ( $relative_time_units ) {
391
+ case 'days':
392
+ $relative_time_h = sprintf( _nx( '%d day', '%d days', $relative_time_number, 'expiration notices', 'WPBDM' ), $relative_time_number );
393
+ break;
394
+ case 'weeks':
395
+ $relative_time_h = sprintf( _nx( '%d week', '%d weeks', $relative_time_number, 'expiration notices', 'WPBDM' ), $relative_time_number );
396
+ break;
397
+ case 'months':
398
+ $relative_time_h = sprintf( _nx( '%d month', '%d months', $relative_time_number, 'expiration notices', 'WPBDM' ), $relative_time_number );
399
+ break;
400
+ }
401
+
402
+ if ( $relative_time[0] == '+' ) {
403
+ $summary = sprintf( _x( 'Sent %1$s before a listing (%2$s) expires.', 'expiration notices', 'WPBDM' ), $relative_time_h, $recurring_modifier );
404
+ } else {
405
+ $summary = sprintf( _x( 'Sent %1$s after a listing (%2$s) expires.', 'expiration notices', 'WPBDM' ), $relative_time_h, $recurring_modifier );
406
+ }
407
+ }
408
+ }
409
+
410
+ ob_start();
411
+ ?>
412
+ <div class="wpbdp-expiration-notice-email-schedule-summary">
413
+ <?php echo $summary; ?>
414
+ </div>
415
+ <?php
416
+ return ob_get_clean();
417
+ }
418
+
419
+ private function setting_expiration_notices_schedule() {
420
+ // Notices schedule.
421
+ $notices_schedule = array(
422
+ array( 'expiration', '0 days', _x( 'At the time of expiration', 'expiration notices', 'WPBDM' ) ),
423
+ array( 'renewal', '0 days', _x( 'Right after a successful renewal', 'expiration notices', 'WPBDM' ) )
424
+ );
425
+ foreach ( array( 'days' => array( 1, 2, 3, 4, 5 ),
426
+ 'weeks' => array( 1, 2 ),
427
+ 'months' => array( 1, 2 ) ) as $unit => $periods ) {
428
+ foreach ( $periods as $i ) {
429
+ foreach ( array( '+', '-' ) as $sign ) {
430
+ switch ( $unit ) {
431
+ case 'days':
432
+ $label = sprintf( '+' == $sign ? _nx( '%d day before expiration', '%d days before expiration', $i, 'expiration notices', 'WPBDM' ) : _nx( '%d day after expiration', '%d days after expiration', $i, 'expiration notices', 'WPBDM' ), $i );
433
+ break;
434
+ case 'weeks':
435
+ $label = sprintf( '+' == $sign ? _nx( '%d week before expiration', '%d weeks before expiration', $i, 'expiration notices', 'WPBDM' ) : _nx( '%d week after expiration', '%d weeks after expiration', $i, 'expiration notices', 'WPBDM' ), $i );
436
+ break;
437
+ case 'months':
438
+ $label = sprintf( '+' == $sign ? _nx( '%d month before expiration', '%d months before expiration', $i, 'expiration notices', 'WPBDM' ) : _nx( '%d month after expiration', '%d months after expiration', $i, 'expiration notices', 'WPBDM' ), $i );
439
+ break;
440
+ }
441
+
442
+ $notices_schedule[] = array( 'expiration', $sign . $i . ' ' . $unit, $label );
443
+ }
444
+ }
445
+ }
446
+
447
+ return apply_filters( 'wpbdp_expiration_notices_schedule', $notices_schedule );
448
+ }
449
+
450
+ private function setting_expiration_notices_email_extra_fields( $name, $uid, $notice ) {
451
+ if ( is_null( $notice ) ) {
452
+ $notice = array( 'event' => 'expiration', 'listings' => 'both', 'relative_time' => '0 days', 'subject' => '', 'body' => '' );
453
+ }
454
+
455
+ ob_start();
456
+ ?>
457
+ <tr>
458
+ <th scope="row"><label for="<?php echo $uid; ?>-listings"><?php _ex( 'Applies to', 'expiration notices', 'WPBDM' ); ?></label></th>
459
+ <td>
460
+ <select id="<?php echo $uid; ?>-listings" name="<?php echo $name; ?>[listings]">
461
+ <option value="non-recurring" <?php selected( 'non-recurring', $notice['listings'] ); ?>><?php _ex( 'Non-recurring listings', 'expiration notices', 'WPBDM' ); ?></option>
462
+ <option value="recurring" <?php selected( 'recurring', $notice['listings'] ); ?>><?php _ex( 'Recurring listings', 'expiration notices', 'WPBDM' ); ?></option>
463
+ <option value="both" <?php selected( 'both', $notice['listings'] ); ?>><?php _ex( 'Recurring and non-recurring listings', 'expiration notices', 'WPBDM' ); ?></option>
464
+ </select>
465
+ </td>
466
+ </tr>
467
+ <tr>
468
+ <th scope="row"><label for="<?php echo $uid; ?>-relative-time-and-event"><?php _ex( 'When to send?', 'expiration notices', 'WPBDM' ); ?></label></th>
469
+ <td>
470
+ <input type="hidden" value="<?php echo $notice['event']; ?>" class="stored-notice-event" />
471
+ <input type="hidden" value="<?php echo ! empty( $notice['relative_time'] ) ? $notice['relative_time'] : ''; ?>" class="stored-notice-relative-time" />
472
+
473
+ <input type="hidden" name="<?php echo $name; ?>[event]" value="<?php echo $notice['event']; ?>" class="notice-event" />
474
+ <input type="hidden" name="<?php echo $name; ?>[relative_time]" value="<?php echo ! empty( $notice['relative_time'] ) ? $notice['relative_time'] : ''; ?>" class="notice-relative-time" />
475
+
476
+ <select id="<?php echo $uid; ?>-relative-time-and-event" class="relative-time-and-event">
477
+ <?php foreach ( $this->setting_expiration_notices_schedule() as $item ): ?>
478
+ <?php if ( 'renewal' == $item[0] ): ?>
479
+ <option value="<?php echo $item[0]; ?>,<?php echo $item[1]; ?>" <?php selected( $item[0], $notice['event'] ); ?>><?php echo $item[2]; ?></option>
480
+ <?php else: ?>
481
+ <option value="<?php echo $item[0]; ?>,<?php echo $item[1]; ?>" <?php selected( $item[0] == $notice['event'] && ! empty( $notice['relative_time'] ) && $item[1] == $notice['relative_time'], true ); ?>><?php echo $item[2]; ?></option>
482
+ <?php endif; ?>
483
+ <?php endforeach; ?>
484
+ </select>
485
+ </td>
486
+ </tr>
487
+ <?php
488
+ return ob_get_clean();
489
+ }
490
+
491
+
492
+ public function settings_page() {
493
+ $all_groups = wpbdp()->settings->get_registered_groups();
494
+
495
+ // Filter out empty groups.
496
+ $all_groups = wp_list_filter( $all_groups, array( 'count' => 0 ), 'NOT' );
497
+
498
+ $tabs = wp_list_filter( $all_groups, array( 'type' => 'tab' ) );
499
+ if ( ! empty( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $tabs ) ) {
500
+ $active_tab = $_GET['tab'];
501
+ } else {
502
+ $active_tab = 'general';
503
+ }
504
+
505
+ $subtabs = wp_list_filter( $all_groups, array( 'parent' => $active_tab ) );
506
+ if ( ! empty( $_GET['subtab'] ) && array_key_exists( $_GET['subtab'], $subtabs ) ) {
507
+ $active_subtab = $_GET['subtab'];
508
+ } else {
509
+ $subtabs_ids = array_keys( $subtabs );
510
+ $active_subtab = reset( $subtabs_ids );
511
+ }
512
+
513
+ $active_subtab_description = ! empty( $all_groups[ $active_subtab ]['desc'] ) ? $all_groups[ $active_subtab ]['desc'] : '';
514
+ $custom_form = ( ! empty( $all_groups[ $active_subtab ]['custom_form'] ) ) && $all_groups[ $active_subtab ]['custom_form'];
515
+
516
+ echo wpbdp_render_page( WPBDP_PATH . 'templates/admin/settings-page.tpl.php', compact( 'tabs', 'subtabs', 'active_tab', 'active_subtab', 'active_subtab_description', 'custom_form' ) );
517
+ }
518
+
519
+ // FIXME: before fees-revamp.
520
+ // public function settings_reset_defaults() {
521
+ // $do_reset = ( ! empty ( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'reset defaults' ) );
522
+ //
523
+ // if ( $do_reset ) {
524
+ // global $wpbdp;
525
+ // $wpbdp->settings->reset_defaults();
526
+ // }
527
+ //
528
+ // wp_redirect( admin_url( 'admin.php?page=wpbdp_admin_settings&settings-updated=1&groupid=general' ) );
529
+ // exit();
530
+ // }
531
+
532
+ }
includes/admin/settings/class-settings-bootstrap.php ADDED
@@ -0,0 +1,1106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ final class WPBDP__Settings__Bootstrap {
3
+
4
+ public static function register_initial_groups() {
5
+ wpbdp_register_settings_group( 'general', _x( 'General', 'settings', 'WPBDM' ) );
6
+
7
+ wpbdp_register_settings_group( 'listings', _x( 'Listings', 'settings', 'WPBDM' ) );
8
+ wpbdp_register_settings_group( 'listings/main', _x( 'General Settings', 'settings', 'WPBDM' ), 'listings' );
9
+
10
+ wpbdp_register_settings_group( 'email', _x( 'E-Mail', 'settings', 'WPBDM' ) );
11
+ wpbdp_register_settings_group( 'email/main', _x( 'General Settings', 'settings', 'WPBDM' ), 'email' );
12
+
13
+ wpbdp_register_settings_group( 'payment', _x( 'Payment', 'settings', 'WPBDM' ) );
14
+ wpbdp_register_settings_group( 'payment/main', _x( 'General Settings', 'settings', 'WPBDM' ), 'payment' );
15
+
16
+ wpbdp_register_settings_group( 'appearance', _x( 'Appearance', 'settings', 'WPBDM' ) );
17
+ wpbdp_register_settings_group( 'appearance/main', _x( 'General Settings', 'settings', 'WPBDM' ), 'appearance' );
18
+
19
+ // wpbdp_register_settings_group( 'licenses', _x( 'Licenses', 'settings', 'WPBDM' ) );
20
+
21
+ wpbdp_register_settings_group( 'modules', _x( 'Premium Modules', 'settings', 'WPBDM' ) );
22
+ }
23
+
24
+ public static function register_initial_settings() {
25
+ self::settings_general();
26
+ self::settings_listings();
27
+ self::settings_email();
28
+ self::settings_payment();
29
+ self::settings_appearance();
30
+ }
31
+
32
+ private static function settings_general() {
33
+ wpbdp_register_settings_group( 'general/main', _x( 'General Settings', 'settings', 'WPBDM' ), 'general' );
34
+
35
+ // Permalinks.
36
+ wpbdp_register_settings_group( 'permalink_settings', _x( 'Permalink Settings', 'settings', 'WPBDM' ), 'general/main' );
37
+ wpbdp_register_setting( array(
38
+ 'id' => 'permalinks-directory-slug',
39
+ 'type' => 'text',
40
+ 'name' => _x( 'Directory Listings Slug', 'settings', 'WPBDM' ),
41
+ 'default' => 'wpbdp_listing',
42
+ 'group' => 'permalink_settings',
43
+ 'validator' => 'no-spaces,trim,required'
44
+ ) );
45
+ wpbdp_register_setting( array(
46
+ 'id' => 'permalinks-category-slug',
47
+ 'type' => 'text',
48
+ 'name' => _x( 'Categories Slug', 'settings', 'WPBDM' ),
49
+ 'desc' => _x( 'The slug can\'t be in use by another term. Avoid "category", for instance.', 'settings', 'WPBDM' ),
50
+ 'default' => 'wpbdp_category',
51
+ 'group' => 'permalink_settings',
52
+ 'taxonomy' => WPBDP_CATEGORY_TAX,
53
+ 'validator' => 'taxonomy_slug'
54
+ ) );
55
+ wpbdp_register_setting( array(
56
+ 'id' => 'permalinks-tags-slug',
57
+ 'type' => 'text',
58
+ 'name' => _x( 'Tags Slug', 'settings', 'WPBDM' ),
59
+ 'desc' => _x( 'The slug can\'t be in use by another term. Avoid "tag", for instance.', 'settings', 'WPBDM' ),
60
+ 'default' => 'wpbdp_tag',
61
+ 'group' => 'permalink_settings',
62
+ 'taxonomy' => WPBDP_TAGS_TAX,
63
+ 'validator' => 'taxonomy_slug'
64
+ ) );
65
+ wpbdp_register_setting( array(
66
+ 'id' => 'permalinks-no-id',
67
+ 'type' => 'checkbox',
68
+ 'name' => _x( 'Remove listing ID from directory URLs?', 'settings', 'WPBDM' ),
69
+ 'desc' => _x( 'Check this setting to remove the ID for better SEO.', 'settings', 'WPBDM' ),
70
+ 'tooltip' => _x( 'Prior to 3.5.1, we included the ID in the listing URL, like "/business-directory/1809/listing-title".', 'settings', 'WPBDM' ) . _x( '<strong>IMPORTANT:</strong> subpages of the main directory page cannot be accesed while this settings is checked.', 'admin settings', 'WPBDM' ),
71
+ 'group' => 'permalink_settings'
72
+ ) );
73
+
74
+ // reCAPTCHA.
75
+ wpbdp_register_settings_group(
76
+ 'recaptcha',
77
+ _x( 'reCAPTCHA', 'settings', 'WPBDM' ),
78
+ 'general',
79
+ array(
80
+ 'desc' => str_replace( '<a>', '<a href="http://www.google.com/recaptcha" target="_blank">', _x( 'Need API keys for reCAPTCHA? Get them <a>here</a>.', 'settings', 'WPBDM' ) )
81
+ )
82
+ );
83
+ wpbdp_register_setting( array(
84
+ 'id' => 'recaptcha-on',
85
+ 'type' => 'checkbox',
86
+ 'name' => _x( 'Use reCAPTCHA for contact forms', 'settings', 'WPBDM' ),
87
+ 'group' => 'recaptcha'
88
+ ) );
89
+ wpbdp_register_setting( array(
90
+ 'id' => 'hide-recaptcha-loggedin',
91
+ 'type' => 'checkbox',
92
+ 'name' => _x( 'Turn off reCAPTCHA for logged in users?', 'settings', 'WPBDM' ),
93
+ 'group' => 'recaptcha'
94
+ ) );
95
+ wpbdp_register_setting( array(
96
+ 'id' => 'recaptcha-for-submits',
97
+ 'type' => 'checkbox',
98
+ 'name' => _x( 'Use reCAPTCHA for listing submits', 'settings', 'WPBDM' ),
99
+ 'group' => 'recaptcha'
100
+ ) );
101
+ wpbdp_register_setting( array(
102
+ 'id' => 'recaptcha-for-comments',
103
+ 'type' => 'checkbox',
104
+ 'name' => _x( 'Use reCAPTCHA for listing comments?', 'settings', 'WPBDM' ),
105
+ 'group' => 'recaptcha'
106
+ ) );
107
+ wpbdp_register_setting( array(
108
+ 'id' => 'recaptcha-public-key',
109
+ 'type' => 'text',
110
+ 'name' => _x( 'reCAPTCHA Public Key', 'settings', 'WPBDM' ),
111
+ 'default' => '',
112
+ 'group' => 'recaptcha'
113
+ ) );
114
+ wpbdp_register_setting( array(
115
+ 'id' => 'recaptcha-private-key',
116
+ 'type' => 'text',
117
+ 'name' => _x( 'reCAPTCHA Private Key', 'settings', 'WPBDM' ),
118
+ 'default' => '',
119
+ 'group' => 'recaptcha'
120
+ ) );
121
+
122
+ wpbdp_register_settings_group( 'registration', _x( 'Registration', 'settings', 'WPBDM' ), 'general', array( 'desc' => _x( "We expect that a membership plugin supports the 'redirect_to' parameter for the URLs below to work. If the plugin does not support them, these settings will not function as expected. Please contact the membership plugin and ask them to support the WP standard 'redirect_to' query parameter.", 'settings', 'WPBDM' ) ) );
123
+ wpbdp_register_setting( array(
124
+ 'id' => 'require-login',
125
+ 'type' => 'checkbox',
126
+ 'name' => _x( 'Require login to post listings?', 'settings', 'WPBDM' ),
127
+ 'default' => 1,
128
+ 'group' => 'registration'
129
+ ) );
130
+ wpbdp_register_setting( array(
131
+ 'id' => 'enable-key-access',
132
+ 'type' => 'checkbox',
133
+ 'name' => _x( 'Allow anonymous users to edit/manage listings with an access key?', 'settings', 'WPBDM' ),
134
+ 'group' => 'registration'
135
+ ) );
136
+ wpbdp_register_setting( array(
137
+ 'id' => 'login-url',
138
+ 'type' => 'text',
139
+ 'name' => _x( 'Login URL', 'settings', 'WPBDM' ),
140
+ 'desc' => _x( 'Only enter this if using a membership plugin or custom login page.', 'settings', 'WPBDM' ),
141
+ 'placeholder' => _x( 'URL of your membership plugin\'s login page.', 'settings', 'WPBDM' ),
142
+ 'default' => '',
143
+ 'group' => 'registration'
144
+ ) );
145
+ wpbdp_register_setting( array(
146
+ 'id' => 'registration-url',
147
+ 'type' => 'text',
148
+ 'name' => _x( 'Registration URL', 'settings', 'WPBDM' ),
149
+ 'desc' => _x( 'Only enter this if using a membership plugin or custom registration page.', 'settings', 'WPBDM' ),
150
+ 'placeholder' => _x( 'URL of your membership plugin\'s registration page.', 'settings', 'WPBDM' ),
151
+ 'default' => '',
152
+ 'group' => 'registration'
153
+ ) );
154
+ wpbdp_register_setting( array(
155
+ 'id' => 'create-account-during-submit-mode',
156
+ 'type' => 'radio',
157
+ 'name' => _x( 'Allow users to create accounts during listing submit?', 'settings', 'WPBDM' ),
158
+ 'default' => 'disabled',
159
+ 'options' => array(
160
+ 'disabled' => _x( 'No', 'settings', 'WPBDM' ),
161
+ 'optional' => _x( 'Yes, and make it optional', 'settings', 'WPBDM' ),
162
+ 'required' => _x( 'Yes, and make it required', 'settings', 'WPBDM' ),
163
+ ),
164
+ 'group' => 'registration'
165
+ ) );
166
+
167
+
168
+ // Terms & Conditions.
169
+ wpbdp_register_settings_group( 'tos_settings', _x( 'Terms and Conditions', 'settings', 'WPBDM' ), 'general/main' );
170
+ wpbdp_register_setting( array(
171
+ 'id' => 'display-terms-and-conditions',
172
+ 'type' => 'checkbox',
173
+ 'name' => _x( 'Display and require user agreement to Terms and Conditions', 'settings', 'WPBDM' ),
174
+ 'group' => 'tos_settings'
175
+ ) );
176
+ wpbdp_register_setting( array(
177
+ 'id' => 'terms-and-conditions',
178
+ 'type' => 'textarea',
179
+ 'name' => _x( 'Terms and Conditions', 'settings', 'WPBDM' ),
180
+ 'desc' => _x( 'Enter text or a URL starting with http. If you use a URL, the Terms and Conditions text will be replaced by a link to the appropiate page.', 'settings', 'WPBDM' ),
181
+ 'default' => '',
182
+ 'placeholder' => _x( 'Terms and Conditions text goes here.', 'settings', 'WPBDM' ),
183
+ 'group' => 'tos_settings'
184
+ ) );
185
+
186
+ // Tracking.
187
+ wpbdp_register_settings_group( 'tracking_settings', _x( 'Data Collection', 'settings', 'WPBDM' ), 'general/main' );
188
+ wpbdp_register_setting( array(
189
+ 'id' => 'tracking-on',
190
+ 'type' => 'checkbox',
191
+ 'name' => _x( 'Allow BD to anonymously collect information about your installed plugins, themes and WP version?', 'settings', 'WPBDM' ),
192
+ 'desc' => str_replace( '<a>', '<a href="http://businessdirectoryplugin.com/what-we-track/" target="_blank">', _x( '<a>Learn more</a> about what BD does and does NOT track.', 'admin settings', 'WPBDM' ) ),
193
+ 'group' => 'tracking_settings'
194
+ ) );
195
+
196
+ // Search.
197
+ wpbdp_register_settings_group( 'search_settings', _x( 'Directory Search', 'settings', 'WPBDM' ), 'general/main' );
198
+ wpbdp_register_setting( array(
199
+ 'id' => 'search-form-in-results',
200
+ 'type' => 'radio',
201
+ 'name' => _x( 'Search form display', 'settings', 'WPBDM' ),
202
+ 'default' => 'above',
203
+ 'options' => array(
204
+ 'above' => _x( 'Above results', 'admin settings', 'WPBDM' ),
205
+ 'below' => _x( 'Below results', 'admin settings', 'WPBDM' ),
206
+ 'none' => _x( 'Don\'t show with results', 'admin settings', 'WPBDM' )
207
+ ),
208
+ 'group' => 'search_settings'
209
+ ) );
210
+
211
+ $too_many_fields = '<span class="text-fields-warning wpbdp-note" style="display: none;">';
212
+ $too_many_fields .= _x( 'You have selected a textarea field to be included in quick searches. Searches involving those fields are very expensive and could result in timeouts and/or general slowness.', 'admin settings', 'WPBDM' );
213
+ $too_many_fields .= '</span>';
214
+
215
+ list( $fields, $text_fields ) = self::get_quicksearch_fields();
216
+ wpbdp_register_setting( array(
217
+ 'id' => 'quick-search-fields',
218
+ 'type' => 'multicheck',
219
+ 'name' => _x( 'Quick search fields', 'settings', 'WPBDM' ),
220
+ 'desc' => _x( 'Choosing too many fields for inclusion into Quick Search can result in very slow search performance.', 'settings', 'WPBDM' ) . $too_many_fields,
221
+ 'default' => array(),
222
+ 'multiple' => true,
223
+ 'options' => $fields,
224
+ 'group' => 'search_settings',
225
+ 'attrs' => array(
226
+ 'data-text-fields' => json_encode( $text_fields )
227
+ )
228
+ ) );
229
+ wpbdp_register_setting( array(
230
+ 'id' => 'quick-search-enable-performance-tricks',
231
+ 'type' => 'checkbox',
232
+ 'name' => _x( 'Enable high performance searches?', 'settings', 'WPBDM' ),
233
+ 'desc' => _x( 'Enabling this makes BD sacrifice result quality to improve speed. This is helpful if you\'re on shared hosting plans, where database performance is an issue.', 'settings', 'WPBDM' ),
234
+ 'group' => 'search_settings'
235
+ ) );
236
+
237
+ // Advanced settings.
238
+ wpbdp_register_settings_group( 'general/advanced', _x( 'Advanced', 'settings', 'WPBDM' ), 'general' );
239
+
240
+ wpbdp_register_setting( array(
241
+ 'id' => 'disable-cpt',
242
+ 'type' => 'checkbox',
243
+ 'name' => _x( 'Disable advanced CPT integration?', 'settings', 'WPBDM' ),
244
+ 'group' => 'general/advanced'
245
+ ) );
246
+ wpbdp_register_setting( array(
247
+ 'id' => 'ajax-compat-mode',
248
+ 'type' => 'checkbox',
249
+ 'name' => _x( 'Enable AJAX compatibility mode?', 'settings', 'WPBDM' ),
250
+ 'desc' => _x( 'Check this if you are having trouble with BD, particularly when importing or exporting CSV files.', 'admin settings', 'WPBDM' )
251
+ . ' ' . str_replace( '<a>', '<a href="http://businessdirectoryplugin.com/support-forum/faq/how-to-check-for-plugin-and-theme-conflicts-with-bd/" target="_blank">', _x( 'If this compatibility mode doesn\'t solve your issue, you may be experiencing a more serious conflict. <a>Here is an article</a> about how to test for theme and plugin conflicts with Business Directory.', 'settings', 'WPBDM' ) ),
252
+ 'group' => 'general/advanced',
253
+ 'on_update' => array( __CLASS__, 'setup_ajax_compat_mode' )
254
+ ) );
255
+ wpbdp_register_setting( array(
256
+ 'id' => 'disable-submit-listing',
257
+ 'type' => 'checkbox',
258
+ 'name' => _x( 'Disable Frontend Listing Submission?', 'settings', 'WPBDM' ),
259
+ 'group' => 'general/advanced'
260
+ ) );
261
+ }
262
+
263
+ private static function get_quicksearch_fields() {
264
+ $fields = array();
265
+ $text_fields = array();
266
+
267
+ foreach ( wpbdp_get_form_fields( 'association=-custom' ) as $field ) {
268
+ if ( in_array( $field->get_association(), array( 'excerpt', 'content' ) ) || 'textarea' == $field->get_field_type_id() ) {
269
+ $text_fields[] = $field->get_id();
270
+ }
271
+
272
+ $fields[ $field->get_id() ] = $field->get_label();
273
+ }
274
+
275
+ return array( $fields, $text_fields );
276
+ }
277
+
278
+ private static function settings_listings() {
279
+ wpbdp_register_setting( array(
280
+ 'id' => 'listings-per-page',
281
+ 'type' => 'number',
282
+ 'name' => _x( 'Listings per page', 'settings', 'WPBDM' ),
283
+ 'desc' => _x( 'Number of listings to show per page. Use a value of "0" to show all listings.', 'settings', 'WPBDM' ),
284
+ 'default' => '10',
285
+ 'min' => 0, 'step' => 1,
286
+ 'group' => 'listings/main'
287
+ ) );
288
+ wpbdp_register_setting( array(
289
+ 'id' => 'listing-duration',
290
+ 'type' => 'number',
291
+ 'name' => _x( 'Listing duration for no-fee sites (in days)', 'settings', 'WPBDM' ),
292
+ 'desc' => _x( 'Use a value of "0" to keep a listing alive indefinitely or enter a number less than 10 years (3650 days).', 'settings', 'WPBDM' ),
293
+ 'default' => '365',
294
+ 'min' => 0, 'step' => 1, 'max' => 3650,
295
+ 'group' => 'listings/main'
296
+ ) );
297
+ wpbdp_register_setting( array(
298
+ 'id' => 'listing-renewal',
299
+ 'type' => 'checkbox',
300
+ 'name' => _x( 'Turn on listing renewal option?', 'settings', 'WPBDM' ),
301
+ 'default' => true,
302
+ 'group' => 'listings/main'
303
+ ) );
304
+ wpbdp_register_setting( array(
305
+ 'id' => 'listing-link-in-new-tab',
306
+ 'type' => 'checkbox',
307
+ 'name' => _x( 'Open detailed view of listing in new tab?', 'settings', 'WPBDM' ),
308
+ 'default' => false,
309
+ 'group' => 'listings/main'
310
+ ) );
311
+
312
+
313
+ wpbdp_register_settings_group( 'listings/contact', _x( 'Contact Form', 'settings', 'WPBDM' ), 'listings/main' );
314
+ wpbdp_register_setting( array(
315
+ 'id' => 'show-contact-form',
316
+ 'type' => 'checkbox',
317
+ 'name' => _x( 'Include listing contact form on listing pages?', 'settings', 'WPBDM' ),
318
+ 'desc' => _x( 'Allows visitors to contact listing authors privately. Authors will receive the messages via email.', 'settings', 'WPBDM' ),
319
+ 'default' => true,
320
+ 'group' => 'listings/contact'
321
+ ) );
322
+ wpbdp_register_setting( array(
323
+ 'id' => 'contact-form-require-login',
324
+ 'type' => 'checkbox',
325
+ 'name' => _x( 'Require login for using the contact form?', 'settings', 'WPBDM' ),
326
+ 'default' => false,
327
+ 'group' => 'listings/contact',
328
+ 'requirements' => array( 'show-contact-form' )
329
+ ) );
330
+ wpbdp_register_setting( array(
331
+ 'id' => 'contact-form-daily-limit',
332
+ 'type' => 'number',
333
+ 'name' => _x( 'Maximum number of contact form submits per day', 'settings', 'WPBDM' ),
334
+ 'desc' => _x( 'Use this to prevent spamming of listing owners. 0 means unlimited submits per day.', 'settings', 'WPBDM' ),
335
+ 'default' => '0',
336
+ 'group' => 'listings/contact',
337
+ 'requirements' => array( 'show-contact-form' )
338
+ ) );
339
+ wpbdp_register_setting( array(
340
+ 'id' => 'allow-comments-in-listings',
341
+ 'type' => 'radio',
342
+ 'name' => _x( 'Include comment form on listing pages?', 'settings', 'WPBDM' ),
343
+ 'desc' => _x( 'BD uses the standard comment inclusion from WordPress, but most themes only allow for comments on posts, not pages. Some themes handle both. BD is displayed on a page, so we need a theme that can handle both to show comments. Use the 2nd option if you want to allow comments on listings first, and if that doesn\'t work, try the 3rd option instead.', 'settings', 'WPBDM' ),
344
+ 'default' => get_option( 'wpbdp-show-comment-form', false) ? 'allow-comments-and-insert-template' : 'do-not-allow-comments',
345
+ 'options' => array(
346
+ 'do-not-allow-comments' => _x( 'Do not include comments in listings', 'admin settings', 'WPBDM' ),
347
+ 'allow-comments' => _x( 'Include comment form, theme invoked (standard option)', 'admin settings', 'WPBDM' ),
348
+ 'allow-comments-and-insert-template' => _x( "Include comment form, BD invoked (use only if 2nd option doesn't work)", 'admin settings', 'WPBDM' )
349
+ ),
350
+ 'group' => 'listings/main'
351
+ ) );
352
+ wpbdp_register_setting( array(
353
+ 'id' => 'show-listings-under-categories',
354
+ 'type' => 'checkbox',
355
+ 'name' => _x( 'Show listings under categories on main page?', 'settings', 'WPBDM' ),
356
+ 'default' => false,
357
+ 'group' => 'listings/main'
358
+ ) );
359
+ wpbdp_register_setting( array(
360
+ 'id' => 'status-on-uninstall',
361
+ 'type' => 'radio',
362
+ 'name' => _x( 'Status of listings upon uninstalling plugin', 'settings', 'WPBDM' ),
363
+ 'default' => 'trash',
364
+ 'options' => array(
365
+ 'draft' => _x( 'Draft', 'post status' ),
366
+ 'trash' => _x( 'Trash', 'post status' )
367
+ ),
368
+ 'group' => 'listings/main'
369
+ ) );
370
+ wpbdp_register_setting( array(
371
+ 'id' => 'deleted-status',
372
+ 'type' => 'radio',
373
+ 'name' => _x( 'Status of deleted listings', 'settings', 'WPBDM' ),
374
+ 'default' => 'trash',
375
+ 'options' => array(
376
+ 'draft' => _x( 'Draft', 'post status' ),
377
+ 'trash' => _x( 'Trash', 'post status' )
378
+ ),
379
+ 'group' => 'listings/main'
380
+ ) );
381
+ wpbdp_register_setting( array(
382
+ 'id' => 'submit-instructions',
383
+ 'type' => 'textarea',
384
+ 'name' => _x( 'Submit Listing instructions message', 'settings', 'WPBDM' ),
385
+ 'desc' => _x( 'This text is displayed at the first page of the Submit Listing process for Business Directory. You can use it for instructions about filling out the form or anything you want to tell users before they get started.', 'settings', 'WPBDM' ),
386
+ 'default' => '',
387
+ 'group' => 'listings/main'
388
+ ) );
389
+
390
+ wpbdp_register_settings_group( 'listings/post_category', _x( 'Post/Category Settings', 'settings', 'WPBDM' ), 'listings/main' );
391
+ wpbdp_register_setting( array(
392
+ 'id' => 'new-post-status',
393
+ 'type' => 'radio',
394
+ 'name' => _x( 'Default new post status', 'settings', 'WPBDM' ),
395
+ 'default' => 'pending',
396
+ 'options' => array(
397
+ 'publish' => _x( 'Published', 'post status' ),
398
+ 'pending' => _x( 'Pending', 'post status' )
399
+ ),
400
+ 'group' => 'listings/post_category'
401
+ ) );
402
+ wpbdp_register_setting( array(
403
+ 'id' => 'edit-post-status',
404
+ 'type' => 'radio',
405
+ 'name' => _x( 'Edit post status', 'settings', 'WPBDM' ),
406
+ 'default' => 'publish',
407
+ 'options' => array(
408
+ 'publish' => _x( 'Published', 'post status' ),
409
+ 'pending' => _x( 'Pending', 'post status' )
410
+ ),
411
+ 'group' => 'listings/post_category'
412
+ ) );
413
+ wpbdp_register_setting( array(
414
+ 'id' => 'categories-order-by',
415
+ 'type' => 'radio',
416
+ 'name' => _x( 'Order categories list by', 'settings', 'WPBDM' ),
417
+ 'default' => 'name',
418
+ 'options' => array(
419
+ 'name' => _x( 'Name', 'admin settings', 'WPBDM' ),
420
+ 'slug' => _x( 'Slug', 'admin settings', 'WPBDM' ),
421
+ 'count' => _x( 'Listing Count', 'admin settings', 'WPBDM' )
422
+ ),
423
+ 'group' => 'listings/post_category'
424
+ ) );
425
+ wpbdp_register_setting( array(
426
+ 'id' => 'categories-sort',
427
+ 'type' => 'radio',
428
+ 'name' => _x( 'Sort order for categories', 'settings', 'WPBDM' ),
429
+ 'default' => 'ASC',
430
+ 'options' => array(
431
+ 'ASC' => _x('Ascending', 'admin settings', 'WPBDM'),
432
+ 'DESC' => _x('Descending', 'admin settings', 'WPBDM')
433
+ ),
434
+ 'group' => 'listings/post_category'
435
+ ) );
436
+ wpbdp_register_setting( array(
437
+ 'id' => 'show-category-post-count',
438
+ 'type' => 'checkbox',
439
+ 'name' => _x( 'Show category post count?', 'settings', 'WPBDM' ),
440
+ 'default' => true,
441
+ 'group' => 'listings/post_category'
442
+ ) );
443
+ wpbdp_register_setting( array(
444
+ 'id' => 'hide-empty-categories',
445
+ 'type' => 'checkbox',
446
+ 'name' => _x( 'Hide empty categories?', 'settings', 'WPBDM' ),
447
+ 'default' => false,
448
+ 'group' => 'listings/post_category'
449
+ ) );
450
+ wpbdp_register_setting( array(
451
+ 'id' => 'show-only-parent-categories',
452
+ 'type' => 'checkbox',
453
+ 'name' => _x( 'Show only parent categories in category list?', 'settings', 'WPBDM' ),
454
+ 'default' => false,
455
+ 'group' => 'listings/post_category'
456
+ ) );
457
+
458
+ wpbdp_register_settings_group( 'listings/sorting', _x( 'Listings Sorting', 'settings', 'WPBDM' ), 'listings/main' );
459
+ wpbdp_register_setting( array(
460
+ 'id' => 'listings-order-by',
461
+ 'type' => 'select',
462
+ 'name' => _x( 'Order directory listings by', 'settings', 'WPBDM' ),
463
+ 'default' => 'title',
464
+ 'options' => array(
465
+ 'title' => _x( 'Title', 'admin settings', 'WPBDM' ),
466
+ 'author' => _x( 'Author', 'admin settings', 'WPBDM' ),
467
+ 'date' => _x( 'Date posted', 'admin settings', 'WPBDM' ),
468
+ 'modified' => _x( 'Date last modified', 'admin settings', 'WPBDM' ),
469
+ 'rand' => _x( 'Random', 'admin settings', 'WPBDM' ),
470
+ 'paid' => _x( 'Paid first then free. Inside each group by date.', 'admin settings', 'WPBDM' ),
471
+ 'paid-title' => _x( 'Paid first then free. Inside each group by title.', 'admin settings', 'WPBDM' )
472
+ ),
473
+ 'group' => 'listings/sorting'
474
+ ) );
475
+ wpbdp_register_setting( array(
476
+ 'id' => 'listings-sort',
477
+ 'type' => 'radio',
478
+ 'name' => _x( 'Sort directory listings by', 'settings', 'WPBDM' ),
479
+ 'desc' => _x( 'Ascending for ascending order A-Z, Descending for descending order Z-A', 'settings', 'WPBDM' ),
480
+ 'default' => 'ASC',
481
+ 'options' => array(
482
+ 'ASC' => _x('Ascending', 'admin settings', 'WPBDM'),
483
+ 'DESC' => _x('Descending', 'admin settings', 'WPBDM')
484
+ ),
485
+ 'group' => 'listings/sorting'
486
+ ) );
487
+ wpbdp_register_setting( array(
488
+ 'id' => 'listings-sortbar-enabled',
489
+ 'type' => 'checkbox',
490
+ 'name' => _x( 'Enable sort bar?', 'settings', 'WPBDM' ),
491
+ 'default' => false,
492
+ 'group' => 'listings/sorting'
493
+ ) );
494
+ wpbdp_register_setting( array(
495
+ 'id' => 'listings-sortbar-fields',
496
+ 'type' => 'multicheck',
497
+ 'name' => _x( 'Sortbar Fields', 'settings', 'WPBDM' ),
498
+ 'default' => array(),
499
+ 'options' => wpbdp_sortbar_get_field_options(),
500
+ 'group' => 'listings/sorting',
501
+ 'requirements' => array( 'listings-sortbar-enabled' )
502
+ ) );
503
+ }
504
+
505
+ private static function settings_appearance() {
506
+ // Display Options.
507
+ wpbdp_register_settings_group( 'display_options', _x( 'Directory Display Options', 'settings', 'WPBDM' ), 'appearance/main' );
508
+ wpbdp_register_setting( array(
509
+ 'id' => 'show-submit-listing',
510
+ 'type' => 'checkbox',
511
+ 'name' => _x( 'Show the "Submit listing" button.', 'settings', 'WPBDM' ),
512
+ 'default' => true,
513
+ 'group' => 'display_options',
514
+ 'requirements' => array( '!disable-submit-listing' )
515
+ ) );
516
+ wpbdp_register_setting( array(
517
+ 'id' => 'show-search-listings',
518
+ 'type' => 'checkbox',
519
+ 'name' => _x( 'Show "Search listings".', 'settings', 'WPBDM' ),
520
+ 'default' => true,
521
+ 'group' => 'display_options'
522
+ ) );
523
+ wpbdp_register_setting( array(
524
+ 'id' => 'show-view-listings',
525
+ 'type' => 'checkbox',
526
+ 'name' => _x( 'Show the "View Listings" button.', 'settings', 'WPBDM' ),
527
+ 'default' => true,
528
+ 'group' => 'display_options'
529
+ ) );
530
+ wpbdp_register_setting( array(
531
+ 'id' => 'show-directory-button',
532
+ 'type' => 'checkbox',
533
+ 'name' => _x( 'Show the "Directory" button.', 'settings', 'WPBDM' ),
534
+ 'default' => true,
535
+ 'group' => 'display_options'
536
+ ) );
537
+
538
+ // Themes.
539
+ wpbdp_register_settings_group( 'themes', _x( 'Theme Settings', 'settings', 'WPBDM' ), 'appearance', array( 'desc' => str_replace( '<a>', '<a href="' . admin_url( 'admin.php?page=wpbdp-themes' ) . '">', _x( 'You can manage your themes on <a>Directory Themes</a>.', 'admin settings', 'WPBDM' ) ) ) );
540
+
541
+ wpbdp_register_setting( array(
542
+ 'id' => 'themes-button-style',
543
+ 'type' => 'radio',
544
+ 'name' => _x( 'Theme button style', 'settings', 'WPBDM' ),
545
+ 'default' => 'theme',
546
+ 'options' => array(
547
+ 'theme' => _x( 'Use the BD theme style for BD buttons', 'admin settings', 'WPBDM' ),
548
+ 'none' =>_x( 'Use the WP theme style for BD buttons', 'admin settings', 'WPBDM' )
549
+ ),
550
+ 'group' => 'themes'
551
+ ) );
552
+ wpbdp_register_setting( array(
553
+ 'id' => 'include-button-styles',
554
+ 'type' => 'checkbox',
555
+ 'name' => _x( 'Include CSS rules to give their own style to View, Edit and Delete buttons?', 'settings', 'WPBDM' ),
556
+ 'default' => 1,
557
+ 'group' => 'themes'
558
+ ) );
559
+
560
+ // Image.
561
+ wpbdp_register_settings_group( 'appearance/image', _x( 'Image', 'settings', 'WPBDM' ), 'appearance' );
562
+ wpbdp_register_settings_group( 'images/general', _x( 'Image Settings', 'settings', 'WPBDM' ), 'appearance/image', array( 'desc' => 'Any changes to these settings will affect new listings only. Existing listings will not be affected. If you wish to change existing listings, you will need to re-upload the image(s) on that listing after changing things here.' ) );
563
+ wpbdp_register_setting( array(
564
+ 'id' => 'allow-images',
565
+ 'type' => 'checkbox',
566
+ 'name' => _x( 'Allow images?', 'settings', 'WPBDM' ),
567
+ 'default' => true,
568
+ 'group' => 'images/general'
569
+ ) );
570
+ wpbdp_register_setting( array(
571
+ 'id' => 'image-min-filesize',
572
+ 'type' => 'number',
573
+ 'min' => 0, 'step' => 1,
574
+ 'name' => _x( 'Min Image File Size (KB)', 'settings', 'WPBDM' ),
575
+ 'default' => '0',
576
+ 'group' => 'images/general'
577
+ ) );
578
+ wpbdp_register_setting( array(
579
+ 'id' => 'image-max-filesize',
580
+ 'type' => 'number',
581
+ 'min' => 0, 'step' => 1,
582
+ 'name' => _x( 'Max Image File Size (KB)', 'settings', 'WPBDM' ),
583
+ 'default' => '10000',
584
+ 'group' => 'images/general'
585
+ ) );
586
+ wpbdp_register_setting( array(
587
+ 'id' => 'image-min-width',
588
+ 'type' => 'number',
589
+ 'min' => 0, 'step' => 1,
590
+ 'name' => _x( 'Min image width (px)', 'settings', 'WPBDM' ),
591
+ 'default' => '0',
592
+ 'group' => 'images/general'
593
+ ) );
594
+ wpbdp_register_setting( array(
595
+ 'id' => 'image-min-height',
596
+ 'type' => 'number',
597
+ 'name' => _x( 'Min image height (px)', 'settings', 'WPBDM' ),
598
+ 'default' => '0',
599
+ 'min' => 0, 'step' => 1,
600
+ 'group' => 'images/general'
601
+ ) );
602
+ wpbdp_register_setting( array(
603
+ 'id' => 'image-max-width',
604
+ 'type' => 'number',
605
+ 'min' => 0, 'step' => 1,
606
+ 'name' => _x( 'Max image width (px)', 'settings', 'WPBDM' ),
607
+ 'default' => '500',
608
+ 'group' => 'images/general'
609
+ ) );
610
+ wpbdp_register_setting( array(
611
+ 'id' => 'image-max-height',
612
+ 'type' => 'number',
613
+ 'min' => 0, 'step' => 1,
614
+ 'name' => _x( 'Max image height (px)', 'settings', 'WPBDM' ),
615
+ 'default' => '500',
616
+ 'group' => 'images/general'
617
+ ) );
618
+ wpbdp_register_setting( array(
619
+ 'id' => 'use-thickbox',
620
+ 'type' => 'checkbox',
621
+ 'min' => 0, 'step' => 1,
622
+ 'name' => _x( 'Turn on thickbox/lightbox?', 'settings', 'WPBDM' ),
623
+ 'desc' => _x( 'Uncheck if it conflicts with other elements or plugins installed on your site', 'settings', 'WPBDM' ),
624
+ 'default' => false,
625
+ 'group' => 'images/general'
626
+ ) );
627
+
628
+ wpbdp_register_settings_group( 'image/thumbnails', _x( 'Thumbnails', 'settings', 'WPBDM' ), 'appearance/image' );
629
+ wpbdp_register_setting( array(
630
+ 'id' => 'thumbnail-width',
631
+ 'type' => 'number',
632
+ 'min' => 0, 'step' => 1,
633
+ 'name' => _x( 'Thumbnail width (px)', 'settings', 'WPBDM' ),
634
+ 'default' => '150',
635
+ 'group' => 'image/thumbnails'
636
+ ) );
637
+ wpbdp_register_setting( array(
638
+ 'id' => 'thumbnail-height',
639
+ 'type' => 'number',
640
+ 'min' => 0, 'step' => 1,
641
+ 'name' => _x( 'Thumbnail height (px)', 'settings', 'WPBDM' ),
642
+ 'default' => '150',
643
+ 'group' => 'image/thumbnails'
644
+ ) );
645
+ wpbdp_register_setting( array(
646
+ 'id' => 'thumbnail-crop',
647
+ 'type' => 'checkbox',
648
+ 'name' => _x( 'Crop thumbnails to exact dimensions?', 'settings', 'WPBDM' ),
649
+ 'desc' => _x( 'When enabled images will match exactly the dimensions above but part of the image may be cropped out. If disabled, image thumbnails will be resized to match the specified width and their height will be adjusted proportionally. Depending on the uploaded images, thumbnails may have different heights.', 'settings', 'WPBDM' ),
650
+ 'default' => false,
651
+ 'group' => 'image/thumbnails'
652
+ ) );
653
+
654
+ wpbdp_register_settings_group( 'image/listings', _x( 'Listings', 'settings', 'WPBDM' ), 'appearance/image' );
655
+ wpbdp_register_setting( array(
656
+ 'id' => 'free-images',
657
+ 'type' => 'number',
658
+ 'name' => _x( 'Number of free images', 'settings', 'WPBDM' ),
659
+ 'default' => '2',
660
+ 'min' => 0, 'step' => 1,
661
+ 'desc' => str_replace( '<a>', '<a href="' . admin_url( 'admin.php?page=wpbdp-admin-fees' ) . '">', _x( 'For paid listing images, configure that by adding or editing a <a>Fee Plan</a> instead of this setting, which is ignored for paid listings.', 'admin settings', 'WPBDM' ) ),
662
+ 'group' => 'image/listings'
663
+ ) );
664
+ wpbdp_register_setting( array(
665
+ 'id' => 'use-default-picture',
666
+ 'type' => 'checkbox',
667
+ 'name' => _x( 'Use default picture for listings with no picture?', 'settings', 'WPBDM' ),
668
+ 'default' => true,
669
+ 'group' => 'image/listings'
670
+ ) );
671
+ wpbdp_register_setting( array(
672
+ 'id' => 'show-thumbnail',
673
+ 'type' => 'checkbox',
674
+ 'name' => _x( 'Show Thumbnail on main listings page?', 'settings', 'WPBDM' ),
675
+ 'default' => true,
676
+ 'group' => 'image/listings'
677
+ ) );
678
+ }
679
+
680
+ private static function settings_payment() {
681
+ wpbdp_register_setting( array(
682
+ 'id' => 'fee-order',
683
+ 'type' => 'silent',
684
+ 'name' => _x( 'Fee Order', 'settings', 'WPBDM' ),
685
+ 'default' => array( 'method' => 'label', 'order' => 'asc' ),
686
+ 'group' => 'payment/main'
687
+ ) );
688
+
689
+ wpbdp_register_setting( array(
690
+ 'id' => 'payments-on',
691
+ 'type' => 'checkbox',
692
+ 'name' => _x( 'Turn On payments?', 'settings', 'WPBDM' ),
693
+ 'default' => false,
694
+ 'group' => 'payment/main'
695
+ ) );
696
+ wpbdp_register_setting( array(
697
+ 'id' => 'payments-test-mode',
698
+ 'type' => 'checkbox',
699
+ 'name' => _x( 'Put payment gateways in test mode?', 'settings', 'WPBDM' ),
700
+ 'default' => true,
701
+ 'group' => 'payment/main',
702
+ 'requirements' => array( 'payments-on' )
703
+ ) );
704
+ wpbdp_register_setting( array(
705
+ 'id' => 'payments-use-https',
706
+ 'type' => 'checkbox',
707
+ 'name' => _x( 'Perform checkouts on the secure (HTTPS) version of your site?', 'settings', 'WPBDM' ),
708
+ 'desc' => _x( 'Recommended for added security. For this to work you need to enable HTTPS on your server and obtain an SSL certificate.', 'settings', 'WPBDM' ),
709
+ 'default' => false,
710
+ 'group' => 'payment/main',
711
+ 'requirements' => array( 'payments-on' )
712
+ ) );
713
+ wpbdp_register_setting( array(
714
+ 'id' => 'currency',
715
+ 'type' => 'select',
716
+ 'name' => _x( 'Currency Code', 'settings', 'WPBDM' ),
717
+ 'default' => 'USD',
718
+ 'options' => array(
719
+ 'AUD' => _x('Australian Dollar (AUD)', 'admin settings', 'WPBDM'),
720
+ 'BRL' => _x('Brazilian Real (BRL)', 'admin settings', 'WPBDM'),
721
+ 'CAD' => _x('Canadian Dollar (CAD)', 'admin settings', 'WPBDM'),
722
+ 'CZK' => _x('Czech Koruna (CZK)', 'admin settings', 'WPBDM'),
723
+ 'DKK' => _x('Danish Krone (DKK)', 'admin settings', 'WPBDM'),
724
+ 'EUR' => _x('Euro (EUR)', 'admin settings', 'WPBDM'),
725
+ 'HKD' => _x('Hong Kong Dollar (HKD)', 'admin settings', 'WPBDM'),
726
+ 'HUF' => _x('Hungarian Forint (HUF)', 'admin settings', 'WPBDM'),
727
+ 'ILS' => _x('Israeli New Shequel (ILS)', 'admin settings', 'WPBDM'),
728
+ 'JPY' => _x('Japanese Yen (JPY)', 'admin settings', 'WPBDM'),
729
+ 'MAD' => _x('Moroccan Dirham (MAD)', 'admin settings', 'WPBDM'),
730
+ 'MYR' => _x('Malasian Ringgit (MYR)', 'admin settings', 'WPBDM'),
731
+ 'MXN' => _x('Mexican Peso (MXN)', 'admin settings', 'WPBDM'),
732
+ 'NOK' => _x('Norwegian Krone (NOK)', 'admin settings', 'WPBDM'),
733
+ 'NZD' => _x('New Zealand Dollar (NZD)', 'admin settings', 'WPBDM'),
734
+ 'PHP' => _x('Philippine Peso (PHP)', 'admin settings', 'WPBDM'),
735
+ 'PLN' => _x('Polish Zloty (PLN)', 'admin settings', 'WPBDM'),
736
+ 'GBP' => _x('Pound Sterling (GBP)', 'admin settings', 'WPBDM'),
737
+ 'SGD' => _x('Singapore Dollar (SGD)', 'admin settings', 'WPBDM'),
738
+ 'SEK' => _x('Swedish Krona (SEK)', 'admin settings', 'WPBDM'),
739
+ 'CHF' => _x('Swiss Franc (CHF)', 'admin settings', 'WPBDM'),
740
+ 'TWD' => _x('Taiwan Dollar (TWD)', 'admin settings', 'WPBDM'),
741
+ 'THB' => _x('Thai Baht (THB)', 'admin settings', 'WPBDM'),
742
+ 'TRY' => _x('Turkish Lira (TRY)', 'admin settings', 'WPBDM'),
743
+ 'USD' => _x('U.S. Dollar (USD)', 'admin settings', 'WPBDM')
744
+ ),
745
+ 'group' => 'payment/main',
746
+ 'requirements' => array( 'payments-on' )
747
+ ) );
748
+ wpbdp_register_setting( array(
749
+ 'id' => 'currency-symbol',
750
+ 'type' => 'text',
751
+ 'name' => _x( 'Currency Symbol', 'settings', 'WPBDM' ),
752
+ 'default' => '$',
753
+ 'group' => 'payment/main',
754
+ 'requirements' => array( 'payments-on' )
755
+ ) );
756
+ wpbdp_register_setting( array(
757
+ 'id' => 'currency-symbol-position',
758
+ 'type' => 'radio',
759
+ 'name' => _x( 'Currency symbol display', 'settings', 'WPBDM' ),
760
+ 'default' => 'left',
761
+ 'options' => array(
762
+ 'left' => _x( 'Show currency symbol on the left', 'admin settings', 'WPBDM' ),
763
+ 'right' =>_x( 'Show currency symbol on the right', 'admin settings', 'WPBDM'),
764
+ 'none' => _x( 'Do not show currency symbol', 'admin settings', 'WPBDM' )
765
+ ),
766
+ 'group' => 'payment/main',
767
+ 'requirements' => array( 'payments-on' )
768
+ ) );
769
+ wpbdp_register_setting( array(
770
+ 'id' => 'payment-message',
771
+ 'type' => 'textarea',
772
+ 'name' => _x( 'Thank you for payment message', 'settings', 'WPBDM' ),
773
+ 'default' => _x( 'Thank you for your payment. Your payment is being verified and your listing reviewed. The verification and review process could take up to 48 hours.', 'admin settings', 'WPBDM' ),
774
+ 'group' => 'payment/main',
775
+ 'requirements' => array( 'payments-on' )
776
+ ) );
777
+ wpbdp_register_setting( array(
778
+ 'id' => 'payment-abandonment',
779
+ 'type' => 'checkbox',
780
+ 'name' => _x( 'Ask users to come back for abandoned payments?', 'settings', 'WPBDM' ),
781
+ 'desc' => _x( 'An abandoned payment is when a user attempts to place a listing and gets to the end, but fails to complete their payment for the listing. This results in listings that look like they failed, when the user simply didn\'t complete the transaction. BD can remind them to come back and continue.', 'settings', 'WPBDM' ),
782
+ 'default' => false,
783
+ 'group' => 'payment/main',
784
+ 'requirements' => array( 'payments-on' )
785
+ ) );
786
+ wpbdp_register_setting( array(
787
+ 'id' => 'payment-abandonment-threshold',
788
+ 'type' => 'number',
789
+ 'name' => _x( 'Listing abandonment threshold (hours)', 'settings', 'WPBDM' ),
790
+ 'desc' => str_replace( '<a>', '<a href="' . admin_url( 'admin.php?page=wpbdp_settings&tab=email' ) . '#email-templates-payment-abandoned">', _x( 'Listings with pending payments are marked as abandoned after this time. You can also <a>customize the e-mail</a> users receive.', 'admin settings', 'WPBDM' ) ),
791
+ 'default' => '24',
792
+ 'min' => 0, 'step' => 1,
793
+ 'group' => 'payment/main',
794
+ 'requirements' => array( 'payment-abandonment' )
795
+ ) );
796
+ }
797
+
798
+ private static function settings_email() {
799
+ wpbdp_register_settings_group( 'email/main/general', _x( 'General Settings', 'settings', 'WPBDM' ), 'email/main' );
800
+ wpbdp_register_setting( array(
801
+ 'id' => 'override-email-blocking',
802
+ 'type' => 'checkbox',
803
+ 'name' => _x( 'Display email address fields publicly?', 'settings', 'WPBDM' ),
804
+ 'desc' => _x( 'Shows the email address of the listing owner to all web users. NOT RECOMMENDED as this increases spam to the address and allows spam bots to harvest it for future use.', 'settings', 'WPBDM' ),
805
+ 'default' => false,
806
+ 'group' => 'email/main/general'
807
+ ) );
808
+ wpbdp_register_setting( array(
809
+ 'id' => 'listing-email-mode',
810
+ 'type' => 'radio',
811
+ 'name' => _x( 'How to determine the listing\'s email address?', 'settings', 'WPBDM' ),
812
+ 'desc' => _x( 'This affects emails sent to listing owners via contact forms or when their listings expire.', 'settings', 'WPBDM' ),
813
+ 'default' => 'field',
814
+ 'options' => array(
815
+ 'field' => _x( 'Try listing\'s email field first, then author\'s email.', 'admin settings', 'WPBDM' ),
816
+ 'user' => _x( 'Try author\'s email first and then listing\'s email field.', 'admin settings', 'WPBDM' )
817
+ ),
818
+ 'group' => 'email/main/general'
819
+ ) );
820
+
821
+ wpbdp_register_settings_group( 'email_notifications', _x( 'E-Mail Notifications', 'settings', 'WPBDM' ), 'email/main' );
822
+ wpbdp_register_setting( array(
823
+ 'id' => 'admin-notifications',
824
+ 'type' => 'multicheck',
825
+ 'name' => _x( 'Notify admin via e-mail when...', 'settings', 'WPBDM' ),
826
+ 'default' => array(),
827
+ 'options' => array(
828
+ 'new-listing' => _x( 'A new listing is submitted.', 'admin settings', 'WPBDM' ),
829
+ 'listing-edit' => _x( 'A listing is edited.', 'admin settings', 'WPBDM' ),
830
+ 'renewal' => _x( 'A listing expires.', 'admin settings', 'WPBDM' ),
831
+ 'listing-contact' => _x( 'A contact message is sent to a listing\'s owner.', 'admin settings', 'WPBDM' )
832
+ ),
833
+ 'group' => 'email_notifications'
834
+ ) );
835
+ wpbdp_register_setting( array(
836
+ 'id' => 'admin-notifications-cc',
837
+ 'type' => 'text',
838
+ 'name' => _x( 'CC this e-mail address too', 'settings', 'WPBDM' ),
839
+ 'group' => 'email_notifications'
840
+ ) );
841
+ wpbdp_register_setting( array(
842
+ 'id' => 'user-notifications',
843
+ 'type' => 'multicheck',
844
+ 'name' => _x( 'Notify users via e-mail when...', 'settings', 'WPBDM' ),
845
+ 'desc' => _x( 'You can modify the text template used for most of these e-mails below.', 'settings', 'WPBDM' ),
846
+ 'default' => array( 'new-listing', 'listing-published' ),
847
+ 'options' => array(
848
+ 'new-listing' => _x( 'Their listing is submitted.', 'admin settings', 'WPBDM' ),
849
+ 'listing-published' => _x( 'Their listing is approved/published.', 'admin settings', 'WPBDM' )
850
+ ),
851
+ 'group' => 'email_notifications'
852
+ ) );
853
+
854
+ wpbdp_register_settings_group( 'email_templates', _x( 'Templates', 'settings', 'WPBDM' ), 'email' );
855
+ wpbdp_register_setting( array(
856
+ 'id' => 'email-confirmation-message',
857
+ 'type' => 'email_template',
858
+ 'name' => _x( 'Email confirmation message', 'settings', 'WPBDM' ),
859
+ 'desc' => _x( 'Sent after a listing has been submitted.', 'settings', 'WPBDM' ),
860
+ 'default' => array(
861
+ 'subject' => '[[site-title]] Listing "[listing]" received',
862
+ 'body' => 'Your submission \'[listing]\' has been received and it\'s pending review. This review process could take up to 48 hours.'
863
+ ),
864
+ 'placeholders' => array(
865
+ 'listing' => array( _x( 'Listing\'s title', 'admin settings', 'WPBDM' ) )
866
+ ),
867
+ 'group' => 'email_templates'
868
+ ) );
869
+ wpbdp_register_setting( array(
870
+ 'id' => 'email-templates-listing-published',
871
+ 'type' => 'email_template',
872
+ 'name' => _x( 'Listing published message', 'settings', 'WPBDM' ),
873
+ 'desc' => _x( 'Sent when the listing has been published or approved by an admin.', 'settings', 'WPBDM' ),
874
+ 'default' => array(
875
+ 'subject' => '[[site-title]] Listing "[listing]" published',
876
+ 'body' => _x( 'Your listing "[listing]" is now available at [listing-url] and can be viewed by the public.', 'admin settings', 'WPBDM' )
877
+ ),
878
+ 'placeholders' => array(
879
+ 'listing' => _x( 'Listing\'s title', 'admin settings', 'WPBDM' ),
880
+ 'listing-url' => _x( 'Listing\'s URL', 'admin settings', 'WPBDM' )
881
+ ),
882
+ 'group' => 'email_templates'
883
+ ) );
884
+ wpbdp_register_setting( array(
885
+ 'id' => 'email-templates-contact',
886
+ 'type' => 'email_template',
887
+ 'name' => _x( 'Listing Contact Message', 'settings', 'WPBDM' ),
888
+ 'desc' => _x( 'Sent to listing owners when someone uses the contact form on their listing pages.', 'settings', 'WPBDM' ),
889
+ 'default' => array(
890
+ 'subject' => '[[site-title]] Contact via "[listing]"',
891
+ 'body' => '' .
892
+ sprintf( _x( 'You have received a reply from your listing at %s.', 'contact email', 'WPBDM' ), '[listing-url]' ) . "\n\n" .
893
+ sprintf( _x( 'Name: %s', 'contact email', 'WPBDM' ), '[name]' ) . "\n" .
894
+ sprintf( _x( 'E-Mail: %s', 'contact email', 'WPBDM' ), '[email]' ) . "\n" .
895
+ _x( 'Message:', 'contact email', 'WPBDM' ) . "\n" .
896
+ '[message]' . "\n\n" .
897
+ sprintf( _x( 'Time: %s', 'contact email', 'WPBDM' ), '[date]' )
898
+ ),
899
+ 'placeholders' => array(
900
+ 'listing-url' => 'Listing\'s URL',
901
+ 'listing' => 'Listing\'s title',
902
+ 'name' => 'Sender\'s name',
903
+ 'email' => 'Sender\'s e-mail address',
904
+ 'message' => 'Contact message',
905
+ 'date' => 'Date and time the message was sent'
906
+ ),
907
+ 'group' => 'email_templates'
908
+ ) );
909
+
910
+ wpbdp_register_setting( array(
911
+ 'id' => 'email-templates-payment-abandoned',
912
+ 'type' => 'email_template',
913
+ 'name' => _x( 'Payment abandoned reminder message', 'settings', 'WPBDM' ),
914
+ 'desc' => _x( 'Sent some time after a pending payment is abandoned by users.', 'settings', 'WPBDM' ),
915
+ 'default' => array(
916
+ 'subject' => '[[site-title]] Pending payment for "[listing]"',
917
+ 'body' => '
918
+ Hi there,
919
+
920
+ We noticed that you tried submitting a listing on [site-link] but didn\'t finish
921
+ the process. If you want to complete the payment and get your listing
922
+ included, just click here to continue:
923
+
924
+ [link]
925
+
926
+ If you have any issues, please contact us directly by hitting reply to this
927
+ email!
928
+
929
+ Thanks,
930
+ - The Administrator of [site-title]'
931
+ ),
932
+ 'placeholders' => array(
933
+ 'listing' => _x( 'Listing\'s title', 'admin settings', 'WPBDM' ),
934
+ 'link' => _x( 'Checkout URL link', 'admin settings', 'WPBDM' )
935
+ ),
936
+ 'group' => 'email_templates'
937
+ ) );
938
+
939
+ // wpbdp_register_setting( array(
940
+ // 'id' => 'email-renewal-reminders_settings',
941
+ // 'type' => 'section',
942
+ // 'name' => _x( 'Expiration/Renewal Notices', 'settings', 'WPBDM' ),
943
+ // 'desc' => _x( 'You can configure here the text for the expiration/renewal emails and also how long before/after expiration/renewal they are sent.', 'settings', 'WPBDM' ),
944
+ // 'tab' => 'email'
945
+ // ) );
946
+ wpbdp_register_setting( array(
947
+ 'id' => 'expiration-notices',
948
+ 'type' => 'expiration_notices',
949
+ 'name' => _x( 'E-Mail Notices', 'settings', 'WPBDM' ),
950
+ 'default' => self::get_default_expiration_notices(),
951
+ 'group' => 'email_templates',
952
+ 'validator' => array( __class__, 'validate_expiration_notices' )
953
+ ) );
954
+ }
955
+
956
+ public static function get_default_expiration_notices() {
957
+ $notices = array();
958
+
959
+ /* renewal-pending-message, non-recurring only */
960
+ $notices[] = array(
961
+ 'event' => 'expiration',
962
+ 'relative_time' => '+5 days', /* renewal-email-threshold, def: 5 days */
963
+ 'listings' => 'non-recurring',
964
+ 'subject' => '[[site-title]] [listing] - Expiration notice',
965
+ 'body' => 'Your listing "[listing]" is about to expire at [site]. You can renew it here: [link].'
966
+ );
967
+ // array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
968
+ // 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
969
+ // 'expiration' => _x( 'Expiration date', 'settings', 'WPBDM' ),
970
+ // 'category' => _x( 'Category that is going to expire', 'settings', 'WPBDM' ),
971
+ // 'link' => _x( 'Link to renewal page', 'settings', 'WPBDM' ),
972
+ // 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
973
+
974
+ /* listing-renewal-message, non-recurring only */
975
+ $notices[] = array(
976
+ 'event' => 'expiration',
977
+ 'relative_time' => '0 days', /* at time of expiration */
978
+ 'listings' => 'non-recurring',
979
+ 'subject' => '[[site-title]] [listing] - Expiration notice',
980
+ 'body' => "Your listing \"[listing]\" in category [category] expired on [expiration]. To renew your listing click the link below.\n[link]"
981
+ );
982
+ // array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
983
+ // 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
984
+ // 'expiration' => _x( 'Expiration date', 'settings', 'WPBDM' ),
985
+ // 'category' => _x( 'Category that expired', 'settings', 'WPBDM' ),
986
+ // 'link' => _x( 'Link to renewal page', 'settings', 'WPBDM' ),
987
+ // 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
988
+
989
+ /* renewal-reminder-message, both recurring and non-recurring */
990
+ $notices[] = array(
991
+ 'event' => 'expiration',
992
+ 'relative_time' => '-5 days', /* renewal-reminder-threshold */
993
+ 'listings' => 'both',
994
+ 'subject' => '[[site-title]] [listing] - Expiration reminder',
995
+ 'body' => "Dear Customer\nWe've noticed that you haven't renewed your listing \"[listing]\" for category [category] at [site] and just wanted to remind you that it expired on [expiration]. Please remember you can still renew it here: [link]."
996
+ );
997
+ // array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
998
+ // 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
999
+ // 'expiration' => _x( 'Expiration date', 'settings', 'WPBDM' ),
1000
+ // 'category' => _x( 'Category that expired', 'settings', 'WPBDM' ),
1001
+ // 'link' => _x( 'Link to renewal page', 'settings', 'WPBDM' ),
1002
+ // 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
1003
+
1004
+ /* listing-autorenewal-notice, recurring only, controlled by the send-autorenewal-expiration-notice setting */
1005
+ $notices[] = array(
1006
+ 'event' => 'expiration',
1007
+ 'relative_time' => '+5 days' /* renewal-email-threshold, def: 5 days */,
1008
+ 'listings' => 'recurring',
1009
+ 'subject' => '[[site-title]] [listing] - Renewal reminder',
1010
+ 'body' => "Hey [author],\n\nThis is just to remind you that your listing [listing] is going to be renewed on [date] for another period.\nIf you want to review or cancel your subscriptions please visit [link].\n\nIf you have any questions, contact us at [site]."
1011
+ );
1012
+ // array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
1013
+ // 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
1014
+ // 'date' => _x( 'Renewal date', 'settings', 'WPBDM' ),
1015
+ // 'category' => _x( 'Category that is going to be renewed', 'settings', 'WPBDM' ),
1016
+ // 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ),
1017
+ // 'link' => _x( 'Link to manage subscriptions', 'settings', 'WPBDM' ) ) )
1018
+
1019
+ /* listing-autorenewal-message, after IPN notification of renewal of recurring */
1020
+ $notices[] = array(
1021
+ 'event' => 'renewal',
1022
+ 'listings' => 'recurring',
1023
+ 'subject' => '[[site-title]] [listing] renewed',
1024
+ 'body' => "Hey [author],\n\nThanks for your payment. We just renewed your listing [listing] on [date] for another period.\n\nIf you have any questions, contact us at [site]."
1025
+ );
1026
+ // $replacements['listing'] = sprintf( '<a href="%s">%s</a>',
1027
+ // get_permalink( $payment->get_listing_id() ),
1028
+ // get_the_title( $payment->get_listing_id() ) );
1029
+ // $replacements['author'] = get_the_author_meta( 'display_name', get_post( $payment->get_listing_id() )->post_author );
1030
+ // $replacements['category'] = wpbdp_get_term_name( $recurring_item->rel_id_1 );
1031
+ // $replacements['date'] = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ),
1032
+ // strtotime( $payment->get_processed_on() ) );
1033
+ // $replacements['site'] = sprintf( '<a href="%s">%s</a>',
1034
+ // get_bloginfo( 'url' ),
1035
+ // get_bloginfo( 'name' ) );
1036
+ //
1037
+
1038
+
1039
+ return $notices;
1040
+ }
1041
+
1042
+ public static function validate_expiration_notices( $value ) {
1043
+ // We remove notices with no subject and no content.
1044
+ foreach ( array_keys( $value ) as $notice_id ) {
1045
+ $value[ $notice_id ] = array_map( 'trim', $value[ $notice_id ] );
1046
+
1047
+ if ( empty( $value[ $notice_id ]['subject'] ) && empty( $value[ $notice_id ]['content'] ) ) {
1048
+ unset( $value[ $notice_id ] );
1049
+ }
1050
+ }
1051
+
1052
+ // We make sure that there's always one notice applying to the expiration time of non-recurring listings.
1053
+ $found = false;
1054
+ foreach ( $value as $notice_id => $notice ) {
1055
+ if ( 'expiration' == $notice['event'] && ( 'non-recurring' == $notice['listings'] || 'both' == $notice['listings'] ) && '0 days' == $notice['relative_time'] ) {
1056
+ $found = true;
1057
+ break;
1058
+ }
1059
+ }
1060
+
1061
+ if ( ! $found ) {
1062
+ $default_notices = self::get_default_expiration_notices();
1063
+ $value[] = $default_notices[1];
1064
+ }
1065
+
1066
+ return $value;
1067
+ }
1068
+
1069
+ public static function setup_ajax_compat_mode( $setting, $value ) {
1070
+ $mu_dir = ( defined( 'WPMU_PLUGIN_DIR' ) && defined( 'WPMU_PLUGIN_URL' ) ) ? WPMU_PLUGIN_DIR : trailingslashit( WP_CONTENT_DIR ) . 'mu-plugins';
1071
+ $source = WPBDP_INC . '/compatibility/wpbdp-ajax-compat-mu.php';
1072
+ $dest = trailingslashit( $mu_dir ) . basename( $source );
1073
+
1074
+ if ( 0 == $value && file_exists( $dest ) ) {
1075
+ if ( ! unlink( $dest ) ) {
1076
+ $message = array(
1077
+ sprintf( _x( 'Could not remove the "Business Directory Plugin - AJAX Compatibility Module". Please remove the file "%s" manually or deactivate the plugin.',
1078
+ 'admin settings',
1079
+ 'WPBDM' ),
1080
+ $dest ),
1081
+ 'error'
1082
+ );
1083
+ update_option( 'wpbdp-ajax-compat-mode-notice', $message );
1084
+ }
1085
+ } elseif ( 1 == $value && ! file_exists( $dest ) ) {
1086
+ // Install plugin.
1087
+ $success = true;
1088
+
1089
+ if ( ! wp_mkdir_p( $mu_dir ) ) {
1090
+ $message = array( sprintf( _x( 'Could not activate AJAX Compatibility mode: the directory "%s" could not be created.', 'admin settings', 'WPBDM' ), $mu_dir ), 'error' );
1091
+ $success = false;
1092
+ }
1093
+
1094
+ if ( $success && ! copy( $source, $dest ) ) {
1095
+ $message = array( sprintf( _x( 'Could not copy the AJAX compatibility plugin "%s". Compatibility mode was not activated.', 'admin settings', 'WPBDM' ), $dest ), 'error' );
1096
+ $success = false;
1097
+ }
1098
+
1099
+ if ( ! $success ) {
1100
+ update_option( 'wpbdp-ajax-compat-mode-notice', $message );
1101
+ wpbdp_set_option( $setting['id'], 0 );
1102
+ }
1103
+ }
1104
+ }
1105
+
1106
+ }
includes/admin/settings/class-settings.php CHANGED
@@ -1,1044 +1,400 @@
1
  <?php
2
- class WPBDP_Settings {
 
3
 
4
  const PREFIX = 'wpbdp-';
5
 
6
- const _EMAIL_RENEWAL_MESSAGE = "Your listing \"[listing]\" in category [category] expired on [expiration]. To renew your listing click the link below.\n[link]";
7
- const _EMAIL_AUTORENEWAL_MESSAGE = "Hey [author],\n\nThanks for your payment. We just renewed your listing [listing] on [date] for another period.\n\nIf you have any questions, contact us at [site].";
8
- const _EMAIL_AUTORENEWAL_PENDING_MESSAGE = "Hey [author],\n\nThis is just to remind you that your listing [listing] is going to be renewed on [date] for another period.\nIf you want to review or cancel your subscriptions please visit [link].\n\nIf you have any questions, contact us at [site].";
9
- const _EMAIL_PENDING_RENEWAL_MESSAGE = 'Your listing "[listing]" is about to expire at [site]. You can renew it here: [link].';
10
 
11
  private $deps = array();
12
 
13
 
14
  public function __construct() {
15
- $this->groups = array();
16
- $this->settings = array();
 
 
17
 
18
- add_action( 'wp_ajax_wpbdp-admin-settings-email-preview', array( &$this, '_ajax_email_preview' ) );
19
- add_filter( 'wpbdp_settings_render', array( &$this, 'after_render' ), 0, 3 );
20
- }
 
21
 
22
- public function register_settings() {
23
- /* General settings */
24
- $g = $this->add_group('general', _x('General', 'admin settings', 'WPBDM'));
25
-
26
- $s = $this->add_section( $g, 'tracking', _x( 'Data Collection', 'admin settings', 'WPBDM' ) );
27
- $this->add_setting( $s,
28
- 'tracking-on',
29
- _x( 'Allow BD to anonymously collect information about your installed plugins, themes and WP version?', 'admin settings', 'WPBDM' ),
30
- 'boolean',
31
- false,
32
- str_replace( '<a>',
33
- '<a href="http://businessdirectoryplugin.com/what-we-track/" target="_blank">',
34
- _x( '<a>Learn more</a> about what BD does and does NOT track.', 'admin settings', 'WPBDM' ) )
35
- );
36
-
37
- $s = $this->add_section($g, 'permalink', _x('Permalink Settings', 'admin settings', 'WPBDM'));
38
- $this->add_setting($s, 'permalinks-directory-slug', _x('Directory Listings Slug', 'admin settings', 'WPBDM'), 'text', WPBDP_POST_TYPE, null, null, array($this, '_validate_listings_permalink'));
39
- $this->add_setting($s, 'permalinks-category-slug', _x('Categories Slug', 'admin settings', 'WPBDM'), 'text', WPBDP_CATEGORY_TAX, _x('The slug can\'t be in use by another term. Avoid "category", for instance.', 'admin settings', 'WPBDM'), null, array($this, '_validate_term_permalink'));
40
- $this->add_setting($s, 'permalinks-tags-slug', _x('Tags Slug', 'admin settings', 'WPBDM'), 'text', WPBDP_TAGS_TAX, _x('The slug can\'t be in use by another term. Avoid "tag", for instance.', 'admin settings', 'WPBDM'), null, array($this, '_validate_term_permalink'));
41
-
42
- $description_tex = _x( 'Prior to 3.5.1, we included the ID in the listing URL, like "/business-directory/1809/listing-title". Check this setting to remove the ID for better SEO.', 'admin settings', 'WPBDM' );
43
- $warning_text = _x( '<strong>IMPORTANT:</strong> subpages of the main directory page cannot be accesed while this settings is checked.', 'admin settings', 'WPBDM' );
44
-
45
- $this->add_setting( $s,
46
- 'permalinks-no-id',
47
- _x( 'Remove listing ID from directory URLs?', 'admin settings', 'WPBDM' ),
48
- 'boolean',
49
- false,
50
- $description_tex . '<br/><br/>' . $warning_text
51
- );
52
 
53
- $s = $this->add_section( $g,
54
- 'recaptcha',
55
- _x( 'reCAPTCHA Settings', 'admin settings', 'WPBDM' ),
56
- str_replace( '<a>',
57
- '<a href="http://www.google.com/recaptcha" target="_blank">',
58
- _x( 'Need API keys for reCAPTCHA? Get them <a>here</a>.', 'admin settings', 'WPBDM' ) )
59
- );
60
- $this->add_setting($s, 'recaptcha-on', _x('Use reCAPTCHA for contact forms', 'admin settings', 'WPBDM'), 'boolean', false);
61
- $this->add_setting($s, 'hide-recaptcha-loggedin', _x('Turn off reCAPTCHA for logged in users?', 'admin settings', 'WPBDM'), 'boolean', false);
62
- $this->add_setting($s, 'recaptcha-for-submits', _x('Use reCAPTCHA for listing submits', 'admin settings', 'WPBDM'), 'boolean', false);
63
- $this->add_setting( $s,
64
- 'recaptcha-for-comments',
65
- _x( 'Use reCAPTCHA for listing comments?', 'admin settings', 'WPBDM' ),
66
- 'boolean',
67
- false );
68
- $this->add_setting($s, 'recaptcha-public-key', _x('reCAPTCHA Public Key', 'admin settings', 'WPBDM'));
69
- $this->add_setting($s, 'recaptcha-private-key', _x('reCAPTCHA Private Key', 'admin settings', 'WPBDM'));
70
-
71
-
72
- // {{ Registration settings.
73
- // $s = $this->add_group( 'registration',
74
- // _x('Registration', 'admin settings', 'WPBDM' ) );
75
- $msg = _x( "We expect that a membership plugin supports the 'redirect_to' parameter for the URLs below to work. If the plugin does not support them, these settings will not function as expected. Please contact the membership plugin and ask them to support the WP standard 'redirect_to' query parameter.",
76
- 'admin settings',
77
- 'WPBDM' );
78
- $s = $this->add_section( $g, 'registration', _x( 'Registration Settings', 'admin settings', 'WPBDM' ), $msg );
79
- $this->add_setting($s, 'require-login', _x('Require login to post listings?', 'admin settings', 'WPBDM'), 'boolean', true);
80
-
81
- // deprecated as of 2.1, added again for 3.6.10
82
- $this->add_setting( $s,
83
- 'login-url',
84
- _x( 'Login URL', 'admin settings', 'WPBDM'),
85
- 'text',
86
- '',
87
- _x( 'URL of your membership plugin\'s login page. Only enter this if using a membership plugin or custom login page.', 'admin settings', 'WPBDM' ) );
88
-
89
- // deprecated as of 2.1, added again for 3.4
90
- $this->add_setting( $s,
91
- 'registration-url',
92
- _x( 'Registration URL', 'admin settings', 'WPBDM' ),
93
- 'text',
94
- '',
95
- _x( 'URL of your membership plugin\'s registration page. Only enter this if using a membership plugin or custom registration page.', 'admin settings', 'WPBDM' ) );
96
- // }}
97
-
98
- $s = $this->add_section( $g,
99
- 'terms-and-conditions',
100
- _x( 'Terms and Conditions', 'admin settings', 'WPBDM' ) );
101
- $this->add_setting( $s,
102
- 'display-terms-and-conditions',
103
- _x( 'Display and require user agreement to Terms and Conditions', 'admin settings', 'WPBDM' ),
104
- 'boolean',
105
- false
106
- );
107
- $this->add_setting( $s,
108
- 'terms-and-conditions',
109
- _x( 'Terms and Conditions', 'admin settings', 'WPBDM' ),
110
- 'text',
111
- _x( "Terms and Conditions text goes here...", 'admin settings', 'WPBDM' ) . "\n\n",
112
- _x( 'Enter text or a URL starting with http. If you use a URL, the Terms and Conditions text will be replaced by a link to the appropiate page.', 'admin settings', 'WPBDM' ),
113
- array( 'use_textarea' => true )
114
- );
115
-
116
- $s = $this->add_section($g, 'displayoptions', _x('Directory Display Options', 'admin settings', 'WPBDM'));
117
- $this->add_setting( $s, 'disable-submit-listing', _x( 'Disable Frontend Listing Submission?', 'admin settings', 'WPBDM' ), 'boolean', false );
118
- $this->add_setting($s, 'show-submit-listing', _x('Show the "Submit listing" button.', 'admin settings', 'WPBDM'), 'boolean', true);
119
- $this->register_dep( 'show-submit-listing', 'requires-false', 'disable-submit-listing' );
120
- $this->add_setting($s, 'show-search-listings', _x('Show "Search listings".', 'admin settings', 'WPBDM'), 'boolean', true);
121
- $this->add_setting($s, 'show-view-listings', _x('Show the "View Listings" button.', 'admin settings', 'WPBDM'), 'boolean', true);
122
- $this->add_setting($s, 'show-directory-button', _x('Show the "Directory" button.', 'admin settings', 'WPBDM'), 'boolean', true);
123
- $this->add_setting( $s, 'disable-cpt', _x( 'Disable advanced CPT integration?', 'admin settings', 'WPBDM' ), 'boolean', false );
124
-
125
- // {{ Directory search.
126
- $s = $this->add_section( $g,
127
- 'search',
128
- _x( 'Directory Search', 'admin settings', 'WPBDM' ) );
129
- // $this->add_setting( $s,
130
- // 'show-search-form-in-results',
131
- // _x( 'Display search form when displaying search results?', 'admin settings', 'WPBDM' ),
132
- // 'boolean',
133
- // true );
134
- $this->add_setting( $s,
135
- 'search-form-in-results',
136
- _x( 'Search form display', 'admin settings', 'WPBDM' ),
137
- 'choice',
138
- 'above',
139
- '',
140
- array(
141
- 'choices' => array(
142
- 'above' => _x( 'Above results', 'admin settings', 'WPBDM' ),
143
- 'below' => _x( 'Below results', 'admin settings', 'WPBDM' ),
144
- 'none' => _x( 'Don\'t show with results', 'admin settings', 'WPBDM' ),
145
- ),
146
- 'widget' => 'radio',
147
- )
148
- );
149
 
150
- // Quick search fields.
151
- $desc = '';
152
- $desc .= '<span class="text-fields-warning wpbdp-note" style="display: none;">';
153
- $desc .= _x( 'You have selected a textarea field to be included in quick searches. Searches involving those fields are very expensive and could result in timeouts and/or general slowness.', 'admin settings', 'WPBDM' );
154
- $desc .= '</span>';
155
- $desc .= _x( 'Use Ctrl-Click to include multiple fields in the search. Choosing too many fields for inclusion into Quick Search can result in very slow search performance.', 'admin settings', 'WPBDM' );
156
-
157
- $this->add_setting( $s,
158
- 'quick-search-fields',
159
- _x( 'Quick search fields', 'admin settings', 'WPBDM' ),
160
- 'choice',
161
- array(),
162
- $desc,
163
- array(
164
- 'choices' => array( &$this, 'quicksearch_fields_cb' ),
165
- 'multiple' => true,
166
- 'widget' => 'checkbox',
167
- )
168
- );
169
 
170
- $this->add_setting( $s,
171
- 'quick-search-enable-performance-tricks',
172
- _x( 'Enable high performance searches?', 'admin settings', 'WPBDM' ),
173
- 'boolean',
174
- false,
175
- _x( 'Enabling this makes BD sacrifice result quality to improve speed. This is helpful if you\'re on shared hosting plans, where database performance is an issue.', 'admin settings', 'WPBDM' ) );
176
- // }}
177
-
178
- // Misc. settings.
179
-
180
- $s = $this->add_section($g, 'misc', _x('Miscellaneous Settings', 'admin settings', 'WPBDM'));
181
- // $this->add_setting($s, 'hide-tips', _x('Hide tips for use and other information?', 'admin settings', 'WPBDM'), 'boolean', false);
182
-
183
- $desc = '';
184
- $desc .= _x( 'Check this if you are having trouble with BD, particularly when importing or exporting CSV files.', 'admin settings', 'WPBDM' );
185
- $desc .=str_replace( '<a>',
186
- '<a href="http://businessdirectoryplugin.com/support-forum/faq/how-to-check-for-plugin-and-theme-conflicts-with-bd/" target="_blank">',
187
- _x( 'If this compatibility mode doesn\'t solve your issue, you may be experiencing a more serious conflict. <a>Here is an article</a> about how to test for theme and plugin conflicts with Business Directory.', 'admin settings', 'WPBDM' ) );
188
- $this->add_setting( $s,
189
- 'ajax-compat-mode',
190
- _x( 'Enable AJAX compatibility mode?', 'admin settings', 'WPBDM' ),
191
- 'boolean',
192
- false,
193
- $desc,
194
- null,
195
- array( &$this, 'setup_ajax_compat_mode' ) );
196
-
197
- $this->add_setting(
198
- $s,
199
- 'include-button-styles',
200
- _x( 'Include CSS rules to give their own style to View, Edit and Delete buttons?', 'admin settings', 'WPBDM' ),
201
- 'boolean',
202
- true
203
- );
204
 
205
- /* Listings settings */
206
- $g = $this->add_group('listings', _x('Listings', 'admin settings', 'WPBDM'));
207
- $s = $this->add_section($g, 'general', _x('General Settings', 'admin settings', 'WPBDM'));
208
-
209
- $this->add_setting($s, 'listings-per-page', _x('Listings per page', 'admin settings', 'WPBDM'), 'text', '10',
210
- _x('Number of listings to show per page. Use a value of "0" to show all listings.', 'admin settings', 'WPBDM'));
211
-
212
- $this->add_setting($s, 'listing-duration', _x('Listing duration for no-fee sites (in days)', 'admin settings', 'WPBDM'), 'text', '365',
213
- _x('Use a value of "0" to keep a listing alive indefinitely or enter a number less than 10 years (3650 days).', 'admin settings', 'WPBDM'),
214
- null,
215
- array($this, '_validate_listing_duration'));
216
-
217
- $this->add_setting( $s,
218
- 'show-contact-form',
219
- _x( 'Include listing contact form on listing pages?', 'admin settings', 'WPBDM' ),
220
- 'boolean',
221
- true,
222
- _x( 'Allows visitors to contact listing authors privately. Authors will receive the messages via email.', 'admin settings', 'WPBDM' ) );
223
- $this->add_setting( $s,
224
- 'listing-link-in-new-tab',
225
- _x( 'Open detailed view of listing in new tab?', 'admin settings', 'WPBDM' ),
226
- 'boolean',
227
- false);
228
- $this->add_setting( $s,
229
- 'contact-form-require-login',
230
- _x( 'Require login for using the contact form?', 'admin settings', 'WPBDM' ),
231
- 'boolean',
232
- false );
233
- $this->register_dep( 'contact-form-require-login', 'requires-true', 'show-contact-form' );
234
- $this->add_setting( $s,
235
- 'contact-form-daily-limit',
236
- _x( 'Maximum number of contact form submits per day', 'admin settings', 'WPBDM' ),
237
- 'text',
238
- '0',
239
- _x( 'Use this to prevent spamming of listing owners. 0 means unlimited submits per day.',
240
- 'admin settings',
241
- 'WPBDM') );
242
- $this->register_dep( 'contact-form-daily-limit', 'requires-true', 'show-contact-form' );
243
-
244
- $this->add_setting(
245
- $s,
246
- 'allow-comments-in-listings',
247
- _x( 'Include comment form on listing pages?', 'admin settings', 'WPBDM' ),
248
- 'choice',
249
- get_option( self::PREFIX . 'show-comment-form', false ) ? 'allow-comments-and-insert-template' : 'do-not-allow-comments',
250
- _x( "BD uses the standard comment inclusion from WordPress, but most themes only allow for comments on posts, not pages. Some themes handle both. BD is displayed on a page, so we need a theme that can handle both to show comments. Use the 2nd option if you want to allow comments on listings first, and if that doesn't work, try the 3rd option instead.", 'admin settings', 'WPBDM' ),
251
- array(
252
- 'choices' => array(
253
- 'do-not-allow-comments' => _x( 'Do not include comments in listings', 'admin settings', 'WPBDM' ),
254
- 'allow-comments' => _x( 'Include comment form, theme invoked (standard option)', 'admin settings', 'WPBDM' ),
255
- 'allow-comments-and-insert-template' => _x( "Include comment form, BD invoked (use only if 2nd option doesn't work)", 'admin settings', 'WPBDM' ),
256
- ),
257
- 'widget' => 'radio',
258
- )
259
- );
260
 
 
 
 
 
261
 
 
 
262
 
263
- $this->add_setting($s, 'show-listings-under-categories', _x('Show listings under categories on main page?', 'admin settings', 'WPBDM'), 'boolean', false);
 
 
 
 
 
 
 
 
 
264
 
265
- $this->add_setting(
266
- $s,
267
- 'status-on-uninstall',
268
- _x('Status of listings upon uninstalling plugin', 'admin settings', 'WPBDM'),
269
- 'choice',
270
- 'trash',
271
- '',
272
- array(
273
- 'choices' => array(
274
- 'draft' => _x( 'Draft', 'post status' ),
275
- 'trash' => _x( 'Trash', 'post status' ),
276
- ),
277
- 'widget' => 'radio',
278
- )
279
- );
280
 
281
- $this->add_setting(
282
- $s,
283
- 'deleted-status',
284
- _x( 'Status of deleted listings', 'admin settings', 'WPBDM' ),
285
- 'choice',
286
- 'trash',
287
- '',
288
- array(
289
- 'choices' => array(
290
- 'draft'=> _x( 'Draft', 'post status' ),
291
- 'trash' => _x( 'Trash', 'post status' ),
292
- ),
293
- 'widget' => 'radio',
294
- )
295
- );
296
 
297
- $this->add_setting( $s, 'submit-instructions', _x( 'Submit Listing instructions message', 'admin settings', 'WPBDM' ), 'text','', _x( 'This text is displayed at the first page of the Submit Listing process for Business Directory. You can use it for instructions about filling out the form or anything you want to tell users before they get started.', 'admin settings', 'WPBDM' ), array( 'use_textarea' => true ) );
298
-
299
- $s = $this->add_section($g, 'listings/renewals', _x('Listing Renewal', 'admin settings', 'WPBDM'));
300
- $this->add_setting($s, 'listing-renewal', _x('Turn on listing renewal option?', 'admin settings', 'WPBDM'), 'boolean', true);
301
- $this->add_setting( $s,
302
- 'listing-renewal-auto',
303
- _x( 'Allow recurring renewal payments?', 'admin settings', 'WPBDM' ),
304
- 'boolean',
305
- false,
306
- _x( 'Allow users to opt in for automatic renewal of their listings. The fee is charged at the time the listing expires without user intervention.', 'admin settings', 'WPBDM' )
307
- );
308
- $this->add_setting( $s,
309
- 'listing-renewal-auto-dontask',
310
- _x( 'Use recurring payments as the default payment method?', 'admin settings', 'WPBDM' ),
311
- 'boolean',
312
- false,
313
- _x( 'Enable automatic renewal without having users opt in during the submit process.', 'admin settings', 'WPBDM' ) );
314
- $this->register_dep( 'listing-renewal-auto-dontask', 'requires-true', 'listing-renewal-auto' );
315
-
316
- $this->add_setting( $s,
317
- 'renewal-email-threshold',
318
- _x( 'Listing renewal e-mail threshold (in days)', 'admin settings', 'WPBDM' ),
319
- 'text',
320
- '5',
321
- _x( 'Configure how many days before listing expiration is the renewal e-mail sent.', 'admin settings', 'WPBDM' )
322
- );
323
- $this->add_setting( $s,
324
- 'send-autorenewal-expiration-notice',
325
- _x( 'Send expiration notices including a cancel links to auto-renewed listings?', 'admin settings', 'WPBDM' ),
326
- 'boolean',
327
- false );
328
-
329
- // Renewal Reminders
330
- $this->add_setting( $s,
331
- 'renewal-reminder',
332
- _x( 'Remind listing owners of expired listings (past due)?', 'admin settings', 'WPBDM' ),
333
- 'boolean',
334
- false );
335
- $this->add_setting( $s,
336
- 'renewal-reminder-threshold',
337
- _x( 'Listing renewal reminder e-mail threshold (in days)', 'admin settings', 'WPBDM' ),
338
- 'text',
339
- '10',
340
- _x( 'Configure how many days after the expiration of a listing an e-mail reminder should be sent to the owner.', 'admin settings', 'WPBDM' )
341
- );
342
-
343
- $s = $this->add_section($g, 'post/category', _x('Post/Category Settings', 'admin settings', 'WPBDM'));
344
-
345
- $this->add_setting(
346
- $s,
347
- 'new-post-status',
348
- _x( 'Default new post status', 'admin settings', 'WPBDM' ),
349
- 'choice',
350
- 'pending',
351
- '',
352
- array(
353
- 'choices' => array(
354
- 'publish' => _x( 'Published', 'post status' ),
355
- 'pending' => _x( 'Pending', 'post status' ),
356
- ),
357
- 'widget' => 'radio',
358
- )
359
- );
360
 
361
- $this->add_setting(
362
- $s,
363
- 'edit-post-status',
364
- _x('Edit post status', 'admin settings', 'WPBDM'),
365
- 'choice',
366
- 'publish',
367
- '',
368
- array(
369
- 'choices' => array(
370
- 'publish' => _x( 'Published', 'post status' ),
371
- 'pending' => _x( 'Pending', 'post status' ),
372
- ),
373
- 'widget' => 'radio',
374
- )
375
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
 
377
- $this->add_setting( $s, 'categories-order-by', _x('Order categories list by', 'admin settings', 'WPBDM'), 'choice', 'name', '',
378
- array('choices' => array(
379
- 'name' => _x( 'Name', 'admin settings', 'WPBDM' ),
380
- 'slug' => _x( 'Slug', 'admin settings', 'WPBDM' ),
381
- 'count' => _x( 'Listing Count', 'admin settings', 'WPBDM' ),
382
- ),
383
- 'widget' => 'radio',
384
- )
385
- );
386
 
387
- $this->add_setting( $s, 'categories-sort', _x('Sort order for categories', 'admin settings', 'WPBDM'), 'choice', 'ASC', '',
388
- array(
389
- 'choices' => array(
390
- 'ASC' => _x('Ascending', 'admin settings', 'WPBDM'),
391
- 'DESC' => _x('Descending', 'admin settings', 'WPBDM'),
392
- ),
393
- 'widget' => 'radio',
394
- )
395
- );
396
 
397
- $this->add_setting($s, 'show-category-post-count', _x('Show category post count?', 'admin settings', 'WPBDM'), 'boolean', true);
398
- $this->add_setting($s, 'hide-empty-categories', _x('Hide empty categories?', 'admin settings', 'WPBDM'), 'boolean', false);
399
- $this->add_setting($s, 'show-only-parent-categories', _x('Show only parent categories in category list?', 'admin settings', 'WPBDM'), 'boolean', false);
400
-
401
- $s = $this->add_section( $g, 'post/sorting', _x( 'Listings Sorting', 'admin settings', 'WPBDM' ) );
402
- $this->add_setting($s, 'listings-order-by', _x('Order directory listings by', 'admin settings', 'WPBDM'), 'choice', 'title', '',
403
- array('choices' => array(
404
- array( 'title', _x( 'Title', 'admin settings', 'WPBDM' ) ),
405
- array( 'author', _x( 'Author', 'admin settings', 'WPBDM' ) ),
406
- array( 'date', _x( 'Date posted', 'admin settings', 'WPBDM' ) ),
407
- array( 'modified', _x( 'Date last modified', 'admin settings', 'WPBDM' ) ),
408
- array( 'rand', _x( 'Random', 'admin settings', 'WPBDM' ) ),
409
- array( 'paid', _x( 'Paid first then free. Inside each group by date.', 'admin settings', 'WPBDM' ) ),
410
- array( 'paid-title', _x( 'Paid first then free. Inside each group by title.', 'admin settings', 'WPBDM' ) )
411
- )));
412
- $this->add_setting(
413
- $s,
414
- 'listings-sort',
415
- _x( 'Sort order for directory listings', 'admin settings', 'WPBDM' ),
416
- 'choice',
417
- 'ASC',
418
- _x( 'Ascending for ascending order A-Z, Descending for descending order Z-A', 'admin settings', 'WPBDM' ),
419
- array(
420
- 'choices' => array(
421
- 'ASC' => _x('Ascending', 'admin settings', 'WPBDM'),
422
- 'DESC' => _x('Descending', 'admin settings', 'WPBDM'),
423
- ),
424
- 'widget' => 'radio',
425
- )
426
- );
427
 
428
- $this->add_setting( $s,
429
- 'listings-sortbar-enabled',
430
- _x( 'Enable sort bar?', 'admin settings', 'WPBDM' ),
431
- 'boolean',
432
- false );
433
- $this->add_setting( $s,
434
- 'listings-sortbar-fields',
435
- _x( 'Sortbar Fields', 'admin settings', 'WPBDM' ),
436
- 'choice',
437
- array(),
438
- '',
439
- array( 'choices' => array( &$this, 'sortbar_fields_cb' ),
440
- 'widget' => 'checkbox',
441
- 'multiple' =>true ) );
442
- $this->register_dep( 'listings-sortbar-fields', 'requires-true', 'listings-sortbar-enabled' );
443
-
444
- $s = $this->add_section($g, 'featured', _x('Featured (Sticky) listing settings', 'admin settings', 'WPBDM'));
445
- $this->add_setting($s, 'featured-on', _x('Offer sticky listings?', 'admin settings', 'WPBDM'), 'boolean', false);
446
- $this->add_setting($s, 'featured-offer-in-submit', _x('Offer upgrades during submit process?', 'admin settings', 'WPBDM'), 'boolean', false);
447
- $this->add_setting($s, 'featured-price', _x('Sticky listing price', 'admin settings', 'WPBDM'), 'text', '39.99');
448
- $this->add_setting($s, 'featured-description', _x('Sticky listing page description text', 'admin settings', 'WPBDM'), 'text',
449
- _x('You can upgrade your listing to featured status. Featured listings will always appear on top of regular listings.', 'admin settings', 'WPBDM'));
450
-
451
- /*
452
- * E-Mail settings.
453
- */
454
- $g = $this->add_group( 'email', _x( 'E-Mail', 'admin settings', 'WPBDM' ) );
455
- $s = $this->add_section( $g, 'email-general', _x( 'General Settings', 'admin settings', 'WPBDM' ) );
456
- $this->add_setting( $s,
457
- 'override-email-blocking',
458
- _x( 'Display email address fields publicly?', 'admin settings', 'WPBDM' ),
459
- 'boolean',
460
- false,
461
- _x('Shows the email address of the listing owner to all web users. NOT RECOMMENDED as this increases spam to the address and allows spam bots to harvest it for future use.', 'admin settings', 'WPBDM') );
462
- $this->add_setting( $s,
463
- 'listing-email-mode',
464
- _x( 'How to determine the listing\'s email address?', 'admin settings', 'WPBDM' ),
465
- 'choice',
466
- 'field',
467
- _x( 'This affects emails sent to listing owners via contact forms or when their listings expire.', 'admin settings', 'WPBDM' ),
468
- array( 'choices' => array(
469
- 'field' => _x( 'Try listing\'s email field first, then author\'s email.', 'admin settings', 'WPBDM' ),
470
- 'user' => _x( 'Try author\'s email first and then listing\'s email field.', 'admin settings', 'WPBDM' ),
471
- ),
472
- 'widget' => 'radio',
473
- )
474
- );
475
 
476
- $s = $this->add_section( $g, 'email-notifications', _x( 'E-Mail Notifications', 'admin settings', 'WPBDM' ) );
477
- $this->add_setting( $s,
478
- 'admin-notifications',
479
- _x( 'Notify admin via e-mail when...', 'admin settings', 'WPBDM' ),
480
- 'choice',
481
- array(),
482
- '',
483
- array( 'choices' => array( 'new-listing' => _x( 'A new listing is submitted.', 'admin settings', 'WPBDM' ),
484
- 'listing-edit' => _x( 'A listing is edited.', 'admin settings', 'WPBDM' ),
485
- 'renewal' => _x( 'A listing expires.', 'admin settings', 'WPBDM' ),
486
- 'listing-contact' => _x( 'A contact message is sent to a listing\'s owner.', 'admin settings', 'WPBDM' ) ),
487
- 'widget' => 'checkbox',
488
- 'multiple' => true )
489
- );
490
- $this->add_setting( $s,
491
- 'admin-notifications-cc',
492
- _x( 'CC this e-mail address too', 'admin settings', 'WPBDM' ),
493
- 'text',
494
- '' );
495
-
496
- $this->add_setting( $s,
497
- 'user-notifications',
498
- _x( 'Notify users via e-mail when...', 'admin settings', 'WPBDM' ),
499
- 'choice',
500
- array( 'new-listing', 'listing-published'/*, 'payment-status-change'*/ ),
501
- _x( 'You can modify the text template used for most of these e-mails below.', 'admin settings', 'WPBDM' ),
502
- array( 'choices' => array( 'new-listing' => _x( 'Their listing is submitted.', 'admin settings', 'WPBDM' ),
503
- 'listing-published' => _x( 'Their listing is approved/published.', 'admin settings', 'WPBDM' )/*,
504
- 'payment-status-change' => _x( 'A payment status changes (sends a receipt).', 'admin settings', 'WPBDM' ),*/
505
- ),
506
- 'widget' => 'checkbox',
507
- 'multiple' => true )
508
- );
509
-
510
- // Listing contact.
511
- $email_contact_template = '';
512
- $email_contact_template .= sprintf( _x( 'You have received a reply from your listing at %s.', 'contact email', 'WPBDM' ), '[listing-url]' ) . "\n\n";
513
- $email_contact_template .= sprintf( _x( 'Name: %s', 'contact email', 'WPBDM' ), '[name]' ) . "\n";
514
- $email_contact_template .= sprintf( _x( 'E-Mail: %s', 'contact email', 'WPBDM' ), '[email]' ) . "\n";
515
- $email_contact_template .= _x( 'Message:', 'contact email', 'WPBDM' ) . "\n";
516
- $email_contact_template .= '[message]' . "\n\n";
517
- $email_contact_template .= sprintf( _x( 'Time: %s', 'contact email', 'WPBDM' ), '[date]' );
518
-
519
- $s = $this->add_section( $g, 'email/templates', _x( 'E-Mail Templates', 'admin settings', 'WPBDM' ) );
520
-
521
- $this->add_setting( $s,
522
- 'email-confirmation-message', _x( 'Email confirmation message', 'admin settings', 'WPBDM' ),
523
- 'email_template',
524
- array( 'subject' => '[[site-title]] Listing "[listing]" received',
525
- 'body' => 'Your submission \'[listing]\' has been received and it\'s pending review. This review process could take up to 48 hours.' ),
526
- _x( 'Sent after a listing has been submitted.', 'admin settings', 'WPBDM' ),
527
- array( 'placeholders' => array( 'listing' => array( _x( 'Listing\'s title', 'admin settings', 'WPBDM' ) ) ) )
528
- );
529
- $this->add_setting( $s,
530
- 'email-templates-listing-published', _x( 'Listing published message', 'admin settings', 'WPBDM' ),
531
- 'email_template',
532
- array( 'subject' => '[[site-title]] Listing "[listing]" published',
533
- 'body' => _x( 'Your listing "[listing]" is now available at [listing-url] and can be viewed by the public.', 'admin settings', 'WPBDM' ) ),
534
- _x( 'Sent when the listing has been published or approved by an admin.', 'admin settings', 'WPBDM' ),
535
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s title', 'admin settings', 'WPBDM' ),
536
- 'listing-url' => _x( 'Listing\'s URL', 'admin settings', 'WPBDM' ) ) )
537
- );
538
- $this->add_setting( $s,
539
- 'email-templates-contact',
540
- _x( 'Listing Contact Message', 'admin settings', 'WPBDM' ),
541
- 'email_template',
542
- array( 'subject' => '[[site-title]] Contact via "[listing]"',
543
- 'body' => $email_contact_template ),
544
- _x( 'Sent to listing owners when someone uses the contact form on their listing pages.', 'admin settings', 'WPBDM' ),
545
- array( 'placeholders' => array( 'listing-url' => 'Listing\'s URL',
546
- 'listing' => 'Listing\'s title',
547
- 'name' => 'Sender\'s name',
548
- 'email' => 'Sender\'s e-mail address',
549
- 'message' => 'Contact message',
550
- 'date' => 'Date and time the message was sent' ) ) );
551
-
552
- $s = $this->add_section( $g,
553
- 'email-payments',
554
- _x( 'Payment related', 'admin settings', 'WPBDM' ) );
555
- $body_template = <<<EOF
556
- Hi there,
557
-
558
- We noticed that you tried submitting a listing on [site-link] but didn't finish
559
- the process. If you want to complete the payment and get your listing
560
- included, just click here to continue:
561
-
562
- [link]
563
-
564
- If you have any issues, please contact us directly by hitting reply to this
565
- email!
566
-
567
- Thanks,
568
- - The Administrator of [site-title]
569
- EOF;
570
- $this->add_setting( $s,
571
- 'email-templates-payment-abandoned', _x( 'Payment abandoned reminder message', 'admin settings', 'WPBDM' ),
572
- 'email_template',
573
- array( 'subject' => '[[site-title]] Pending payment for "[listing]"',
574
- 'body' => $body_template ),
575
- _x( 'Sent some time after a pending payment is abandoned by users.', 'admin settings', 'WPBDM' ),
576
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s title', 'admin settings', 'WPBDM' ),
577
- 'link' => _x( 'Checkout URL link', 'admin settings', 'WPBDM' ) ) )
578
- );
579
-
580
- $url = admin_url( 'admin.php?page=wpbdp_admin_settings&groupid=listings' ) . '#listings/renewals';
581
- $s = $this->add_section( $g,
582
- 'email-renewal-reminders',
583
- _x( 'Renewal Reminders', 'admin settings', 'WPBDM' ),
584
- str_replace( '<a>',
585
- '<a href="' . esc_url( $url ) . '">',
586
- _x( 'This section refers only to the text of the renewal/expiration notices. You can also <a>configure when the e-mails are sent</a>.', 'admin settings', 'WPBDM' ) ) );
587
-
588
- $this->add_setting( $s,
589
- 'renewal-pending-message',
590
- _x( 'Pending expiration e-mail message', 'admin settings', 'WPBDM' ),
591
- 'email_template',
592
- array( 'subject' => '[[site-title]] [listing] - Expiration notice',
593
- 'body' => self::_EMAIL_PENDING_RENEWAL_MESSAGE ),
594
- _x( 'Sent some time before the listing expires. Applies to non-recurring renewals only.', 'settings', 'WPBDM' ),
595
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
596
- 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
597
- 'expiration' => _x( 'Expiration date', 'settings', 'WPBDM' ),
598
- 'category' => _x( 'Category that is going to expire', 'settings', 'WPBDM' ),
599
- 'link' => _x( 'Link to renewal page', 'settings', 'WPBDM' ),
600
- 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
601
- );
602
- $this->add_setting( $s,
603
- 'listing-renewal-message', _x('Listing Renewal e-mail message', 'admin settings', 'WPBDM'),
604
- 'email_template',
605
- array( 'subject' => '[[site-title]] [listing] - Expiration notice',
606
- 'body' => self::_EMAIL_RENEWAL_MESSAGE ),
607
- _x( 'Sent at the time of listing expiration. Applies to non-recurring renewals only.', 'settings', 'WPBDM' ),
608
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
609
- 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
610
- 'expiration' => _x( 'Expiration date', 'settings', 'WPBDM' ),
611
- 'category' => _x( 'Category that expired', 'settings', 'WPBDM' ),
612
- 'link' => _x( 'Link to renewal page', 'settings', 'WPBDM' ),
613
- 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
614
- );
615
- $this->add_setting( $s,
616
- 'listing-autorenewal-notice', _x( 'Listing auto-renewal reminder (recurring payments)', 'admin settings', 'WPBDM'),
617
- 'email_template',
618
- array( 'subject' => '[[site-title]] [listing] - Renewal reminder',
619
- 'body' => self::_EMAIL_AUTORENEWAL_PENDING_MESSAGE ),
620
- _x( 'Sent some time before the listing is auto-renewed. Applies to recurring renewals only.', 'settings', 'WPBDM' ),
621
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
622
- 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
623
- 'date' => _x( 'Renewal date', 'settings', 'WPBDM' ),
624
- 'category' => _x( 'Category that is going to be renewed', 'settings', 'WPBDM' ),
625
- 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ),
626
- 'link' => _x( 'Link to manage subscriptions', 'settings', 'WPBDM' ) ) )
627
- );
628
- $this->add_setting( $s,
629
- 'listing-autorenewal-message', _x('Listing Renewal e-mail message (recurring payments)', 'admin settings', 'WPBDM'),
630
- 'email_template',
631
- array( 'subject' => '[[site-title]] [listing] renewed',
632
- 'body' => self::_EMAIL_AUTORENEWAL_MESSAGE ),
633
- _x( 'Sent after the listing is auto-renewed. Applies to recurring renewals only.', 'settings', 'WPBDM' ),
634
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
635
- 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
636
- 'category' => _x( 'Renewed category', 'settings', 'WPBDM' ),
637
- 'date' => _x( 'Renewal date', 'settings', 'WPBDM' ),
638
- 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
639
- );
640
- $this->add_setting( $s,
641
- 'renewal-reminder-message',
642
- _x( 'Renewal reminder e-mail message', 'admin settings', 'WPBDM' ),
643
- 'email_template',
644
- array( 'subject' => '[[site-title]] [listing] - Expiration reminder',
645
- 'body' => "Dear Customer\nWe've noticed that you haven't renewed your listing \"[listing]\" for category [category] at [site] and just wanted to remind you that it expired on [expiration]. Please remember you can still renew it here: [link]." ),
646
- _x( 'Sent some time after listing expiration and when no renewal has occurred. Applies to both recurring and non-recurring renewals.', 'settings', 'WPBDM' ),
647
- array( 'placeholders' => array( 'listing' => _x( 'Listing\'s name (with link)', 'settings', 'WPBDM' ),
648
- 'author' => _x( 'Author\'s name', 'settings', 'WPBDM' ),
649
- 'expiration' => _x( 'Expiration date', 'settings', 'WPBDM' ),
650
- 'category' => _x( 'Category that expired', 'settings', 'WPBDM' ),
651
- 'link' => _x( 'Link to renewal page', 'settings', 'WPBDM' ),
652
- 'site' => _x( 'Link to your site', 'settings', 'WPBDM' ) ) )
653
- );
654
-
655
- /* Payment settings */
656
- $g = $this->add_group('payment', _x('Payment', 'admin settings', 'WPBDM'));
657
- $s = $this->add_section($g, 'general', _x('Payment Settings', 'admin settings', 'WPBDM'));
658
-
659
- $this->add_setting( $s, 'fee-order', 'Fee Order', 'core', array( 'method' => 'label', 'order' => 'asc' ) );
660
- $this->add_setting($s, 'payments-on', _x('Turn On payments?', 'admin settings', 'WPBDM'), 'boolean', false);
661
-
662
- $this->add_setting($s, 'payments-test-mode', _x('Put payment gateways in test mode?', 'admin settings', 'WPBDM'), 'boolean', true);
663
- $this->register_dep( 'payments-test-mode', 'requires-true', 'payments-on' );
664
-
665
- $this->add_setting( $s,
666
- 'payments-use-https',
667
- _x( 'Perform checkouts on the secure (HTTPS) version of your site?', 'admin settings', 'WPBDM' ),
668
- 'boolean',
669
- false,
670
- _x( 'Recommended for added security. For this to work you need to enable HTTPS on your server and <a>obtain an SSL certificate</a>.', 'admin settings', 'WPBDM' ) );
671
- $this->register_dep( 'payments-use-https', 'requires-true', 'payments-on' );
672
-
673
- // PayPal currency codes from https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_nvp_currency_codes
674
- $this->add_setting($s, 'currency', _x('Currency Code', 'admin settings', 'WPBDM'), 'choice', 'USD', '',
675
- array('choices' => array(
676
- array('AUD', _x('Australian Dollar (AUD)', 'admin settings', 'WPBDM')),
677
- array('BRL', _x('Brazilian Real (BRL)', 'admin settings', 'WPBDM')),
678
- array('CAD', _x('Canadian Dollar (CAD)', 'admin settings', 'WPBDM')),
679
- array('CZK', _x('Czech Koruna (CZK)', 'admin settings', 'WPBDM')),
680
- array('DKK', _x('Danish Krone (DKK)', 'admin settings', 'WPBDM')),
681
- array('EUR', _x('Euro (EUR)', 'admin settings', 'WPBDM')),
682
- array('HKD', _x('Hong Kong Dollar (HKD)', 'admin settings', 'WPBDM')),
683
- array('HUF', _x('Hungarian Forint (HUF)', 'admin settings', 'WPBDM')),
684
- array('ILS', _x('Israeli New Shequel (ILS)', 'admin settings', 'WPBDM')),
685
- array('JPY', _x('Japanese Yen (JPY)', 'admin settings', 'WPBDM')),
686
- array( 'MAD', _x( 'Moroccan Dirham (MAD)', 'admin settings', 'WPBDM' ) ),
687
- array('MYR', _x('Malasian Ringgit (MYR)', 'admin settings', 'WPBDM')),
688
- array('MXN', _x('Mexican Peso (MXN)', 'admin settings', 'WPBDM')),
689
- array('NOK', _x('Norwegian Krone (NOK)', 'admin settings', 'WPBDM')),
690
- array('NZD', _x('New Zealand Dollar (NZD)', 'admin settings', 'WPBDM')),
691
- array('PHP', _x('Philippine Peso (PHP)', 'admin settings', 'WPBDM')),
692
- array('PLN', _x('Polish Zloty (PLN)', 'admin settings', 'WPBDM')),
693
- array('GBP', _x('Pound Sterling (GBP)', 'admin settings', 'WPBDM')),
694
- array('SGD', _x('Singapore Dollar (SGD)', 'admin settings', 'WPBDM')),
695
- array('SEK', _x('Swedish Krona (SEK)', 'admin settings', 'WPBDM')),
696
- array('CHF', _x('Swiss Franc (CHF)', 'admin settings', 'WPBDM')),
697
- array('TWD', _x('Taiwan Dollar (TWD)', 'admin settings', 'WPBDM')),
698
- array('THB', _x('Thai Baht (THB)', 'admin settings', 'WPBDM')),
699
- array('TRY', _x('Turkish Lira (TRY)', 'admin settings', 'WPBDM')),
700
- array('USD', _x('U.S. Dollar (USD)', 'admin settings', 'WPBDM')),
701
- )));
702
- $this->register_dep( 'currency', 'requires-true', 'payments-on' );
703
-
704
- $this->add_setting($s, 'currency-symbol', _x('Currency Symbol', 'admin settings', 'WPBDM'), 'text', '$');
705
- $this->register_dep( 'currency-symbol', 'requires-true', 'payments-on' );
706
-
707
- $this->add_setting( $s,
708
- 'currency-symbol-position',
709
- _x( 'Currency symbol display', 'admin settings', 'WPBDM' ),
710
- 'choice',
711
- 'left',
712
- '',
713
- array(
714
- 'choices' => array(
715
- 'left' => _x( 'Show currency symbol on the left', 'admin settings', 'WPBDM' ),
716
- 'right' => _x( 'Show currency symbol on the right', 'admin settings', 'WPBDM' ),
717
- 'none' => _x( 'Do not show currency symbol', 'admin settings', 'WPBDM' ),
718
- ),
719
- 'widget' => 'radio',
720
- )
721
- );
722
 
723
- $this->register_dep( 'currency-symbol-position', 'requires-true', 'payments-on' );
724
-
725
- $this->add_setting($s, 'payment-message', _x('Thank you for payment message', 'admin settings', 'WPBDM'), 'text',
726
- _x('Thank you for your payment. Your payment is being verified and your listing reviewed. The verification and review process could take up to 48 hours.', 'admin settings', 'WPBDM'));
727
- $this->register_dep( 'payment-message', 'requires-true', 'payments-on' );
728
-
729
- $this->add_setting( $s,
730
- 'payment-abandonment',
731
- _x( 'Ask users to come back for abandoned payments?', 'admin settings', 'WPBDM' ),
732
- 'boolean',
733
- false,
734
- _x( 'An abandoned payment is when a user attempts to place a listing and gets to the end, but fails to complete their payment for the listing. This results in listings that look like they failed, when the user simply didn\'t complete the transaction. BD can remind them to come back and continue.', 'admin settings', 'WPBDM' )
735
- );
736
-
737
- $this->register_dep( 'payment-abandonment', 'requires-true', 'payments-on' );
738
- $this->add_setting( $s,
739
- 'payment-abandonment-threshold',
740
- _x( 'Listing abandonment threshold (hours)', 'admin settings', 'WPBDM' ),
741
- 'text',
742
- '24',
743
- str_replace( '<a>',
744
- '<a href="' . admin_url( 'admin.php?page=wpbdp_admin_settings&groupid=email' ) . '#email-templates-payment-abandoned">',
745
- _x( 'Listings with pending payments are marked as abandoned after this time. You can also <a>customize the e-mail</a> users receive.', 'admin settings', 'WPBDM' )
746
- ) );
747
- $this->register_dep( 'payment-abandonment-threshold', 'requires-true', 'payment-abandonment' );
748
-
749
- // TODO: we probably should merge this and 'Images' into an 'Appearance' tab. {
750
- $g = $this->add_group( 'themes', _x( 'Themes', 'admin settings', 'WPBDM' ) );
751
-
752
- $msg = str_replace( '<a>', '<a href="' . admin_url( 'admin.php?page=wpbdp-themes' ) . '">', _x( 'You can manage your themes on <a>Directory Themes</a>.', 'admin settings', 'WPBDM' ) );
753
- $s = $this->add_section( $g, 'general', _x( 'General Settings', 'admin settings', 'WPBDM' ), $msg );
754
-
755
- $this->add_setting( $s,
756
- 'themes-button-style',
757
- _x( 'Theme button style', 'admin settings', 'WPBDM' ),
758
- 'choice',
759
- 'theme',
760
- '',
761
  array(
762
- 'choices' => array(
763
- 'theme' => _x( 'Use the BD theme style for BD buttons', 'admin settings', 'WPBDM' ),
764
- 'none' => _x( 'Use the WP theme style for BD buttons', 'admin settings', 'WPBDM' ),
765
- ),
766
- 'widget' => 'radio',
767
  )
768
  );
769
- // }
770
-
771
-
772
- /* Image settings */
773
- $g = $this->add_group( 'image',
774
- _x( 'Image', 'admin settings', 'WPBDM' ),
775
- _x( 'Any changes to these settings will affect new listings only. Existing listings will not be affected. If you wish to change existing listings, you will need to re-upload the image(s) on that listing after changing things here.', 'admin settings', 'WPBDM' ) );
776
- $s = $this->add_section($g, 'image', _x('Image Settings', 'admin settings', 'WPBDM'));
777
- $this->add_setting($s, 'allow-images', _x('Allow images?', 'admin settings', 'WPBDM'), 'boolean', true);
778
-
779
- $this->add_setting($s, 'image-min-filesize', _x('Min Image File Size (KB)', 'admin settings', 'WPBDM'), 'text', '0' );
780
- $this->add_setting($s, 'image-max-filesize', _x('Max Image File Size (KB)', 'admin settings', 'WPBDM'), 'text', '10000');
781
-
782
- $this->add_setting($s, 'image-min-width', _x( 'Min image width (px)', 'admin settings', 'WPBDM'), 'text', '0' );
783
- $this->add_setting($s, 'image-min-height', _x( 'Min image height (px)', 'admin settings', 'WPBDM'), 'text', '0' );
784
-
785
- $this->add_setting($s, 'image-max-width', _x('Max image width (px)', 'admin settings', 'WPBDM'), 'text', '500');
786
- $this->add_setting($s, 'image-max-height', _x('Max image height (px)', 'admin settings', 'WPBDM'), 'text', '500');
787
-
788
- $this->add_setting( $s, 'use-thickbox', _x( 'Turn on thickbox/lightbox?', 'admin settings', 'WPBDM' ), 'boolean', false, _x( 'Uncheck if it conflicts with other elements or plugins installed on your site', 'admin settings', 'WPBDM' ) );
789
-
790
- $s = $this->add_section( $g, 'image/thumbnails', _x( 'Thumbnails', 'admin settings', 'WPBDM' ) );
791
- $this->add_setting($s, 'thumbnail-width', _x('Thumbnail width (px)', 'admin settings', 'WPBDM'), 'text', '150');
792
- $this->add_setting($s, 'thumbnail-height', _x('Thumbnail height (px)', 'admin settings', 'WPBDM'), 'text', '150');
793
- $this->add_setting( $s,
794
- 'thumbnail-crop',
795
- _x( 'Crop thumbnails to exact dimensions?', 'admin settings', 'WPBDM'),
796
- 'boolean',
797
- false,
798
- _x( 'When enabled images will match exactly the dimensions above but part of the image may be cropped out. If disabled, image thumbnails will be resized to match the specified width and their height will be adjusted proportionally. Depending on the uploaded images, thumbnails may have different heights.', 'admin settings', 'WPBDM' )
799
- );
800
-
801
- $s = $this->add_section($g, 'listings', _x('Listings', 'admin settings', 'WPBDM'));
802
- $this->add_setting( $s,
803
- 'free-images',
804
- _x( 'Number of free images', 'admin settings', 'WPBDM' ),
805
- 'text',
806
- '2',
807
- str_replace( '<a>',
808
- '<a href="' . admin_url( 'admin.php?page=wpbdp_admin_fees' ) . '">',
809
- _x( 'For paid listing images, configure that by adding or editing a <a>Fee Plan</a> instead of this setting, which is ignored for paid listings.', 'admin settings', 'WPBDM' ) ),
810
- null,
811
- array( &$this, '_validate_free_images' ) );
812
- $this->add_setting($s, 'use-default-picture', _x('Use default picture for listings with no picture?', 'admin settings', 'WPBDM'), 'boolean', true);
813
- $this->add_setting($s, 'show-thumbnail', _x('Show Thumbnail on main listings page?', 'admin settings', 'WPBDM'), 'boolean', true);
814
  }
815
 
816
- public function quicksearch_fields_cb() {
817
- $fields = array();
818
-
819
- foreach ( wpbdp_get_form_fields( 'association=-custom' ) as $field ) {
820
- $is_text_field = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
821
 
822
- if ( in_array( $field->get_association(), array( 'excerpt', 'content' ) ) || 'textarea' == $field->get_field_type_id() )
823
- $is_text_field = true;
 
 
 
 
 
 
 
 
 
824
 
825
- $fields[ $field->get_id() ] = array( $field->get_label(), $is_text_field ? 'textfield' : '' );
 
826
  }
827
 
828
- return $fields;
829
- }
 
 
830
 
831
- public function sortbar_fields_cb() {
832
- $fields = array();
 
833
 
834
- foreach ( wpbdp_get_form_fields() as $f ) {
835
- if ( in_array( $f->get_field_type_id(), array( 'textarea', 'select', 'checkbox', 'url' ), true ) ||
836
- in_array( $f->get_association(), array( 'category', 'tags' ), true ) )
837
- continue;
838
 
839
- $fields[ $f->get_id() ] = apply_filters( 'wpbdp_render_field_label', $f->get_label(), $f );
 
840
  }
841
 
842
- $fields['user_login'] = _x( 'User', 'admin settings', 'WPBDM' );
843
- $fields['user_registered'] = _x( 'User registration date', 'admin settings', 'WPBDM' );
844
- $fields['date'] = _x( 'Date posted', 'admin settings', 'WPBDM' );
845
- $fields['modified'] = _x( 'Date last modified', 'admin settings', 'WPBDM' );
846
-
847
- return $fields;
848
  }
849
 
850
- public function _validate_listings_permalink($setting, $newvalue, $oldvalue=null) {
851
- return trim(str_replace(' ', '', $newvalue));
852
  }
853
 
854
- public function setup_ajax_compat_mode( $setting, $newvalue, $oldvalue = null ) {
855
- if ( $newvalue == $oldvalue )
856
- return;
857
-
858
- $mu_dir = ( defined( 'WPMU_PLUGIN_DIR' ) && defined( 'WPMU_PLUGIN_URL' ) ) ? WPMU_PLUGIN_DIR : trailingslashit( WP_CONTENT_DIR ) . 'mu-plugins';
859
- $source = WPBDP_INC . 'compatibility/wpbdp-ajax-compat-mu.php';
860
- $dest = trailingslashit( $mu_dir ) . basename( $source );
861
-
862
- $message = false;
863
- $install = (bool) $newvalue;
864
-
865
- if ( $install ) {
866
- // Install plugin.
867
- if ( wp_mkdir_p( $mu_dir ) ) {
868
- if ( ! copy( $source, $dest ) ) {
869
- $message = array( sprintf( _x( 'Could not copy the AJAX compatibility plugin "%s". Compatibility mode was not activated.', 'admin settings', 'WPBDM' ),
870
- $dest ),
871
- 'error' );
872
- $newvalue = $oldvalue;
873
- }/* else {
874
- $message = _x( 'AJAX compatibility mode activated. "Business Directory Plugin - AJAX Compatibility Module" was installed.', 'admin settings', 'WPBDM' );
875
- }*/
876
- } else {
877
- $message = array( sprintf( _x( 'Could not activate AJAX Compatibility mode: the directory "%s" could not be created.', 'admin settings', 'WPBDM' ),
878
- $mu_dir ),
879
- 'error' );
880
- $newvalue = $oldvalue;
881
- }
882
- } else {
883
- // Uninstall.
884
- if ( file_exists( $dest ) && ! unlink( $dest ) ) {
885
- $message = array(
886
- sprintf( _x( 'Could not remove the "Business Directory Plugin - AJAX Compatibility Module". Please remove the file "%s" manually or deactivate the plugin.',
887
- 'admin settings',
888
- 'WPBDM' ),
889
- $dest ),
890
- 'error'
891
- );
892
-
893
- $newvalue = $oldvalue;
894
- }
895
- }
896
-
897
- if ( $message )
898
- update_option( 'wpbdp-ajax-compat-mode-notice', $message );
899
-
900
- return $newvalue;
901
  }
902
 
903
- public function _validate_term_permalink($setting, $newvalue, $oldvalue=null) {
904
- if ( empty( $newvalue ) ) {
905
- return $oldvalue;
906
- }
 
 
 
 
907
 
908
- $bd_taxonomy = $setting->name == 'permalinks-category-slug' ? WPBDP_CATEGORY_TAX : WPBDP_TAGS_TAX;
 
 
 
909
 
910
- foreach (get_taxonomies(null, 'objects') as $taxonomy) {
911
- if ($taxonomy->rewrite && $taxonomy->rewrite['slug'] == $newvalue && $taxonomy->name != $bd_taxonomy) {
912
- return $oldvalue;
 
 
 
 
 
 
 
 
913
  }
914
  }
915
 
916
- return trim(str_replace(' ', '', $newvalue));
917
- }
918
-
919
- public function _validate_free_images( $setting, $newvalue, $oldvalue = null ) {
920
- $v = absint( $newvalue );
921
-
922
- global $_wpbdp_fee_plan_recursion_guard;
923
- if ( ! isset( $_wpbdp_fee_plan_recursion_guard ) || ! $_wpbdp_fee_plan_recursion_guard ) {
924
- $freeplan = WPBDP_Fee_Plan::get_free_plan();
925
- $freeplan->update( array( 'images' => $v ) );
926
- }
927
 
928
- return $v;
929
  }
930
 
931
- public function _validate_listing_duration($setting, $newvalue, $oldvalue=null) {
932
- // limit 'duration' because of TIMESTAMP limited range (issue #157).
933
- // FIXME: this is not a long-term fix. we should move to DATETIME to avoid this entirely.
934
- $v = min(max(intval($newvalue), 0), 3650);
935
-
936
- global $_wpbdp_fee_plan_recursion_guard;
937
- if ( ! isset( $_wpbdp_fee_plan_recursion_guard ) || ! $_wpbdp_fee_plan_recursion_guard ) {
938
- $freeplan = WPBDP_Fee_Plan::get_free_plan();
939
- $freeplan->update( array( 'days' => $v ) );
940
- }
941
-
942
- return $v;
943
  }
944
 
945
- public function add_group($slug, $name, $help_text='') {
946
- $group = new StdClass();
947
- $group->wpslug = self::PREFIX . $slug;
948
- $group->slug = $slug;
949
- $group->name = esc_attr( $name );
950
- $group->help_text = $help_text;
951
- $group->sections = array();
952
 
953
- $this->groups[$slug] = $group;
 
 
 
 
 
 
954
 
955
  return $slug;
956
  }
957
 
 
 
 
958
  public function add_section($group_slug, $slug, $name, $help_text='') {
959
- $section = new StdClass();
960
- $section->name = esc_attr( $name );
961
- $section->slug = $slug;
962
- $section->help_text = $help_text;
963
- $section->settings = array();
 
964
 
965
- $this->groups[$group_slug]->sections[$slug] = $section;
966
 
967
- return "$group_slug:$slug";
968
  }
969
 
 
 
 
970
  public function add_core_setting( $name, $default=null ) {
971
- $setting = new StdClass();
972
- $setting->name = $name;
973
- $setting->label = '';
974
- $setting->help_text = '';
975
- $setting->default = $default;
976
- $setting->type = 'core';
977
- $setting->args = array();
978
- $setting->validator = '';
979
-
980
- if ( !isset( $this->settings[ $name ] ) ) {
981
- $this->settings[ $name ] = $setting;
982
- }
983
-
984
- return true;
985
  }
986
 
987
- public function add_setting( $section_key, $name, $label, $type = 'text', $default = null, $help_text = '', $args = array(),
988
- $validator = null, $callback = null ) {
989
-
990
- if ( $type == 'core' )
991
- return $this->add_core_setting( $name, $default );
992
-
993
- list($group, $section) = explode(':', $section_key);
994
- $args = !$args ? array() : $args;
995
-
996
- if (!$group || !$section)
997
- return false;
998
-
999
- if ( isset($this->groups[$group]) && isset($this->groups[$group]->sections[$section]) ) {
1000
- $_default = $default;
1001
- if (is_null($_default)) {
1002
- switch ($type) {
1003
- case 'text':
1004
- case 'choice':
1005
- $_default = '';
1006
- break;
1007
- case 'boolean':
1008
- $_default = false;
1009
- break;
1010
- default:
1011
- $_default = null;
1012
- break;
1013
- }
1014
- }
1015
-
1016
- $setting = new StdClass();
1017
- $setting->name = esc_attr( $name );
1018
- $setting->label = $label;
1019
- $setting->help_text = $help_text;
1020
- $setting->default = $_default;
1021
- $setting->type = $type;
1022
- $setting->args = $args;
1023
- $setting->validator = $validator;
1024
- $setting->callback = $callback;
1025
-
1026
- $setup_cb = '_setting_' . $setting->type . '_setup';
1027
- if ( is_callable( array( $this, $setup_cb ) ) ) {
1028
- call_user_func_array( array( $this, $setup_cb ), array( &$setting ) );
1029
- }
1030
-
1031
- $this->groups[$group]->sections[$section]->settings[$name] = $setting;
1032
- }
 
1033
 
1034
- if (!isset($this->settings[$name])) {
1035
- $this->settings[$name] = $setting;
1036
- }
1037
 
1038
- return $name;
1039
  }
1040
 
 
 
 
1041
  public function register_dep( $setting, $dep, $arg = null ) {
 
 
 
1042
  if ( ! isset( $this->deps[ $setting ] ) )
1043
  $this->deps[ $setting ] = array();
1044
 
@@ -1069,57 +425,13 @@ EOF;
1069
  return $res;
1070
  }
1071
 
1072
- function get_setting( $name ) {
1073
  if ( isset( $this->settings[ $name ] ) )
1074
  return $this->settings[ $name ];
1075
 
1076
  return false;
1077
  }
1078
 
1079
- public function get($name, $ifempty=null) {
1080
- $value = get_option(self::PREFIX . $name, null);
1081
-
1082
- if (is_null($value)) {
1083
- $default_value = isset($this->settings[$name]) ? $this->settings[$name]->default : null;
1084
-
1085
- if (is_null($default_value))
1086
- return $ifempty;
1087
-
1088
- return $default_value;
1089
- }
1090
-
1091
- if (!is_null($ifempty) && empty($value))
1092
- $value = $ifempty;
1093
-
1094
- if ( ! isset( $this->settings[ $name ] ) )
1095
- return false;
1096
-
1097
- if ($this->settings[$name]->type == 'boolean') {
1098
- return (boolean) intval($value);
1099
- } elseif ( 'choice' == $this->settings[$name]->type && isset( $this->settings[$name]->args['multiple'] ) && $this->settings[$name]->args['multiple'] ) {
1100
- if ( ! $value )
1101
- return array();
1102
- }
1103
-
1104
- return $value;
1105
- }
1106
-
1107
- public function set($name, $value, $onlyknown=true) {
1108
- $name = strtolower($name);
1109
-
1110
- if ($onlyknown && !isset($this->settings[$name]))
1111
- return false;
1112
-
1113
- if (isset($this->settings[$name]) && $this->settings[$name]->type == 'boolean') {
1114
- $value = (boolean) intval($value);
1115
- }
1116
-
1117
- // wpbdp_debug("Setting $name = $value");
1118
- update_option(self::PREFIX . $name, $value);
1119
-
1120
- return true;
1121
- }
1122
-
1123
  /* emulates get_wpbusdirman_config_options() in version 2.0 until
1124
  * all deprecated code has been ported. */
1125
  public function pre_2_0_compat_get_config_options() {
@@ -1141,426 +453,110 @@ EOF;
1141
  return $legacy_options;
1142
  }
1143
 
1144
-
1145
-
1146
- public function reset_defaults() {
1147
- foreach ($this->settings as $setting) {
1148
- if ( preg_match( '/^license-key-/', $setting->name ) ) {
1149
- continue;
1150
- }
1151
-
1152
- delete_option(self::PREFIX . $setting->name);
1153
- }
1154
- }
1155
-
1156
- /*
1157
- * admin
1158
  */
1159
- public function after_render( $html, $setting, $args = array() ) {
1160
- $html = '<a name="' . $setting->name . '"></a>' . $html;
1161
- return $html;
1162
- }
1163
-
1164
- public function _setting_custom($args) {
1165
- $setting = $args['setting'];
1166
- $value = $this->get( $setting->name );
1167
-
1168
- $html = '';
1169
-
1170
- ob_start();
1171
- call_user_func( $setting->callback, $setting, $value );
1172
- $custom_content = ob_get_contents();
1173
- ob_end_clean();
1174
-
1175
- $html .= $custom_content;
1176
-
1177
- echo apply_filters( 'wpbdp_settings_render', $html, $setting, $args );
1178
- }
1179
-
1180
- public function _setting_text($args) {
1181
- $setting = $args['setting'];
1182
- $value = $this->get($setting->name);
1183
-
1184
- if (isset($args['use_textarea']) || strlen($value) > 100) {
1185
- $html = '<textarea id="' . $setting->name . '" name="' . self::PREFIX . $setting->name . '" rows="' . ( isset( $args['textarea_rows'] ) ? $args['textarea_rows'] : 4 ) . '">';
1186
- $html .= esc_textarea($value);
1187
- $html .= '</textarea><br />';
1188
- } else {
1189
- $html = '<input type="text" id="' . $setting->name . '" name="' . self::PREFIX . $setting->name . '" value="' . esc_attr( $value ) . '" size="' . (strlen($value) > 0 ? strlen($value) : 20). '" />';
1190
- }
1191
-
1192
- $html .= '<span class="description">' . $setting->help_text . '</span>';
1193
-
1194
- echo apply_filters( 'wpbdp_settings_render', $html, $setting, $args );
1195
- }
1196
-
1197
- public function _setting_license_key($args) {
1198
- $setting = $args['setting'];
1199
- $value = trim( $this->get( $setting->name ) );
1200
-
1201
- $module_id = str_replace( 'license-key-', '', $setting->name );
1202
- $license_status = get_option( 'wpbdp-license-status-' . $module_id, false );
1203
-
1204
- $html = '';
1205
- $html .= '<input type="text"
1206
- id="' . $setting->name . '"
1207
- name="' . self::PREFIX . $setting->name . '"
1208
- value="' . esc_attr( $value ) . '"
1209
- size="25"
1210
- ' . ( 'valid' == $license_status ? 'readonly="readonly"' : '' ) . '/>';
1211
-
1212
- $html .= '<span class="license-activation" data-module-id="' . esc_attr( $module_id ) . '">';
1213
- $html .= wp_nonce_field( 'license activation', 'nonce', false, false );
1214
- $html .= '<input type="button"
1215
- value="' . _x( 'Deactivate License', 'settings', 'WPBDM' ) . '"
1216
- class="button license-deactivate"
1217
- data-L10n="' . esc_attr( _x( 'Deactivating license...', 'settings', 'WPBDM' ) ) . '"
1218
- style="' . ( 'valid' == $license_status ? '' : 'display: none;' ) . '" />';
1219
- $html .= '<input type="button"
1220
- value="' . _x( 'Activate License', 'settings', 'WPBDM' ) . '"
1221
- class="button license-activate"
1222
- data-L10n="' . esc_attr( _x( 'Activating license...', 'settings', 'WPBDM' ) ) . '"
1223
- style="' . ( 'valid' == $license_status ? 'display: none;' : '' ) . '" />';
1224
- $html .= '<br />';
1225
- $html .= '<div class="status-message"></div>';
1226
- $html .= '</span>';
1227
-
1228
- echo apply_filters( 'wpbdp_settings_render', $html, $setting, $args );
1229
- }
1230
-
1231
- public function _setting_text_template( $args ) {
1232
- $setting = $args['setting'];
1233
- $help_text_original = $setting->help_text;
1234
-
1235
- $placeholders = isset( $args['placeholders'] ) ? $args['placeholders'] : array();
1236
-
1237
- if ( $placeholders ) {
1238
- $placeholders_text = '';
1239
 
1240
- foreach ( $placeholders as $pholder => $desc ) {
1241
- $placeholders_text .= sprintf( '%s - %s, ', '[' . $pholder . ']', $desc );
 
1242
  }
1243
- $placeholders_text = substr( $placeholders_text, 0, -2 ) . '.';
1244
 
1245
- $setting->help_text = ( $help_text_original ? $help_text_original . '<br />' : '' ) . sprintf( _x( 'Valid placeholders: %s', 'admin settings', 'WPBDM' ),
1246
- $placeholders_text );
1247
  }
1248
 
1249
- $args['use_textarea'] = true;
1250
-
1251
- // TODO: this is a proxy for _setting_text (for now).
1252
- ob_start();
1253
- $this->_setting_text( $args );
1254
- $html = ob_get_contents();
1255
- ob_end_clean();
1256
-
1257
- $setting->help_text = $help_text_original;
1258
-
1259
- echo $html;
1260
  }
1261
 
1262
- function _setting_email_template( $args ) {
1263
- $setting = $args['setting'];
1264
- $value = $this->get( $setting->name );
1265
 
1266
- if ( ! is_array( $value ) ) {
1267
- $body = $value;
1268
-
1269
- $value = array();
1270
- $value['subject'] = $setting->default['subject'];
1271
- $value['body'] = $body;
1272
- }
1273
-
1274
- $html = '';
1275
- $html .= '<span class="description">' . $setting->help_text . '</span>';
1276
- $html .= sprintf( '<div class="wpbdp-settings-email" data-setting="%s">',
1277
- $setting->name );
1278
-
1279
- $html .= '<div class="short-preview" title="' . _x( 'Click to edit e-mail', 'settings email', 'WPBDM' ) . '">';
1280
- $html .= '<span class="edit-toggle tag">' . _x( 'Click to edit', 'settings email', 'WPBDM' ) . '</span>';
1281
- $html .= '<h4>';
1282
- $html .= $value['subject'];
1283
- $html .= '</h4>';
1284
- $html .= $value['body'];
1285
- $html .= '...';
1286
- $html .= '</div>';
1287
-
1288
- $html .= sprintf( '<div class="editor" style="display: none;" data-preview-nonce="%s">', wp_create_nonce( 'preview email ' . $setting->name ) );
1289
- $html .= '<table class="form-table"><tbody>';
1290
- $html .= '<tr>';
1291
- $html .= sprintf( '<th scope="row"><label for="%s-subject">%s</label</th>',
1292
- $setting->name,
1293
- _x( 'E-Mail Subject', 'settings email', 'WPBDM' ) );
1294
- $html .= '<td>';
1295
- $html .= sprintf( '<input type="text" name="%s" value="%s" id="%s" class="subject-text">',
1296
- self::PREFIX . $setting->name . '[subject]',
1297
- esc_attr( $value['subject'] ),
1298
- $setting->name . '-subject' );
1299
- $html .= '</td>';
1300
- $html .= '</tr>';
1301
- $html .= '<tr>';
1302
- $html .= sprintf( '<th scope="row"><label for="%s-body">%s</label</th>',
1303
- $setting->name,
1304
- _x( 'E-Mail Body', 'settings email', 'WPBDM' ) );
1305
- $html .= '<td>';
1306
- $html .= sprintf( '<textarea id="%s" name="%s" class="body-text">%s</textarea>',
1307
- $setting->name . '-body',
1308
- self::PREFIX . $setting->name . '[body]',
1309
- esc_textarea( $value['body'] ) );
1310
-
1311
- $placeholders = isset( $args['placeholders'] ) ? $args['placeholders'] : array();
1312
-
1313
- if ( $placeholders ) {
1314
- $html .= '<div class="placeholders">';
1315
- $html .= _x( 'You can use the following placeholders:', 'settings email', 'WPBDM' );
1316
- $html .= '<br /><br />';
1317
-
1318
- $added_sep = false;
1319
-
1320
- foreach ( $placeholders as $placeholder => $placeholder_data ) {
1321
- $description = is_array( $placeholder_data ) ? $placeholder_data[0] : $placeholder_data;
1322
- $is_core_placeholder = is_array( $placeholder_data ) && isset( $placeholder_data[2] ) && $placeholder_data[2];
1323
-
1324
- if ( $is_core_placeholder && ! $added_sep ) {
1325
- $html .= '<div class="placeholder-separator"></div>';
1326
- $added_sep = true;
1327
- }
1328
-
1329
- $html .= sprintf( '<div class="placeholder" data-placeholder="%s"><span class="placeholder-code">[%s]</span> - <span class="placeholder-description">%s</span></div>',
1330
- esc_attr( $placeholder ),
1331
- $placeholder,
1332
- $description );
1333
  }
1334
- $html .= '</div>';
1335
- }
1336
-
1337
- $html .= '<div class="buttons">';
1338
- $html .= '<a href="#" class="button preview-email">' . _x( 'Preview e-mail', 'settings email', 'WPBDM' ) . '</a> ';
1339
- $html .= '<a href="#" class="button cancel">' . _x( 'Cancel', 'settings email', 'WPBDM' ) . '</a> ';
1340
- $html .= '<a href="#" class="button button-primary save">' . _x( 'Save Changes', 'settings email', 'WPBDM' ) . '</a> ';
1341
- $html .= '</div>';
1342
-
1343
- $html .= '</td>';
1344
- $html .= '</tr>';
1345
- $html .= '</tbody></table>';
1346
- $html .= '</div>';
1347
-
1348
- $html .= '</div>';
1349
-
1350
- echo apply_filters( 'wpbdp_settings_render', $html, $setting, $args );
1351
- }
1352
-
1353
- function _setting_email_template_setup( &$setting ) {
1354
- if ( ! isset( $setting->args['placeholders'] ) || ! is_array( $setting->args['placeholders'] ) )
1355
- $setting->args['placeholders'] = array();
1356
-
1357
- // Add default placeholders.
1358
- $setting->args['placeholders'] = array_merge( $setting->args['placeholders'], array(
1359
- 'site-title' => array( _x( 'Site title', 'settings email', 'WPBDM' ),
1360
- get_bloginfo( 'name' ),
1361
- 'core' ),
1362
- 'site-link' => array( _x( 'Site title (with link)', 'settings email', 'WPBDM' ),
1363
- sprintf( '<a href="%s">%s</a>', get_bloginfo( 'url' ), get_bloginfo( 'name' ) ),
1364
- 'core' ),
1365
- 'site-url' => array( _x( 'Site address (with link)', 'settings email', 'WPBDM' ),
1366
- sprintf( '<a href="%s">%s</a>', get_bloginfo( 'url' ), get_bloginfo( 'url' ) ),
1367
- 'core' ),
1368
- 'directory-url' => array( _x( 'Directory URL (with link)', 'settings email', 'WPBDM' ),
1369
- sprintf( '<a href="%1$s">%1$s</a>', wpbdp_get_page_link( 'main' ) ),
1370
- 'core' ),
1371
- 'today' => array( _x( 'Current date', 'settings email', 'WPBDM' ),
1372
- date_i18n( get_option( 'date_format' ) ),
1373
- 'core' ),
1374
- 'now' => array( _x( 'Current time', 'settings email', 'WPBDM' ),
1375
- date_i18n( get_option( 'time_format' ) ),
1376
- 'core' )
1377
- ) );
1378
- }
1379
-
1380
- function _ajax_email_preview() {
1381
- $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
1382
- $setting = $this->get_setting( isset( $_POST['setting'] ) ? $_POST['setting'] : '' );
1383
-
1384
- if ( ! $setting || 'email_template' != $setting->type || ! wp_verify_nonce( $nonce, 'preview email ' . $setting->name ) )
1385
- die();
1386
-
1387
- $placeholders = isset( $setting->args['placeholders'] ) ? $setting->args['placeholders'] : array();
1388
-
1389
- $subject = stripslashes( isset( $_POST['subject'] ) ? trim( $_POST['subject'] ) : '' );
1390
- $body = stripslashes( isset( $_POST['body'] ) ? trim( $_POST['body'] ) : '' );
1391
-
1392
- $res = new WPBDP_Ajax_Response();
1393
-
1394
- foreach ( $placeholders as $pholder => $pdata ) {
1395
- $repl = ( is_array( $pdata ) && count( $pdata ) >= 2 && $pdata[1] ) ? $pdata[1] : '[' . $pholder . ']';
1396
-
1397
- $subject = str_replace( '[' . $pholder . ']', $repl, $subject );
1398
- $body = str_replace( '[' . $pholder . ']', $repl, $body );
1399
- }
1400
-
1401
- $html = '';
1402
- $html .= '<div class="wpbdp-settings-email-preview">';
1403
- $html .= '<h4>' . $subject . '</h4>';
1404
- $html .= nl2br( $body );
1405
- $html .= '</div>';
1406
-
1407
- $res->add( 'subject', $subject );
1408
- $res->add( 'body', $body );
1409
- $res->add( 'html', $html );
1410
- $res->send();
1411
- }
1412
-
1413
- public function _setting_boolean($args) {
1414
- $setting = $args['setting'];
1415
-
1416
- $value = (boolean) $this->get($setting->name);
1417
-
1418
- $html = '<label for="' . $setting->name . '">';
1419
- $html .= '<input type="checkbox" id="' .$setting->name . '" name="' . self::PREFIX . $setting->name . '" value="1" '
1420
- . ($value ? 'checked="checked"' : '') . '/>';
1421
- $html .= '&nbsp;<span class="description">' . $setting->help_text . '</span>';
1422
- $html .= '</label>';
1423
-
1424
- echo apply_filters( 'wpbdp_settings_render', $html, $setting, $args );
1425
- }
1426
-
1427
- public function _setting_choice($args) {
1428
- $setting = $args['setting'];
1429
- $choices = is_callable( $args['choices'] ) ? call_user_func( $args['choices'] ) : $args['choices'];
1430
-
1431
- $value = $this->get($setting->name);
1432
-
1433
- $multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
1434
-
1435
- if ( isset( $args['widget'] ) ) {
1436
- $widget = $args['widget'];
1437
- } elseif ( $multiple ) {
1438
- $widget = 'multiselect';
1439
  } else {
1440
- $widget = 'select';
 
1441
  }
1442
 
1443
- if ( 'multiselect' == $widget )
1444
- $multiple = true;
1445
-
1446
- $html = '';
1447
-
1448
- if ( $widget == 'select' || $widget == 'multiselect' ) {
1449
- $html .= '<select id="' . $setting->name . '" name="' . self::PREFIX . $setting->name . ( $multiple ? '[]' : '' ) . '" ' . ( $multiple ? 'multiple="multiple"' : '' ) . '>';
1450
-
1451
- $value = is_array( $value ) ? $value : array( $value );
1452
-
1453
- foreach ($choices as $ch) {
1454
- $opt_label = is_array($ch) ? $ch[1] : $ch;
1455
- $opt_value = is_array($ch) ? $ch[0] : $ch;
1456
- $opt_class = ( is_array( $ch ) && isset( $ch[2] ) ) ? $ch[2] : '';
1457
-
1458
- $html .= '<option value="' . $opt_value . '"' . ( $value && in_array( $opt_value, $value ) ? ' selected="selected"' : '') . ' class="' . $opt_class . '">'
1459
- . $opt_label . '</option>';
1460
- }
1461
-
1462
- $html .= '</select>';
1463
- } elseif ( $widget == 'checkbox' || $widget == 'radio' ) {
1464
- $value = (array) $value;
1465
-
1466
- if ( $widget == 'radio' ) {
1467
- $name = self::PREFIX . $setting->name;
1468
- } else {
1469
- $name = self::PREFIX . $setting->name . '[]';
1470
- }
1471
-
1472
- $html .= '<ul id="' . $setting->name . '" class="wpbdp-choices-list">';
1473
-
1474
- foreach ( $choices as $k => $v ) {
1475
- if ( is_array( $v ) ) {
1476
- $choice_label = $v[0];
1477
- $choice_class = $v[1];
1478
- } else {
1479
- $choice_label = $v;
1480
- $choice_class = null;
1481
  }
1482
 
1483
- $html .= sprintf( '<li class="%s"><label><input type="%s" name="%s" value="%s" %s />%s</label></li>',
1484
- $choice_class ? $choice_class : '',
1485
- $widget,
1486
- $name,
1487
- $k,
1488
- ( $value && in_array( $k, $value ) ) ? 'checked="checked"' : '',
1489
- $choice_label
1490
- );
1491
- }
1492
-
1493
- $html .= '</ul>';
1494
- }
1495
-
1496
- if ( $setting->help_text ) {
1497
- $html .= '<span class="description">' . $setting->help_text . '</span>';
1498
- }
1499
 
1500
- echo apply_filters( 'wpbdp_settings_render', $html, $setting, $args );
1501
- }
 
 
1502
 
1503
- public function register_in_admin() {
1504
- foreach ($this->groups as $group) {
1505
- foreach ($group->sections as $section) {
1506
- $callback = create_function( '', 'WPBDP_Settings::_section_cb("' . $group->slug . '", "' . $section->slug . '");' );
1507
- add_settings_section($section->slug, $section->name, $callback, $group->wpslug);
1508
-
1509
- foreach ($section->settings as $setting) {
1510
- register_setting($group->wpslug, self::PREFIX . $setting->name/*, array( &$this, 'filter_x' ) */);
1511
- add_settings_field(self::PREFIX . $setting->name, $setting->label,
1512
- array($this, '_setting_' . $setting->type),
1513
- $group->wpslug,
1514
- $section->slug,
1515
- array_merge($setting->args, array('label_for' => $setting->name, 'setting' => $setting))
1516
- );
1517
-
1518
- if ( $setting->validator || ( $setting->type == 'choice' && isset( $setting->args['multiple'] ) && $setting->args['multiple'] ) ) {
1519
- add_filter('pre_update_option_' . self::PREFIX . $setting->name, create_function('$n, $o=null', 'return WPBDP_Settings::_validate_setting("' . $setting->name . '", $n, $o);'), 10, 2);
1520
  }
 
1521
 
1522
- add_action( 'update_option_' . self::PREFIX . $setting->name, array( $this, '_option_updated' ), 10, 3 );
 
 
 
 
 
 
 
 
1523
  }
 
 
1524
  }
1525
  }
1526
- }
1527
 
1528
- public static function _section_cb( $g, $s ) {
1529
- $api = wpbdp_settings_api();
1530
-
1531
- $group = $api->groups[ $g ];
1532
- $section = $group->sections[ $s ];
1533
-
1534
- echo '<a name="' . $section->slug . '"></a>';
1535
-
1536
- if ( $section->help_text ) {
1537
- echo '<p class="description">';
1538
- echo stripslashes( $section->help_text );
1539
- echo '</p>';
1540
- }
1541
  }
1542
 
1543
- public static function _validate_setting($name, $newvalue=null, $oldvalue=null) {
1544
- $api = wpbdp_settings_api();
1545
- $setting = $api->settings[$name];
1546
 
1547
- if ( $setting->type == 'choice' && isset( $setting->args['multiple'] ) && $setting->args['multiple'] ) {
1548
- if ( isset( $_POST[ self::PREFIX . $name ] ) ) {
1549
- $newvalue = $_POST[ self::PREFIX . $name ];
1550
- $newvalue = is_array( $newvalue ) ? $newvalue : array( $newvalue );
1551
-
1552
- if ( $setting->validator )
1553
- $newvalue = call_user_func( $setting->validator, $setting, $newvalue, $api->get( $setting->name ) );
1554
- }
1555
 
1556
- return $newvalue;
 
 
 
1557
  }
1558
 
1559
- return call_user_func($setting->validator, $setting, $newvalue, $api->get($setting->name));
1560
- }
 
1561
 
1562
- public function _option_updated( $old_value, $new_value, $option_name ) {
1563
- do_action( 'wpbdp_option_updated_' . str_replace( self::PREFIX, '', $option_name ), $old_value, $new_value );
1564
  }
1565
 
1566
  /* upgrade from old-style settings to new options */
@@ -1670,3 +666,6 @@ EOF;
1670
 
1671
  }
1672
 
 
 
 
1
  <?php
2
+
3
+ class WPBDP__Settings {
4
 
5
  const PREFIX = 'wpbdp-';
6
 
7
+ private $groups = array();
8
+ private $settings = array();
9
+ private $options = array();
 
10
 
11
  private $deps = array();
12
 
13
 
14
  public function __construct() {
15
+ // Make sure our option exists.
16
+ if ( false === ( $settings_opt = get_option( 'wpbdp_settings' ) ) ) {
17
+ add_option( 'wpbdp_settings', array() );
18
+ }
19
 
20
+ // register_setting is not available on init in WordPress 4.3
21
+ if ( ! function_exists( 'register_setting' ) && file_exists( ABSPATH . 'wp-admin/includes/plugin.php' ) ) {
22
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
23
+ }
24
 
25
+ register_setting( 'wpbdp_settings', 'wpbdp_settings', array( $this, 'sanitize_settings' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ // Cache current values.
28
+ $this->options = is_array( $settings_opt ) ? $settings_opt : array();
29
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ public function bootstrap() {
32
+ // Add initial settings.
33
+ require_once( WPBDP_INC . 'admin/settings/class-settings-bootstrap.php' );
34
+ WPBDP__Settings__Bootstrap::register_initial_groups();
35
+ WPBDP__Settings__Bootstrap::register_initial_settings();
36
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ public function sanitize_settings( $input ) {
39
+ $on_admin = ! empty( $_POST['_wp_http_referer'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ $output = array_merge( $this->options, $input );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ // Validate each setting.
44
+ foreach ( $input as $setting_id => $value ) {
45
+ $output[ $setting_id ] = apply_filters( 'wpbdp_settings_sanitize', $value, $setting_id );
46
+ $output[ $setting_id ] = apply_filters( 'wpbdp_settings_sanitize_' . $setting_id, $input[ $setting_id ], $setting_id );
47
 
48
+ if ( ! empty( $this->settings[ $setting_id ] ) ) {
49
+ $setting = $this->settings[ $setting_id ];
50
 
51
+ // XXX: maybe this should always be executed, not only admin side?
52
+ if ( $on_admin ) {
53
+ switch ( $setting['type'] ) {
54
+ case 'checkbox':
55
+ case 'multicheck':
56
+ if ( '-1' === $value ) {
57
+ $input[ $setting_id ] = ( 'multicheck' == $setting['type'] ? array() : 0 );
58
+ $output[ $setting_id ] = ( 'multicheck' == $setting['type'] ? array() : 0 );
59
+ // unset( $this->options[ $setting_id ] );
60
+ }
61
 
62
+ break;
63
+ default:
64
+ break;
65
+ }
66
+ }
 
 
 
 
 
 
 
 
 
 
67
 
68
+ if ( ! empty( $setting['on_update'] ) && is_callable( $setting['on_update'] ) ) {
69
+ call_user_func( $setting['on_update'], $setting, $input[ $setting_id ], ! empty( $this->options[ $setting_id ] ) ? $this->options[ $setting_id ] : null );
70
+ }
71
+ }
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ do_action( 'wpbdp_setting_updated', $setting_id, $output[ $setting_id ], $value );
74
+ do_action( "wpbdp_setting_updated_{$setting_id}", $output[ $setting_id ], $value, $setting_id );
75
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
+ $this->options = $output;
78
+
79
+ return $this->options;
80
+
81
+ // function edd_settings_sanitize( $input = array() ) {
82
+ // global $edd_options;
83
+ // $doing_section = false;
84
+ // if ( ! empty( $_POST['_wp_http_referer'] ) ) {
85
+ // $doing_section = true;
86
+ // }
87
+ // $setting_types = edd_get_registered_settings_types();
88
+ // $input = $input ? $input : array();
89
+ // if ( $doing_section ) {
90
+ // parse_str( $_POST['_wp_http_referer'], $referrer ); // Pull out the tab and section
91
+ // $tab = isset( $referrer['tab'] ) ? $referrer['tab'] : 'general';
92
+ // $section = isset( $referrer['section'] ) ? $referrer['section'] : 'main';
93
+ // if ( ! empty( $_POST['edd_section_override'] ) ) {
94
+ // $section = sanitize_text_field( $_POST['edd_section_override'] );
95
+ // }
96
+ // $setting_types = edd_get_registered_settings_types( $tab, $section );
97
+ // // Run a general sanitization for the tab for special fields (like taxes)
98
+ // $input = apply_filters( 'edd_settings_' . $tab . '_sanitize', $input );
99
+ // // Run a general sanitization for the section so custom tabs with sub-sections can save special data
100
+ // $input = apply_filters( 'edd_settings_' . $tab . '-' . $section . '_sanitize', $input );
101
+ // }
102
+ // // Merge our new settings with the existing
103
+ // $output = array_merge( $edd_options, $input );
104
+ // foreach ( $setting_types as $key => $type ) {
105
+ // if ( empty( $type ) ) {
106
+ // continue;
107
+ // }
108
+ // // Some setting types are not actually settings, just keep moving along here
109
+ // $non_setting_types = apply_filters( 'edd_non_setting_types', array(
110
+ // 'header', 'descriptive_text', 'hook',
111
+ // ) );
112
+ // if ( in_array( $type, $non_setting_types ) ) {
113
+ // continue;
114
+ // }
115
+ // if ( array_key_exists( $key, $output ) ) {
116
+ // $output[ $key ] = apply_filters( 'edd_settings_sanitize_' . $type, $output[ $key ], $key );
117
+ // $output[ $key ] = apply_filters( 'edd_settings_sanitize', $output[ $key ], $key );
118
+ // }
119
+ // if ( $doing_section ) {
120
+ // switch( $type ) {
121
+ // case 'checkbox':
122
+ // case 'gateways':
123
+ // case 'multicheck':
124
+ // case 'payment_icons':
125
+ // if ( array_key_exists( $key, $input ) && $output[ $key ] === '-1' ) {
126
+ // unset( $output[ $key ] );
127
+ // }
128
+ // break;
129
+ // default:
130
+ // if ( array_key_exists( $key, $input ) && empty( $input[ $key ] ) || ( array_key_exists( $key, $output ) && ! array_key_exists( $key, $input ) ) ) {
131
+ // unset( $output[ $key ] );
132
+ // }
133
+ // break;
134
+ // }
135
+ // } else {
136
+ // if ( empty( $input[ $key ] ) ) {
137
+ // unset( $output[ $key ] );
138
+ // }
139
+ // }
140
+ // }
141
+ // if ( $doing_section ) {
142
+ // add_settings_error( 'edd-notices', '', __( 'Settings updated.', 'easy-digital-downloads' ), 'updated' );
143
+ // }
144
+ // return $output;
145
+ // }
146
+ }
147
 
148
+ /**
149
+ * Register a setings group within the Settings API.
150
+ * @since 5.0
151
+ */
152
+ public function register_group( $slug, $title = '', $parent = '', $args = array() ) {
153
+ if ( $parent && ! isset( $this->groups[ $parent ] ) ) {
154
+ // throw new Exception( sprintf( 'Parent settings group does not exist: %s', $parent ) );
155
+ return false;
156
+ }
157
 
158
+ $parents = array();
159
+ $parent_ = $parent;
 
 
 
 
 
 
 
160
 
161
+ while( $parent_ ) {
162
+ $parents[] = $parent_;
163
+ $parent_ = $this->groups[ $parent_ ]['parent'];
164
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
+ switch ( count( $parents ) ) {
167
+ case 0:
168
+ $group_type = 'tab';
169
+ break;
170
+ case 1:
171
+ $group_type = 'subtab';
172
+ break;
173
+ case 2:
174
+ $group_type = 'section';
175
+ break;
176
+ default:
177
+ // throw new Exception( sprintf( 'Invalid # of parents in the tree for settings group "%s"', $slug ) );
178
+ return false;
179
+ break;
180
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
+ if ( $parent ) {
183
+ $this->groups[ $parent ]['count'] += 1;
184
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
+ $this->groups[ $slug ] = array_merge(
187
+ $args,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  array(
189
+ 'title' => $title,
190
+ 'desc' => ! empty( $args['desc'] ) ? $args['desc'] : '',
191
+ 'type' => $group_type,
192
+ 'parent' => $parent,
193
+ 'count' => 0
194
  )
195
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
197
 
198
+ /**
199
+ * Register a setting within the Settings API.
200
+ * @since 5.0
201
+ */
202
+ public function register_setting( $id_or_args, $name = '', $type = 'text', $group = '', $args = array() ) {
203
+ if ( is_array( $id_or_args ) ) {
204
+ $args = $id_or_args;
205
+ } else {
206
+ $args = array_merge(
207
+ $args,
208
+ array(
209
+ 'id' => $id_or_args,
210
+ 'name' => $name,
211
+ 'type' => $type,
212
+ 'group' => $group
213
+ )
214
+ );
215
+ }
216
 
217
+ $args = wp_parse_args( $args, array(
218
+ 'id' => '',
219
+ 'name' => '',
220
+ 'type' => 'text',
221
+ 'group' => 'general/main',
222
+ 'desc' => '',
223
+ 'validator' => false,
224
+ 'default' => false,
225
+ 'on_update' => false,
226
+ 'dependencies' => array()
227
+ ) );
228
 
229
+ if ( isset( $this->settings[ $args['id' ] ] ) ) {
230
+ return false;
231
  }
232
 
233
+ if ( 'silent' != $args['type'] && ! isset( $this->groups[ $args['group'] ] ) ) {
234
+ // throw new Exception( sprintf( 'Invalid settings group "%s" for setting "%s".', $args['group'], $args['id'] ) );
235
+ return false;
236
+ }
237
 
238
+ if ( 'number' == $args['type'] ) {
239
+ add_filter( 'wpbdp_settings_sanitize_' . $args['id'], array( $this, 'validate_number_setting' ), 10, 2 );
240
+ }
241
 
242
+ $this->settings[ $args['id' ] ] = $args;
 
 
 
243
 
244
+ if ( 'silent' != $args['type'] ) {
245
+ $this->groups[ $args['group'] ]['count'] += 1;
246
  }
247
 
248
+ if ( ! empty( $args['validator'] ) ) {
249
+ add_filter( 'wpbdp_settings_sanitize_' . $args['id'], array( $this, 'validate_setting' ), 10, 2 );
250
+ }
 
 
 
251
  }
252
 
253
+ public function get_registered_groups() {
254
+ return $this->groups;
255
  }
256
 
257
+ public function get_registered_settings() {
258
+ return $this->settings;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  }
260
 
261
+ public function get_option( $setting_id, $default = false ) {
262
+ $default_provided = func_num_args() > 1;
263
+
264
+ if ( array_key_exists( $setting_id, $this->options ) ) {
265
+ $value = $this->options[ $setting_id ];
266
+ } else {
267
+ // Try old options.
268
+ $old_value = get_option( 'wpbdp-' . $setting_id, null );
269
 
270
+ if ( ! is_null( $old_value ) ) {
271
+ $value = $old_value;
272
+ $this->options[ $setting_id ] = $old_value;
273
+ update_option( 'wpbdp_settings', $this->options );
274
 
275
+ // delete_option( 'wpbdp-' . $setting_id );
276
+ } else {
277
+ if ( $default_provided ) {
278
+ $value = $default;
279
+ } else {
280
+ if ( ! empty( $this->settings[ $setting_id ] ) ) {
281
+ $value = $this->settings[ $setting_id ]['default'];
282
+ } else {
283
+ $value = false;
284
+ }
285
+ }
286
  }
287
  }
288
 
289
+ $value = apply_filters( 'wpbdp_get_option', $value, $setting_id );
290
+ $value = apply_filters( 'wpbdp_get_option_' . $setting_id, $value );
 
 
 
 
 
 
 
 
 
291
 
292
+ return $value;
293
  }
294
 
295
+ public function set_option( $setting_id, $value = null ) {
296
+ $old = get_option( 'wpbdp_settings' );
297
+ $old[ $setting_id ] = $value;
298
+ update_option( 'wpbdp_settings', $old );
 
 
 
 
 
 
 
 
299
  }
300
 
 
 
 
 
 
 
 
301
 
302
+ /**
303
+ * @deprecated 5.0. Use {@link WPBDP__Settings::register_group()}.
304
+ */
305
+ public function add_group( $slug, $name, $help_text = '' ) {
306
+ if ( ! isset( $this->groups[ $slug ] ) ) {
307
+ $this->register_group( $slug, $name, '', array( 'desc' => $help_text ) );
308
+ }
309
 
310
  return $slug;
311
  }
312
 
313
+ /**
314
+ * @deprecated 5.0. Use {@link WPBDP__Settings::register_group()}.
315
+ */
316
  public function add_section($group_slug, $slug, $name, $help_text='') {
317
+ $tab = $group_slug;
318
+ $subtab = $group_slug . '/main';
319
+
320
+ if ( ! isset( $this->groups[ $subtab ] ) ) {
321
+ $this->register_group( $subtab, _x( 'General Settings', 'settings', 'WPBDM' ), $tab );
322
+ }
323
 
324
+ $this->register_group( "{$subtab}:{$slug}", $name, $subtab, array( 'desc' => $help_text ) );
325
 
326
+ return "{$subtab}:{$slug}";
327
  }
328
 
329
+ /**
330
+ * @deprecated 5.0. Use {@link WPBDP__Settings::register_setting()}.
331
+ */
332
  public function add_core_setting( $name, $default=null ) {
333
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  }
335
 
336
+ /**
337
+ * @deprecated 5.0. Use {@link WPBDP__Settings::register_setting()}.
338
+ */
339
+ public function add_setting( $section_key, $name, $label, $type = 'text', $default = null, $help_text = '', $args = array(), $validator = null, $callback = null ) {
340
+ return;
341
+ wpbdp_debug_e( 'add setting called', func_get_args() );
342
+
343
+ // list($group, $section) = explode(':', $section_key);
344
+ // $args = !$args ? array() : $args;
345
+ //
346
+ // if (!$group || !$section)
347
+ // return false;
348
+ //
349
+ // if ( isset($this->groups[$group]) && isset($this->groups[$group]->sections[$section]) ) {
350
+ // $_default = $default;
351
+ // if (is_null($_default)) {
352
+ // switch ($type) {
353
+ // case 'text':
354
+ // case 'choice':
355
+ // $_default = '';
356
+ // break;
357
+ // case 'boolean':
358
+ // $_default = false;
359
+ // break;
360
+ // default:
361
+ // $_default = null;
362
+ // break;
363
+ // }
364
+ // }
365
+ //
366
+ // $setting = new StdClass();
367
+ // $setting->name = esc_attr( $name );
368
+ // $setting->label = $label;
369
+ // $setting->help_text = $help_text;
370
+ // $setting->default = $_default;
371
+ // $setting->type = $type;
372
+ // $setting->args = $args;
373
+ // $setting->validator = $validator;
374
+ // $setting->callback = $callback;
375
+ //
376
+ // $setup_cb = '_setting_' . $setting->type . '_setup';
377
+ // if ( is_callable( array( $this, $setup_cb ) ) ) {
378
+ // call_user_func_array( array( $this, $setup_cb ), array( &$setting ) );
379
+ // }
380
+ //
381
+ // $this->groups[$group]->sections[$section]->settings[$name] = $setting;
382
+ // }
383
 
384
+ // if (!isset($this->settings[$name])) {
385
+ // $this->settings[$name] = $setting;
386
+ // }
387
 
388
+ // return $name;
389
  }
390
 
391
+ /**
392
+ * @deprecated 5.0. Specify dependencies while registering the setting using {@link WPBDP__Settings::register_setting()}.
393
+ */
394
  public function register_dep( $setting, $dep, $arg = null ) {
395
+ return;
396
+ wpbdp_debug_e( 'register dep called' );
397
+
398
  if ( ! isset( $this->deps[ $setting ] ) )
399
  $this->deps[ $setting ] = array();
400
 
425
  return $res;
426
  }
427
 
428
+ public function get_setting( $name ) {
429
  if ( isset( $this->settings[ $name ] ) )
430
  return $this->settings[ $name ];
431
 
432
  return false;
433
  }
434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  /* emulates get_wpbusdirman_config_options() in version 2.0 until
436
  * all deprecated code has been ported. */
437
  public function pre_2_0_compat_get_config_options() {
453
  return $legacy_options;
454
  }
455
 
456
+ /**
457
+ * Resets settings to their default values. This includes ALL premium modules too, so use with care.
 
 
 
 
 
 
 
 
 
 
 
 
458
  */
459
+ public function reset_defaults() {
460
+ $options = $this->options;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
 
462
+ foreach ( $options as $option_id => $option_value ) {
463
+ if ( preg_match( '/^license-key-/', $option_id ) ) {
464
+ continue;
465
  }
 
466
 
467
+ unset( $this->options[ $option_id ] );
 
468
  }
469
 
470
+ update_option( 'wpbdp_settings', $this->options );
 
 
 
 
 
 
 
 
 
 
471
  }
472
 
473
+ public function validate_setting( $value, $setting_id ) {
474
+ if ( ! empty( $this->settings[ $setting_id ] ) ) {
475
+ $setting = $this->get_setting( $setting_id );
476
 
477
+ if ( is_string( $setting['validator'] ) ) {
478
+ $validators = explode( ',', $setting['validator'] );
479
+ } else if ( is_callable( $setting['validator'] ) ) {
480
+ $validators = array( $setting['validator'] );
481
+ } else if ( is_array( $setting['validator'] ) ) {
482
+ $validators = $setting['validator'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  } else {
485
+ $setting = null;
486
+ $validators = array();
487
  }
488
 
489
+ $old_value = $this->options[ $setting_id ];
490
+ $has_error = false;
491
+
492
+ foreach ( $validators as $validator ) {
493
+ switch ( $validator ) {
494
+ case 'trim':
495
+ $value = trim( $value );
496
+ break;
497
+ case 'no-spaces':
498
+ $value = trim( preg_replace( '/\s+/', '', $value ) );
499
+ break;
500
+ case 'required':
501
+ if ( empty( $value ) ) {
502
+ add_settings_error( 'wpbdp_settings', $setting_id, sprintf( _x( '"%s" can not be empty.', 'settings', 'WPBDM' ), $setting['name'] ), 'error' );
503
+ $has_error = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  }
505
 
506
+ break;
507
+ case 'taxonomy_slug':
508
+ $value = trim( sanitize_title( $value ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
509
 
510
+ if ( empty( $value ) ) {
511
+ add_settings_error( 'wpbdp_settings', $setting_id, sprintf( _x( '"%s" can not be empty.', 'settings', 'WPBDM' ), $setting['name'] ), 'error' );
512
+ $has_error = true;
513
+ }
514
 
515
+ if ( ! empty( $setting ) && ! empty( $setting['taxonomy'] ) ) {
516
+ foreach ( get_taxonomies( null, 'objects' ) as $taxonomy ) {
517
+ if ( $taxonomy->rewrite && $taxonomy->rewrite['slug'] == $value && $taxonomy->name != $setting['taxonomy'] ) {
518
+ add_settings_error( 'wpbdp_settings', $setting_id, sprintf( _x( 'The slug "%s" is already in use for another taxonomy.', 'settings', 'WPBDM' ), $value ), 'error' );
519
+ $has_error = true;
520
+ }
 
 
 
 
 
 
 
 
 
 
 
521
  }
522
+ }
523
 
524
+ break;
525
+ default:
526
+ // TODO: How to handle errors to set $has_error = true?
527
+ if ( is_callable( $validator ) ) {
528
+ if ( is_string( $validator ) ) {
529
+ $value = call_user_func( $validator, $value );
530
+ } else {
531
+ $value = call_user_func( $validator, $value, $old_value, $setting );
532
+ }
533
  }
534
+
535
+ break;
536
  }
537
  }
 
538
 
539
+ return ( $has_error ? $old_value : $value );
 
 
 
 
 
 
 
 
 
 
 
 
540
  }
541
 
542
+ public function validate_number_setting( $value, $setting_id ) {
543
+ $setting = $this->get_setting( $setting_id );
 
544
 
545
+ if ( ! $setting ) {
546
+ return $value;
547
+ }
 
 
 
 
 
548
 
549
+ if ( ! empty( $setting['step'] ) && is_int( $setting['step'] ) ) {
550
+ $value = intval( $value );
551
+ } else {
552
+ $value = floatval( $value );
553
  }
554
 
555
+ // Min and max.
556
+ $value = ( array_key_exists( 'min', $setting ) && $value < $setting['min'] ) ? $setting['min'] : $value;
557
+ $value = ( array_key_exists( 'max', $setting ) && $value > $setting['max'] ) ? $setting['max'] : $value;
558
 
559
+ return $value;
 
560
  }
561
 
562
  /* upgrade from old-style settings to new options */
666
 
667
  }
668
 
669
+ // For backwards compat.
670
+ class WPBDP_Settings extends WPBDP__Settings {}
671
+
includes/admin/upgrades/class-installer-installation-error.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Installer__Installation_Error {
4
+
5
+ private $exception;
6
+
7
+ public function __construct( $exception ) {
8
+ $this->exception = $exception;
9
+
10
+ add_action( 'admin_notices', array( $this, 'installation_error_notice' ) );
11
+ }
12
+
13
+ public function installation_error_notice() {
14
+ print '<div class="notice notice-error"><p>';
15
+ print '<strong>' . __( 'Business Directory - Installation Failed', 'WPBDM' ) . '</strong>';
16
+ print '<br />';
17
+ print __( 'Business Directory installation failed. An exception with following message was generated:', 'WPBDM' );
18
+ print '<br/><br/>';
19
+ print '<i>' . $this->exception->getMessage() . '</i>';
20
+ print '<br /><br />';
21
+
22
+ $message = __( 'Please <contact-link>contact customer support</a>.', 'WPBDM' );
23
+ $message = str_replace( '<contact-link>', sprintf( '<a href="%s">', 'http://businessdirectoryplugin.com/contact/' ), $message );
24
+
25
+ print $message;
26
+ print '</p></div>';
27
+ }
28
+ }
includes/admin/upgrades/class-manual-upgrade-helper.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Manual_Upgrade_Helper {
3
+
4
+ private $installer;
5
+ private $data = array();
6
+ private $callback;
7
+ private $config_callback = null;
8
+
9
+
10
+ public function __construct( &$installer, $upgrade_config ) {
11
+ // Try to load class.
12
+ $this->installer = $installer;
13
+ $this->data = $upgrade_config;
14
+
15
+ $callback_definition = isset( $this->data['callback'] ) ? $this->data['callback'] : $this->data;
16
+ $config_callback_definition = isset( $this->data['config_callback'] ) ? $this->data['config_callback'] : null;
17
+
18
+ $this->callback = $this->get_callback( $callback_definition );
19
+
20
+ if ( $config_callback_definition ) {
21
+ $this->config_callback = $this->get_configuration_callback( $config_callback_definition );
22
+ } else {
23
+ $this->config_callback = null;
24
+ }
25
+
26
+ add_action( 'admin_notices', array( &$this, 'upgrade_required_notice' ) );
27
+ add_action( 'admin_menu', array( &$this, 'add_upgrade_page' ) );
28
+ add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
29
+ add_action( 'wp_ajax_wpbdp-manual-upgrade', array( &$this, 'handle_ajax' ) );
30
+ }
31
+
32
+ private function get_callback( $params ) {
33
+ $callback = $this->get_migration_callback( $params );
34
+
35
+ if ( ! is_callable( $callback ) ) {
36
+ throw new Exception( 'Invalid upgrade callback provided.' );
37
+ }
38
+
39
+ return $callback;
40
+ }
41
+
42
+ private function get_migration_callback( $params ) {
43
+ if ( is_array( $params ) ) {
44
+ $classname = $params[0];
45
+ $method = $params[1];
46
+
47
+ $migration = $this->installer->load_migration_class( $classname );
48
+
49
+ $callback = array( $migration, $method );
50
+ } else {
51
+ $callback = $params;
52
+ }
53
+
54
+ return $callback;
55
+ }
56
+
57
+ private function get_configuration_callback( $params ) {
58
+ $callback = $this->get_migration_callback( $params );
59
+
60
+ if ( ! is_callable( $callback ) ) {
61
+ throw new Exception( 'Invalid upgrade config callback provided.' );
62
+ }
63
+
64
+ return $callback;
65
+ }
66
+
67
+ public function upgrade_required_notice() {
68
+ global $pagenow;
69
+
70
+ if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'wpbdp-upgrade-page' == $_GET['page'] )
71
+ return;
72
+
73
+ if ( ! current_user_can( 'administrator' ) )
74
+ return;
75
+
76
+ print '<div class="error"><p>';
77
+ print '<strong>' . __( 'Business Directory - Manual Upgrade Required', 'WPBDM' ) . '</strong>';
78
+ print '<br />';
79
+ _e( 'Business Directory features are currently disabled because the plugin needs to perform a manual upgrade before continuing.', 'WPBDM' );
80
+ print '<br /><br />';
81
+ printf( '<a class="button button-primary" href="%s">%s</a>', admin_url( 'admin.php?page=wpbdp-upgrade-page' ), __( 'Perform Manual Upgrade', 'WPBDM' ) );
82
+ print '</p></div>';
83
+ }
84
+
85
+ public function add_upgrade_page() {
86
+ global $submenu;
87
+
88
+ // Make "Directory" menu items point to upgrade page.
89
+ $menu_id = 'edit.php?post_type=' . WPBDP_POST_TYPE;
90
+ if ( isset( $submenu[ $menu_id ] ) ) {
91
+ foreach ( $submenu[ $menu_id ] as &$item ) {
92
+ $item[2] = admin_url( 'admin.php?page=wpbdp-upgrade-page' );
93
+ }
94
+ }
95
+
96
+ add_submenu_page( 'options.php',
97
+ __( 'Business Directory - Manual Upgrade', 'WPBDM' ),
98
+ __( 'Business Directory - Manual Upgrade', 'WPBDM' ),
99
+ 'administrator',
100
+ 'wpbdp-upgrade-page',
101
+ array( &$this, 'upgrade_page' ) );
102
+ }
103
+
104
+ public function enqueue_scripts() {
105
+ wp_enqueue_style( 'wpbdp-admin', WPBDP_URL . 'assets/css/admin.min.css' );
106
+ wp_enqueue_style( 'wpbdp-manual-upgrade-css', WPBDP_URL . 'assets/css/admin-manual-upgrade.min.css' );
107
+ wp_enqueue_script( 'wpbdp-manual-upgrade' , WPBDP_URL . 'assets/js/admin-manual-upgrade.min.js' );
108
+ }
109
+
110
+ private function is_configured() {
111
+ if ( ! $this->config_callback )
112
+ return true;
113
+
114
+ $latest_data = (array) get_option( 'wpbdp-manual-upgrade-pending', array() );
115
+ return ! empty( $latest_data['configured'] );
116
+ }
117
+
118
+ public function upgrade_page() {
119
+ echo wpbdp_admin_header( __( 'Business Directory - Manual Upgrade', 'WPBDM' ), 'manual-upgrade', null, false );
120
+ echo '<div class="wpbdp-manual-upgrade-wrapper">';
121
+
122
+ if ( ! $this->is_configured() ) {
123
+ ob_start();
124
+ call_user_func( $this->config_callback );
125
+ $output = ob_get_contents();
126
+ ob_end_clean();
127
+
128
+ if ( ! $this->is_configured() ) {
129
+ echo '<form action="" method="post">';
130
+ echo '<div class="wpbdp-manual-upgrade-configuration">';
131
+ echo $output;
132
+ echo '<div class="cf"><input type="submit" class="right button button-primary" value="' . _x( 'Continue', 'manual-upgrade', 'WPBDM' ) . '"/></div>';
133
+ echo '</div>';
134
+ echo '</form>';
135
+ }
136
+ }
137
+
138
+ if ( $this->is_configured() ) {
139
+ echo '<div class="step-upgrade">';
140
+ echo '<p>';
141
+ _e( 'Business Directory features are currently disabled because the plugin needs to perform a manual upgrade before it can be used.', 'WPBDM' );
142
+ echo '<br />';
143
+ _e( 'Click "Start Upgrade" and wait until the process finishes.', 'WPBDM' );
144
+ echo '</p>';
145
+ echo '<p>';
146
+ echo '<a href="#" class="start-upgrade button button-primary">' . _x( 'Start Upgrade', 'manual-upgrade', 'WPBDM' ) . '</a>';
147
+ echo ' ';
148
+ echo '<a href="#" class="pause-upgrade button">' . _x( 'Pause Upgrade', 'manual-upgrade', 'WPBDM' ) . '</a>';
149
+ echo '</p>';
150
+ echo '<textarea id="manual-upgrade-progress" rows="20" style="width: 90%; font-family: courier, monospaced; font-size: 12px;" readonly="readonly"></textarea>';
151
+ echo '</div>';
152
+
153
+ echo '<div class="step-done" style="display: none;">';
154
+ echo '<p>' . _x( 'The upgrade was successfully performed. Business Directory Plugin is now available.', 'manual-upgrade', 'WPBDM' ) . '</p>';
155
+ printf ( '<a href="%s" class="button button-primary">%s</a>',
156
+ admin_url( 'admin.php?page=wpbdp_admin' ),
157
+ _x( 'Go to "Directory Admin"', 'manual-upgrade', 'WPBDM' ) );
158
+ echo '</div>';
159
+ }
160
+
161
+ echo '</div>';
162
+ echo wpbdp_admin_footer();
163
+ }
164
+
165
+ public function handle_ajax() {
166
+ if ( ! current_user_can( 'administrator' ) )
167
+ return;
168
+
169
+ $response = call_user_func( $this->callback );
170
+
171
+ print json_encode( $response );
172
+
173
+ if ( $response['done'] )
174
+ delete_option( 'wpbdp-manual-upgrade-pending' );
175
+
176
+ exit();
177
+ }
178
+
179
+ }
180
+
includes/admin/upgrades/class-migration.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migration {
4
+
5
+ public function request_manual_upgrade( $callback ) {
6
+ return $this->request_manual_upgrade_with_configuration( $callback, null );
7
+ }
8
+
9
+ public function request_manual_upgrade_with_configuration( $callback, $config_callback ) {
10
+ update_option( 'wpbdp-manual-upgrade-pending', array( 'callback' => array( get_class( $this ), $callback ),
11
+ 'config_callback' => $config_callback ? array( get_class( $this ), $config_callback ) : null ) );
12
+ }
13
+
14
+ public function manual_upgrade_configured() {
15
+ $manual_upgrade = get_option( 'wpbdp-manual-upgrade-pending', false );
16
+
17
+ if ( ! $manual_upgrade || ! is_array( $manual_upgrade ) )
18
+ return;
19
+
20
+ $manual_upgrade['configured'] = true;
21
+ update_option( 'wpbdp-manual-upgrade-pending', $manual_upgrade );
22
+ }
23
+
24
+ public function set_manual_upgrade_config( $conf ) {
25
+ $manual_upgrade = get_option( 'wpbdp-manual-upgrade-pending', false );
26
+ $manual_upgrade = is_array( $manual_upgrade ) ? $manual_upgrade : array();
27
+
28
+ $manual_upgrade['config'] = $conf;
29
+ update_option( 'wpbdp-manual-upgrade-pending', $manual_upgrade );
30
+ }
31
+
32
+ public function get_config() {
33
+ $manual_upgrade = get_option( 'wpbdp-manual-upgrade-pending', false );
34
+
35
+ if ( ! $manual_upgrade || ! is_array( $manual_upgrade ) || empty( $manual_upgrade['config'] ) )
36
+ return array();
37
+
38
+ return $manual_upgrade['config'];
39
+ }
40
+
41
+ }
includes/admin/upgrades/migrations/manual-upgrade-18_0-featured-levels.php ADDED
@@ -0,0 +1,309 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Manual_Upgrade__18_0__Featured_Levels {
4
+
5
+ function __construct() {
6
+ // Check if we actually need to perform the migration.
7
+ global $wpdb;
8
+ if ( 0 === absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value != %s", '_wpbdp[sticky]', 'normal' ) ) ) ) {
9
+ delete_option( 'wpbdp-migrate-18_0-featured-pending' );
10
+ return;
11
+ }
12
+
13
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
14
+ add_action( 'admin_menu', array( &$this, 'add_upgrade_page' ) );
15
+ add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
16
+ }
17
+
18
+ function add_upgrade_page() {
19
+ add_submenu_page( 'options.php',
20
+ __( 'Business Directory - Featured Levels migration', 'WPBDM' ),
21
+ __( 'Business Directory - Featured Levels migration', 'WPBDM' ),
22
+ 'administrator',
23
+ 'wpbdp_migration_18_0_featured_levels',
24
+ array( &$this, 'migration_page' ) );
25
+ }
26
+
27
+ function _fee_form() {
28
+ $form = wpbdp_render_page( WPBDP_PATH . 'templates/admin/fees-form.tpl.php', array( 'fee' => new WPBDP__Fee_Plan() ) );
29
+ return $form;
30
+ }
31
+
32
+ function _validate_config( $levels ) {
33
+ $posted = ! empty( $_POST['level'] ) ? $_POST['level'] : false;
34
+
35
+ if ( ! $posted )
36
+ return false;
37
+
38
+ $config = array();
39
+
40
+ foreach ( $levels as $level_id => $level_data ) {
41
+ if ( ! isset( $posted[ $level_id ] ) )
42
+ return false;
43
+
44
+ $strategy = wpbdp_getv( $posted[ $level_id ], 'strategy', false );
45
+ $move_to = absint( wpbdp_getv( $posted[ $level_id ], 'move_to', 0 ) );
46
+ $new_details = wpbdp_getv( $posted[ $level_id ], 'details', false );
47
+
48
+ switch ( $strategy ) {
49
+ case 'remove':
50
+ $config[ $level_id ] = array( 'strategy' => 'remove' );
51
+ break;
52
+ case 'move':
53
+ $plan = wpbdp_get_fee_plan( $move_to );
54
+
55
+ if ( ! $plan )
56
+ return false;
57
+
58
+ $config[ $level_id ] = array( 'strategy' => 'move', 'fee_id' => $move_to );
59
+ break;
60
+ case 'create':
61
+ parse_str( $new_details, $fee_details );
62
+ $fee = stripslashes_deep( $fee_details['fee'] );
63
+
64
+ if ( ! isset( $fee_details['limit_categories'] ) )
65
+ $fee['supported_categories'] = 'all';
66
+
67
+ if ( ! isset( $fee_details['sticky'] ) )
68
+ $fee['sticky'] = 0;
69
+
70
+ $config[ $level_id ] = array( 'strategy' => 'create', 'fee' => $fee );
71
+ break;
72
+ default:
73
+ return false;
74
+ break;
75
+ }
76
+ }
77
+
78
+ return $config;
79
+ }
80
+
81
+ function _update_db( $config ) {
82
+ global $wpdb;
83
+
84
+ if ( ! $config ) {
85
+ // Delete all sticky info.
86
+ // $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp[sticky]' );
87
+ // $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp[sticky_level]' );
88
+ return;
89
+ }
90
+
91
+ $featured_fee_translation = array();
92
+
93
+ foreach ( $config as $level_id => $level_config ) {
94
+ switch ( $level_config['strategy'] ) {
95
+ case 'remove':
96
+ $featured_fee_translation[ $level_id ] = 0;
97
+ break;
98
+ case 'move':
99
+ $featured_fee_translation[ $level_id ] = $level_config['fee_id'];
100
+
101
+ $fee = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_plans WHERE id = %d", $level_config['fee_id'] ) );
102
+
103
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listings SET fee_id = %d, fee_price = %s, fee_days = %d, fee_images = %d, is_sticky = %d WHERE listing_id IN ( SELECT pm.post_id FROM {$wpdb->postmeta} pm WHERE pm.meta_key = %s AND pm.meta_value = %s )",
104
+ $fee->id,
105
+ $fee->amount,
106
+ $fee->days,
107
+ $fee->images,
108
+ $fee->sticky,
109
+ '_wpbdp[sticky_level]',
110
+ $level_id ) );
111
+
112
+ break;
113
+ case 'create':
114
+ $fee = new WPBDP__Fee_Plan( $level_config['fee'] );
115
+
116
+ if ( $fee->save() ) {
117
+ $featured_fee_translation[ $level_id ] = $fee->id;
118
+
119
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listings SET fee_id = %d, fee_price = %s, fee_days = %d, fee_images = %d, is_sticky = %d WHERE listing_id IN ( SELECT pm.post_id FROM {$wpdb->postmeta} pm WHERE pm.meta_key = %s AND pm.meta_value = %s )",
120
+ $fee->id,
121
+ $fee->amount,
122
+ $fee->days,
123
+ $fee->images,
124
+ $fee->sticky,
125
+ '_wpbdp[sticky_level]',
126
+ $level_id ) );
127
+ } else {
128
+ $featured_fee_translation[ $level_id ] = 0;
129
+ }
130
+
131
+ break;
132
+ }
133
+ }
134
+
135
+ // $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp[sticky]' ) );
136
+ // $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp[sticky_level]' ) );
137
+
138
+ delete_option( 'wpbdp-migrate-18_0-featured-pending' );
139
+ }
140
+
141
+ function migration_page() {
142
+ if ( ! get_option( 'wpbdp-migrate-18_0-featured-pending', false ) ) {
143
+ return;
144
+ }
145
+
146
+ global $wpdb;
147
+
148
+ $levels = array();
149
+
150
+ if ( $wpdb->get_row( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->prefix . 'wpbdp_x_featured_levels' ) ) ) {
151
+ $db_levels = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wpbdp_x_featured_levels" );
152
+
153
+ foreach ( $db_levels as $db_level ) {
154
+ $levels[ $db_level->id ] = (array) $db_level;
155
+ }
156
+ }
157
+
158
+ unset( $levels['normal'] );
159
+ if ( ! isset( $levels['sticky'] ) ) {
160
+ $levels['sticky'] = array( 'name' => _x( 'Featured Listing', 'listings-api', 'WPBDM' ),
161
+ 'description' => wpbdp_get_option( 'featured-description' ),
162
+ 'cost' => floatval( wpbdp_get_option( 'featured-price' ) ) );
163
+ }
164
+
165
+ // Validate (in case data was POSTed).
166
+ if ( $config = $this->_validate_config( $levels ) ) {
167
+ $this->_update_db( $config );
168
+
169
+ echo wpbdp_admin_header( __( 'Business Directory - Featured Levels Migration', 'WPBDM' ), 'manual-upgrade', null, false );
170
+ echo _x( 'Featured Levels migration is complete.', 'migrate-18', 'WPBDM' );
171
+ echo '<br /><br />';
172
+ echo '<a href="' . esc_url( admin_url( 'admin.php?page=wpbdp_admin' ) ) . '" class="button button-secondary">' . _x( '← Return to Directory dashboard', 'upgrade-18', 'WPBDM' ) . '</a>';
173
+ echo wpbdp_admin_footer();
174
+
175
+ return;
176
+ }
177
+
178
+ echo wpbdp_admin_header( __( 'Business Directory - Featured Levels Migration', 'WPBDM' ), 'manual-upgrade', null, false );
179
+ echo '<div class="wpbdp-manual-upgrade-wrapper">';
180
+
181
+ echo '<div id="wpbdp-manual-upgrade-18_0-config">';
182
+
183
+ echo '<div id="add-fee-form" data-title="' . _x( 'Configure Plan', 'upgrade-18', 'WPBDM' ) . '">';
184
+ echo $this->_fee_form();
185
+ echo '</div>';
186
+
187
+ _ex( 'Business Directory <b>version 5.0</b> is changing how Featured Levels plugin works. We are leaving restricted features for fee plans, but removing the confusing notion of a "featured level" that was limited to sticky listings.', 'migrate-18', 'WPBDM');
188
+ echo '<br />';
189
+ _ex( 'We need to migrate your existing "featured levels" to fee plans for use by the upgrade. YOUR DATA WILL NOT BE LOST HERE! Our new setup will make it easier to configure and manage your listings with restricted feature access. If you are unsure about what to do here, <support-link>contact support</support-link> and <cancel-link>cancel migration</cancel-link>.', 'migrate-18', 'WPBDM');
190
+ echo '<br /><br />';
191
+ _ex( 'Before we do the migration, we need to ask a few simple questions to move your data from the old "featured level" to the new "restricted feature fee plan" that is right for you.', 'migrate-18', 'WPBDM');
192
+
193
+
194
+ // Compute listing counts.
195
+ foreach ( array_keys( $levels ) as $level_id ) {
196
+ $levels[ $level_id ]['count'] = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->posts} p JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID WHERE p.post_type = %s AND pm.meta_key = %s AND pm.meta_value = %s", WPBDP_POST_TYPE, '_wpbdp[sticky_level]', $level_id ) );
197
+ }
198
+
199
+ // Gather possible fee options for migration.
200
+ $fee_options = '';
201
+ foreach ( $wpdb->get_results( "SELECT id, label FROM {$wpdb->prefix}wpbdp_plans" ) as $r ) {
202
+ $fee_options .= '<option value="' . $r->id . '">' . $r->label . '</option>';
203
+ }
204
+
205
+ echo '<form action="" method="post">';
206
+ echo '<table id="fee-decisions">';
207
+ echo '<thead>';
208
+ echo '<tr>';
209
+ echo '<th class="level-name">' . _x( 'Featured Level', 'upgrade-18', 'WPBDM' ) . '</th>';
210
+ echo '<th>' . _x( 'What to do with it?', 'upgrade-18', 'WPBDM' ) . '</th>';
211
+ echo '</tr>';
212
+ echo '</thead>';
213
+ echo '<tbody>';
214
+
215
+ foreach ( $levels as $level_id => $level ) {
216
+ echo '<tr>';
217
+ echo '<td class="level-name">';
218
+ echo '<strong>' . $level['name'] . '</strong><br />';
219
+ echo sprintf( _nx( '%d listing is on this level.', '%d listings are on this level.', $level['count'], 'upgrade-18', 'WPBDM' ), $level['count'] );
220
+ echo '</td>';
221
+ echo '<td>';
222
+ echo '<select data-level-id="' . $level_id . '" class="level-migration" name="level[' . $level_id . '][strategy]">';
223
+ echo '<option class="placeholder" value="">' . _x( 'Select an option', 'upgrade-18', 'WPBDM' ) . '</option>';
224
+ echo '<option data-description="' . esc_attr( _x( 'Remove "sticky" status for listings.', 'upgrade-18', 'WPBDM' ) ) . '" value="remove">' . _x( 'Remove this (old) level, and leave the listing on the old fee plan.', 'upgrade-18', 'WPBDM' ) . '</option>';
225
+
226
+ if ( $fee_options )
227
+ echo '<option data-description="' . esc_attr( _x( 'May change "sticky" status depending on fee plan.', 'upgrade-18', 'WPBDM' ) ) . '" value="move">' . _x( 'Move listings with this level to existing fee plan.', 'upgrade-18', 'WPBDM' ) . '</option>';
228
+
229
+ echo '<option data-description="' . esc_attr( _x( 'Keep "sticky" status of listings.', 'upgrade-18', 'WPBDM' ) ) . '" value="create">' . _x( 'Replace this level with a new fee plan.', 'upgrade-18', 'WPBDM' ) . '</option>';
230
+
231
+ echo '</select>';
232
+ echo '<div class="option-description"></div>';
233
+
234
+ if ( $fee_options ):
235
+ echo '<div class="option-configuration option-move" >';
236
+ echo _x( 'Move to: ', 'migrate-18', 'WPBDM' );
237
+ echo '<select name="level[' . $level_id . '][move_to]">';
238
+ echo $fee_options;
239
+ echo '</select>';
240
+ echo '</div>';
241
+ endif;
242
+
243
+ echo '<div class="option-configuration option-create">';
244
+ echo '<input type="hidden" name="level[' . $level_id . '][details]" />';
245
+
246
+ echo '<h4>' . _x( 'New plan summary', 'migrate-18', 'WPBDM') . '</h4>';
247
+ echo '<table class="new-fee-summary" data-level-id="' . $level_id . '">';
248
+ echo '<thead><tr>';
249
+ echo '<th>' . _x( 'Fee Label', 'migrate-18', 'WPBDM' ) . '</th>';
250
+ echo '<th>' . _x( 'Amount', 'migrate-18', 'WPBDM' ) . '</th>';
251
+ echo '<th>' . _x( 'Duration', 'migrate-18', 'WPBDM' ) . '</th>';
252
+ echo '<th>' . _x( 'Images', 'migrate-18', 'WPBDM' ) . '</th>';
253
+ echo '</tr></thead>';
254
+ echo '<tbody>';
255
+ echo '<tr>';
256
+ echo '<td data-attr="fee_label"></td>';
257
+ echo '<td data-attr="fee_amount"></td>';
258
+ echo '<td data-attr="fee_duration"></td>';
259
+ echo '<td data-attr="fee_images"></td>';
260
+ echo '</tr>';
261
+ echo '</tbody>';
262
+ echo '</table>';
263
+
264
+ echo '</div>';
265
+ echo '</td>';
266
+ echo '</tr>';
267
+ }
268
+
269
+ echo '</tbody>';
270
+ echo '</table>';
271
+
272
+ echo '<p>';
273
+ echo '<input type="submit" value="' . _x( 'Perform migration', 'migrate-18', 'WPBDM' ) . '" class="button button-primary" />';
274
+ echo '</p>';
275
+
276
+ echo '</form>';
277
+
278
+ // $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value = %s", $level->downgrade, '_wpbdp[sticky_level]', $level->id) );
279
+ echo '</div>';
280
+
281
+ echo '</div>';
282
+ echo wpbdp_admin_footer();
283
+ }
284
+
285
+ public function enqueue_scripts() {
286
+ add_thickbox();
287
+ wp_enqueue_style( 'wpbdp-admin', WPBDP_URL . 'assets/css/admin.min.css' );
288
+ wp_enqueue_style( 'wpbdp-manual-upgrade-css', WPBDP_URL . 'assets/css/admin-manual-upgrade.min.css' );
289
+ wp_enqueue_script( 'wpbdp-manual-upgrade' , WPBDP_URL . 'assets/js/admin-manual-upgrade.min.js', array( 'jquery' ) );
290
+ }
291
+ //
292
+
293
+ function admin_notices() {
294
+ if ( ! empty( $_GET['page'] ) && 'wpbdp_migration_18_0_featured_levels' == $_GET['page'] )
295
+ return;
296
+
297
+ echo '<div class="wpbdp-notice error"><p>';
298
+ echo '<strong>';
299
+ echo _x( 'Business Directory Plugin - Featured Levels migration required.', 'migrate-18', 'WPBDM' );
300
+ echo '</strong><br />';
301
+ echo str_replace(
302
+ '<a>',
303
+ '<a href="' . admin_url( 'admin.php?page=wpbdp_migration_18_0_featured_levels' ) . '">',
304
+ _x( 'Featured levels were removed in 5.0. You need to perform your <a>Featured Levels migration here</a>.', 'migrate-18', 'WPBDM' )
305
+ );
306
+ echo '</p></div>';
307
+ }
308
+
309
+ }
includes/admin/upgrades/migrations/migration-11_0.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Migrations__11_0 {
3
+
4
+ public function migrate() {
5
+ // Users upgrading from < 4.x get the pre-4.0 theme.
6
+ update_option( 'wpbdp-active-theme', 'no_theme' );
7
+ }
8
+
9
+ }
includes/admin/upgrades/migrations/migration-12_0.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__12_0 {
4
+
5
+ public function migrate() {
6
+ delete_transient( 'wpbdp-themes-updates' );
7
+ }
8
+
9
+ }
includes/admin/upgrades/migrations/migration-13_0.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__13_0 {
4
+
5
+ public function migrate() {
6
+ // Make sure no field shortnames conflict.
7
+ $fields = wpbdp_get_form_fields();
8
+
9
+ foreach ( $fields as $f )
10
+ $f->save();
11
+ }
12
+
13
+ }
includes/admin/upgrades/migrations/migration-17_0.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__17_0 {
4
+
5
+ public function migrate() {
6
+ $form_fields = $this->get_list_form_fields();
7
+
8
+ foreach ( $form_fields as $form_field ) {
9
+ $options = array();
10
+
11
+ foreach ( $form_field->data( 'options' ) as $key => $value ) {
12
+ $new_key = trim( preg_replace( '/[\r\n]/', '', $key ) );
13
+ $options[ $new_key ] = trim( preg_replace( '/[\r\n]/', '', $value ) );
14
+ }
15
+
16
+ $form_field->set_data( 'options', $options );
17
+ $form_field->save();
18
+ }
19
+
20
+ if ( $this->count_listing_meta_with_invalid_characters( array_keys( $form_fields ) ) ) {
21
+ $this->request_manual_upgrade( 'upgrade_to_16_fix_form_fields_data' );
22
+ }
23
+ }
24
+
25
+ private function get_list_form_fields() {
26
+ $form_fields = array();
27
+ $find_params = array(
28
+ 'association' => 'meta',
29
+ 'field_type' => array( 'select', 'checkbox', 'radio', 'multiselect' )
30
+ );
31
+
32
+ foreach ( wpbdp_get_form_fields( $find_params ) as $form_field ) {
33
+ $form_fields[ "_wpbdp[fields][" . $form_field->get_id() . "]" ] = $form_field;
34
+ }
35
+
36
+ return $form_fields;
37
+ }
38
+
39
+ private function get_listing_meta_with_invalid_characters( $meta_keys ) {
40
+ global $wpdb;
41
+
42
+ if ( ! $meta_keys ) {
43
+ return array();
44
+ }
45
+
46
+ $sql = "SELECT post_id, meta_id, meta_key, meta_value FROM {$wpdb->postmeta} ";
47
+ $sql.= "WHERE meta_key IN (%s) AND meta_value REGEXP '^ |\\t | \\t| $|[\\r\\n]' ";
48
+ $sql.= "LIMIT 50";
49
+
50
+ $sql = sprintf( $sql, "'" . implode( "', '", $meta_keys ) . "'" );
51
+
52
+ return $wpdb->get_results( $sql );
53
+ }
54
+
55
+ public function upgrade_to_16_fix_form_fields_data() {
56
+ $form_fields = $this->get_list_form_fields();
57
+ $meta_entries = $this->get_listing_meta_with_invalid_characters( array_keys( $form_fields ) );
58
+
59
+ foreach ( $meta_entries as $meta_entry ) {
60
+ $meta_value = maybe_unserialize( $meta_entry->meta_value );
61
+
62
+ if ( is_string( $meta_value ) ) {
63
+ $meta_value = explode( "\t", $meta_entry->meta_value );
64
+ }
65
+
66
+ $sanitized_value = array();
67
+
68
+ foreach ( (array) $meta_value as $key => $value ) {
69
+ $sanitized_value[ $key ] = trim( preg_replace( '/[\r\n]/', '', $value ) );
70
+ }
71
+
72
+ $form_fields[ $meta_entry->meta_key ]->store_value( $meta_entry->post_id, $sanitized_value );
73
+ }
74
+
75
+ $records_left = $this->count_listing_meta_with_invalid_characters( array_keys( $form_fields ) );
76
+
77
+ $message = _x( 'Cleaning up stored meta data for Checkbox, Radio and Select fields... (%d records left)', 'installer', 'WPBDM' );
78
+
79
+ return array(
80
+ 'ok' => true,
81
+ 'done' => $records_left == 0,
82
+ 'status' => sprintf( $message, $records_left ),
83
+ );
84
+ }
85
+
86
+ private function count_listing_meta_with_invalid_characters( $meta_keys ) {
87
+ global $wpdb;
88
+
89
+ if ( ! $meta_keys ) {
90
+ return 0;
91
+ }
92
+
93
+ $sql = "SELECT COUNT(meta_id) FROM {$wpdb->postmeta} WHERE meta_key IN (%s) AND meta_value REGEXP '^ |\\t | \\t| $|[\\r\\n]'";
94
+ $sql = sprintf( $sql, "'" . implode( "', '", $meta_keys ) . "'" );
95
+
96
+ return intval( $wpdb->get_var( $sql ) );
97
+ }
98
+
99
+ }
includes/admin/upgrades/migrations/migration-18_0.php ADDED
@@ -0,0 +1,545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once( WPBDP_PATH . 'includes/utils.php' );
3
+
4
+
5
+ class WPBDP__Migrations__18_0 extends WPBDP__Migration {
6
+
7
+ public function migrate() {
8
+ global $wpdb;
9
+
10
+ // Remove orphans of everything first to make things easier for us.
11
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id NOT IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = %s)", WPBDP_POST_TYPE ) );
12
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id NOT IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = %s)", WPBDP_POST_TYPE ) );
13
+ $wpdb->query( "DELETE FROM {$wpdb->prefix}wpbdp_payments_items WHERE payment_id NOT IN (SELECT id FROM {$wpdb->prefix}wpbdp_payments)" );
14
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_payments SET status = %s WHERE status = %s", 'failed', 'rejected' ) );
15
+
16
+ $this->request_manual_upgrade( '_upgrade_to_18_migrate_fees' );
17
+ }
18
+
19
+ public function _upgrade_to_18_migrate_fees() {
20
+ $status_msg = '';
21
+ $done = false;
22
+
23
+ $subroutines = array(
24
+ '_migrate_licenses',
25
+ '_migrate_email_notices',
26
+ '_migrate_fee_plans',
27
+ '_migrate_payment_items',
28
+ '_migrate_listings',
29
+ '_set_featured_migration_flag'
30
+ );
31
+
32
+ foreach ( $subroutines as $sr ) {
33
+ $done = call_user_func_array( array( $this, $sr ), array( &$status_msg ) );
34
+
35
+ if ( ! $done )
36
+ break;
37
+ }
38
+
39
+ return array( 'ok' => true, 'done' => $done, 'status' => $status_msg );
40
+ }
41
+
42
+ /**
43
+ * Sets an option that tells BD that a Featured levels migration is pending.
44
+ * This process can be performed manually by the admin at any time later after this manual upgrade.
45
+ */
46
+ public function _set_featured_migration_flag( &$msg ) {
47
+ update_option( 'wpbdp-migrate-18_0-featured-pending', true, false );
48
+ return true;
49
+ }
50
+
51
+ public function _migrate_licenses( &$msg ) {
52
+ global $wpdb;
53
+
54
+ $settings = get_option( 'wpbdp_settings', array() );
55
+ $licenses = get_option( 'wpbdp_licenses', array() );
56
+
57
+ $module_keys = $wpdb->get_results( "SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE 'wpbdp-license-key-%'", ARRAY_A );
58
+ $theme_keys = get_option( 'wpbdp-themes-licenses', array() );
59
+
60
+ foreach ( $module_keys as $item ) {
61
+ $module_id = str_replace( 'wpbdp-license-key-', '', $item['option_name'] );
62
+ $key = $item['option_value'];
63
+ $status = get_option( 'wpbdp-license-status-' . $module_id, 'invalid' );
64
+
65
+ $settings[ 'license-key-module-' . $module_id ] = $key;
66
+ $licenses[ 'module-' . $module_id ] = array(
67
+ 'license_key' => $key,
68
+ 'status' => $status,
69
+ 'expires' => '',
70
+ 'last_checked' => 0
71
+ );
72
+ }
73
+
74
+ foreach ( $theme_keys as $theme_id => $license_data ) {
75
+ $settings[ 'license-key-theme-' . $theme_id ] = $license_data['license'];
76
+ $licenses[ 'theme-' . $theme_id ] = array(
77
+ 'license_key' => $license_data['license'],
78
+ 'status' => $license_data['status'],
79
+ 'expires' => '',
80
+ 'last_checked' => $license_data['updated']
81
+ );
82
+ }
83
+
84
+ update_option( 'wpbdp_settings', $settings );
85
+ update_option( 'wpbdp_licenses', $licenses );
86
+
87
+ $msg = _x( 'Migrating license information to new format...', 'installer', 'WPBDM' );
88
+ return true;
89
+ }
90
+
91
+ public function _migrate_email_notices( &$msg ) {
92
+ require_once( WPBDP_INC . 'admin/settings/class-settings-bootstrap.php' );
93
+ $defaults = WPBDP__Settings__Bootstrap::get_default_expiration_notices();
94
+
95
+ $notices = array();
96
+
97
+ if ( true ) {
98
+ if ( $email = get_option( 'wpbdp-listing-renewal-message', false ) ) {
99
+ $notices[] = array(
100
+ 'event' => 'expiration',
101
+ 'relative_time' => '0 days',
102
+ 'listings' => 'non-recurring',
103
+ 'subject' => $email['subject'],
104
+ 'body' => $email['body']
105
+ );
106
+ } else {
107
+ $notices[] = $defaults[1];
108
+ }
109
+ }
110
+
111
+ if ( $t = get_option( 'wpbdp-renewal-email-threshold', false ) ) {
112
+ if ( $email = get_option( 'wpbdp-renewal-pending-message' ) ) {
113
+ $notices[] = array(
114
+ 'event' => 'expiration',
115
+ 'relative_time' => '+' . $t . ' days',
116
+ 'listings' => 'non-recurring',
117
+ 'subject' => $email['subject'],
118
+ 'body' => $email['body']
119
+ );
120
+ } else {
121
+ $email = $defaults[0];
122
+ $email['relative_time'] = '+' . $t . ' days';
123
+ $notices[] = $email;
124
+ }
125
+
126
+ if ( get_option( 'wpbdp-send-autorenewal-expiration-notice', false ) ) {
127
+ if ( $email = get_option( 'wpbdp-listing-autorenewal-notice', false ) ) {
128
+ $notices[] = array(
129
+ 'event' => 'expiration',
130
+ 'relative_time' => '+' . $t . ' days',
131
+ 'listings' => 'recurring',
132
+ 'subject' => $email['subject'],
133
+ 'body' => $email['body']
134
+ );
135
+ } else {
136
+ $email = $defaults[3];
137
+ $email['relative_time'] = '+' . $t . ' days';
138
+ $notices[] = $email;
139
+ }
140
+ }
141
+ }
142
+
143
+ if ( $t = get_option( 'wpbdp-renewal-reminder-threshold', false ) ) {
144
+ if ( $email = get_option( 'wpbdp-renewal-reminder-message' ) ) {
145
+ $notices[] = array(
146
+ 'event' => 'expiration',
147
+ 'relative_time' => '-' . $t . ' days',
148
+ 'listings' => 'both',
149
+ 'subject' => $email['subject'],
150
+ 'body' => $email['body']
151
+ );
152
+ } else {
153
+ $email = $defaults[2];
154
+ $email['relative_time'] = '-' . $t . ' days';
155
+ $notices[] = $email;
156
+ }
157
+ }
158
+
159
+ if ( true ) {
160
+ if ( $email = get_option( 'wpbdp-listing-autorenewal-message' ) ) {
161
+ $notices[] = array(
162
+ 'event' => 'renewal',
163
+ 'listings' => 'recurring',
164
+ 'subject' => $email['subject'],
165
+ 'body' => $email['body']
166
+ );
167
+ } else {
168
+ $notices[] = $defaults[4];
169
+ }
170
+ }
171
+
172
+ // Clamp relative times to what we can handle.
173
+ foreach ( $notices as &$notice ) {
174
+ if ( empty( $notice['relative_time'] ) || '0 days' == $notice['relative_time'] ) {
175
+ continue;
176
+ }
177
+
178
+ $mod = substr( $notice['relative_time'], 0, 1 );
179
+ $days = absint( trim( str_replace( array( '+', '-', 'days' ), '', $notice['relative_time'] ) ) );
180
+
181
+ if ( $days > 45 ) {
182
+ $notice['relative_time'] = $mod . '2 months';
183
+ } elseif ( $days > 23 ) {
184
+ $notice['relative_time'] = $mod . '1 months';
185
+ } else if ( $days > 11 ) {
186
+ $notice['relative_time'] = $mod . '2 weeks';
187
+ } else if ( $days > 5) {
188
+ $notice['relative_time'] = $mod . '1 weeks';
189
+ } else {
190
+ $notice['relative_time'] = $mod . $days . ' days';
191
+ }
192
+ }
193
+
194
+ update_option( 'wpbdp-expiration-notices', $notices );
195
+
196
+ $msg = _x( 'Migrating email notices to new format...', 'installer', 'WPBDM' );
197
+ return true;
198
+ }
199
+
200
+ /**
201
+ * Updates (if needed) current fees to add information for the new columns:
202
+ * supported_categories, pricing_model.
203
+ */
204
+ public function _migrate_fee_plans( &$msg ) {
205
+ global $wpdb;
206
+
207
+ $msg = _x( 'Migrating fee plans...', 'installer', 'WPBDM' );
208
+
209
+ if ( ! wpbdp_table_exists( $wpdb->prefix . 'wpbdp_fees' ) ) {
210
+ return true;
211
+ }
212
+
213
+ foreach ( $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wpbdp_fees" ) as $fee ) {
214
+ $old_categories = isset( $fee->categories ) ? unserialize( $fee->categories ) : array();
215
+
216
+ if ( ! is_array( $old_categories ) || empty( $old_categories ) || ( isset( $old_categories['all'] ) && $old_categories['all'] ) ) {
217
+ $categories = 'all';
218
+ } else {
219
+ $categories = implode( ',', array_map( 'absint', $old_categories['categories'] ) );
220
+ }
221
+
222
+ $row = array(
223
+ 'id' => $fee->id,
224
+ 'label' => $fee->label,
225
+ 'amount' => $fee->amount,
226
+ 'days' => $fee->days,
227
+ 'images' => $fee->images,
228
+ 'sticky' => $fee->sticky,
229
+ 'pricing_model' => 'flat',
230
+ 'supported_categories' => $categories ? $categories : 'all',
231
+ 'weight' => $fee->weight,
232
+ 'enabled' => $fee->enabled,
233
+ 'description' => $fee->description,
234
+ 'tag' => $fee->tag,
235
+ 'recurring' => ( 0 != $fee->days && $fee->amount > 0.0 && get_option( 'wpbdp-listing-renewal-auto' ) && get_option( 'wpbdp-listing-renewal-auto-dontask' ) ) ? 1 : 0
236
+ );
237
+
238
+ // Check if fee plan already exists.
239
+ $exists = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_plans WHERE id = %d", $fee->id ) );
240
+ $success = true;
241
+
242
+ if ( $exists ) {
243
+ $success = ( false !== $wpdb->update( $wpdb->prefix . 'wpbdp_plans', $row, array( 'id' => $fee->id ) ) );
244
+ } else {
245
+ $success = ( false !== $wpdb->insert( $wpdb->prefix . 'wpbdp_plans', $row ) );
246
+ }
247
+
248
+ if ( ! $success ) {
249
+ $msg = sprintf( _x( '! Could not migrate fee "%s" (%d)', 'installer', 'WPBDM' ), $fee->label, $fee->id );
250
+ return false;
251
+ }
252
+ }
253
+
254
+ return true;
255
+ }
256
+
257
+ /**
258
+ * Removes rows from payments_items and adds the items to the new payment_items column in the payments table.
259
+ */
260
+ public function _migrate_payment_items( &$msg ) {
261
+ global $wpdb;
262
+
263
+ $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_payments WHERE payment_items IS NULL OR payment_items = %s", '' ) );
264
+ $batch_size = 20;
265
+
266
+ if ( ! $count )
267
+ return true;
268
+
269
+ foreach ( $wpdb->get_results( $wpdb->prepare( "SELECT id, tag FROM {$wpdb->prefix}wpbdp_payments WHERE payment_items IS NULL OR payment_items = %s ORDER BY id ASC LIMIT {$batch_size}", '' ) ) as $payment ) {
270
+ $payment_id = $payment->id;
271
+ $payment_type = $payment->tag;
272
+ $items = array();
273
+
274
+ foreach ( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_payments_items WHERE payment_id = %d", $payment_id ) ) as $item ) {
275
+ $new_item = array();
276
+
277
+ switch ( $item->item_type ) {
278
+ case 'fee':
279
+ $new_item['type'] = 'plan';
280
+ break;
281
+ case 'recurring_fee':
282
+ $new_item['type'] = 'recurring_plan';
283
+ break;
284
+ default:
285
+ $new_item['type'] = $item->item_type;
286
+ break;
287
+ }
288
+
289
+ $new_item['description'] = $item->description;
290
+ $new_item['amount'] = $item->amount;
291
+
292
+ if ( $data = unserialize( $item->data ) ) {
293
+ if ( ! is_array( $data ) )
294
+ $new_item['deprecated_data'] = $data;
295
+
296
+ foreach ( $data as $key => $val ) {
297
+ if ( ! isset( $new_item[ $key ] ) )
298
+ $new_item[ $key ] = $val;
299
+ }
300
+ }
301
+
302
+ if ( ! empty( $new_item['is_renewal'] ) )
303
+ $new_item['type'] = 'plan_renewal';
304
+
305
+ $new_item['rel_id_1'] = $item->rel_id_1;
306
+ $new_item['rel_id_2'] = $item->rel_id_2;
307
+
308
+ $items[] = $new_item;
309
+ }
310
+
311
+ if ( ! $payment_type ) {
312
+ // TODO: Try to find out the payment type from the items.
313
+ }
314
+
315
+ if ( false === $wpdb->update( $wpdb->prefix . 'wpbdp_payments', array( 'payment_items' => serialize( $items ), 'payment_type' => $payment_type ), array( 'id' => $payment_id ) ) ) {
316
+ $msg = sprintf( _x( '! Could not migrate payment #%d', 'installer', 'WPBDM' ), $payment_id );
317
+ return false;
318
+ }
319
+ }
320
+
321
+ $msg = sprintf( _x( 'Updating payment items format: %d items remaining...', 'installer', 'WPBDM' ), max( $count - $batch_size, 0 ) );
322
+ return false;
323
+ }
324
+
325
+ /**
326
+ * Makes sure that ALL listings have an entry in listings. The fee is extracted from available information:
327
+ * - the (now deprecated) listing fees table
328
+ * - pending payments (recurring taking precedence over regular ones).
329
+ * If nothing useful is found, the default free fee is assigned.
330
+ */
331
+ public function _migrate_listings( &$msg ) {
332
+ global $wpdb;
333
+
334
+ if ( ! wpbdp_table_exists( $wpdb->prefix . 'wpbdp_listing_fees' ) ) {
335
+ return true;
336
+ }
337
+
338
+
339
+ $batch_size = 20;
340
+
341
+ $count = absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} p WHERE p.post_type = %s AND p.ID NOT IN (SELECT lp.listing_id FROM {$wpdb->prefix}wpbdp_listings lp) ORDER BY ID ASC LIMIT {$batch_size}", WPBDP_POST_TYPE ) ) );
342
+ $listings = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} p WHERE p.post_type = %s AND p.ID NOT IN (SELECT lp.listing_id FROM {$wpdb->prefix}wpbdp_listings lp) ORDER BY ID ASC LIMIT {$batch_size}", WPBDP_POST_TYPE ) );
343
+
344
+ if ( ! $count )
345
+ return true;
346
+
347
+ foreach ( $listings as $listing_id ) {
348
+ $this->set_listing_categories( $listing_id ); // Set listing categories.
349
+
350
+ // Obtain new fee plan.
351
+ $new_plan = $this->plan_from_fees( $listing_id );
352
+
353
+ if ( ! $new_plan )
354
+ $new_plan = $this->plan_from_payments( $listing_id );
355
+
356
+ // This shouldn't happen but... just in case.
357
+ if ( ! $new_plan ) {
358
+ $free_plan = wpbdp_get_fee_plan( 'free' );
359
+ $new_plan = array(
360
+ 'listing_id' => $listing_id,
361
+ 'fee_id' => $free_plan->id,
362
+ 'fee_price' => 0.0,
363
+ 'fee_days' => $free_plan->days,
364
+ 'fee_images' => $free_plan->images,
365
+ 'is_sticky' => $free_plan->sticky,
366
+ );
367
+
368
+ if ( $expiration = $free_plan->calculate_expiration_time() )
369
+ $new_plan['expiration_date'] = $expiration;
370
+
371
+ $recurring_data = $wpdb->get_var( $wpdb->prepare( "SELECT recurring_data FROM {$wpdb->prefix}wpbdp_listing_fees WHERE recurring_data IS NOT NULL AND listing_id = %d LIMIT 1", $listing_id ) );
372
+ if ( ! empty( $new_plan['is_recurring'] ) && $new_plan['is_recurring'] && $recurring_data )
373
+ $new_plan['recurring_data'] = $recurring_data;
374
+ }
375
+
376
+ $wpdb->delete( $wpdb->prefix . 'wpbdp_listings', array( 'listing_id' => $listing_id ) );
377
+ $wpdb->insert( $wpdb->prefix . 'wpbdp_listings', $new_plan );
378
+
379
+ $l = WPBDP_Listing::get( $listing_id );
380
+ $l->get_status( true );
381
+ }
382
+
383
+ $msg = sprintf( _x( 'Migrating listing information: %d items remaining...', 'installer', 'WPBDM' ), max( $count - $batch_size, 0 ) );
384
+ return false;
385
+ }
386
+
387
+ private function set_listing_categories( $listing_id ) {
388
+ global $wpdb;
389
+
390
+ $cat_ids = array();
391
+
392
+ // From current fees.
393
+ $cat_ids = array_merge( $cat_ids, $wpdb->get_col( $wpdb->prepare( "SELECT category_id FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d", $listing_id ) ) );
394
+
395
+ // From pending payments.
396
+ $pending = $wpdb->get_col( $wpdb->prepare( "SELECT payment_items FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id = %d AND status = %s", $listing_id, 'pending' ) );
397
+ if ( $pending ) {
398
+ $pending = array_map( 'unserialize', $pending );
399
+ $pending = call_user_func_array( 'array_merge', $pending );
400
+
401
+ foreach ( $pending as $item ) {
402
+ if ( ! in_array( $item['type'], array( 'plan', 'plan_renewal', 'recurring_plan' ), true ) )
403
+ continue;
404
+
405
+ if ( ! empty( $item['rel_id_1'] ) )
406
+ $cat_ids[] = $item['rel_id_1'];
407
+ }
408
+ }
409
+
410
+ $cat_ids = array_map( 'intval', $cat_ids );
411
+
412
+ if ( $cat_ids )
413
+ wp_set_object_terms( $listing_id, $cat_ids, WPBDP_CATEGORY_TAX, true );
414
+ }
415
+
416
+ private function plan_from_fees( $listing_id ) {
417
+ global $wpdb;
418
+
419
+ $key_translations = array(
420
+ 'expiration_date' => 'expires_on',
421
+ 'is_recurring' => 'recurring',
422
+ 'subscription_id' => 'recurring_id',
423
+ 'is_sticky' => 'sticky'
424
+ );
425
+
426
+ $choices = array();
427
+ foreach ( array( 'fee_id', 'fee_days', 'fee_images', 'fee_price', 'is_sticky', 'expiration_date' ) as $key ) {
428
+ $choices[ $key ] = array();
429
+ }
430
+
431
+ $fees = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d", $listing_id ) );
432
+
433
+ if ( ! $fees )
434
+ return false;
435
+
436
+ foreach ( $fees as $fee ) {
437
+ if ( $fee->recurring ) {
438
+ if ( $x = wpbdp_get_fee( $fee->fee_id ) )
439
+ $price = $x->amount;
440
+ else
441
+ $price = 0.0;
442
+
443
+ return array(
444
+ 'listing_id' => $listing_id,
445
+ 'fee_id' => $fee->fee_id,
446
+ 'fee_price' => $price,
447
+ 'fee_days' => $fee->fee_days,
448
+ 'fee_images' => $fee->fee_images,
449
+ 'expiration_date' => $fee->expires_on,
450
+ 'is_recurring' => 1,
451
+ 'is_sticky' => $fee->sticky,
452
+ 'subscription_id' => $fee->recurring_id
453
+ );
454
+ }
455
+
456
+ foreach ( array_keys( $choices ) as $key ) {
457
+ $oldkey = isset( $key_translations[ $key ] ) ? $key_translations[ $key ] : $key;
458
+
459
+ if ( 'fee_price' == $key ) {
460
+ if ( $x = wpbdp_get_fee( $fee->fee_id ) )
461
+ $fee->fee_price = $x->amount;
462
+ else
463
+ $fee->fee_price = 0.0;
464
+ }
465
+
466
+ if ( 'expiration_date' == $key && ! $fee->expires_on )
467
+ $fee->expires_on = -1;
468
+
469
+ $choices[ $key ][] = $fee->{$oldkey};
470
+ }
471
+ }
472
+
473
+ $res['listing_id'] = $listing_id;
474
+ $res['fee_id'] = $choices['fee_id'][0]; // Use the first fee id.
475
+ $res['fee_days'] = in_array( -1, $choices['fee_days'] ) ? 0 : max( $choices['fee_days'] );
476
+
477
+ foreach ( array( 'fee_images', 'fee_price', 'is_sticky' ) as $key )
478
+ $res[ $key ] = max( $choices[ $key ] );
479
+
480
+ if ( ! in_array( -1, $choices['expiration_date'] ) ) {
481
+ $res['expiration_date'] = date( 'Y-m-d H:i:s', max( array_map( 'strtotime', $choices['expiration_date'] ) ) );
482
+ }
483
+
484
+ $res['is_recurring'] = 0;
485
+ $res['subscription_id'] = '';
486
+
487
+ return $res;
488
+ }
489
+
490
+ private function plan_from_payments( $listing_id ) {
491
+ global $wpdb;
492
+
493
+ $fee = null;
494
+ $pending_payments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id = %d AND status = %s", $listing_id, 'pending' ) );
495
+
496
+ if ( ! $pending_payments )
497
+ return false;
498
+
499
+ foreach ( $pending_payments as $payment ) {
500
+ $items = unserialize( $payment->payment_items );
501
+
502
+ foreach ( $items as $item_ ) {
503
+ $item = (object) $item_;
504
+
505
+ if ( $item->type == 'recurring_plan' ) {
506
+ $fee = array(
507
+ 'fee_id' => isset( $item->fee_id ) ? $item->fee_id : ( isset( $item->rel_id_2 ) ? $item->rel_id_2 : 0 ),
508
+ 'fee_days' => ! empty( $item->fee_days ) ? $item->fee_days : 0,
509
+ 'fee_images' => ! empty( $item->fee_images ) ? $item->fee_images : 0,
510
+ 'fee_price' => $item->amount,
511
+ 'start_date' => $payment->created_on,
512
+ 'is_recurring' => 1
513
+ );
514
+ }
515
+
516
+ if ( is_null( $fee ) && in_array( $item->type, array( 'plan', 'plan_renewal' ), true ) ) {
517
+ $fee = array(
518
+ 'fee_id' => isset( $item->fee_id ) ? $item->fee_id : ( isset( $item->rel_id_2 ) ? $item->rel_id_2 : 0 ),
519
+ 'fee_days' => ! empty( $item->fee_days ) ? $item->fee_days : 0,
520
+ 'fee_images' => ! empty( $item->fee_images ) ? $item->fee_images : 0,
521
+ 'fee_price' => $item->amount,
522
+ 'start_date' => $payment->created_on,
523
+ 'is_recurring' => 0
524
+ );
525
+ }
526
+ }
527
+ }
528
+
529
+ if ( $_ = wpbdp_get_fee( $fee['fee_id'] ) ) {
530
+ $fee['is_sticky'] = $_->sticky;
531
+
532
+ if ( 0 == $fee['fee_days'] )
533
+ $fee['fee_days'] = absint( $_->days );
534
+ }
535
+
536
+ if ( 0 != $fee['fee_days'] )
537
+ $fee['expiration_date'] = date( 'Y-m-d H:i:s', strtotime( sprintf( '+%d days', $fee['fee_days'] ), strtotime( $fee['start_date'] ) ) );
538
+
539
+ $fee['listing_id'] = $listing_id;
540
+ unset( $fee['start_date'] );
541
+
542
+ return $fee;
543
+ }
544
+
545
+ }
includes/admin/upgrades/migrations/migration-18_1.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__18_1 extends WPBDP__Migration {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ // wpbdp_payments: move from 'created_on' column to 'created_at'.
9
+ $wpdb->query( "UPDATE {$wpdb->prefix}wpbdp_payments SET created_at = FROM_UNIXTIME(UNIX_TIMESTAMP(created_on))" );
10
+ }
11
+
12
+ }
includes/admin/upgrades/migrations/migration-2_0.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__2_0 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+ global $wpbdp;
8
+
9
+ $wpbdp->settings->upgrade_options();
10
+ wpbdp_log('WPBDP settings updated to 2.0-style');
11
+
12
+ // make directory-related metadata hidden
13
+ $old_meta_keys = array(
14
+ 'termlength', 'image', 'listingfeeid', 'sticky', 'thumbnail', 'paymentstatus', 'buyerfirstname', 'buyerlastname',
15
+ 'paymentflag', 'payeremail', 'paymentgateway', 'totalallowedimages', 'costoflisting'
16
+ );
17
+
18
+ foreach ($old_meta_keys as $meta_key) {
19
+ $query = $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s AND {$wpdb->postmeta}.post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = %s)",
20
+ '_wpbdp_' . $meta_key, $meta_key, 'wpbdm-directory');
21
+ $wpdb->query($query);
22
+ }
23
+
24
+ wpbdp_log('Made WPBDP directory metadata hidden attributes');
25
+ }
26
+
27
+ }
includes/admin/upgrades/migrations/migration-2_1.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__2_1 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ /* This is only to make this routine work for BD 3.0. It's not necessary in other versions. */
9
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields ADD COLUMN validator VARCHAR(255) NULL;" );
10
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields ADD COLUMN display_options BLOB NULL;" );
11
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields ADD COLUMN is_required TINYINT(1) NOT NULL DEFAULT 0;" );
12
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields ADD COLUMN type VARCHAR(255) NOT NULL;" );
13
+
14
+ static $pre_2_1_types = array(null, 'textfield', 'select', 'textarea', 'radio', 'multiselect', 'checkbox');
15
+ static $pre_2_1_validators = array(
16
+ 'email' => 'EmailValidator',
17
+ 'url' => 'URLValidator',
18
+ 'missing' => null, /* not really used */
19
+ 'numericwhole' => 'IntegerNumberValidator',
20
+ 'numericdeci' => 'DecimalNumberValidator',
21
+ 'date' => 'DateValidator'
22
+ );
23
+ static $pre_2_1_associations = array(
24
+ 'title' => 'title',
25
+ 'description' => 'content',
26
+ 'category' => 'category',
27
+ 'excerpt' => 'excerpt',
28
+ 'meta' => 'meta',
29
+ 'tags' => 'tags'
30
+ );
31
+
32
+ $field_count = $wpdb->get_var(
33
+ sprintf("SELECT COUNT(*) FROM {$wpdb->prefix}options WHERE option_name LIKE '%%%s%%'", 'wpbusdirman_postform_field_label'));
34
+
35
+ for ($i = 1; $i <= $field_count; $i++) {
36
+ $label = get_option('wpbusdirman_postform_field_label_' . $i);
37
+ $type = get_option('wpbusdirman_postform_field_type_'. $i);
38
+ $validation = get_option('wpbusdirman_postform_field_validation_'. $i);
39
+ $association = get_option('wpbusdirman_postform_field_association_'. $i);
40
+ $required = strtolower(get_option('wpbusdirman_postform_field_required_'. $i));
41
+ $show_in_excerpt = strtolower(get_option('wpbusdirman_postform_field_showinexcerpt_'. $i));
42
+ $hide_field = strtolower(get_option('wpbusdirman_postform_field_hide_'. $i));
43
+ $options = get_option('wpbusdirman_postform_field_options_'. $i);
44
+
45
+ $newfield = array();
46
+ $newfield['label'] = $label;
47
+ $newfield['type'] = wpbdp_getv($pre_2_1_types, intval($type), 'textfield');
48
+ $newfield['validator'] = wpbdp_getv($pre_2_1_validators, $validation, null);
49
+ $newfield['association'] = wpbdp_getv($pre_2_1_associations, $association, 'meta');
50
+ $newfield['is_required'] = $required == 'yes' ? true : false;
51
+ $newfield['display_options'] = serialize(
52
+ array('show_in_excerpt' => $show_in_excerpt == 'yes' ? true : false,
53
+ 'hide_field' => $hide_field == 'yes' ? true : false)
54
+ );
55
+ $newfield['field_data'] = $options ? serialize(array('options' => explode(',', $options))) : null;
56
+
57
+ if ($wpdb->insert($wpdb->prefix . 'wpbdp_form_fields', $newfield)) {
58
+ delete_option('wpbusdirman_postform_field_label_' . $i);
59
+ delete_option('wpbusdirman_postform_field_type_' . $i);
60
+ delete_option('wpbusdirman_postform_field_validation_' . $i);
61
+ delete_option('wpbusdirman_postform_field_association_' . $i);
62
+ delete_option('wpbusdirman_postform_field_required_' . $i);
63
+ delete_option('wpbusdirman_postform_field_showinexcerpt_' . $i);
64
+ delete_option('wpbusdirman_postform_field_hide_' . $i);
65
+ delete_option('wpbusdirman_postform_field_options_' . $i);
66
+ delete_option('wpbusdirman_postform_field_order_' . $i);
67
+ }
68
+
69
+ }
70
+ }
71
+
72
+ }
includes/admin/upgrades/migrations/migration-2_2.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__2_2 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+ $wpdb->query("ALTER TABLE {$wpdb->prefix}wpbdp_form_fields CHARACTER SET utf8 COLLATE utf8_general_ci");
8
+ $wpdb->query("ALTER TABLE {$wpdb->prefix}wpbdp_form_fields CHANGE `label` `label` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL");
9
+ $wpdb->query("ALTER TABLE {$wpdb->prefix}wpbdp_form_fields CHANGE `description` `description` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL");
10
+ }
11
+
12
+ }
includes/admin/upgrades/migrations/migration-2_3.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__2_3 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ $count = $wpdb->get_var(
9
+ sprintf("SELECT COUNT(*) FROM {$wpdb->prefix}options WHERE option_name LIKE '%%%s%%'", 'wpbusdirman_settings_fees_label_'));
10
+
11
+ for ($i = 1; $i <= $count; $i++) {
12
+ $label = get_option('_settings_fees_label_' . $i, get_option('wpbusdirman_settings_fees_label_' . $i));
13
+ $amount = get_option('_settings_fees_amount' . $i, get_option('wpbusdirman_settings_fees_amount_' . $i, '0.00'));
14
+ $days = intval( get_option('_settings_fees_increment_' . $i, get_option('wpbusdirman_settings_fees_increment_' . $i, 0)) );
15
+ $images = intval( get_option('_settings_fees_images_' . $i, get_option('wpbusdirman_settings_fees_images_' . $i, 0)) );
16
+ $categories = get_option('_settings_fees_categories_' . $i, get_option('wpbusdirman_settings_fees_categories_' . $i, ''));
17
+
18
+ $newfee = array();
19
+ $newfee['label'] = $label;
20
+ $newfee['amount'] = $amount;
21
+ $newfee['days'] = $days;
22
+ $newfee['images'] = $images;
23
+
24
+ $category_data = array('all' => false, 'categories' => array());
25
+ if ($categories == '0') {
26
+ $category_data['all'] = true;
27
+ } else {
28
+ foreach (explode(',', $categories) as $category_id) {
29
+ $category_data['categories'][] = intval($category_id);
30
+ }
31
+ }
32
+
33
+ $newfee['categories'] = serialize($category_data);
34
+
35
+ if ($wpdb->insert($wpdb->prefix . 'wpbdp_fees', $newfee)) {
36
+ $new_id = $wpdb->insert_id;
37
+
38
+ $query = $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value = %s AND {$wpdb->postmeta}.post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = %s)",
39
+ $new_id, '_wpbdp_listingfeeid', $i, 'wpbdm-directory');
40
+ $wpdb->query($query);
41
+
42
+ foreach (array('label', 'amount', 'increment', 'images', 'categories') as $k) {
43
+ delete_option('wpbusdirman_settings_fees_' . $k . '_' . $i);
44
+ delete_option('_settings_fees_' . $k . '_' . $i);
45
+ }
46
+ }
47
+
48
+ }
49
+ }
50
+
51
+ }
includes/admin/upgrades/migrations/migration-2_4.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__2_4 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+ global $wpbdp;
8
+
9
+ $fields = $wpbdp->formfields->get_fields();
10
+
11
+ foreach ($fields as &$field) {
12
+ $query = $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s AND {$wpdb->postmeta}.post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = %s)",
13
+ '_wpbdp[fields][' . $field->get_id() . ']', $field->get_label(), 'wpbdm-directory');
14
+ $wpdb->query($query);
15
+ }
16
+ }
17
+
18
+ }
includes/admin/upgrades/migrations/migration-2_5.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__2_5 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ wpbdp_log('Updating payment/sticky status values.');
9
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s", '_wpbdp[sticky]', '_wpbdp_sticky'));
10
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value = %s", 'sticky', '_wpbdp[sticky]', 'approved'));
11
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value != %s", 'pending', '_wpbdp[sticky]', 'approved'));
12
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s", '_wpbdp[payment_status]', '_wpbdp_paymentstatus'));
13
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value != %s", 'not-paid', '_wpbdp[payment_status]', 'paid'));
14
+
15
+ // Misc updates
16
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_totalallowedimages'));
17
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_termlength'));
18
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_costoflisting'));
19
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_listingfeeid'));
20
+
21
+ wpbdp_log('Updating listing images to new framework.');
22
+
23
+ $old_images = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_image'));
24
+ foreach ($old_images as $old_image) {
25
+ require_once(ABSPATH . 'wp-admin/includes/file.php');
26
+ require_once(ABSPATH . 'wp-admin/includes/image.php');
27
+
28
+ $filename = ABSPATH . 'wp-content/uploads/wpbdm/' . $old_image->meta_value;
29
+
30
+ $wp_filetype = wp_check_filetype(basename($filename), null);
31
+
32
+ $attachment_id = wp_insert_attachment(array(
33
+ 'post_mime_type' => $wp_filetype['type'],
34
+ 'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
35
+ 'post_content' => '',
36
+ 'post_status' => 'inherit'
37
+ ), $filename, $old_image->post_id);
38
+ $attach_data = wp_generate_attachment_metadata( $attachment_id, $filename );
39
+ wp_update_attachment_metadata( $attachment_id, $attach_data );
40
+ }
41
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_image'));
42
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp_thumbnail'));
43
+ }
44
+
45
+ }
includes/admin/upgrades/migrations/migration-3_1.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Migrations__3_1 {
3
+
4
+ public function migrate() {
5
+ global $wpdb;
6
+
7
+ $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_type = %s WHERE post_type = %s", WPBDP_POST_TYPE, 'wpbdm-directory'));
8
+
9
+ if (function_exists('flush_rewrite_rules'))
10
+ flush_rewrite_rules(false);
11
+ }
12
+
13
+ }
includes/admin/upgrades/migrations/migration-3_2.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Migrations__3_2 {
3
+
4
+ /*
5
+ * This update converts all form fields to a new, more flexible format that uses a new API introduced in BD 2.3.
6
+ */
7
+ public function migrate() {
8
+ global $wpdb;
9
+
10
+ $validators_trans = array(
11
+ 'EmailValidator' => 'email',
12
+ 'URLValidator' => 'url',
13
+ 'IntegerNumberValidator' => 'integer_number',
14
+ 'DecimalNumberValidator' => 'decimal_number',
15
+ 'DateValidator' => 'date_'
16
+ );
17
+
18
+ $old_fields = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wpbdp_form_fields" );
19
+
20
+ foreach ( $old_fields as &$f ) {
21
+ $newfield = array();
22
+ $newfield['field_type'] = strtolower( $f->type );
23
+
24
+ if ( empty( $newfield['field_type'] ) )
25
+ $newfield['field_type'] = 'textfield';
26
+
27
+ $newfield['display_flags'] = array();
28
+ $newfield['field_data'] = array();
29
+ $newfield['validators'] = array();
30
+
31
+ // display options
32
+ $f_display_options = array_merge(array('show_in_excerpt' => true, 'show_in_listing' => true, 'show_in_search' => true), $f->display_options ? (array) unserialize($f->display_options) : array());
33
+ if ( isset( $f_display_options['hide_field'] ) && $f_display_options['hide_field'] ) {
34
+ // do nothing
35
+ } else {
36
+ if ( $f_display_options['show_in_excerpt'] ) $newfield['display_flags'][] = 'excerpt';
37
+ if ( $f_display_options['show_in_listing'] ) $newfield['display_flags'][] = 'listing';
38
+ if ( $f_display_options['show_in_search'] ) $newfield['display_flags'][] = 'search';
39
+ }
40
+
41
+ // validators
42
+ if ( $f->validator && isset( $validators_trans[ $f->validator ] ) ) $newfield['validators'] = array( $validators_trans[ $f->validator ] );
43
+ if ( $f->is_required ) $newfield['validators'][] = 'required';
44
+
45
+ // options for multivalued fields
46
+ $f_data = $f->field_data ? unserialize( $f->field_data ) : null;
47
+ $f_data = is_array( $f_data ) ? $f_data : array();
48
+
49
+ if ( isset( $f_data['options'] ) && is_array( $f_data['options'] ) ) $newfield['field_data']['options'] = $f_data['options'];
50
+ if ( isset( $f_data['open_in_new_window'] ) && $f_data['open_in_new_window'] ) $newfield['field_data']['open_in_new_window'] = true;
51
+
52
+ if ( $newfield['field_type'] == 'textfield' && in_array( 'url', $newfield['validators']) )
53
+ $newfield['field_type'] = 'url';
54
+
55
+ $newfield['display_flags'] = implode( ',', $newfield['display_flags'] );
56
+ $newfield['validators'] = implode( ',', $newfield['validators'] );
57
+ $newfield['field_data'] = serialize( $newfield['field_data'] );
58
+
59
+ $wpdb->update( "{$wpdb->prefix}wpbdp_form_fields", $newfield, array( 'id' => $f->id ) );
60
+ }
61
+
62
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields DROP COLUMN validator;" );
63
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields DROP COLUMN display_options;" );
64
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields DROP COLUMN is_required;" );
65
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields DROP COLUMN type;" );
66
+
67
+ add_action( 'admin_notices', array( $this, 'disable_regions_in_3_2_upgrade' ) );
68
+ }
69
+
70
+ public function disable_regions_in_3_2_upgrade() {
71
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
72
+
73
+ if ( class_exists( 'WPBDP_RegionsPlugin' ) && version_compare( WPBDP_RegionsPlugin::VERSION, '1.1', '<' ) ) {
74
+ deactivate_plugins( 'business-directory-regions/business-directory-regions.php', true );
75
+ echo sprintf( '<div class="error"><p>%s</p></div>',
76
+ _x( '<b>Business Directory Plugin - Regions Module</b> was disabled because it is incompatible with the current version of Business Directory. Please update the Regions module.', 'installer', 'WPBDM' )
77
+ );
78
+ }
79
+ }
80
+
81
+ }
includes/admin/upgrades/migrations/migration-3_4.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__3_4 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ $query = $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listing_fees SET email_sent = %d WHERE email_sent = %d", 2, 1 );
9
+ $wpdb->query( $query );
10
+ }
11
+
12
+ }
includes/admin/upgrades/migrations/migration-3_5.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__3_5 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->term_taxonomy} SET taxonomy = %s WHERE taxonomy = %s", WPBDP_CATEGORY_TAX, 'wpbdm-category' ) );
8
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->term_taxonomy} SET taxonomy = %s WHERE taxonomy = %s", WPBDP_TAGS_TAX, 'wpbdm-tags' ) );
9
+ }
10
+
11
+ }
includes/admin/upgrades/migrations/migration-3_6.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__3_6 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_form_fields MODIFY id bigint(20) AUTO_INCREMENT" );
9
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_fees MODIFY id bigint(20) AUTO_INCREMENT" );
10
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_payments MODIFY id bigint(20) AUTO_INCREMENT" );
11
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_listing_fees MODIFY id bigint(20) AUTO_INCREMENT" );
12
+
13
+ update_option(WPBDP_Settings::PREFIX . "listings-per-page", get_option("posts_per_page"));
14
+ }
15
+
16
+ }
includes/admin/upgrades/migrations/migration-3_7.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__3_7 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ // Try to disable incompatible modules.
9
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
10
+
11
+ if ( is_plugin_active( 'business-directory-regions/business-directory-regions.php' ) ) {
12
+ deactivate_plugins( 'business-directory-regions/business-directory-regions.php' );
13
+ }
14
+
15
+ // Remove invalid listing fees (quick).
16
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id NOT IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = %s)", WPBDP_POST_TYPE ) );
17
+ $wpdb->query( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE category_id NOT IN (SELECT term_id FROM {$wpdb->terms})" );
18
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_listing_fees DROP charged" );
19
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_listing_fees DROP updated_on" );
20
+
21
+ // Update notify-admin email option.
22
+ if ( get_option( WPBDP_Settings::PREFIX . 'notify-admin', false ) )
23
+ update_option( WPBDP_Settings::PREFIX . 'admin-notifications', array( 'new-listing') );
24
+
25
+ $this->request_manual_upgrade( 'upgrade_to_3_7_migrate_payments' );
26
+ }
27
+
28
+ public function upgrade_to_3_7_migrate_payments() {
29
+ global $wpdb;
30
+
31
+ $status_msg = '';
32
+
33
+ // Remove/update listing fees.
34
+ if ( ! $wpdb->get_col( $wpdb->prepare( "SHOW COLUMNS FROM {$wpdb->prefix}wpbdp_listing_fees LIKE %s", 'migrated' ) ) )
35
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_listing_fees ADD migrated tinyint(1) DEFAULT 0" );
36
+
37
+ $n_fees = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_listing_fees" ) );
38
+ $n_fees_migrated = intval( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_listing_fees WHERE migrated = %d", 1 ) ) );
39
+ $fees_done = ( $n_fees_migrated == $n_fees ) ? true : false;
40
+
41
+ if ( ! $fees_done ) {
42
+ $status_msg = sprintf( _x( 'Cleaning up listing fees information... %d/%d', 'installer', 'WPBDM' ), $n_fees_migrated, $n_fees );
43
+
44
+ $fees = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE migrated = %d ORDER BY id ASC LIMIT 50", 0 ), ARRAY_A );
45
+
46
+ foreach ( $fees as &$f ) {
47
+ // Delete fee if category does not exist.
48
+ if ( ! term_exists( intval( $f['category_id'] ), WPBDP_CATEGORY_TAX ) ) {
49
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d", $f['id'] ) );
50
+ } else {
51
+ // Delete duplicated listing fees.
52
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id < %d AND category_id = %d AND listing_id = %d",
53
+ $f['id'],
54
+ $f['category_id'],
55
+ $f['listing_id'] ) );
56
+
57
+ $f['fee'] = (array) unserialize( $f['fee'] );
58
+ $f['fee_days'] = abs( intval( $f['fee']['days'] ) );
59
+ $f['fee_images'] = abs( intval( $f['fee']['images'] ) );
60
+ $f['fee_id'] = intval( $f['fee']['id'] );
61
+ $f['fee'] = '';
62
+ $f['migrated'] = 1;
63
+
64
+ unset( $f['fee'] );
65
+
66
+ if ( ! $f['expires_on'] )
67
+ unset( $f['expires_on'] );
68
+
69
+ $wpdb->update( $wpdb->prefix . 'wpbdp_listing_fees', $f, array( 'id' => $f['id'] ) );
70
+ }
71
+ }
72
+ }
73
+
74
+ // Migrate transactions.
75
+ $transactions_done = false;
76
+
77
+ if ( $fees_done ) {
78
+ if ( ! $wpdb->get_col( $wpdb->prepare( "SHOW COLUMNS FROM {$wpdb->prefix}wpbdp_payments LIKE %s", 'migrated' ) ) )
79
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_payments ADD migrated tinyint(1) DEFAULT 0" );
80
+
81
+ $n_transactions = intval( $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_payments" ) );
82
+ $n_transactions_migrated = intval( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_payments WHERE migrated = %d", 1 ) ) );
83
+ $transactions_done = ( $n_transactions_migrated == $n_transactions ) ? true : false;
84
+
85
+ if ( $transactions_done ) {
86
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_payments DROP payment_type" );
87
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_payments DROP migrated" );
88
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_listing_fees DROP fee" );
89
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_listing_fees DROP migrated" );
90
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", '_wpbdp[payment_status]' ) );
91
+ } else {
92
+ $status_msg = sprintf( _x( 'Migrating previous transactions to new Payments API... %d/%d', 'installer', 'WPBDM' ), $n_transactions_migrated, $n_transactions );
93
+
94
+ $transactions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_payments WHERE migrated = %d ORDER BY id ASC LIMIT 50", 0 ), ARRAY_A );
95
+
96
+ foreach ( $transactions as &$t ) {
97
+ $t['status'] = 'approved' == $t['status'] ? 'completed' : ( 'pending' == $t['status'] ? 'pending' : 'rejected' );
98
+ $t['currency_code'] = get_option( 'wpbdp-currency' );
99
+ $t['migrated'] = 1;
100
+
101
+ if ( ! isset( $t['processed_on'] ) || empty( $t['processed_on'] ) )
102
+ unset( $t['processed_on'] );
103
+
104
+ if ( ! isset( $t['created_on'] ) || empty( $t['created_on'] ) )
105
+ unset( $t['created_on'] );
106
+
107
+ if ( ! isset( $t['listing_id'] ) || empty( $t['listing_id'] ) )
108
+ $t['listing_id'] = 0;
109
+
110
+ if ( ! isset( $t['amount'] ) || empty( $t['amount'] ) )
111
+ $t['amount'] = '0.0';
112
+
113
+ // TODO: delete duplicated pending transactions (i.e. two renewals for the same category & listing ID that are 'pending').
114
+
115
+ switch ( $t['payment_type'] ) {
116
+ case 'initial':
117
+ $wpdb->insert( $wpdb->prefix . 'wpbdp_payments_items',
118
+ array( 'payment_id' => $t['id'],
119
+ 'amount' => $t['amount'],
120
+ 'item_type' => 'charge',
121
+ 'description' => _x( 'Initial listing payment (BD < 3.4)', 'installer', 'WPBDM' )
122
+ ) );
123
+ $wpdb->update( $wpdb->prefix . 'wpbdp_payments', $t, array( 'id' => $t['id'] ) );
124
+
125
+ break;
126
+
127
+ case 'edit':
128
+ $wpdb->insert( $wpdb->prefix . 'wpbdp_payments_items',
129
+ array( 'payment_id' => $t['id'],
130
+ 'amount' => $t['amount'],
131
+ 'item_type' => 'charge',
132
+ 'description' => _x( 'Listing edit payment (BD < 3.4)', 'installer', 'WPBDM' )
133
+ ) );
134
+ $wpdb->update( $wpdb->prefix . 'wpbdp_payments', $t, array( 'id' => $t['id'] ) );
135
+
136
+ break;
137
+
138
+ case 'renewal':
139
+ $data = unserialize( $t['extra_data'] );
140
+ $fee_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d", $data['renewal_id'] ) );
141
+
142
+ if ( ! $fee_info || ! term_exists( intval( $fee_info->category_id ), WPBDP_CATEGORY_TAX ) ) {
143
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_payments WHERE id = %d", $t['id'] ) );
144
+ continue;
145
+ }
146
+
147
+ $fee_info->fee = unserialize( $fee_info->fee );
148
+
149
+ $item = array();
150
+ $item['payment_id'] = $t['id'];
151
+ $item['amount'] = $t['amount'];
152
+ $item['item_type'] = 'fee';
153
+ $item['description'] = sprintf( _x( 'Renewal fee "%s" for category "%s"', 'installer', 'WPBDM' ),
154
+ $fee_info->fee['label'],
155
+ wpbdp_get_term_name( $fee_info->category_id ) );
156
+ $item['data'] = serialize( array( 'fee' => $fee_info->fee ) );
157
+ $item['rel_id_1'] = $fee_info->category_id;
158
+ $item['rel_id_2'] = $fee_info->fee['id'];
159
+
160
+ $wpdb->insert( $wpdb->prefix . 'wpbdp_payments_items', $item );
161
+ $wpdb->update( $wpdb->prefix . 'wpbdp_payments', $t, array( 'id' => $t['id'] ) );
162
+
163
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d", $data['renewal_id'] ) );
164
+
165
+ break;
166
+
167
+ case 'upgrade-to-sticky':
168
+ $wpdb->insert( $wpdb->prefix . 'wpbdp_payments_items',
169
+ array( 'payment_id' => $t['id'],
170
+ 'amount' => $t['amount'],
171
+ 'item_type' => 'upgrade',
172
+ 'description' => _x( 'Listing upgrade to featured', 'installer', 'WPBDM' )
173
+ ) );
174
+ $wpdb->update( $wpdb->prefix . 'wpbdp_payments', $t, array( 'id' => $t['id'] ) );
175
+
176
+ break;
177
+
178
+ default:
179
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_payments WHERE id = %d", $t['id'] ) );
180
+ break;
181
+ }
182
+
183
+ }
184
+ }
185
+ }
186
+
187
+ $res = array( 'ok' => true,
188
+ 'done' => $transactions_done,
189
+ 'status' => $status_msg );
190
+
191
+ return $res;
192
+ }
193
+
194
+ }
includes/admin/upgrades/migrations/migration-3_9.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__3_9 {
4
+
5
+ public function migrate() {
6
+ // TODO: make sure this works when passing through manual 3.7 upgrade.
7
+ global $wpdb;
8
+
9
+ if ( $wpdb->get_col( $wpdb->prepare( "SHOW COLUMNS FROM {$wpdb->prefix}wpbdp_submit_state LIKE %s", 'created' ) ) )
10
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_submit_state DROP COLUMN created" );
11
+
12
+ if ( $wpdb->get_col( $wpdb->prepare( "SHOW COLUMNS FROM {$wpdb->prefix}wpbdp_submit_state LIKE %s", 'updated' ) ) ) {
13
+ $wpdb->query( "UPDATE {$wpdb->prefix}wpbdp_submit_state SET updated_on = updated" );
14
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_submit_state DROP COLUMN updated" );
15
+ }
16
+ }
17
+
18
+ }
includes/admin/upgrades/migrations/migration-4_0.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__4_0 {
4
+
5
+ public function migrate() {
6
+ $o = (bool) get_option( WPBDP_Settings::PREFIX . 'send-email-confirmation', false );
7
+
8
+ if ( ! $o ) {
9
+ update_option( WPBDP_Settings::PREFIX . 'user-notifications', array( 'listing-published' ) );
10
+ }
11
+ delete_option( WPBDP_Settings::PREFIX . 'send-email-confirmation' );
12
+ }
13
+
14
+ }
includes/admin/upgrades/migrations/migration-5_0.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__5_0 {
4
+
5
+ /**
6
+ * This upgrade routine takes care of the term splitting feature that is going to be introduced in WP 4.2.
7
+ * @since 3.6.4
8
+ */
9
+ public function migrate() {
10
+ global $wp_version;
11
+
12
+ if ( ! function_exists( 'wp_get_split_term' ) )
13
+ return;
14
+
15
+ $terms = $this->gather_pre_split_term_ids();
16
+ foreach ( $terms as $term_id )
17
+ $this->process_term_split( $term_id );
18
+ }
19
+
20
+ /**
21
+ * @since 3.6.4
22
+ */
23
+ private function gather_pre_split_term_ids() {
24
+ global $wpdb;
25
+
26
+ $res = array();
27
+
28
+ // Fees.
29
+ $fees = $wpdb->get_col( "SELECT categories FROM {$wpdb->prefix}wpbdp_fees" );
30
+ foreach ( $fees as $f ) {
31
+ $data = unserialize( $f );
32
+
33
+ if ( isset( $data['all'] ) && $data['all'] )
34
+ continue;
35
+
36
+ if ( ! empty( $data['categories'] ) )
37
+ $res = array_merge( $res, $data['categories'] );
38
+
39
+ }
40
+
41
+ // Listing fees.
42
+ if ( $fee_ids = $wpdb->get_col( "SELECT DISTINCT category_id FROM {$wpdb->prefix}wpbdp_listing_fees" ) ) {
43
+ $res = array_merge( $res, $fee_ids );
44
+ }
45
+
46
+ // Payments.
47
+ $payments_terms = $wpdb->get_col(
48
+ $wpdb->prepare( "SELECT DISTINCT rel_id_1 FROM {$wpdb->prefix}wpbdp_payments_items WHERE ( item_type = %s OR item_type = %s )",
49
+ 'fee',
50
+ 'recurring_fee' )
51
+ );
52
+ $res = array_merge( $res, $payments_terms );
53
+
54
+ // Category images.
55
+ $imgs = get_option( 'wpbdp[category_images]', false );
56
+ if ( $imgs && is_array( $imgs ) ) {
57
+ if ( !empty ( $imgs['images'] ) )
58
+ $res = array_merge( $res, array_keys( $imgs['images'] ) );
59
+
60
+ if ( ! empty( $imgs['temp'] ) )
61
+ $res = array_merge( $res, array_keys( $imgs['temp'] ) );
62
+ }
63
+
64
+ return array_map( 'intval', array_unique( $res ) );
65
+ }
66
+
67
+ /**
68
+ * Use this function to update BD references of a pre-split term ID to use the new term ID.
69
+ * @since 3.6.4
70
+ */
71
+ public function process_term_split( $old_id = 0 ) {
72
+ global $wpdb;
73
+
74
+ if ( ! $old_id )
75
+ return;
76
+
77
+ $new_id = wp_get_split_term( $old_id, WPBDP_CATEGORY_TAX );
78
+ if ( ! $new_id )
79
+ return;
80
+
81
+ // Fees.
82
+ $fees = $wpdb->get_results( "SELECT id, categories FROM {$wpdb->prefix}wpbdp_fees" );
83
+ foreach ( $fees as &$f ) {
84
+ $categories = unserialize( $f->categories );
85
+
86
+ if ( ( isset( $categories['all'] ) && $categories['all'] ) || empty( $categories['categories'] ) )
87
+ continue;
88
+
89
+ $index = array_search( $old_id, $categories['categories'] );
90
+
91
+ if ( $index === false )
92
+ continue;
93
+
94
+ $categories['categories'][ $index ] = $new_id;
95
+ $wpdb->update( $wpdb->prefix . 'wpbdp_fees',
96
+ array( 'categories' => serialize( $categories ) ),
97
+ array( 'id' => $f->id ) );
98
+ }
99
+
100
+ // Listing fees.
101
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listing_fees SET category_id = %d WHERE category_id = %d",
102
+ $new_id,
103
+ $old_id ) );
104
+
105
+ // Payments.
106
+ $wpdb->query(
107
+ $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_payments_items SET rel_id_1 = %d WHERE ( rel_id_1 = %d AND ( item_type = %s OR item_type = %s ) )",
108
+ $new_id,
109
+ $old_id,
110
+ 'fee',
111
+ 'recurring_fee' )
112
+ );
113
+
114
+ // Category images.
115
+ $imgs = get_option( 'wpbdp[category_images]', false );
116
+ if ( empty( $imgs ) || ! is_array( $imgs ) )
117
+ return;
118
+
119
+ if ( ! empty( $imgs['images'] ) && isset( $imgs['images'][ $old_id ] ) ) {
120
+ $imgs['images'][ $new_id ] = $imgs['images'][ $old_id ];
121
+ unset( $imgs['images'][ $old_id ] );
122
+ }
123
+
124
+ if ( ! empty( $imgs['temp'] ) && isset( $imgs['temp'][ $old_id ] ) ) {
125
+ $imgs['temp'][ $new_id ] = $imgs['temp'][ $old_id ];
126
+ unset( $imgs['temp'][ $old_id ] );
127
+ }
128
+
129
+ update_option( 'wpbdp[category_images]', $imgs );
130
+ }
131
+
132
+ }
includes/admin/upgrades/migrations/migration-6_0.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPBDP__Migrations__6_0 {
4
+
5
+ public function migrate() {
6
+ global $wpdb;
7
+
8
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}wpbdp_payments MODIFY created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" );
9
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_payments SET processed_on = NULL WHERE processed_on = %s", '0000-00-00 00:00:00' ) );
10
+ }
11
+
12
+ }
includes/admin/upgrades/migrations/migration-7_0.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Migrations__7_0 {
3
+
4
+ public function migrate() {
5
+ global $wpdb;
6
+
7
+ $fields = $wpdb->get_results( $wpdb->prepare( "SELECT id, field_type FROM {$wpdb->prefix}wpbdp_form_fields WHERE field_type IN (%s, %s, %s, %s) AND association = %s",
8
+ 'select', 'multiselect', 'checkbox', 'radio', 'meta' ) );
9
+
10
+ foreach ( $fields as $f ) {
11
+ $listing_values = $wpdb->get_results( $wpdb->prepare( "SELECT meta_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s",
12
+ '_wpbdp[fields][' . $f->id . ']' ) );
13
+
14
+ foreach ( $listing_values as $lv ) {
15
+ $v = maybe_unserialize( $lv->meta_value );
16
+
17
+ if ( in_array( $f->field_type, array( 'select', 'radio' ), true ) ) {
18
+ if ( is_array( $v ) )
19
+ $v = array_pop( $v );
20
+ } else {
21
+ if ( is_array( $v ) )
22
+ $v = implode( "\t", $v );
23
+ }
24
+
25
+ $wpdb->update( $wpdb->postmeta, array( 'meta_value' => $v ), array( 'meta_id' => $lv->meta_id ) );
26
+ }
27
+ }
28
+ }
29
+
30
+ }
includes/admin/upgrades/migrations/migration-8_0.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Migrations__8_0 {
3
+
4
+ public function migrate() {
5
+ if ( get_option( WPBDP_Settings::PREFIX . 'show-search-form-in-results', false ) )
6
+ update_option( WPBDP_Settings::PREFIX . 'search-form-in-results', 'above' );
7
+ delete_option( WPBDP_Settings::PREFIX . 'show-search-form-in-results' );
8
+ }
9
+
10
+ }
includes/class-assets.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Assets {
6
+
7
+ public function __construct() {
8
+ add_action( 'wp_enqueue_scripts', array( $this, 'register_common_scripts' ) );
9
+ add_action( 'admin_enqueue_scripts', array( $this, 'register_common_scripts' ) );
10
+
11
+ // Scripts & styles.
12
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
13
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_css_override' ), 9999, 0 );
14
+
15
+ $this->register_image_sizes();
16
+ }
17
+
18
+ /**
19
+ * Registers scripts and styles that can be used either by frontend or backend code.
20
+ * The scripts are just registered, not enqueued.
21
+ *
22
+ * @since 3.4
23
+ */
24
+ public function register_common_scripts() {
25
+ wp_register_script(
26
+ 'jquery-file-upload-iframe-transport',
27
+ WPBDP_URL . 'vendors/jQuery-File-Upload-9.5.7/js/jquery.iframe-transport.min.js'
28
+ );
29
+ wp_register_script(
30
+ 'jquery-file-upload',
31
+ WPBDP_URL . 'vendors/jQuery-File-Upload-9.5.7/js/jquery.fileupload.min.js',
32
+ array( 'jquery', 'jquery-ui-widget', 'jquery-file-upload-iframe-transport' )
33
+ );
34
+ wp_register_script(
35
+ 'jquery-breakpoints',
36
+ WPBDP_URL . 'vendors/jquery-breakpoints.min.js',
37
+ array( 'jquery' ),
38
+ null,
39
+ true
40
+ );
41
+
42
+ // Views
43
+ wp_register_script(
44
+ 'wpbdp-checkout',
45
+ WPBDP_URL . 'assets/js/checkout.js',
46
+ array( 'wpbdp-js' ),
47
+ WPBDP_VERSION
48
+ );
49
+
50
+ // Drag & Drop.
51
+ wp_register_style( 'wpbdp-dnd-upload', WPBDP_URL . 'assets/css/dnd-upload.min.css', array(), WPBDP_VERSION );
52
+ wp_register_script( 'wpbdp-dnd-upload', WPBDP_URL . 'assets/js/dnd-upload.min.js', array( 'jquery-file-upload' ), WPBDP_VERSION );
53
+
54
+ // Select2.
55
+ wp_register_style( 'wpbdp-js-select2-css', WPBDP_URL . 'vendors/select2-4.0.3/css/select2.min.css' );
56
+ wp_register_script( 'wpbdp-js-select2', WPBDP_URL . 'vendors/select2-4.0.3/js/select2.full.min.js', array( 'jquery' ) );
57
+ }
58
+
59
+ public function enqueue_scripts() {
60
+ $only_in_plugin_pages = true;
61
+ $enqueue_scripts_and_styles = apply_filters( 'wpbdp_should_enqueue_scripts_and_styles', wpbdp()->is_plugin_page() );
62
+
63
+ wp_enqueue_style( 'wpbdp-widgets', WPBDP_URL . 'assets/css/widgets.min.css' );
64
+
65
+ if ( $only_in_plugin_pages && ! $enqueue_scripts_and_styles )
66
+ return;
67
+
68
+ wp_register_style( 'wpbdp-base-css', WPBDP_URL . 'assets/css/wpbdp.min.css', array( 'wpbdp-js-select2-css' ), WPBDP_VERSION );
69
+
70
+ wp_register_script(
71
+ 'wpbdp-js',
72
+ WPBDP_URL . 'assets/js/wpbdp.min.js',
73
+ array( 'jquery', 'jquery-breakpoints', 'wpbdp-js-select2', 'jquery-ui-sortable' ),
74
+ WPBDP_VERSION
75
+ );
76
+
77
+ wp_localize_script( 'wpbdp-js', 'wpbdp_global', array(
78
+ 'ajaxurl' => wpbdp_ajaxurl()
79
+ ) );
80
+
81
+ wp_enqueue_style( 'wpbdp-dnd-upload' );
82
+ wp_enqueue_script( 'wpbdp-dnd-upload' );
83
+
84
+ if ( wpbdp_get_option( 'use-thickbox' ) ) {
85
+ add_thickbox();
86
+ }
87
+
88
+ wp_enqueue_style( 'wpbdp-base-css' );
89
+ wp_enqueue_script( 'wpbdp-js' );
90
+
91
+ do_action( 'wpbdp_enqueue_scripts' );
92
+
93
+ // enable legacy css (should be removed in a future release) XXX
94
+ if (_wpbdp_template_mode('single') == 'template' || _wpbdp_template_mode('category') == 'template' )
95
+ wp_enqueue_style('wpbdp-legacy-css', WPBDP_URL . 'assets/css/wpbdp-legacy.min.css');
96
+ }
97
+
98
+ /**
99
+ * @since 3.5.3
100
+ */
101
+ public function enqueue_css_override() {
102
+ $stylesheet_dir = trailingslashit( get_stylesheet_directory() );
103
+ $stylesheet_dir_uri = trailingslashit( get_stylesheet_directory_uri() );
104
+ $template_dir = trailingslashit( get_template_directory() );
105
+ $template_dir_uri = trailingslashit( get_template_directory_uri() );
106
+
107
+ $folders_uris = array(
108
+ array( trailingslashit( WP_PLUGIN_DIR ), trailingslashit( WP_PLUGIN_URL ) ),
109
+ array( $stylesheet_dir, $stylesheet_dir_uri ),
110
+ array( $stylesheet_dir . 'css/', $stylesheet_dir_uri . 'css/' )
111
+ );
112
+
113
+ if ( $template_dir != $stylesheet_dir ) {
114
+ $folders_uris[] = array( $template_dir, $template_dir_uri );
115
+ $folders_uris[] = array( $template_dir . 'css/', $template_dir_uri . 'css/' );
116
+ }
117
+
118
+ $filenames = array( 'wpbdp.css',
119
+ 'wpbusdirman.css',
120
+ 'wpbdp_custom_style.css',
121
+ 'wpbdp_custom_styles.css',
122
+ 'wpbdm_custom_style.css',
123
+ 'wpbdm_custom_styles.css' );
124
+
125
+ $n = 0;
126
+ foreach ( $folders_uris as $folder_uri ) {
127
+ list( $dir, $uri ) = $folder_uri;
128
+
129
+ foreach ( $filenames as $f ) {
130
+ if ( file_exists( $dir . $f ) ) {
131
+ wp_enqueue_style( 'wpbdp-custom-' . $n, $uri . $f );
132
+ $n++;
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ public function register_image_sizes() {
139
+ $thumbnail_width = absint( wpbdp_get_option( 'thumbnail-width' ) );
140
+ $thumbnail_height = absint( wpbdp_get_option( 'thumbnail-height' ) );
141
+
142
+ $max_width = absint( wpbdp_get_option('image-max-width') );
143
+ $max_height = absint( wpbdp_get_option('image-max-height') );
144
+
145
+ $crop = (bool) wpbdp_get_option( 'thumbnail-crop' );
146
+
147
+ add_image_size( 'wpbdp-mini', 50, 50, true ); // Used for the submit process.
148
+ add_image_size( 'wpbdp-thumb', $thumbnail_width, $crop ? $thumbnail_height : 9999, $crop ); // Thumbnail size.
149
+ add_image_size( 'wpbdp-large', $max_width, $max_height, false ); // Large size.
150
+ }
151
+
152
+ }
153
+
includes/class-cpt-integration.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__CPT_Integration {
6
+
7
+ public function __construct() {
8
+ $this->register_post_type();
9
+ }
10
+
11
+ private function register_post_type() {
12
+ // Listing type.
13
+ $args = array(
14
+ 'labels' => array(
15
+ 'name' => _x( 'Directory', 'post type general name', 'WPBDM' ),
16
+ 'singular_name' => _x( 'Listing', 'post type singular name', 'WPBDM' ),
17
+ 'add_new' => _x( 'Add New Listing', 'listing', 'WPBDM' ),
18
+ 'add_new_item' => _x( 'Add New Listing', 'post type', 'WPBDM' ),
19
+ 'edit_item' => __( 'Edit Listing', 'WPBDM' ),
20
+ 'new_item' => __( 'New Listing', 'WPBDM' ),
21
+ 'view_item' => __( 'View Listing', 'WPBDM' ),
22
+ 'search_items' => __( 'Search Listings', 'WPBDM' ),
23
+ 'not_found' => __( 'No listings found', 'WPBDM' ),
24
+ 'not_found_in_trash' => __( 'No listings found in trash', 'WPBDM' )
25
+ ),
26
+ 'public' => true,
27
+ 'menu_icon' => WPBDP_URL . 'assets/images/menuico.png',
28
+ 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments', 'custom-fields' ),
29
+ 'rewrite' => array(
30
+ 'slug' => wpbdp_get_option( 'permalinks-directory-slug', WPBDP_POST_TYPE ),
31
+ 'with_front' => true,
32
+ 'feeds' => true
33
+ )
34
+ );
35
+ register_post_type( WPBDP_POST_TYPE, $args );
36
+
37
+ // Category tax.
38
+ $cat_args = array(
39
+ 'labels' => array(
40
+ 'name' => __( 'Directory Categories', 'WPBDM' ),
41
+ 'singular_name' => __( 'Directory Category', 'WPBDM' )
42
+ ),
43
+ 'hierarchical' => true,
44
+ 'public' => true,
45
+ 'rewrite' => array( 'slug' => wpbdp_get_option( 'permalinks-category-slug', WPBDP_CATEGORY_TAX ) )
46
+ );
47
+ register_taxonomy( WPBDP_CATEGORY_TAX, WPBDP_POST_TYPE, $cat_args );
48
+
49
+ // Tag tax.
50
+ $tags_args = array(
51
+ 'labels' => array(
52
+ 'name' => __( 'Directory Tags', 'WPBDM' ),
53
+ 'singular_name' => __( 'Directory Tag', 'WPBDM' )
54
+ ),
55
+ 'hierarchical' => false,
56
+ 'public' => true,
57
+ 'rewrite' => array( 'slug' => wpbdp_get_option( 'permalinks-tags-slug', WPBDP_TAGS_TAX ) )
58
+ );
59
+
60
+ $tags_slug = wpbdp_get_option( 'permalinks-tags-slug', WPBDP_TAGS_TAX );
61
+ register_taxonomy( WPBDP_TAGS_TAX, WPBDP_POST_TYPE, $tags_args );
62
+ }
63
+
64
+ public function register_hooks() {
65
+ add_filter( 'post_type_link', array( &$this, '_post_link' ), 10, 3 );
66
+ add_filter( 'get_shortlink', array( &$this, '_short_link' ), 10, 4 );
67
+ // add_filter('post_type_link', array($this, '_post_link_qtranslate'), 11, 2); // basic support for qTranslate
68
+ add_filter('preview_post_link', array($this, '_preview_post_link'), 10, 2);
69
+
70
+ add_filter('term_link', array($this, '_category_link'), 10, 3);
71
+ add_filter('term_link', array($this, '_tag_link'), 10, 3);
72
+
73
+ add_filter('comments_open', array($this, '_allow_comments'), 10, 2);
74
+
75
+ add_action( 'before_delete_post', array( &$this, 'after_listing_delete' ) );
76
+ add_action( 'delete_term', array( &$this, 'handle_delete_term' ), 10, 3 );
77
+
78
+ add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );
79
+ }
80
+
81
+ public function _category_link($link, $category, $taxonomy) {
82
+ if ( WPBDP_CATEGORY_TAX != $taxonomy )
83
+ return $link;
84
+
85
+ if ( ! wpbdp_rewrite_on() ) {
86
+ if ( wpbdp_get_option( 'disable-cpt' ) )
87
+ return wpbdp_url( '/' ) . '&_' . wpbdp_get_option( 'permalinks-category-slug' ) . '=' . $category->slug;
88
+
89
+ return $link;
90
+ }
91
+
92
+ $link = wpbdp_url( sprintf( '/%s/%s/', wpbdp_get_option( 'permalinks-category-slug' ), $category->slug ) );
93
+
94
+ return apply_filters( 'wpbdp_category_link', $link, $category );
95
+ }
96
+
97
+ public function _tag_link($link, $tag, $taxonomy) {
98
+ if ( WPBDP_TAGS_TAX != $taxonomy )
99
+ return $link;
100
+
101
+ if ( ! wpbdp_rewrite_on() ) {
102
+ if ( wpbdp_get_option( 'disable-cpt' ) )
103
+ $link = wpbdp_url( '/' ) . '&_' . wpbdp_get_option( 'permalinks-tags-slug' ) . '=' . $tag->slug;
104
+
105
+ return $link;
106
+ }
107
+
108
+ $link = wpbdp_url( sprintf( '/%s/%s/', wpbdp_get_option( 'permalinks-tags-slug' ), $tag->slug ) );
109
+
110
+ return $link;
111
+ }
112
+
113
+ public function _post_link( $link, $post = null, $leavename = false ) {
114
+ if ( WPBDP_POST_TYPE != get_post_type( $post ) )
115
+ return $link;
116
+
117
+ if ( $querystring = parse_url( $link, PHP_URL_QUERY ) )
118
+ $querystring = '?' . $querystring;
119
+ else
120
+ $querystring = '';
121
+
122
+ if ( ! wpbdp_rewrite_on() ) {
123
+ if ( wpbdp_get_option( 'disable-cpt' ) ) {
124
+ $link = wpbdp_url( '/' ) . '&' . '_' . wpbdp_get_option( 'permalinks-directory-slug' ) . '=' . $post->post_name;
125
+ }
126
+ } else {
127
+ if ( $leavename )
128
+ return wpbdp_url( '/' . '%' . WPBDP_POST_TYPE . '%' . '/' . $querystring );
129
+
130
+ if ( wpbdp_get_option( 'permalinks-no-id' ) ) {
131
+ if ( $post->post_name ) {
132
+ $link = wpbdp_url( '/' . $post->post_name . '/' );
133
+ } else {
134
+ // Use default $link.
135
+ return $link;
136
+ }
137
+ } else {
138
+ $link = wpbdp_url( '/' . $post->ID . '/' . ( $post->post_name ? $post->post_name : '' ) );
139
+ }
140
+
141
+ $link .= $querystring;
142
+ }
143
+
144
+ return apply_filters( 'wpbdp_listing_link', $link, $post->ID );
145
+ }
146
+
147
+ public function _short_link( $shortlink, $id = 0, $context = 'post', $allow_slugs = true ) {
148
+ if ( 'post' !== $context || WPBDP_POST_TYPE != get_post_type( $id ) )
149
+ return $shortlink;
150
+
151
+ $post = get_post( $id );
152
+ return $this->_post_link( $shortlink, $post );
153
+ }
154
+
155
+ public function _post_link_qtranslate( $url, $post ) {
156
+ if ( is_admin() || !function_exists( 'qtrans_convertURL' ) )
157
+ return $url;
158
+
159
+ global $q_config;
160
+
161
+ $lang = isset( $_GET['lang'] ) ? $_GET['lang'] : $q_config['language'];
162
+ $default_lang = $q_config['default_language'];
163
+
164
+ if ( $lang != $default_lang )
165
+ return add_query_arg( 'lang', $lang, $url );
166
+
167
+ return $url;
168
+ }
169
+
170
+ public function _preview_post_link( $url, $post = null ) {
171
+ if ( is_null( $post ) && isset( $GLOBALS['post'] ) )
172
+ $post = $GLOBALS['post'];
173
+
174
+ if ( WPBDP_POST_TYPE != get_post_type( $post ) )
175
+ return $url ;
176
+
177
+ if ( wpbdp_rewrite_on() ) {
178
+ if ( ! wpbdp_get_option( 'permalinks-no-id' ) || ! empty( $post->post_name ) ) {
179
+ $url = remove_query_arg( array( 'post_type', 'p' ), $url );
180
+ }
181
+ }
182
+
183
+ return $url;
184
+ }
185
+
186
+ public function _allow_comments($open, $post_id) {
187
+ // comments on directory pages
188
+ if ($post_id == wpbdp_get_page_id('main'))
189
+ return false;
190
+
191
+ // comments on listings
192
+ if ( get_post_type( $post_id ) == WPBDP_POST_TYPE ) {
193
+ return in_array(
194
+ wpbdp_get_option( 'allow-comments-in-listings' ),
195
+ array( 'allow-comments', 'allow-comments-and-insert-template' )
196
+ );
197
+ }
198
+
199
+ return $open;
200
+ }
201
+
202
+ /**
203
+ * Handles cleanup after a listing is deleted.
204
+ * @since 3.4
205
+ */
206
+ public function after_listing_delete( $post_id ) {
207
+ if ( WPBDP_POST_TYPE != get_post_type( $post_id ) )
208
+ return;
209
+
210
+ $listing = wpbdp_get_listing( $post_id );
211
+ $listing->after_delete( 'delete_post' );
212
+ }
213
+
214
+ /**
215
+ * @since 5.0
216
+ */
217
+ public function save_post( $post_id, $post, $update ) {
218
+ if ( WPBDP_POST_TYPE != $post->post_type )
219
+ return;
220
+
221
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
222
+ return;
223
+
224
+ if ( ! $update ) {
225
+ wpbdp_insert_log( array( 'log_type' => 'listing.created', 'object_id' => $post_id ) );
226
+ }
227
+
228
+ if ( 'auto-draft' == $post->post_status )
229
+ return;
230
+
231
+ $listing = wpbdp_get_listing( $post_id );
232
+ $listing->_after_save( 'save_post' );
233
+ }
234
+
235
+ public function handle_delete_term( $term_id, $tt_id, $taxonomy ) {
236
+ global $wpdb;
237
+
238
+ if ( WPBDP_CATEGORY_TAX != $taxonomy )
239
+ return;
240
+ }
241
+
242
+ }
includes/class-cron.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Cron {
6
+
7
+ public function __construct() {
8
+ $this->schedule_events();
9
+ }
10
+
11
+ private function schedule_events() {
12
+ if ( ! wp_next_scheduled( 'wpbdp_hourly_events' ) )
13
+ wp_schedule_event( current_time( 'timestamp' ), 'hourly', 'wpbdp_hourly_events' );
14
+
15
+ if ( ! wp_next_scheduled( 'wpbdp_daily_events' ) )
16
+ wp_schedule_event( current_time( 'timestamp' ), 'daily', 'wpbdp_daily_events' );
17
+ }
18
+
19
+ }
includes/class-dispatcher.php CHANGED
@@ -1,10 +1,9 @@
1
  <?php
2
- require_once( WPBDP_INC . 'class-view.php' );
3
 
4
  /**
5
  * @since 4.0
6
  */
7
-
8
  class WPBDP__Dispatcher {
9
 
10
  private $current_view = '';
@@ -16,6 +15,9 @@ class WPBDP__Dispatcher {
16
  add_action( 'wp', array( $this, '_lookup_current_view' ) );
17
  add_action( 'template_redirect', array( $this, '_execute_view' ), 11 );
18
  add_action( 'wp_enqueue_scripts', array( $this, '_enqueue_view_scripts' ) );
 
 
 
19
  }
20
 
21
  public function _lookup_current_view( $wp ) {
@@ -32,6 +34,23 @@ class WPBDP__Dispatcher {
32
  if ( ! empty( $wp_query->wpbdp_view ) )
33
  $this->current_view = $wp_query->wpbdp_view;
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  $this->current_view = apply_filters( 'wpbdp_current_view', $this->current_view );
36
  $this->current_view_obj = $this->load_view( $this->current_view );
37
 
@@ -70,9 +89,39 @@ class WPBDP__Dispatcher {
70
  $this->current_view_obj->enqueue_resources();
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  public function get_view_locations() {
74
  $dirs = array();
75
- $dirs[] = WPBDP_INC . 'views/';
 
76
 
77
  return apply_filters( 'wpbdp_view_locations', $dirs );
78
  }
1
  <?php
2
+ require_once( WPBDP_PATH . 'includes/class-view.php' );
3
 
4
  /**
5
  * @since 4.0
6
  */
 
7
  class WPBDP__Dispatcher {
8
 
9
  private $current_view = '';
15
  add_action( 'wp', array( $this, '_lookup_current_view' ) );
16
  add_action( 'template_redirect', array( $this, '_execute_view' ), 11 );
17
  add_action( 'wp_enqueue_scripts', array( $this, '_enqueue_view_scripts' ) );
18
+
19
+ add_action( 'wp_ajax_wpbdp_ajax', array( $this, '_ajax_dispatch' ) );
20
+ add_action( 'wp_ajax_nopriv_wpbdp_ajax', array( $this, '_ajax_dispatch' ) );
21
  }
22
 
23
  public function _lookup_current_view( $wp ) {
34
  if ( ! empty( $wp_query->wpbdp_view ) )
35
  $this->current_view = $wp_query->wpbdp_view;
36
 
37
+ // if ( ! $wp_query->wpbdp_is_main_page ) {
38
+ // return;
39
+ // }
40
+
41
+ // If the page contains the submit listing shortcode, dispatch it as if it were the current view.
42
+ // TODO: this is a very special case that we should probably generalize somehow for other shortcodes.
43
+ if ( ! empty( $GLOBALS['post'] ) && 'page' == $GLOBALS['post']->post_type && ! empty( $GLOBALS['post']->post_content ) ) {
44
+ $submit_shortcodes = array( 'businessdirectory-submit-listing', 'businessdirectory-submitlisting', 'business-directory-submitlisting', 'business-directory-submit-listing', 'WPBUSDIRMANADDLISTING' );
45
+
46
+ foreach ( $submit_shortcodes as $test_shortcode ) {
47
+ if ( has_shortcode( $GLOBALS['post']->post_content, $test_shortcode ) ) {
48
+ $this->current_view = 'submit_listing';
49
+ break;
50
+ }
51
+ }
52
+ }
53
+
54
  $this->current_view = apply_filters( 'wpbdp_current_view', $this->current_view );
55
  $this->current_view_obj = $this->load_view( $this->current_view );
56
 
89
  $this->current_view_obj->enqueue_resources();
90
  }
91
 
92
+ /**
93
+ * @since 5.0
94
+ */
95
+ public function _ajax_dispatch() {
96
+ if ( empty( $_REQUEST['handler'] ) )
97
+ return;
98
+
99
+ $handler = trim( $_REQUEST['handler'] );
100
+ $handler = WPBDP__Utils::normalize( $handler );
101
+
102
+ $parts = explode( '__', $handler );
103
+ $view_name = $parts[0];
104
+ $function = isset( $parts[1] ) ? $parts[1] : '';
105
+
106
+ $view = $this->load_view( $view_name );
107
+ if ( ! $view )
108
+ return;
109
+
110
+ if ( ! $function )
111
+ $function = 'ajax_dispatch';
112
+ else
113
+ $function = 'ajax_' . $function;
114
+
115
+ if ( ! method_exists( $view, $function ) )
116
+ return;
117
+
118
+ return call_user_func( array( $view, $function ) );
119
+ }
120
+
121
  public function get_view_locations() {
122
  $dirs = array();
123
+ $dirs[] = WPBDP_PATH . 'includes/views/';
124
+ $dirs[] = WPBDP_PATH . 'core/views/';
125
 
126
  return apply_filters( 'wpbdp_view_locations', $dirs );
127
  }
includes/class-fee-plan.php CHANGED
@@ -1,145 +1,306 @@
1
  <?php
2
- require_once( WPBDP_INC . 'db/class-db-entity.php' );
 
 
 
3
 
 
4
 
5
- class WPBDP_Fee_Plan extends WPBDP_DB_Entity {
 
 
 
 
 
6
 
7
- static $_table_name = 'wpbdp_fees';
8
- static $_serialized = array( 'categories', 'extra_data' );
9
 
 
 
10
 
11
- public function __construct( $args = array() ) {
12
- parent::__construct( $args );
13
- $this->sanitize(); // XXX: Maybe this can be done for ALL entities at construct time?
14
- }
15
 
16
- protected function sanitize() {
17
- $this->label = trim( $this->label );
18
- $this->amount = floatval( trim( $this->amount ) );
19
- $this->images = absint( $this->images );
20
- $this->days = absint( $this->days );
21
- $this->sticky = (bool) $this->sticky;
22
 
23
- if ( 'free' == $this->tag ) {
24
- $this->amount = 0.0;
25
- $this->sticky = false;
26
- $this->categories = array( 'all' => true, 'categories' => array() );
27
- $this->enabled = true;
28
  }
 
29
 
30
- $this->categories = wp_parse_args( $this->categories,
31
- array( 'all' => false, 'categories' => array() ) );
32
- $this->categories['categories'] = array_map( 'absint', $this->categories['categories'] );
 
 
 
 
 
 
33
 
34
- // Adding 0 as a supported category is a shortcut to allowing all categories.
35
- if ( in_array( 0, $this->categories['categories'], true ) ) {
36
- $this->categories['all'] = true;
37
- $this->categories['categories'] = array();
 
 
 
 
 
38
  }
 
39
 
40
- if ( ! is_array( $this->extra_data ) )
41
- $this->extra_data = array();
42
  }
43
 
44
- protected function validate() {
45
- if ( ! $this->label )
46
- $this->errors->add( 'label', _x('Fee label is required.', 'fees-api', 'WPBDM') );
47
 
48
- if ( $this->amount < 0.0 )
49
- $this->errors->add( 'amount', _x('Fee amount must be a non-negative decimal number.', 'fees-api', 'WPBDM') );
50
 
51
- if ( ! $this->categories || ( empty( $this->categories['all'] ) && empty( $this->categories['categories'] ) ) )
52
- $this->errors->add( 'categories', _x('Fee must apply to at least one category.', 'fees-api', 'WPBDM') );
53
 
54
- // limit 'duration' because of TIMESTAMP limited range (issue #157).
55
- // FIXME: this is not a long-term fix. we should move to DATETIME to avoid this entirely.
56
- if ( $this->days > 3650 )
57
- $this->errors->add( 'days', _x('Fee listing duration must be a number less than 10 years (3650 days).', 'fees-api', 'WPBDM') );
58
- }
59
 
60
- public function save( $validate = true ) {
61
- // For backwards compat.
62
- $fee = (array) $this;
63
- do_action_ref_array( 'wpbdp_fee_before_save', array( &$fee ) );
64
 
65
- if ( 'free' == $this->tag ) {
66
- global $_wpbdp_fee_plan_recursion_guard;
67
- $_wpbdp_fee_plan_recursion_guard = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
- // Update associated settings.
70
- wpbdp_set_option( 'free-images', $this->images );
71
- wpbdp_set_option( 'listing-duration', $this->days );
 
72
 
73
- $_wpbdp_fee_plan_recursion_guard = false;
 
74
  }
75
 
76
- return parent::save( $validate );
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
  public function supports_category( $category_id ) {
80
- if ( $this->categories['all'] )
81
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- $requested_cats = wpbdp_get_parent_catids( $category_id );
 
 
84
 
85
- foreach ( $this->categories['categories'] as $s_cat_id ) {
86
- if ( in_array( $s_cat_id, $requested_cats ) )
87
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
 
90
- return false;
91
  }
92
 
93
- public static function for_category( $category_id ) {
94
- return self::filter_for_category( self::find(), $category_id );
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
- private static function filter_for_category( $fees, $category_id ) {
98
- $res = array();
 
 
 
 
 
 
99
 
100
- foreach ( $fees as $f ) {
101
- if ( $f->supports_category( $category_id ) )
102
- $res[] = $f;
103
  }
104
 
105
- return $res;
 
 
 
 
106
  }
107
 
108
- public static function active_fees_for_category( $category_id ) {
109
- return self::filter_for_category( self::active_fees(), $category_id );
 
 
 
 
 
 
 
 
 
 
110
  }
111
 
112
- public static function active_fees() {
113
- if ( wpbdp_payments_possible() ) {
114
- $fees = self::find( array( 'enabled' => 1, '-tag' => 'free' ) );
115
- } else {
116
- $fees = self::find( array( 'enabled' => 1, 'tag' => 'free' ) );
117
  }
118
 
119
- return $fees;
 
 
120
  }
121
 
122
- public static function get_free_plan() {
123
- return self::find( array( 'tag' => 'free', '_limit' => 1 ) );
124
- }
 
 
 
 
 
 
125
 
126
- static function before_find( $args ) {
127
- if ( $args['limit'] > 0 || $args['order'] )
128
- return $args;
129
 
130
- $order = wpbdp_get_option( 'fee-order' );
 
 
131
 
132
- if ( ! $order )
133
- return $args;
 
 
 
 
 
 
 
134
 
135
- $args['orderby'] = ( 'custom' == $order['method'] ) ? 'weight' : $order['method'];
136
- $args['order'] = ( 'custom' == $order['method'] ) ? 'DESC' : $order['order'];
 
 
137
 
138
- return $args;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
- public static function create( $args ) { return parent::_create( $args, __class__ ); }
142
- public static function find( $args = '' ) { return parent::_find( $args, __class__ ); }
 
 
 
 
 
 
143
 
 
 
 
 
 
 
 
 
144
  }
145
 
 
1
  <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ final class WPBDP__Fee_Plan {
6
 
7
+ private $id = 0;
8
 
9
+ private $label = '';
10
+ private $description = '';
11
+ private $amount = 0.0;
12
+ private $days = 0;
13
+ private $images = 0;
14
+ private $enabled = true;
15
 
16
+ private $sticky = false;
17
+ private $recurring = false;
18
 
19
+ private $pricing_model = 'flat';
20
+ private $pricing_details = array();
21
 
22
+ private $supported_categories = 'all';
 
 
 
23
 
24
+ private $weight = 0;
25
+ private $tag = '';
26
+ private $extra_data = array();
 
 
 
27
 
28
+
29
+ public function __construct( $data = array() ) {
30
+ if ( $data ) {
31
+ $this->setup_plan( $data );
 
32
  }
33
+ }
34
 
35
+ public function __get( $key ) {
36
+ if ( method_exists( $this, 'get_' . $key ) ) {
37
+ $value = call_user_func( array( $this, 'get_' . $key ) );
38
+ } else {
39
+ $value = $this->{$key};
40
+ }
41
+
42
+ return $value;
43
+ }
44
 
45
+ public function __set( $key, $value ) {
46
+ $this->{$key} = $value;
47
+ }
48
+
49
+ public function __isset( $key ) {
50
+ if ( property_exists( $this, $key ) ) {
51
+ return false === empty( $this->{$key} );
52
+ } else {
53
+ return null;
54
  }
55
+ }
56
 
57
+ public function exists() {
58
+ return ! empty( $this->id );
59
  }
60
 
61
+ public function save( $fire_hooks = true ) {
62
+ global $wpdb;
 
63
 
64
+ // Validate.
65
+ $validation_errors = $this->validate();
66
 
67
+ if ( ! empty( $validation_errors ) ) {
68
+ $error = new WP_Error();
69
 
70
+ foreach ( $validation_errors as $col => $msg ) {
71
+ $error->add( 'validation_error', $msg, array( 'field' => $col ) );
72
+ }
 
 
73
 
74
+ return $error;
75
+ }
 
 
76
 
77
+ if ( $fire_hooks ) {
78
+ do_action_ref_array( 'wpbdp_fee_before_save', array( $this ) );
79
+ }
80
+
81
+ $row = array();
82
+ foreach ( get_object_vars( $this ) as $key => $value ) {
83
+ $row[ $key ] = $value;
84
+ }
85
+
86
+ if ( ! $this->exists() ) {
87
+ unset( $row[ 'id' ] );
88
+ }
89
+
90
+ $row['pricing_details'] = serialize( $row['pricing_details'] );
91
+
92
+ if ( 'all' !== $row['supported_categories'] ) {
93
+ $row['supported_categories'] = implode( ',', $row['supported_categories'] );
94
+ }
95
+
96
+ if ( empty( $row['extra_data'] ) ) {
97
+ unset( $row['extra_data'] );
98
+ } else {
99
+ $row['extra_data'] = serialize( $row['extra_data'] );
100
+ }
101
+
102
+ $saved = false;
103
+ $update = $this->exists();
104
+ if ( $update ) {
105
+ $saved = $wpdb->update( $wpdb->prefix . 'wpbdp_plans', $row, array( 'id' => $this->id ) );
106
+ } else {
107
+ $saved = $wpdb->insert( $wpdb->prefix . 'wpbdp_plans', $row );
108
 
109
+ if ( $saved ) {
110
+ $this->id = $wpdb->insert_id;
111
+ }
112
+ }
113
 
114
+ if ( $saved && $fire_hooks ) {
115
+ do_action( 'wpbdp_fee_save', $this, $update );
116
  }
117
 
118
+ return $saved;
119
+ }
120
+
121
+ public function update( $data ) {
122
+ unset( $data['id'] );
123
+ $this->setup_plan( $data );
124
+ return $this->save();
125
+ }
126
+
127
+ public function delete() {
128
+ global $wpdb;
129
+ return $wpdb->delete( $wpdb->prefix . 'wpbdp_plans', array( 'id' => $this->id ) );
130
  }
131
 
132
  public function supports_category( $category_id ) {
133
+ return $this->supports_category_selection( array( $category_id ) );
134
+ }
135
+
136
+ /**
137
+ * @since 5.0
138
+ */
139
+ public function get_feature_list() {
140
+ $items = array();
141
+
142
+ if ( wpbdp_get_option( 'allow-images' ) ) {
143
+ if ( ! $this->images )
144
+ $items['images'] = _x( 'No images allowed.', 'fee plan', 'WPBDM' );
145
+ else
146
+ $items['images'] = sprintf( _nx( '%d image allowed.', '%d images allowed.', $this->images, 'fee plan', 'WPBDM' ), $this->images );
147
+ }
148
 
149
+ $items = apply_filters( 'wpbdp_plan_feature_list', $items, $this );
150
+ return $items;
151
+ }
152
 
153
+ /**
154
+ * @since 5.0
155
+ */
156
+ public function calculate_amount( $categories = array() ) {
157
+ $amount = 0.0;
158
+ $pricing_info = $this->pricing_details;
159
+
160
+ switch ( $this->pricing_model ) {
161
+ case 'variable':
162
+ $amount = array_sum( wp_array_slice_assoc( $pricing_info, $categories ) );
163
+ break;
164
+ case 'extra':
165
+ $amount = $this->amount + ( $pricing_info['extra'] * count( $categories ) );
166
+ break;
167
+ case 'flat':
168
+ default:
169
+ $amount = $this->amount;
170
+ break;
171
  }
172
 
173
+ return $amount;
174
  }
175
 
176
+ /**
177
+ * @since 5.0
178
+ */
179
+ public function supports_category_selection( $categories = array() ) {
180
+ if ( ! $categories )
181
+ return true;
182
+
183
+ if ( is_string( $this->supported_categories ) && 'all' == $this->supported_categories )
184
+ return true;
185
+
186
+ if ( array_diff( $categories, $this->supported_categories ) )
187
+ return false;
188
+
189
+ return true;
190
  }
191
 
192
+ public static function get_instance( $fee_id ) {
193
+ global $wpdb;
194
+
195
+ $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_plans WHERE id = %d", $fee_id ), ARRAY_A );
196
+
197
+ if ( ! $row ) {
198
+ return false;
199
+ }
200
 
201
+ if ( 'all' !== $row['supported_categories'] ) {
202
+ $row['supported_categories'] = array_map( 'absint', explode( ',', $row['supported_categories'] ) );
 
203
  }
204
 
205
+ $row['pricing_details'] = maybe_unserialize( $row['pricing_details'] );
206
+ $row['extra_data'] = maybe_unserialize( $row['extra_data'] );
207
+
208
+ $instance = new self( $row );
209
+ return $instance;
210
  }
211
 
212
+ /**
213
+ * @since 5.0
214
+ */
215
+ public function calculate_expiration_time( $base_time ) {
216
+ if ( ! $base_time )
217
+ $base_time = current_time( 'timestamp' );
218
+
219
+ if ( $this->days == 0 )
220
+ return null;
221
+
222
+ $expire_time = strtotime( sprintf( '+%d days', $this->days ), $base_time );
223
+ return date( 'Y-m-d H:i:s', $expire_time );
224
  }
225
 
226
+ private function setup_plan( $data ) {
227
+ if ( is_object( $data ) ) {
228
+ $data = get_object_vars( $data );
 
 
229
  }
230
 
231
+ foreach ( $data as $key => $value ) {
232
+ $this->{$key} = $value;
233
+ }
234
  }
235
 
236
+ private function sanitize() {
237
+ $this->label = trim( $this->label );
238
+ $this->amount = floatval( trim( $this->amount ) );
239
+ $this->days = absint( $this->days );
240
+ $this->images = absint( $this->images );
241
+ $this->sticky = (bool) $this->sticky;
242
+ $this->recurring = (bool) $this->recurring;
243
+ $this->pricing_model = empty( $this->pricing_model ) ? 'flat' : $this->pricing_model;
244
+ $this->tag = strtolower( trim( $this->tag ) );
245
 
246
+ if ( empty( $this->supported_categories ) ) {
247
+ $this->supported_categories = 'all';
248
+ }
249
 
250
+ if ( 'all' !== $this->supported_categories ) {
251
+ $this->supported_categories = array_map( 'absint', (array) $this->supported_categories );
252
+ }
253
 
254
+ if ( 'extra' == $this->pricing_model ) {
255
+ $this->pricing_details = array( 'extra' => $this->pricing_details['extra'] );
256
+ } else {
257
+ unset( $this->pricing_details['extra'] );
258
+ }
259
+
260
+ // Unset details for categories that are not supported.
261
+ if ( 'variable' == $this->pricing_model ) {
262
+ $this->amount = 0.0;
263
 
264
+ if ( 'all' !== $this->supported_categories ) {
265
+ $this->pricing_details = wp_array_slice_assoc( $this->pricing_details, $this->supported_categories );
266
+ }
267
+ }
268
 
269
+ if ( 'flat' == $this->pricing_model ) {
270
+ $this->pricing_details = array();
271
+ }
272
+
273
+ if ( 0 == $this->days || ( 0 == $this->amount && 'flat' == $this->pricing_model ) ) {
274
+ $this->recurring = 0;
275
+ }
276
+
277
+ // Free plan is special.
278
+ if ( 'free' == $this->tag ) {
279
+ $this->amount = 0.0;
280
+ $this->sticky = false;
281
+ $this->recurring = false;
282
+ $this->supported_categories = 'all';
283
+ $this->enabled = true;
284
+ }
285
  }
286
 
287
+ private function validate() {
288
+ $this->sanitize();
289
+
290
+ $errors = array();
291
+
292
+ if ( ! $this->label ) {
293
+ $errors['label'] = _x( 'Fee label is required.', 'fees-api', 'WPBDM' );
294
+ }
295
 
296
+ // limit 'duration' because of TIMESTAMP limited range (issue #157).
297
+ // FIXME: this is not a long-term fix. we should move to DATETIME to avoid this entirely.
298
+ if ( $this->days > 3650 ) {
299
+ $errors['days'] = _x( 'Fee listing duration must be a number less than 10 years (3650 days).', 'fees-api', 'WPBDM' );
300
+ }
301
+
302
+ return $errors;
303
+ }
304
  }
305
 
306
+ require_once( WPBDP_INC . 'compatibility/deprecated/class-fee-plan.php' );
includes/class-fees-api.php CHANGED
@@ -7,28 +7,67 @@ class WPBDP_Fees_API {
7
 
8
  public function __construct() {
9
  $this->setup_default_fees();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
11
 
12
  private function setup_default_fees() {
13
  global $wpdb;
14
 
15
- if ( 0 === intval( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_fees WHERE tag = %s", 'free' ) ) ) ) {
16
  // Add free fee to the DB.
17
- $wpdb->insert( $wpdb->prefix . 'wpbdp_fees',
18
  array( 'id' => 0,
19
  'tag' => 'free',
20
  'label' => _x( 'Free Listing', 'fees-api', 'WPBDM' ),
21
  'amount' => 0.0,
22
  'images' => absint( wpbdp_get_option( 'free-images' ) ),
23
  'days' => absint( wpbdp_get_option( 'listing-duration' ) ),
24
- 'categories' => maybe_serialize( array( 'all' => true, 'categories' => array() ) ),
 
25
  'sticky' => 0,
26
  'enabled' => 1 ) );
27
  $fee_id = $wpdb->insert_id;
28
 
29
  // Update all "free fee" listings to use this.
30
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listing_fees SET fee_id = %d WHERE fee_id = %d", $fee_id, 0 ) );
31
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_payments_items SET rel_id_2 = %d WHERE rel_id_2 = %d AND item_type = %s", $fee_id, 0, 'fee' ) );
32
  }
33
  }
34
 
@@ -39,17 +78,17 @@ class WPBDP_Fees_API {
39
  public static function get_free_fee() { return false; }
40
 
41
  /**
42
- * @deprecated since 3.7. See {@link WPBDP_Fee_Plan}.
43
  */
44
  public function get_fees( $categories = null ) {
45
  global $wpdb;
46
 
47
  if ( ! $categories )
48
- return WPBDP_Fee_Plan::find();
49
 
50
  $fees = array();
51
  foreach ( $categories as $cat_id ) {
52
- $category_fees = WPBDP_Fee_Plan::for_category( $cat_id );
53
 
54
  // XXX: For now, we keep the free plan a 'secret' when payments are enabled. This is for backwards compat.
55
  if ( wpbdp_payments_possible() ) {
7
 
8
  public function __construct() {
9
  $this->setup_default_fees();
10
+
11
+ // Keep settings in sync with free plan.
12
+ add_action( "wpbdp_setting_updated_listing-duration", array( $this, 'sync_setting_with_free_plan' ), 10, 3 );
13
+ add_action( "wpbdp_setting_updated_free-images", array( $this, 'sync_setting_with_free_plan' ), 10, 3 );
14
+ add_action( 'wpbdp_fee_save', array( $this, 'sync_fee_plan_with_settings' ), 10, 2 );
15
+ }
16
+
17
+ public function sync_setting_with_free_plan( $value, $old_value, $setting_id ) {
18
+ if ( ! empty( $this->recursion_guard ) ) {
19
+ return;
20
+ }
21
+
22
+ $free_plan = wpbdp_get_fee_plan( 'free' );
23
+
24
+ switch ( $setting_id ) {
25
+ case 'listing-duration':
26
+ $free_plan->days = $value;
27
+ break;
28
+ case 'free-images':
29
+ $free_plan->images = $value;
30
+ break;
31
+ default:
32
+ break;
33
+ }
34
+
35
+ $free_plan->save( false );
36
+ }
37
+
38
+ public function sync_fee_plan_with_settings( $plan, $update ) {
39
+ if ( empty( $plan->tag ) || 'free' != $plan->tag ) {
40
+ return;
41
+ }
42
+
43
+ $this->recursion_guard = true;
44
+
45
+ wpbdp_set_option( 'listing-duration', $plan->days );
46
+ wpbdp_set_option( 'free-images', $plan->images );
47
+
48
+ unset( $this->recursion_guard );
49
  }
50
 
51
  private function setup_default_fees() {
52
  global $wpdb;
53
 
54
+ if ( 0 === intval( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_plans WHERE tag = %s", 'free' ) ) ) ) {
55
  // Add free fee to the DB.
56
+ $wpdb->insert( $wpdb->prefix . 'wpbdp_plans',
57
  array( 'id' => 0,
58
  'tag' => 'free',
59
  'label' => _x( 'Free Listing', 'fees-api', 'WPBDM' ),
60
  'amount' => 0.0,
61
  'images' => absint( wpbdp_get_option( 'free-images' ) ),
62
  'days' => absint( wpbdp_get_option( 'listing-duration' ) ),
63
+ 'supported_categories' => 'all',
64
+ 'pricing_model' => 'flat',
65
  'sticky' => 0,
66
  'enabled' => 1 ) );
67
  $fee_id = $wpdb->insert_id;
68
 
69
  // Update all "free fee" listings to use this.
70
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}wpbdp_listings SET fee_id = %d WHERE fee_id = %d OR fee_id IS NULL", $fee_id, 0 ) );
 
71
  }
72
  }
73
 
78
  public static function get_free_fee() { return false; }
79
 
80
  /**
81
+ * @deprecated since 3.7. See {@link wpbdp_get_fee_plans()}.
82
  */
83
  public function get_fees( $categories = null ) {
84
  global $wpdb;
85
 
86
  if ( ! $categories )
87
+ return wpbdp_get_fee_plans();
88
 
89
  $fees = array();
90
  foreach ( $categories as $cat_id ) {
91
+ $category_fees = wpbdp_get_fee_plans( array( 'categories' => $cat_id ) );
92
 
93
  // XXX: For now, we keep the free plan a 'secret' when payments are enabled. This is for backwards compat.
94
  if ( wpbdp_payments_possible() ) {
includes/class-gateway.php DELETED
@@ -1,163 +0,0 @@
1
- <?php
2
-
3
- abstract class WPBDP_Payment_Gateway {
4
-
5
- const INTEGRATION_BUTTON = 'button';
6
- const INTEGRATION_FORM = 'form';
7
- const CAPABILITIES_RECURRING = 'recurring';
8
-
9
- public function __construct() {
10
- }
11
-
12
- public function get_id() {
13
- return '';
14
- }
15
-
16
- public function get_gateway_url( $args = array() ) {
17
- return add_query_arg( array_merge( array( 'wpbdpx' => 'payments',
18
- 'action' => 'postback',
19
- 'gid' => $this->get_id() ),
20
- $args ),
21
- home_url('/') );
22
- }
23
-
24
- public function get_url( &$payment, $action = '' ) {
25
- // TODO: support pretty URLs
26
- return add_query_arg( array( 'wpbdpx' => 'payments',
27
- 'action' => $action,
28
- 'payment_id' => $payment->get_id() ),
29
- home_url( '/' ) );
30
- }
31
-
32
- public function get_name() {
33
- $classname = get_class( $this );
34
- $classname = str_replace( 'WPBDP' , '', $classname );
35
- $classname = str_replace( '_' , ' ', $classname );
36
- $classname = trim( $classname );
37
-
38
- return $classname;
39
- }
40
-
41
- public function register_config( &$settings ) { }
42
- abstract public function validate_config();
43
-
44
- public function get_supported_currencies() {
45
- return array();
46
- }
47
-
48
- abstract public function get_integration_method();
49
-
50
- public function get_capabilities() {
51
- return array();
52
- }
53
-
54
- /**
55
- * @since 3.5.8
56
- */
57
- public function has_capability( $cap ) {
58
- return in_array( $cap, $this->get_capabilities(), true );
59
- }
60
-
61
- public function render_unsubscribe_integration( &$category, &$listing) {}
62
-
63
- public function setup_payment( &$payment ) {}
64
-
65
- public function process_generic( $action = '' ) {
66
- return;
67
- }
68
-
69
- abstract public function process( &$payment, $action );
70
- abstract public function render_integration( &$payment );
71
-
72
- /**
73
- * @since 3.5.8
74
- */
75
- public function render_billing_information_form( &$payment, $args = array() ) {
76
- $defaults = array(
77
- 'action' => $this->get_url( $payment, 'process' ),
78
- 'posted' => $payment->get_data( 'billing-information' ),
79
- 'errors' => $payment->get_data( 'validation-errors' ),
80
- );
81
- $args = wp_parse_args( $args, $defaults );
82
- $args['payment'] = $payment;
83
-
84
- // Clear errors.
85
- $payment->set_data( 'billing-information', false );
86
- $payment->set_data( 'validation-errors', false );
87
- $payment->save();
88
-
89
- return wpbdp_render( 'billing-information-form', $args );
90
- }
91
-
92
- /**
93
- * @since 3.5.8
94
- */
95
- public function sanitize_billing_information( $data ) {
96
- $fields = array(
97
- 'email',
98
- 'first_name',
99
- 'last_name',
100
- 'cc_number',
101
- 'cc_exp_month',
102
- 'cc_exp_year',
103
- 'cc_cvc',
104
- 'address_country',
105
- 'address_state',
106
- 'address_city',
107
- 'address_line1',
108
- 'address_line2',
109
- 'zipcode',
110
- 'phone'
111
- );
112
-
113
- $sanitized_data = array();
114
-
115
- foreach ( $fields as $f )
116
- $sanitized_data[ $f ] = ! empty( $data[ $f ] ) ? trim( $data[ $f ] ) : '';
117
-
118
- if ( 2 == strlen( $sanitized_data['cc_exp_year'] ) )
119
- $sanitized_data['cc_exp_year'] = '20' . $sanitized_data['cc_exp_year'];
120
-
121
- return $sanitized_data;
122
- }
123
-
124
- /**
125
- * @since 3.5.8
126
- */
127
- public function validate_billing_information( &$payment ) {
128
- $errors = array();
129
-
130
- $data = $this->sanitize_billing_information( stripslashes_deep( $_POST ) );
131
-
132
- if ( ! $data['email'] || ! is_email( $data['email'] ) )
133
- $errors[] = _x( 'Please enter a valid e-mail address.', 'billing info', 'WPBDM' );
134
-
135
- if ( ! $data['first_name'] )
136
- $errors[] = _x( 'First name is required.', 'billing info', 'WPBDM' );
137
-
138
- if ( ! $data['last_name'] )
139
- $errors[] = _x( 'Last name is required.', 'billing info', 'WPBDM' );
140
-
141
- if ( ! $data['cc_number'] || ! is_numeric( $data['cc_number'] ) )
142
- $errors[] = _x( 'Credit card number is required.', 'billing info', 'WPBDM' );
143
-
144
- if ( ! $data['cc_exp_month'] || ! $data['cc_exp_year'] )
145
- $errors[] = _x( 'Credit card expiration date is invalid.', 'billing info', 'WPBDM' );
146
-
147
- if ( ! $data['cc_cvc'] )
148
- $errors[] = _x( 'Credit card CVC number is required.', 'billing info', 'WPBDM' );
149
-
150
- if ( ! $data['address_country'] )
151
- $errors[] = _x( 'Country is required.', 'billing info', 'WPBDM' );
152
-
153
- if ( ! $data['address_line1'] && ! $data['address_line2'] )
154
- $errors[] = _x( 'Address is required.', 'billing info', 'WPBDM' );
155
-
156
- $payment->set_data( 'billing-information', $data );
157
- $payment->set_data( 'validation-errors', $errors );
158
- $payment->save();
159
-
160
- return empty( $errors );
161
- }
162
-
163
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-listing-email-notification.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Listing_Email_Notification {
6
+
7
+ public function __construct() {
8
+ add_action( 'transition_post_status', array( $this, 'listing_published_notification' ), 10, 3 );
9
+ add_action( 'wpbdp_listing_status_change', array( $this, 'status_change_notifications' ), 10, 3 );
10
+ add_action( 'wpbdp_edit_listing', array( $this, 'edit_listing_admin_email' ) );
11
+
12
+ add_action( 'wpbdp_listing_maybe_send_notices', array( $this, 'send_notices' ), 10, 3 );
13
+ }
14
+
15
+ /**
16
+ * Sent when a listing is published either by the admin or automatically.
17
+ */
18
+ public function listing_published_notification( $new_status, $old_status, $post ) {
19
+ if ( WPBDP_POST_TYPE != get_post_type( $post ) )
20
+ return;
21
+
22
+ if ( $new_status == $old_status || 'publish' != $new_status || ( 'pending' != $old_status && 'draft' != $old_status ) )
23
+ return;
24
+
25
+ if ( ! in_array( 'listing-published', wpbdp_get_option( 'user-notifications' ), true ) )
26
+ return;
27
+
28
+ global $wpbdp;
29
+ if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
30
+ return;
31
+
32
+ $email = wpbdp_email_from_template( 'email-templates-listing-published', array(
33
+ 'listing' => get_the_title( $post->ID ),
34
+ 'listing-url' => get_permalink( $post->ID )
35
+ ) );
36
+ $email->to[] = wpbusdirman_get_the_business_email( $post->ID );
37
+ $email->template = 'businessdirectory-email';
38
+ $email->send();
39
+ }
40
+
41
+ /**
42
+ * Used to handle notifications related to listing status changes (i.e. expired, etc.)
43
+ */
44
+ public function status_change_notifications( $listing, $old_status, $new_status ) {
45
+ // Expiration notice.
46
+ if ( 'expired' == $new_status ) {
47
+ $this->send_notices( 'expiration', '0 days', $listing );
48
+ }
49
+
50
+ // When a listing is submitted.
51
+ if ( 'incomplete' == $old_status && ( 'complete' == $new_status || 'pending_payment' == $new_status ) ) {
52
+ $this->send_new_listing_email( $listing );
53
+ }
54
+ }
55
+
56
+ public function send_notices( $event, $relative_time, $listing, $force_resend = false ) {
57
+ $listing = is_object( $listing ) ? $listing : wpbdp_get_listing( absint( $listing ) );
58
+ if ( ! $listing ) {
59
+ return;
60
+ }
61
+
62
+ $post_status = get_post_status( $listing->get_id() );
63
+ if ( ! $post_status || in_array( $post_status, array( 'trash', 'auto-draft' ) ) ) {
64
+ return;
65
+ }
66
+
67
+ $all_notices = wpbdp_get_option( 'expiration-notices' );
68
+
69
+ foreach ( $all_notices as $notice_key => $notice ) {
70
+ if ( $notice['event'] != $event || $notice['relative_time'] != $relative_time )
71
+ continue;
72
+
73
+ if ( ( 'non-recurring' == $notice['listings'] && $listing->is_recurring() ) || ( 'recurring' == $notice['listings'] && ! $listing->is_recurring() ) )
74
+ continue;
75
+
76
+ $already_sent = (int) get_post_meta( $listing->get_id(), '_wpbdp_notice_sent_' . $notice_key, true );
77
+ if ( $already_sent && ! $force_resend )
78
+ continue;
79
+
80
+ $email = wpbdp_email_from_template(
81
+ $notice,
82
+ array(
83
+ 'site' => sprintf( '<a href="%s">%s</a>', get_bloginfo( 'url' ), get_bloginfo( 'name' ) ),
84
+ 'author' => $listing->get_author_meta( 'display_name' ),
85
+ 'listing' => sprintf( '<a href="%s">%s</a>', $listing->get_permalink(), esc_attr( $listing->get_title() ) ),
86
+ 'expiration' => date_i18n( get_option( 'date_format' ), strtotime( $listing->get_expiration_date() ) ),
87
+ 'link' => sprintf( '<a href="%1$s">%1$s</a>', $listing->get_renewal_url() ),
88
+ 'category' => get_the_term_list( $listing->get_id(), WPBDP_CATEGORY_TAX, '', ', ' )
89
+ ) );
90
+
91
+ $email->template = 'businessdirectory-email';
92
+ $email->to[] = wpbusdirman_get_the_business_email( $listing->get_id() );
93
+
94
+ if ( in_array( 'renewal', wpbdp_get_option( 'admin-notifications' ), true ) ) {
95
+ $email->cc[] = get_option( 'admin_email' );
96
+
97
+ if ( wpbdp_get_option( 'admin-notifications-cc' ) )
98
+ $email->cc[] = wpbdp_get_option( 'admin-notifications-cc' );
99
+ }
100
+
101
+ if ( $email->send() ) {
102
+ // update_post_meta( $listing->get_id(), '_wpbdp_notice_sent_' . $notice_key, current_time( 'timestamp' ) );
103
+ }
104
+ }
105
+ }
106
+
107
+ private function send_new_listing_email( $listing ) {
108
+ global $wpbdp;
109
+ if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
110
+ return;
111
+
112
+ // Notify the admin.
113
+ if ( in_array( 'new-listing', wpbdp_get_option( 'admin-notifications' ), true ) ) {
114
+ $admin_email = new WPBDP_Email();
115
+ $admin_email->subject = sprintf( _x( '[%s] New listing notification', 'notify email', 'WPBDM' ), get_bloginfo( 'name' ) );
116
+ $admin_email->to[] = get_bloginfo( 'admin_email' );
117
+
118
+ if ( wpbdp_get_option( 'admin-notifications-cc' ) )
119
+ $admin_email->cc[] = wpbdp_get_option( 'admin-notifications-cc' );
120
+
121
+ $admin_email->body = wpbdp_render( 'email/listing-added', array( 'listing' => $listing ), false );
122
+ $admin_email->send();
123
+ }
124
+
125
+ // Notify the submitter.
126
+ if ( in_array( 'new-listing', wpbdp_get_option( 'user-notifications' ), true ) ) {
127
+ $email = wpbdp_email_from_template( 'email-confirmation-message', array(
128
+ 'listing' => $listing->get_title()
129
+ ) );
130
+ $email->to[] = wpbusdirman_get_the_business_email( $listing->get_id() );
131
+ $email->template = 'businessdirectory-email';
132
+ $email->send();
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Sent when a listing is edited.
138
+ */
139
+ public function edit_listing_admin_email( $listing_id ) {
140
+ global $wpbdp;
141
+ if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
142
+ return;
143
+
144
+ if ( ! in_array( 'listing-edit', wpbdp_get_option( 'admin-notifications' ), true ) )
145
+ return;
146
+
147
+ $listing = wpbdp_get_listing( $listing_id );
148
+
149
+ $email = new WPBDP_Email();
150
+ $email->subject = sprintf( _x( '[%s] Listing edit notification', 'notify email', 'WPBDM' ), get_bloginfo( 'name' ) );
151
+ $email->to[] = get_bloginfo( 'admin_email' );
152
+
153
+ if ( wpbdp_get_option( 'admin-notifications-cc' ) )
154
+ $email->cc[] = wpbdp_get_option( 'admin-notifications-cc' );
155
+
156
+ $email->body = wpbdp_render( 'email/listing-edited', array( 'listing' => $listing ), false );
157
+
158
+ $email->send();
159
+ }
160
+
161
+ }
includes/class-listing-expiration.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Listing_Expiration {
6
+
7
+ function __construct() {
8
+ add_action( 'wpbdp_daily_events', array( $this, 'check_for_expired_listings' ) );
9
+ add_action( 'wpbdp_daily_events', array( $this, 'send_expiration_reminders' ) );
10
+ }
11
+
12
+ function check_for_expired_listings() {
13
+ global $wpdb;
14
+
15
+ $listings = $wpdb->get_col( $wpdb->prepare(
16
+ "SELECT p.ID FROM {$wpdb->posts} p JOIN {$wpdb->prefix}wpbdp_listings l ON l.listing_id = p.ID WHERE p.post_type = %s AND p.post_status != %s AND l.expiration_date IS NOT NULL AND l.expiration_date < %s AND l.listing_status NOT IN (%s, %s)",
17
+ WPBDP_POST_TYPE,
18
+ 'auto-draft',
19
+ current_time( 'mysql' ),
20
+ 'expired',
21
+ 'pending_renewal'
22
+ ) );
23
+
24
+ foreach ( $listings as $listing_id ) {
25
+ $l = wpbdp_get_listing( $listing_id );
26
+ $l->set_status( 'expired' );
27
+ }
28
+ }
29
+
30
+ function send_expiration_reminders() {
31
+ if ( ! wpbdp_get_option( 'listing-renewal' ) )
32
+ return;
33
+
34
+ $notices = wpbdp_get_option( 'expiration-notices', false );
35
+ if ( ! $notices )
36
+ return;
37
+
38
+ $notices = wp_list_filter( $notices, array( 'event' => 'expiration' ) );
39
+ $notices = wp_list_filter( $notices, array( 'relative_time' => '0 days' ), 'NOT' );
40
+ $times = array_unique( wp_list_pluck( $notices, 'relative_time' ) );
41
+
42
+ foreach ( $times as $t ) {
43
+ $listings = $this->get_expiring_listings( $t );
44
+
45
+ foreach ( $listings as $listing_id ) {
46
+ $listing = wpbdp_get_listing( $listing_id );
47
+ do_action( 'wpbdp_listing_maybe_send_notices', 'expiration', $t, $listing );
48
+ }
49
+ }
50
+ }
51
+
52
+ function get_expiring_listings( $period = '+1 month' ) {
53
+ global $wpdb;
54
+
55
+ $date_a = date( 'Y-m-d H:i:s', strtotime( $period . ' midnight' ) );
56
+ $date_b = date( 'Y-m-d H:i:s', strtotime( $period . 'midnight' ) + DAY_IN_SECONDS );
57
+
58
+ $listings = $wpdb->get_col( $wpdb->prepare(
59
+ "SELECT listing_id FROM {$wpdb->prefix}wpbdp_listings WHERE expiration_date IS NOT NULL AND expiration_date >= %s AND expiration_date < %s",
60
+ $date_a,
61
+ $date_b ) );
62
+
63
+ return $listings;
64
+ }
65
+
66
+ }
67
+
includes/class-listing-subscription.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WPBDP__Listing_Subscription {
3
+
4
+ private $parent_payment_id = 0;
5
+ private $listing_id = 0;
6
+ private $subscription_id = '';
7
+
8
+
9
+ public function __construct( $listing_id = 0, $subscription_id = '' ) {
10
+ $listing_id = absint( $listing_id );
11
+ $subscription_id = trim( $subscription_id );
12
+
13
+ if ( $listing_id ) {
14
+ $listing = wpbdp_get_listing( $listing_id );
15
+
16
+ if ( $listing && ! $listing->is_recurring() ) {
17
+ throw new Exception( 'Listing is not recurring!' );
18
+ }
19
+
20
+ if ( $listing ) {
21
+ $this->fill_data_from_db( 'listing_id', $listing_id );
22
+ return;
23
+ }
24
+ }
25
+
26
+ if ( ! $this->fill_data_from_db( 'subscription_id', $subscription_id ) ) {
27
+ throw new Exception( 'Subscription does not exist!' );
28
+ }
29
+ }
30
+
31
+ private function fill_data_from_db( $key, $val ) {
32
+ global $wpdb;
33
+
34
+ $row = $wpdb->get_row( $wpdb->prepare( "SELECT listing_id, subscription_id, subscription_data FROM {$wpdb->prefix}wpbdp_listings WHERE {$key} = %s", $val ) );
35
+ if ( ! $row )
36
+ return false;
37
+
38
+ $susc_id = $row->subscription_id;
39
+ $susc_data = $row->subscription_data ? unserialize( $row->subscription_data ) : array();
40
+
41
+ $this->listing_id = absint( $row->listing_id );
42
+ $this->subscription_id = $susc_id;
43
+ $this->parent_payment_id = ! empty( $susc_data['parent_payment_id'] ) ? absint( $susc_data['parent_payment_id'] ) : 0;
44
+
45
+ $this->data = $susc_data;
46
+ }
47
+
48
+ public function get_parent_payment() {
49
+ if ( $this->parent_payment_id ) {
50
+ return wpbdp_get_payment( $this->parent_payment_id );
51
+ }
52
+
53
+ return null;
54
+ }
55
+
56
+ public function get_payments() {
57
+ return ! empty( $this->data['payments'] ) ? $this->data['payments'] : array();
58
+ }
59
+
60
+ public function set_subscription_id( $subscription_id ) {
61
+ if ( empty( $subscription_id ) ) {
62
+ return;
63
+ }
64
+
65
+ $this->subscription_id = $subscription_id;
66
+ $this->save();
67
+ }
68
+
69
+ public function get_subscription_id() {
70
+ return $this->subscription_id;
71
+ }
72
+
73
+ public function record_payment( $args_or_payment = array() ) {
74
+ $parent_payment = $this->get_parent_payment();
75
+ $payments = $this->get_payments();
76
+
77
+ if ( is_array( $args_or_payment ) ) {
78
+ $args = wp_parse_args(
79
+ $args_or_payment,
80
+ array(
81
+ 'amount' => '0.0',
82
+ 'gateway_tx_id' => '',
83
+ 'gateway' => ''
84
+ )
85
+ );
86
+
87
+ if ( ! empty( $args['gateway_tx_id'] ) ) {
88
+ $p_id = $args['gateway_tx_id'];
89
+ $p_gateway = ( empty( $args['gateway'] ) && $parent_payment ) ? $parent_payment->gateway : $args['gateway'];
90
+ $payment = WPBDP_Payment::objects()->get( array( 'gateway_tx_id' => $p_id, 'gateway' => $p_gateway ) ); // Just in case the payment is already in the database.
91
+ }
92
+
93
+ if ( ! $payment ) {
94
+ $payment = new WPBDP_Payment( $args_or_payment );
95
+ }
96
+ } else {
97
+ $payment = $args_or_payment;
98
+ }
99
+
100
+ if ( $payment->id && in_array( $payment->id, $payments ) )
101
+ return;
102
+
103
+ if ( $parent_payment ) {
104
+ $payment->parent_id = $parent_payment->id;
105
+ $payment->listing_id = $parent_payment->listing_id;
106
+ $payment->payment_type = 'renewal';
107
+ $payment->payer_email = $parent_payment->payer_email;
108
+ $payment->payer_first_name = $parent_payment->payer_first_name;
109
+ $payment->payer_last_name = $parent_payment->payer_last_name;
110
+ $payment->payer_data = $parent_payment->payer_data;
111
+ $payment->currency_code = $parent_payment->currency_code;
112
+ $payment->status = 'completed';
113
+ $payment->gateway = ( ! $payment->gateway ) ? $parent_payment->gateway : $payment->gateway;
114
+
115
+ if ( $item = $parent_payment->find_item( 'recurring_plan' ) ) {
116
+ $payment->payment_items[] = $item;
117
+ }
118
+ }
119
+
120
+ if ( ! $payment->id ) {
121
+ // Save silently (no hooks fired).
122
+ $payment->save( false, false );
123
+ }
124
+
125
+ // This is the first payment.
126
+ if ( ! $payments ) {
127
+ $this->parent_payment_id = $payment->id;
128
+ }
129
+
130
+ $payments[] = $payment->id;
131
+ $this->data['payments'] = $payments;
132
+ $this->save();
133
+ }
134
+
135
+ public function renew() {
136
+ $listing = wpbdp_get_listing( $this->listing_id );
137
+ $listing->update_plan();
138
+ $listing->set_status( 'complete' );
139
+ $listing->set_post_status( 'publish' );
140
+ }
141
+
142
+ public function cancel() {
143
+ global $wpdb;
144
+
145
+ $wpdb->update(
146
+ "{$wpdb->prefix}wpbdp_listings",
147
+ array(
148
+ 'is_recurring' => '0',
149
+ 'subscription_id' => '',
150
+ 'subscription_data' => ''
151
+ ),
152
+ array( 'listing_id' => $this->listing_id )
153
+ );
154
+
155
+ do_action( 'wpbdp_listing_subscription_canceled', $this->listing_id );
156
+ }
157
+
158
+ private function save() {
159
+ global $wpdb;
160
+
161
+ $data = array(
162
+ 'parent_payment_id' => $this->parent_payment_id,
163
+ 'payments' => ! empty( $this->data['payments'] ) ? $this->data['payments'] : array()
164
+ );
165
+
166
+ $row = array(
167
+ 'subscription_id' => $this->subscription_id,
168
+ 'subscription_data' => serialize( $data )
169
+ );
170
+
171
+ return $wpdb->update( $wpdb->prefix . 'wpbdp_listings', $row, array( 'listing_id' => $this->listing_id ) );
172
+ }
173
+ }
includes/class-listing-upgrade-api.php DELETED
@@ -1,224 +0,0 @@
1
- <?php
2
- /**
3
- * @since 2.1.6
4
- */
5
- class WPBDP_Listing_Upgrade_API {
6
-
7
- private static $instance = null;
8
-
9
- private function __construct() {
10
- $this->register_default_levels();
11
- }
12
-
13
- public function register_default_levels() {
14
- // register default levels
15
- $this->register('normal', null, array(
16
- 'name' => _x('Normal Listing', 'listings-api', 'WPBDM'),
17
- 'is_sticky' => false
18
- ));
19
- $this->register('sticky', 'normal', array(
20
- 'name' => _x('Featured Listing', 'listings-api', 'WPBDM'),
21
- 'cost' => wpbdp_get_option('featured-price'),
22
- 'description' => wpbdp_get_option('featured-description'),
23
- 'is_sticky' => true
24
- ));
25
- }
26
-
27
- public static function instance() {
28
- if (is_null(self::$instance)) {
29
- self::$instance = new self;
30
- }
31
-
32
- return self::$instance;
33
- }
34
-
35
- /*
36
- * General functions.
37
- */
38
- public function get_levels() {
39
- $res = array();
40
-
41
- foreach ($this->_order as $level_id) {
42
- $res[] = $this->get($level_id);
43
- }
44
-
45
- return $res;
46
- }
47
-
48
- public function register($upgrade_id, $after_id, $data) {
49
- if ( !isset($this->_levels) )
50
- $this->_levels = array();
51
-
52
- if ( !isset($this->_order) )
53
- $this->_order = array();
54
-
55
- if ( empty($upgrade_id) )
56
- return false;
57
-
58
- if ( $upgrade_id != 'normal' && (!$after_id || !in_array( $after_id, array_keys ($this->_levels) )) )
59
- $after_id = end ( $this->_order );
60
-
61
- $data = array_merge(array(
62
- 'name' => $upgrade_id,
63
- 'cost' => 0.0,
64
- 'description' => '',
65
- 'is_sticky' => false,
66
- 'downgrade' => $after_id,
67
- 'upgrade' => null,
68
- ), $data);
69
-
70
- if ( !isset($this->_levels[$upgrade_id]) ) {
71
- $obj = (object) $data;
72
- $obj->id = $upgrade_id;
73
-
74
- if ($obj->downgrade) {
75
- $prev_upgrade = $this->next($obj->downgrade);
76
- $this->_levels[$obj->downgrade]->upgrade = $obj->id;
77
-
78
- if ($prev_upgrade)
79
- $this->_levels[$prev_upgrade]->downgrade = $obj->id;
80
- }
81
-
82
- $this->_levels[$upgrade_id] = $obj;
83
- } else {
84
- // XXX We only allow changes to name, cost and description of currently registered levels.
85
- foreach ( array( 'name', 'cost', 'description' ) as $k ) {
86
- if ( isset( $data[ $k ] ) )
87
- $this->_levels[ $upgrade_id ]->{$k} = $data[ $k ];
88
- }
89
-
90
- return;
91
- }
92
-
93
- if ($obj->downgrade) {
94
- $down_key = array_search($obj->downgrade, $this->_order);
95
-
96
- array_splice($this->_order, max(0, $down_key + 1), 0, array($obj->id));
97
- } else {
98
- $this->_order[] = $upgrade_id;
99
- }
100
-
101
- }
102
-
103
- public function get($upgrade_id) {
104
- return wpbdp_getv($this->_levels, $upgrade_id, null);
105
- }
106
-
107
- public function prev($upgrade_id) {
108
- if ($u = $this->get($upgrade_id))
109
- return $u->downgrade;
110
- return null;
111
- }
112
-
113
- public function next($upgrade_id) {
114
- if ($u = $this->get($upgrade_id))
115
- return $u->upgrade;
116
- return null;
117
- }
118
-
119
- /**
120
- * Generates a unique level id from a given name. Useful for plugins extending functionality the
121
- * number of featured levels.
122
- * @since 2.1.7
123
- */
124
- public function unique_id($name) {
125
- $key = sanitize_key( $name );
126
-
127
- if ( !in_array( $key, $this->_order ) )
128
- return $key;
129
-
130
- $n = 0;
131
- while ( true ) {
132
- $key = $key . strval( $n );
133
-
134
- if ( !in_array( $key, $this->_order ) )
135
- return $key;
136
-
137
- $n += 1;
138
- }
139
-
140
- }
141
-
142
- /*
143
- * Listing-related.
144
- */
145
-
146
- public function is_sticky($listing_id) {
147
-
148
- // if ($sticky_status = get_post_meta($listing_id, '_wpbdp[sticky]', true)) {
149
- // return $sticky_status;
150
- // }
151
-
152
- // return 'normal';
153
- }
154
-
155
- public function get_listing_level($listing_id) {
156
- $sticky_status = get_post_meta( $listing_id, '_wpbdp[sticky]', true );
157
- $level = get_post_meta( $listing_id, '_wpbdp[sticky_level]', true );
158
-
159
- switch ($sticky_status) {
160
- case 'sticky':
161
- if (!$level)
162
- return $this->get('sticky');
163
- else
164
- return $this->get($level) ? $this->get($level) : $this->get('sticky');
165
-
166
- break;
167
- case 'pending':
168
- if (!$level)
169
- return $this->get('normal');
170
- else
171
- return $this->get($level) ? $this->get($level) : $this->get('sticky');
172
-
173
- break;
174
- case 'normal':
175
- default:
176
- return $this->get('normal');
177
- break;
178
- }
179
-
180
- }
181
-
182
- public function get_info($listing_id) {
183
- if (!$listing_id)
184
- return null;
185
-
186
- $sticky_status = get_post_meta( $listing_id, '_wpbdp[sticky]', true );
187
-
188
- $res = new StdClass();
189
- $res->level = $this->get_listing_level( $listing_id );
190
- $res->status = $sticky_status ? $sticky_status : 'normal';
191
- $res->pending = $sticky_status == 'pending' ? true : false;
192
- $res->sticky = $res->level->is_sticky;
193
- $res->upgradeable = !empty($res->level->upgrade);
194
- $res->upgrade = $res->upgradeable ? $this->get($res->level->upgrade) : null;
195
- $res->downgradeable = $res->pending ? true : !empty($res->level->downgrade);
196
- $res->downgrade = $res->pending ? $this->get($res->level->id) : ($res->downgradeable ? $this->get($res->level->downgrade) : null);
197
-
198
- return $res;
199
- }
200
-
201
- public function set_sticky($listing_id, $level_id, $only_upgrade=false) {
202
- $current_info = $this->get_info( $listing_id );
203
-
204
- if ( $only_upgrade && (array_search($level_id, $this->_order) < array_search($current_info->level->id, $this->_order)) )
205
- return false;
206
-
207
- if ( $level_id == 'normal' ) {
208
- delete_post_meta( $listing_id, '_wpbdp[sticky]' );
209
- delete_post_meta( $listing_id, '_wpbdp[sticky_level]' );
210
- } else {
211
- update_post_meta( $listing_id, '_wpbdp[sticky]', 'sticky' );
212
- update_post_meta( $listing_id, '_wpbdp[sticky_level]', $level_id );
213
- }
214
-
215
- // TODO: approve/cancel transactions related to this operation.
216
- }
217
-
218
- }
219
-
220
- /*
221
- * For compat. with other APIs (< 3.5.4)
222
- */
223
- class WPBDP_ListingUpgrades extends WPBDP_Listing_Upgrade_API {}
224
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-listing.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
- require_once( WPBDP_INC . 'class-payment.php' );
3
- require_once( WPBDP_INC . 'helpers/class-listing-image.php' );
 
4
 
5
  /**
6
  * @since 3.4
@@ -14,24 +15,6 @@ class WPBDP_Listing {
14
  $this->id = intval( $id );
15
  }
16
 
17
- /**
18
- * Sets the values for listing fields.
19
- * @param array $values field_id => value associative array.
20
- * @param boolean $append if TRUE the specified field values are set without clearing the values for the other fields.
21
- */
22
- public function set_field_values( $values = array(), $append = false ) {
23
- $fields = wpbdp_get_form_fields( array( 'association' => array( '-category' ) ) );
24
-
25
- foreach ( $fields as &$f ) {
26
- if ( isset( $values[ $f->get_id() ] ) )
27
- $f->store_value( $this->id, $values[ $f->get_id() ] );
28
- elseif ( ! $append )
29
- $f->store_value( $this->id, $f->convert_input( null ) );
30
- }
31
-
32
- do_action_ref_array( 'WPBDP_Listing::set_field_values', array( &$this, $values ) );
33
- }
34
-
35
  public function get_field_value( $id ) {
36
  $field = null;
37
 
@@ -138,100 +121,14 @@ class WPBDP_Listing {
138
  return $this->id;
139
  }
140
 
141
-
142
- public function get_category_info( $category ) {
143
- $category_id = intval( is_object( $category ) ? $category->term_id : $category );
144
- $categories = $this->get_categories( 'all' );
145
-
146
- if ( isset( $categories[ $category_id ] ) )
147
- return $categories[ $category_id ];
148
-
149
- return null;
150
- }
151
-
152
- public function remove_category( $category, $remove_fee = true, $cleanup = false ) {
153
- global $wpdb;
154
-
155
- $category_id = intval( is_object( $category ) ? $category->term_id : $category );
156
-
157
- if ( $remove_fee )
158
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d AND category_id = %d",
159
- $this->id,
160
- $category_id ) );
161
-
162
- $listing_terms = wp_get_post_terms( $this->id, WPBDP_CATEGORY_TAX, array( 'fields' => 'ids' ) );
163
- wpbdp_array_remove_value( $listing_terms, $category_id );
164
- wp_set_post_terms( $this->id, $listing_terms, WPBDP_CATEGORY_TAX );
165
-
166
- if ( $cleanup ) {
167
- // Remove all payment items related to this category.
168
- $payment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT p.id FROM {$wpdb->prefix}wpbdp_payments p WHERE p.listing_id = %d AND
169
- p.status = %s AND
170
- EXISTS( SELECT 1 FROM {$wpdb->prefix}wpbdp_payments_items pi WHERE pi.payment_id = p.id
171
- AND pi.item_type IN (%s, %s) AND pi.rel_id_1 = %d)",
172
- $this->id,
173
- 'pending',
174
- 'fee',
175
- 'recurring_fee',
176
- $category_id ) );
177
- foreach ( $payment_ids as $pid ) {
178
- $payment = WPBDP_Payment::get( $pid );
179
- $items = $payment->get_items( array( 'item_type' => array( 'fee', 'recurring_fee' ),
180
- 'rel_id_1' => $category_id ) );
181
- foreach ( $items as &$item ) {
182
- $payment->delete_item( $item );
183
- }
184
-
185
- $payment->save();
186
- }
187
  }
188
- }
189
-
190
- // TODO: if there is 'current' information for the category respect the expiration time left.
191
- public function add_category( $category, $fee, $recurring = false, $recurring_data = array(), $cleanup = false ) {
192
- $this->remove_category( $category, true, $cleanup );
193
-
194
- $category_id = $this->add_category_info( $category, $fee, $recurring, $recurring_data, $cleanup );
195
-
196
- wp_set_post_terms( $this->id, array( $category_id ), WPBDP_CATEGORY_TAX, true );
197
- }
198
-
199
- private function add_category_info( $category, $fee, $recurring = false, $recurring_data = array(), $cleanup = false ) {
200
- global $wpdb;
201
-
202
- $category_id = intval( is_object( $category ) ? $category->term_id : $category );
203
- $fee = ( null === $fee ) ? $fee : ( is_object( $fee ) ? $fee : wpbdp_get_fee( $fee ) );
204
-
205
- if ( is_null( $fee ) || ! $fee || ! term_exists( $category_id ) )
206
- return;
207
-
208
- $fee = (array) $fee;
209
-
210
- $fee_info = array();
211
- $fee_info['listing_id'] = $this->id;
212
- $fee_info['category_id'] = $category_id;
213
- $fee_info['fee_id'] = intval( isset( $fee['id'] ) ? $fee['id'] : ( isset( $fee['fee_id'] ) ? $fee['fee_id'] : 0 ) );
214
- $fee_info['fee_days'] = intval( isset( $fee['days'] ) ? $fee['days'] : $fee['fee_days'] );
215
- $fee_info['fee_images'] = intval( isset( $fee['images'] ) ? $fee['images'] : $fee['fee_images'] );
216
- $fee_info['recurring'] = $recurring ? 1 : 0;
217
- $fee_info['sticky'] = (bool) ( isset( $fee['sticky'] ) ? $fee['sticky'] : $fee['fee_sticky'] );
218
-
219
- if ( isset( $recurring_data ) )
220
- $fee_info['recurring_data'] = serialize( $recurring_data );
221
-
222
- if ( isset( $recurring_data['recurring_id'] ) )
223
- $fee_info['recurring_id'] = $recurring_data['recurring_id'];
224
-
225
- if ( $expiration_date = $this->calculate_expiration_date( time(), $fee ) )
226
- $fee_info['expires_on'] = $expiration_date;
227
-
228
- $wpdb->insert( $wpdb->prefix . 'wpbdp_listing_fees', $fee_info );
229
-
230
- return $category_id;
231
- }
232
-
233
- private function calculate_expiration_date( $time, &$fee ) {
234
- $days = isset( $fee['days'] ) ? $fee['days'] : $fee['fee_days'];
235
 
236
  if ( 0 == $days )
237
  return null;
@@ -240,230 +137,42 @@ class WPBDP_Listing {
240
  return date( 'Y-m-d H:i:s', $expire_time );
241
  }
242
 
243
- // TODO: what happens when sections clash? i.e. there is a payment pending for a renewal and somehow the category is also in 'expired'
244
- public function get_categories( $info = 'current' ) {
245
- global $wpdb;
246
-
247
- $current_ids = array();
248
- $expired_ids = array();
249
- $pending_ids = array();
250
- $known = array();
251
-
252
- foreach ( $wpdb->get_results( $wpdb->prepare(
253
- "SELECT *, IF ( expires_on >= %s OR expires_on IS NULL, 0, 1 ) AS _expired FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d",
254
- current_time( 'mysql' ),
255
- $this->id ) ) as $r ) {
256
- $known[ $r->category_id ] = $r;
257
-
258
- if ( 1 == $r->_expired )
259
- $expired_ids[] = $r->category_id;
260
- else
261
- $current_ids[] = $r->category_id;
262
- }
263
-
264
- $pending_payments = $wpdb->get_results( $wpdb->prepare( "SELECT pi.payment_id, pi.id, pi.rel_id_1 FROM {$wpdb->prefix}wpbdp_payments_items pi INNER JOIN {$wpdb->prefix}wpbdp_payments p ON p.id = pi.payment_id WHERE pi.item_type IN (%s, %s) AND p.status = %s AND p.listing_id = %d",
265
- 'fee', 'recurring_fee',
266
- 'pending',
267
- $this->id ) );
268
-
269
- $pending = array();
270
- foreach ( $pending_payments as &$p ) {
271
- $pending[ intval( $p->rel_id_1 ) ] = $p->id;
272
- }
273
-
274
- $pending_ids = array_keys( $pending );
275
-
276
- $category_ids = array();
277
- switch ( $info ) {
278
- case 'all':
279
- $category_ids = array_merge( $current_ids, $expired_ids, $pending_ids );
280
- break;
281
- case 'pending':
282
- $category_ids = $pending_ids;
283
- break;
284
- case 'expired':
285
- $category_ids = $expired_ids;
286
- break;
287
- case 'current':
288
- default:
289
- $category_ids = $current_ids;
290
- break;
291
- }
292
-
293
- $results = array();
294
-
295
- foreach ( $category_ids as $category_id ) {
296
- if ( $category_info = get_term( intval( $category_id ), WPBDP_CATEGORY_TAX ) ) {
297
- $category = new StdClass();
298
- $category->id = intval( $category_info->term_id );
299
- $category->name = $category_info->name;
300
- $category->slug = $category_info->slug;
301
- $category->term_id = intval( $category_info->term_id );
302
- $category->term_taxonomy_id = intval( $category_info->term_taxonomy_id );
303
- $category->status = in_array( $category_id, $pending_ids, true ) ? 'pending' : ( in_array( $category_id, $expired_ids, true ) ? 'expired' : 'ok' );
304
-
305
- switch ( $category->status ) {
306
- case 'expired':
307
- case 'ok':
308
- $fee_info = $known[ $category_id ];
309
- //$fee_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d AND category_id = %d", $this->id, $category_id ) );
310
- $fee_info_recurring_data = unserialize( $fee_info->recurring_data );
311
-
312
- if ( ! $fee_info ) {
313
- // $this->remove_category( $category_id );
314
- continue;
315
- }
316
-
317
- $category->fee_id = intval( $fee_info->fee_id );
318
- $category->fee_days = intval( $fee_info->fee_days );
319
- $category->fee_images = intval( $fee_info->fee_images );
320
-
321
- $category->fee = wpbdp_get_fee( $category->fee_id );
322
- if ( ! $category->fee ) {
323
- $category->fee = new StdClass();
324
- $category->fee->id = $category->fee_id;
325
- $category->fee->label = _x( '(Fee Unavailable)', 'listing', 'WPBDM' );
326
- $category->fee->amount = 0.0;
327
- $category->fee->days = $category->fee_days;
328
- $category->fee->images = $category->fee_images;
329
- $category->fee->categories = array();
330
- $category->fee->extra_data = array();
331
- }
332
-
333
- $category->expires_on = $fee_info->expires_on;
334
- $category->expired = ( $category->expires_on && strtotime( $category->expires_on ) < time() ) ? true : false;
335
- $category->renewal_id = $fee_info->id;
336
- $category->recurring = $fee_info->recurring ? true : false;
337
- $category->recurring_id = trim( $fee_info->recurring_id );
338
- $category->payment_id = isset( $fee_info_recurring_data['payment_id'] ) ? $fee_info_recurring_data['payment_id'] : 0;
339
-
340
- break;
341
-
342
- case 'pending':
343
- $payment_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_payments_items WHERE id = %d", $pending[ $category_id ] ) );
344
- $payment_info->data = unserialize( $payment_info->data );
345
-
346
- $category->fee_id = intval( $payment_info->rel_id_2 );
347
- $category->fee = wpbdp_get_fee( $category->fee_id );
348
- if ( ! $category->fee ) {
349
- $category->fee = new StdClass();
350
- $category->fee->id = $category->fee_id;
351
- $category->fee->label = _x( '(Fee Unavailable)', 'listing', 'WPBDM' );
352
- $category->fee->amount = 0.0;
353
- $category->fee_days = intval( $payment_info->data['fee_days'] );
354
- $category->fee_images = intval( $payment_info->data['fee_images'] );
355
- // $category->fee->days = $category->fee_days;
356
- // $category->fee->images = $category->fee_images;
357
- $category->fee->categories = array();
358
- $category->fee->extra_data = array();
359
- }
360
-
361
- $category->fee_days = intval( $payment_info->data['fee_days'] );
362
- $category->fee_images = intval( $payment_info->data['fee_images'] );
363
- $category->expires_on = null; // TODO: calculate expiration date.
364
- $category->expired = false;
365
- $category->renewal_id = 0;
366
- $category->recurring = ( 'recurring_fee' == $payment_info->item_type ? true : false );
367
- $category->recurring_id = '';
368
- $category->payment_id = intval( $payment_info->payment_id );
369
-
370
- break;
371
- }
372
-
373
- $results[ $category_id ] = $category;
374
- }
375
- }
376
 
377
- return $results;
378
  }
379
 
380
- public function set_categories( $categories, $fix = 'fix' ) {
381
  $category_ids = array_map( 'intval', $categories );
382
-
383
  wp_set_post_terms( $this->id, $category_ids, WPBDP_CATEGORY_TAX, false );
384
-
385
- if ( 'fix' == $fix ) {
386
- $this->fix_categories();
387
- } else {
388
- $this->set_default_fee_for_categories( $category_ids );
389
- }
390
  }
391
 
392
- public function fix_categories( $charge = false ) {
393
- global $wpdb;
394
-
395
- // Delete fee information for categories that no longer exist.
396
- $wpdb->query( $wpdb->prepare( "DELETE lf FROM {$wpdb->prefix}wpbdp_listing_fees lf WHERE lf.listing_id = %d AND lf.category_id NOT IN (SELECT tt.term_id FROM {$wpdb->term_taxonomy} tt WHERE tt.taxonomy=%s)",
397
- $this->id, WPBDP_CATEGORY_TAX ) );
398
-
399
- $terms = wp_get_post_terms( $this->id, WPBDP_CATEGORY_TAX, 'fields=ids' );
400
-
401
- // Remove listing information for categories that no longer apply to the listing.
402
- $removed_cats = array_diff( array_keys( $this->get_categories( 'current' ) ), $terms );
403
- if ( $removed_cats ) {
404
- $cats = implode( ',', $removed_cats );
405
- $wpdb->query( $wpdb->prepare( "DELETE lf FROM {$wpdb->prefix}wpbdp_listing_fees lf WHERE lf.listing_id = %d AND lf.category_id IN ({$cats})", $this->id ) );
406
  }
407
 
408
- // Assign a default fee for categories without a fee.
409
- foreach ( $terms as $category_id ) {
410
- $category_info = $this->get_category_info( $category_id );
411
-
412
- if ( $category_info && 'pending' == $category_info->status ) {
413
- $this->add_category( $category_id, $category_info->fee, false, null, true );
414
- } elseif ( ! $category_info ) {
415
- $fee_options = wpbdp_get_fees_for_category( $category_id );
416
-
417
- // Allow backend listing categories editing to always succeed.
418
- if ( ! $fee_options && is_admin() && current_user_can( 'administrator' ) )
419
- $fee_options[] = WPBDP_Fee_Plan::get_free_plan();
420
-
421
- if ( $charge ) {
422
- $payment = new WPBDP_Payment( array( 'listing_id' => $this->id ) );
423
- $payment->add_category_fee_item( $category_id, reset( $fee_options ) );
424
- $payment->set_status( WPBDP_Payment::STATUS_COMPLETED );
425
- $payment->save();
426
- } else {
427
- $this->add_category( $category_id, reset( $fee_options ) );
428
- }
429
- }
430
- }
431
  }
432
 
433
- private function set_default_fee_for_categories( $terms, $charge = false ) {
434
- foreach ( $terms as $category_id ) {
435
- $fee_options = wpbdp_get_fees_for_category( $category_id );
436
-
437
- // Allow backend listing categories editing to always succeed.
438
- if ( ! $fee_options && is_admin() && current_user_can( 'administrator' ) ) {
439
- $fee_options[] = WPBDP_Fee_Plan::get_free_plan();
440
- }
441
-
442
- $this->add_category_info( $category_id, reset( $fee_options ) );
443
- }
444
  }
445
 
446
- public function make_category_non_recurring( $category_id ) {
 
 
 
447
  global $wpdb;
448
- $wpdb->update( "{$wpdb->prefix}wpbdp_listing_fees",
449
- array( 'recurring' => 0,
450
- 'recurring_id' => null,
451
- 'recurring_data' => null ),
452
- array( 'listing_id' => $this->id, 'category_id' => $category_id ) );
453
- }
454
-
455
- public function get_total_cost() {
456
- $cost = 0.0;
457
-
458
- foreach ( $this->get_categories( 'current' ) as $c ) {
459
- if ( $c->fee )
460
- $cost += floatval( $c->fee->amount );
461
- }
462
-
463
- return $cost;
464
- // global $wpdb;
465
- // $cost = floatval( $wpdb->get_var( $wpdb->prepare( "SELECT SUM(amount) FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id = %d", $this->id ) ) );
466
- // return round( $cost, 2 );
467
  }
468
 
469
  public function is_published() {
@@ -477,34 +186,32 @@ class WPBDP_Listing {
477
  return get_permalink( $this->id );
478
  }
479
 
 
 
 
 
 
 
 
480
  public function get_payment_status() {
481
  $status = 'ok';
482
 
483
- if ( WPBDP_Payment::find( array( 'listing_id' => $this->id, 'status' => 'pending' ), true ) )
484
  $status = 'pending';
485
 
486
  return apply_filters( 'WPBDP_Listing::get_payment_status', $status, $this->id );
487
  }
488
 
489
- public function mark_as_paid() {
490
- $pending = WPBDP_Payment::find( array( 'listing_id' => $this->id, 'status' => 'pending' ) );
491
- $ok = true;
492
-
493
- foreach ( $pending as &$p ) {
494
- if ( $p->has_item_type( 'recurring_fee' ) ) {
495
- $ok = false;
496
- continue;
497
- }
498
-
499
- $p->set_status( WPBDP_Payment::STATUS_COMPLETED, 'admin' );
500
- $p->save();
501
- }
502
-
503
- return $ok;
504
  }
505
 
506
  public function get_latest_payments() {
507
- return WPBDP_Payment::find( array( 'listing_id' => $this->id, '_order' => '-id', '_limit' => 10 ) );
508
  }
509
 
510
  public function publish() {
@@ -514,60 +221,101 @@ class WPBDP_Listing {
514
  wp_update_post( array( 'post_status' => 'publish', 'ID' => $this->id ) );
515
  }
516
 
517
- public function set_post_status( $status ) {
518
- if ( ! $this->id )
 
 
 
 
 
 
 
 
519
  return;
520
 
521
- wp_update_post( array( 'post_status' => $status, 'ID' => $this->id ) );
522
- }
523
 
524
- public function save() {
525
- if ( $this->new )
526
- do_action_ref_array( 'WPBDP_Listing::listing_created', array( &$this ) );
527
- else
528
- do_action_ref_array( 'WPBDP_Listing::listing_edited', array( &$this ) );
 
 
 
 
 
 
 
529
 
530
- $this->new = false;
531
- do_action_ref_array( 'WPBDP_Listing::listing_saved', array( &$this ) );
 
 
 
 
532
 
533
- // do_action( 'wpbdp_save_listing', $listing_id, $data->fields, $data );
534
- do_action_ref_array( 'wpbdp_save_listing', array( &$this ) );
535
  }
536
 
537
  public function delete() {
538
  global $wpdb;
539
  $wpdb->update( $wpdb->posts, array( 'post_status' => wpbdp_get_option( 'deleted-status' ) ), array( 'ID' => $this->id ) );
540
  clean_post_cache( $this->id );
 
 
541
  }
542
 
543
  public function notify( $kind = 'save', &$extra = null ) {
544
- if ( in_array( $kind, array( 'save', 'edit', 'new' ), true ) )
545
- $this->save();
546
-
547
- switch ( $kind ) {
548
- case 'save':
549
- break;
550
-
551
- case 'edit':
552
- do_action_ref_array( 'wpbdp_edit_listing', array( &$this, &$extra ) );
553
- break;
554
-
555
- default:
556
- break;
557
- }
558
  }
559
 
560
  /**
561
  * @since 3.5.3
562
  */
563
- public function get_renewal_hash( $category_id ) {
564
- $hash = base64_encode( 'listing_id=' . $this->id . '&category_id=' . $category_id );
565
  return $hash;
566
  }
567
 
568
- public function get_renewal_url( $category_id ) {
569
- $hash = $this->get_renewal_hash( $category_id );
570
- return wpbdp_url( 'renew_listing', urlencode( $hash ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571
  }
572
 
573
  /**
@@ -583,6 +331,14 @@ class WPBDP_Listing {
583
  return $new_key;
584
  }
585
 
 
 
 
 
 
 
 
 
586
  public function get_author_meta( $meta ) {
587
  if ( ! $this->id )
588
  return '';
@@ -595,134 +351,428 @@ class WPBDP_Listing {
595
  * @since 3.6.9
596
  */
597
  public function get_sticky_status( $consider_plans = true ) {
598
- $sticky_status = get_post_meta( $this->id, '_wpbdp[sticky]', true );
 
 
 
 
 
 
599
 
600
- if ( $sticky_status )
601
- return $sticky_status;
602
 
603
- if ( $consider_plans ) {
604
- global $wpdb;
 
 
 
 
 
 
 
 
 
 
 
605
 
606
- $has_sticky_plan = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT 1 AS x FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d AND sticky = %d", $this->id, 1 ) );
 
 
607
 
608
- if ( $has_sticky_plan )
609
- $sticky_status = 'sticky';
610
- }
 
611
 
612
- return $sticky_status ? $sticky_status : 'normal';
 
 
 
 
613
  }
614
 
 
 
 
 
 
615
 
616
- public function update( $state, $opts = array() ) {
617
- $post_data = self::get_post_data_from_state( $state );
 
 
618
 
619
- if ( $post_data ) {
620
- wp_update_post( array_merge( array( 'ID' => $this->id ), $post_data ) );
621
- }
622
 
623
- // Set categories.
624
- if ( isset( $state->categories ) ) {
625
- $this->set_categories( $state->categories );
 
 
 
 
 
 
 
626
  }
627
 
628
- if ( isset( $state->fields ) ) {
629
- $this->set_field_values( $state->fields, true );
 
 
 
 
 
 
 
 
630
  }
631
 
632
- if ( isset( $state->images ) ) {
633
- $append = ( ! empty( $opts['append-images'] ) );
634
- $this->set_images( $state->images, $append );
 
 
 
635
  }
636
 
637
- $this->save();
638
- }
639
 
640
- public static function create( &$state ) {
641
- $post_data = self::get_post_data_from_state( $state, array(
642
- 'post_title' => 'Untitled Listing',
643
- 'post_status' => 'pending',
644
- 'post_type' => WPBDP_POST_TYPE
645
- ) );
646
 
647
- // Create author user if needed.
648
- if ( isset( $post_data['post_author'] ) && $post_data['post_author'] ) {
649
- $post_author = $post_data['post_author'];
650
- } else {
651
- $current_user = wp_get_current_user();
652
- $post_author = $current_user->ID;
653
- }
654
 
655
- if ( 0 == $post_author ) {
656
- if ( wpbdp_get_option( 'require-login' ) )
657
- throw new Exception('Login required.');
658
-
659
- // Create user.
660
- if ( $email_field = wpbdp_get_form_fields( array( 'validators' => 'email', 'unique' => 1 ) ) ) {
661
- $email = $state->fields[ $email_field->get_id() ];
662
-
663
- if ( email_exists( $email ) ) {
664
- $post_author = get_user_by( 'email', $email );
665
- $post_author = $post_author->ID;
666
- } else {
667
- $post_author = wp_insert_user( array(
668
- 'user_login' => 'guest_' . wp_generate_password( 5, false, false ),
669
- 'user_email' => $email,
670
- 'user_pass' => wp_generate_password()
671
- ) );
672
  }
673
  }
674
  }
675
 
676
- if ( $post_author ) {
677
- $post_data['post_author'] = $post_author;
678
  }
679
 
680
- $post_id = wp_insert_post( $post_data );
 
 
681
 
682
- return new self( $post_id );
683
  }
684
 
685
- private static function get_post_data_from_state( $state, $defaults = array() ) {
686
- $title = wpbdp_getv( $defaults, 'post_title', false );
687
-
688
- if ( isset( $state->title ) ) {
689
- $title = $state->title;
690
- } else {
691
- $title_field = wpbdp_get_form_fields( array( 'association' => 'title', 'unique' => true ) );
692
 
693
- if ( $title_field && isset( $state->fields[ $title_field->get_id() ] ) ) {
694
- $title = $state->fields[ $title_field->get_id() ];
695
- }
 
696
  }
697
 
698
- $post_data = $defaults;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
699
 
700
- if ( $title ) {
701
- $post_data['post_title'] = trim( strip_tags( $title ) );
702
- $post_data['post_name'] = sanitize_title( $title );
703
  }
704
 
705
- if ( isset( $state->post_name ) ) {
706
- $post_data['post_name'] = $state->post_name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
  }
708
 
709
- if ( isset( $state->post_status ) ) {
710
- $post_data['post_status'] = $state->post_status;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
711
  }
712
 
713
- if ( isset( $state->excerpt ) ) {
714
- $post_data['post_excerpt'] = $state->excerpt;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  }
716
 
717
- if ( isset( $state->content ) ) {
718
- $post_data['post_content'] = $state->content;
 
 
 
 
 
719
  }
 
720
 
721
- if ( isset( $state->post_author ) ) {
722
- $post_data['post_author'] = $state->post_author;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
723
  }
 
724
 
725
- return $post_data;
 
 
 
726
  }
727
 
728
  public static function get( $id ) {
@@ -731,7 +781,6 @@ class WPBDP_Listing {
731
 
732
  $l = new self( $id );
733
  $l->new = false;
734
-
735
  return $l;
736
  }
737
 
1
  <?php
2
+ require_once( WPBDP_PATH . 'includes/class-payment.php' );
3
+ require_once( WPBDP_PATH . 'includes/class-listing-subscription.php' );
4
+ require_once( WPBDP_PATH . 'includes/helpers/class-listing-image.php' );
5
 
6
  /**
7
  * @since 3.4
15
  $this->id = intval( $id );
16
  }
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  public function get_field_value( $id ) {
19
  $field = null;
20
 
121
  return $this->id;
122
  }
123
 
124
+ public function calculate_expiration_date( $time, &$fee ) {
125
+ if ( is_array( $fee ) ) {
126
+ $days = isset( $fee['days'] ) ? $fee['days'] : $fee['fee_days'];
127
+ } else if ( is_a( $fee, 'WPBDP__Fee_Plan' ) ) {
128
+ $days = $fee->days;
129
+ } else {
130
+ $days = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
  if ( 0 == $days )
134
  return null;
137
  return date( 'Y-m-d H:i:s', $expire_time );
138
  }
139
 
140
+ public function get_categories( $fields='all' ) {
141
+ $args = array();
142
+ $args['fields'] = $fields;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
+ return wp_get_post_terms( $this->id, WPBDP_CATEGORY_TAX, $args );
145
  }
146
 
147
+ public function set_categories( $categories ) {
148
  $category_ids = array_map( 'intval', $categories );
 
149
  wp_set_post_terms( $this->id, $category_ids, WPBDP_CATEGORY_TAX, false );
 
 
 
 
 
 
150
  }
151
 
152
+ /**
153
+ * @since 5.0
154
+ */
155
+ public function is_recurring() {
156
+ if ( $plan = $this->get_fee_plan() ) {
157
+ return $plan->is_recurring;
 
 
 
 
 
 
 
 
158
  }
159
 
160
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  }
162
 
163
+ /**
164
+ * @since 5.0
165
+ */
166
+ public function get_subscription() {
167
+ return new WPBDP__Listing_Subscription( $this->id );
 
 
 
 
 
 
168
  }
169
 
170
+ /**
171
+ * @since 5.0
172
+ */
173
+ public function has_subscription() {
174
  global $wpdb;
175
+ return absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d AND is_recurring = %d", $this->id, 1 ) ) ) > 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
177
 
178
  public function is_published() {
186
  return get_permalink( $this->id );
187
  }
188
 
189
+ /**
190
+ * @since 5.0
191
+ */
192
+ public function get_admin_edit_link() {
193
+ return admin_url( 'post.php?post=' . $this->id . '&action=edit' );
194
+ }
195
+
196
  public function get_payment_status() {
197
  $status = 'ok';
198
 
199
+ if ( WPBDP_Payment::objects()->filter( array( 'listing_id' => $this->id, 'status' => 'pending' ) )->count() > 0 )
200
  $status = 'pending';
201
 
202
  return apply_filters( 'WPBDP_Listing::get_payment_status', $status, $this->id );
203
  }
204
 
205
+ /**
206
+ * @since 5.0
207
+ */
208
+ public function get_payments() {
209
+ $payments = WPBDP_Payment::objects()->filter( array( 'listing_id' => $this->id ) );
210
+ return $payments;
 
 
 
 
 
 
 
 
 
211
  }
212
 
213
  public function get_latest_payments() {
214
+ return WPBDP_Payment::objects()->filter( array( 'listing_id' => $this->id ) )->order_by( '-id' )->to_array();
215
  }
216
 
217
  public function publish() {
221
  wp_update_post( array( 'post_status' => 'publish', 'ID' => $this->id ) );
222
  }
223
 
224
+ /**
225
+ * @since 5.0
226
+ */
227
+ public function set_status( $status ) {
228
+ global $wpdb;
229
+
230
+ $old_status = $this->get_status( false, false );
231
+ $new_status = $status;
232
+
233
+ if ( $old_status == $new_status || ! in_array( $new_status, array_keys( self::get_stati() ), true ) )
234
  return;
235
 
236
+ $wpdb->update( $wpdb->prefix . 'wpbdp_listings', array( 'listing_status' => $new_status ), array( 'listing_id' => $this->id ) );
 
237
 
238
+ switch ( $new_status ) {
239
+ case 'expired':
240
+ if ( 'trash' != get_post_status( $this->id ) ) {
241
+ $this->set_post_status( 'draft' );
242
+ }
243
+
244
+ wpbdp_insert_log( array( 'log_type' => 'listing.expired', 'object_id' => $this->id, 'message' => _x( 'Listing expired', 'listing', 'WPBDM' ) ) );
245
+ do_action( 'wpbdp_listing_expired', $this );
246
+ break;
247
+ default:
248
+ break;
249
+ }
250
 
251
+ do_action( 'wpbdp_listing_status_change', $this, $old_status, $new_status );
252
+ }
253
+
254
+ public function set_post_status( $status ) {
255
+ if ( ! $this->id )
256
+ return;
257
 
258
+ wp_update_post( array( 'post_status' => $status, 'ID' => $this->id ) );
 
259
  }
260
 
261
  public function delete() {
262
  global $wpdb;
263
  $wpdb->update( $wpdb->posts, array( 'post_status' => wpbdp_get_option( 'deleted-status' ) ), array( 'ID' => $this->id ) );
264
  clean_post_cache( $this->id );
265
+
266
+ return true;
267
  }
268
 
269
  public function notify( $kind = 'save', &$extra = null ) {
270
+ // if ( in_array( $kind, array( 'save', 'edit', 'new' ), true ) )
271
+ // $this->save();
272
+ //
273
+ // switch ( $kind ) {
274
+ // case 'save':
275
+ // break;
276
+ //
277
+ // case 'edit':
278
+ // do_action_ref_array( 'wpbdp_edit_listing', array( &$this, &$extra ) );
279
+ // break;
280
+ //
281
+ // default:
282
+ // break;
283
+ // }
284
  }
285
 
286
  /**
287
  * @since 3.5.3
288
  */
289
+ public function get_renewal_hash( $deprecated = 0 ) {
290
+ $hash = base64_encode( 'listing_id=' . $this->id . '&category_id=' . $deprecated );
291
  return $hash;
292
  }
293
 
294
+ /**
295
+ * @since 5.0
296
+ */
297
+ public function renew() {
298
+ $plan = $this->get_fee_plan();
299
+
300
+ if ( ! $plan )
301
+ return false;
302
+
303
+ global $wpdb;
304
+
305
+ $row = array();
306
+ if ( $expiration = $this->calculate_expiration_date( current_time( 'timestamp' ), $plan ) )
307
+ $row['expiration_date'] = $expiration;
308
+
309
+ if ( ! empty( $row ) )
310
+ $wpdb->update( $wpdb->prefix . 'wpbdp_listings', $row, array( 'listing_id' => $this->id ) );
311
+
312
+ $this->set_status( 'complete' );
313
+ }
314
+
315
+ public function get_renewal_url( $deprecated = 0 ) {
316
+ // TODO: we should probably encode the ID somehow using info that only we have so external users can't
317
+ // start checking renewal for all listings just by changing the ID.
318
+ return wpbdp_url( 'renew_listing', $this->id );
319
  }
320
 
321
  /**
331
  return $new_key;
332
  }
333
 
334
+ /**
335
+ * @since 5.0
336
+ */
337
+ public function validate_access_key_hash( $hash ) {
338
+ $key = $this->get_access_key();
339
+ return sha1( AUTH_KEY . $key ) == $hash;
340
+ }
341
+
342
  public function get_author_meta( $meta ) {
343
  if ( ! $this->id )
344
  return '';
351
  * @since 3.6.9
352
  */
353
  public function get_sticky_status( $consider_plans = true ) {
354
+ global $wpdb;
355
+ $is_sticky = (bool) $wpdb->get_var(
356
+ $wpdb->prepare(
357
+ "SELECT 1 AS x FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d AND is_sticky = %d",
358
+ $this->id,
359
+ 1 )
360
+ );
361
 
362
+ return $is_sticky ? 'sticky' : 'normal';
363
+ }
364
 
365
+ /**
366
+ * @since 5.0
367
+ */
368
+ public function has_fee_plan( $fee = false ) {
369
+ $current = $this->get_fee_plan();
370
+ return ( ! $fee && ! empty( $current ) ) || ( $fee && $current && $current->id == $fee );
371
+ }
372
+
373
+ /**
374
+ * @since 5.0
375
+ */
376
+ public function get_fee_plan() {
377
+ global $wpdb;
378
 
379
+ $res = $wpdb->get_row( $wpdb->prepare( "SELECT listing_id, fee_id, fee_price, fee_days, fee_images, expiration_date, is_recurring, is_sticky FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d LIMIT 1", $this->id ) );
380
+ if ( ! $res )
381
+ return false;
382
 
383
+ if ( $res->fee_id )
384
+ $fee = wpbdp_get_fee_plan( $res->fee_id );
385
+ else
386
+ $fee = null;
387
 
388
+ $res->fee = $fee;
389
+ $res->fee_label = $fee ? $fee->label : _x( '(Unavailable Plan)', 'listing', 'WPBDM' );
390
+ $res->expired = $res->expiration_date ? strtotime( $res->expiration_date ) <= current_time( 'timestamp' ) : false;
391
+
392
+ return $res;
393
  }
394
 
395
+ /**
396
+ * @since 5.0
397
+ */
398
+ public function update_plan( $plan = null, $args = array() ) {
399
+ global $wpdb;
400
 
401
+ $args = wp_parse_args( $args, array(
402
+ 'clear' => 0, /* Whether to use old values (if available). */
403
+ 'recalculate' => 1 /* Whether to recalculate the expiration or not */
404
+ ) );
405
 
406
+ $row = array();
 
 
407
 
408
+ if ( is_numeric( $plan ) || ( is_array( $plan ) && ! empty( $plan['fee_id'] ) ) ) {
409
+ $plan_id = is_numeric( $plan ) ? absint( $plan ) : absint( $plan['fee_id'] );
410
+
411
+ if ( $plan_ = wpbdp_get_fee_plan( $plan_id ) ) {
412
+ $row['fee_id'] = $plan_id;
413
+ $row['fee_images'] = $plan_->images;
414
+ $row['fee_days'] = $plan_->days;
415
+ $row['is_sticky'] = $plan_->sticky;
416
+ $row['fee_price'] = $plan_->amount;
417
+ }
418
  }
419
 
420
+ if ( is_array( $plan ) ) {
421
+ foreach ( array( 'fee_days', 'fee_images', 'fee_price', 'is_sticky', 'expiration_date', 'is_recurring', 'subscription_id', 'subscription_data' ) as $key ) {
422
+ if ( array_key_exists( $key, $plan ) ) {
423
+ $row[ $key ] = $plan[ $key ];
424
+ }
425
+ }
426
+
427
+ if ( ! empty( $plan['amount'] ) ) {
428
+ $row['fee_price'] = $plan['amount'];
429
+ }
430
  }
431
 
432
+ if ( ! $args['clear'] ) {
433
+ $old_row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d", $this->id ), ARRAY_A );
434
+
435
+ if ( $old_row ) {
436
+ $row = array_merge( $old_row, $row );
437
+ }
438
  }
439
 
440
+ if ( empty( $row ) )
441
+ return false;
442
 
443
+ $row['listing_id'] = $this->id;
444
+ $row['is_sticky'] = (int) $row['is_sticky'];
 
 
 
 
445
 
446
+ if ( $args['recalculate'] ) {
447
+ if ( ! array_key_exists( 'expiration_date', $plan ) ) {
448
+ $expiration = $this->calculate_expiration_date( current_time( 'timestamp' ), $row );
 
 
 
 
449
 
450
+ if ( $expiration ) {
451
+ $row['expiration_date'] = $expiration;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452
  }
453
  }
454
  }
455
 
456
+ if ( is_null( $row['expiration_date'] ) || empty( $row['expiration_date'] ) ) {
457
+ unset( $row['expiration_date'] );
458
  }
459
 
460
+ if ( ! empty( $row['recurring_data'] ) ) {
461
+ $row['recurring_data'] = maybe_serialize( $row['recurring_data'] );
462
+ }
463
 
464
+ return $wpdb->replace( "{$wpdb->prefix}wpbdp_listings", $row );
465
  }
466
 
467
+ /**
468
+ * @since 5.0
469
+ */
470
+ public function set_fee_plan( $fee, $recurring_data = array() ) {
471
+ global $wpdb;
 
 
472
 
473
+ if ( is_null( $fee ) ) {
474
+ $wpdb->delete( $wpdb->prefix . 'wpbdp_listings', array( 'listing_id' => $this->id ) );
475
+ // $wpdb->replace( $wpdb->prefix . 'wpbdp_listings', array( 'listing_id' => $this->id, 'fee_id' => null, 'fee_days' => 0, 'fee_images' => 0, 'is_sticky' => 0, 'expiration_date' => null ) );
476
+ return true;
477
  }
478
 
479
+ $fee = is_numeric( $fee ) ? wpbdp_get_fee_plan( $fee ) : $fee;
480
+
481
+ if ( ! $fee )
482
+ return false;
483
+
484
+ $row = array( 'listing_id' => $this->id,
485
+ 'fee_id' => $fee->id,
486
+ 'fee_days' => $fee->days,
487
+ 'fee_images' => $fee->images,
488
+ 'fee_price' => $fee->calculate_amount( wp_get_post_terms( $this->id, WPBDP_CATEGORY_TAX, array( 'fields' => 'ids' ) ) ),
489
+ 'is_recurring' => $fee->recurring || ! empty( $recurring_data ),
490
+ 'is_sticky' => (int) $fee->sticky );
491
+
492
+ if ( $expiration = $this->calculate_expiration_date( current_time( 'timestamp' ), $fee ) )
493
+ $row['expiration_date'] = $expiration;
494
 
495
+ if ( ! empty( $recurring_data ) ) {
496
+ $row['subscription_id'] = ! empty( $recurring_data['subscription_id'] ) ? $recurring_data['subscription_id'] : '';
497
+ $row['subscription_data'] = ! empty( $recurring_data['subscription_data'] ) ? serialize( $recurring_data['subscription_data'] ) : '';
498
  }
499
 
500
+ return $wpdb->replace( $wpdb->prefix . 'wpbdp_listings', $row );
501
+ }
502
+
503
+ /**
504
+ * @since 5.0
505
+ */
506
+ public function set_fee_plan_with_payment( $fee, $recurring = false ) {
507
+ $plan1 = $this->get_fee_plan();
508
+ $fee = is_numeric( $fee ) ? wpbdp_get_fee_plan( $fee ) : $fee;
509
+ $this->set_fee_plan( $fee );
510
+ $plan = $this->get_fee_plan();
511
+
512
+ if ( $fee->id == $plan1->fee_id )
513
+ return null;
514
+
515
+ $payment = new WPBDP_Payment( array( 'listing_id' => $this->id, 'payment_type' => $plan1 ? 'plan_change' : 'initial' ) );
516
+
517
+ $item = array(
518
+ 'type' => $plan->is_recurring ? 'recurring_plan' : 'plan',
519
+ 'description' => sprintf( _x( 'Plan "%s"%s', 'listing', 'WPBDM' ), $plan->fee_label, $plan->recurring ? ' ' . _x( '(recurring)', 'listing', 'WPBDM' ) : '' ),
520
+ 'amount' => $plan->fee_price,
521
+ 'fee_id' => $plan->fee_id,
522
+ 'fee_days' => $plan->fee_days,
523
+ 'fee_images' => $plan->fee_images
524
+ );
525
+
526
+ $payment->payment_items[] = $item;
527
+ $payment->save();
528
+
529
+ return $payment;
530
+ }
531
+
532
+ public function generate_or_retrieve_payment() {
533
+ $plan = $this->get_fee_plan();
534
+
535
+ if ( ! $plan )
536
+ return false;
537
+
538
+ $existing_payment = WPBDP_Payment::objects()->filter( array( 'listing_id' => $this->id, 'payment_type' => 'initial' ) )->get();
539
+
540
+ if ( $existing_payment )
541
+ return $existing_payment;
542
+
543
+ $payment = new WPBDP_Payment( array( 'listing_id' => $this->id, 'payment_type' => 'initial' ) );
544
+
545
+ $item = array(
546
+ 'type' => $plan->is_recurring ? 'recurring_plan' : 'plan',
547
+ 'description' => sprintf( _x( 'Plan "%s"', 'listing', 'WPBDM' ), $plan->fee_label ),
548
+ 'amount' => $plan->fee_price,
549
+ 'fee_id' => $plan->fee_id,
550
+ 'fee_days' => $plan->fee_days,
551
+ 'fee_images' => $plan->fee_images,
552
+ );
553
+
554
+ $payment->payment_items[] = $item;
555
+ $payment->save();
556
+
557
+ return $payment;
558
+ }
559
+
560
+
561
+ /**
562
+ * @since 5.0
563
+ */
564
+ public function get_expiration_date() {
565
+ $plan = $this->get_fee_plan();
566
+ return $plan ? $plan->expiration_date : null;
567
+ }
568
+
569
+ /**
570
+ * @since 5.0
571
+ */
572
+ public function get_expiration_time() {
573
+ return strtotime( $this->get_expiration_date() );
574
+ }
575
+
576
+ /**
577
+ * @since 5.0
578
+ */
579
+ public function get_status( $force_refresh = false, $calculate = true ) {
580
+ global $wpdb;
581
+
582
+ $status_ = $wpdb->get_var( $wpdb->prepare( "SELECT listing_status FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d", $this->id ) );
583
+
584
+ if ( 'unknown' == $status_ || $force_refresh ) {
585
+ if ( $calculate ) {
586
+ $status = $this->calculate_status();
587
+ } else {
588
+ $status = 'unknown';
589
+ }
590
+ } else if ( ! $status_ ) {
591
+ $status = 'incomplete';
592
+ } else {
593
+ $status = $status_;
594
  }
595
 
596
+ $status = apply_filters( 'wpbdp_listing_status', $status, $this->id );
597
+
598
+ if ( ! $status_ || $status_ != $status || $force_refresh )
599
+ $wpdb->update( $wpdb->prefix . 'wpbdp_listings', array( 'listing_status' => $status ), array( 'listing_id' => $this->id ) );
600
+
601
+ return $status;
602
+ }
603
+
604
+ /**
605
+ * @since 5.0
606
+ */
607
+ public function get_status_label() {
608
+ $stati = self::get_stati();
609
+
610
+ return $stati[ $this->get_status() ];
611
+ }
612
+
613
+ /**
614
+ * @since 5.0
615
+ */
616
+ private function calculate_status() {
617
+ global $wpdb;
618
+
619
+ $is_expired = (bool) $wpdb->get_var(
620
+ $wpdb->prepare(
621
+ "SELECT 1 AS x FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d AND expiration_date IS NOT NULL AND expiration_date < %s",
622
+ $this->id,
623
+ current_time( 'mysql' )
624
+ )
625
+ );
626
+ $pending_payment = $wpdb->get_row(
627
+ $wpdb->prepare(
628
+ "SELECT * FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id = %d AND status = %s ORDER BY id DESC LIMIT 1",
629
+ $this->id,
630
+ 'pending'
631
+ )
632
+ );
633
+
634
+ if ( ! $pending_payment || ! in_array( $pending_payment->payment_type, array( 'initial', 'renewal' ), true ) )
635
+ return $is_expired ? 'expired' : 'complete';
636
+
637
+ return ( 'initial' == $pending_payment->payment_type ? 'pending_payment' : 'pending_renewal' );
638
+ }
639
+
640
+ /**
641
+ * @since 5.0
642
+ */
643
+ public static function get_stati() {
644
+ $stati = array(
645
+ 'unknown' => _x( 'Unknown', 'listing status', 'WPBDM' ),
646
+ 'legacy' => _x( 'Legacy', 'listing status', 'WPBDM' ),
647
+ 'incomplete' => _x( 'Incomplete', 'listing status', 'WPBDM' ),
648
+ 'pending_payment' => _x( 'Pending Payment', 'listing status', 'WPBDM' ),
649
+ 'complete' => _x( 'Complete', 'listing status', 'WPBDM' ),
650
+ 'pending_upgrade' => _x( 'Pending Upgrade', 'listing status', 'WPBDM' ),
651
+ 'expired' => _x( 'Expired', 'listing status', 'WPBDM' ),
652
+ 'pending_renewal' => _x( 'Pending Renewal', 'listing status', 'WPBDM' ),
653
+ 'abandoned' => _x( 'Abandoned', 'listing status', 'WPBDM' )
654
+ );
655
+ $stati = apply_filters( 'wpbdp_listing_stati', $stati );
656
+
657
+ return $stati;
658
+ }
659
+
660
+ /**
661
+ * @since 5.0
662
+ */
663
+ public static function validate_access_key( $key, $email = '' ) {
664
+ if ( ! $key )
665
+ return false;
666
+
667
+ global $wpdb;
668
+
669
+ return intval( $wpdb->get_var(
670
+ $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s",
671
+ '_wpbdp[access_key]',
672
+ $key )
673
+ ) ) > 0;
674
+ }
675
+
676
+ /**
677
+ * @since 5.0
678
+ */
679
+ public function get_sequence_id() {
680
+ $sequence_id = get_post_meta( $this->id, '_wpbdp[import_sequence_id]', true );
681
+
682
+ if ( ! $sequence_id ) {
683
+ global $wpdb;
684
+
685
+ $candidate = intval( $wpdb->get_var( $wpdb->prepare( "SELECT MAX(CAST(meta_value AS UNSIGNED INTEGER )) FROM {$wpdb->postmeta} WHERE meta_key = %s",
686
+ '_wpbdp[import_sequence_id]' ) ) );
687
+ $candidate++;
688
+
689
+ if ( false == add_post_meta( $this->id, '_wpbdp[import_sequence_id]', $candidate, true ) )
690
+ $sequence_id = 0;
691
+ else
692
+ $sequence_id = $candidate;
693
  }
694
 
695
+ return $sequence_id;
696
+ }
697
+
698
+ /**
699
+ * @since 5.0
700
+ */
701
+ public function get_flags() {
702
+ global $wpdb;
703
+
704
+ $flags = trim( $wpdb->get_var( $wpdb->prepare( "SELECT flags FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d", $this->id ) ) );
705
+
706
+ if ( ! $flags )
707
+ return array();
708
+
709
+ return explode( ',', $flags );
710
+ }
711
+
712
+ /**
713
+ * @since 5.0
714
+ */
715
+ public function set_flag( $flag ) {
716
+ global $wpdb;
717
+
718
+ $flags = $this->get_flags();
719
+
720
+ if ( ! in_array( $flag, $flags, true ) )
721
+ $flags[] = $flag;
722
+
723
+ $wpdb->update( $wpdb->prefix . 'wpbdp_listings', array( 'flags' => implode( ',', $flags ) ), array( 'listing_id' => $this->id ) );
724
+ }
725
+
726
+ /**
727
+ * @since 5.0
728
+ */
729
+ public function _after_save( $context = '' ) {
730
+ if ( 'submit-new' == $context ) {
731
+ do_action( 'WPBDP_Listing::listing_created', $this->id );
732
+ do_action( 'wpbdp_add_listing', $this->id );
733
+ } elseif ( 'submit-edit' == $context ) {
734
+ do_action( 'wpbdp_edit_listing', $this->id );
735
+ do_action( 'WPBDP_Listing::listing_edited', $this->id );
736
  }
737
 
738
+ do_action( 'wpbdp_save_listing', $this->id, 'submit-new' == $context );
739
+
740
+ $this->get_status(); // This forces a status refresh if there's no status.
741
+
742
+ // Do not let expired listings be public.
743
+ if ( $this->get_status() && in_array( $this->get_status(), array( 'expired', 'pending_renewal' ) ) && 'publish' == get_post_status( $this->id ) ) {
744
+ $this->set_post_status( 'draft' );
745
  }
746
+ }
747
 
748
+ /**
749
+ * @since 5.0
750
+ */
751
+ public function after_delete( $context = '' ) {
752
+ global $wpdb;
753
+
754
+ // Remove attachments.
755
+ $attachments = get_posts( array( 'post_type' => 'attachment', 'post_parent' => $this->id, 'numberposts' => -1, 'fields' => 'ids' ) );
756
+ foreach ( $attachments as $attachment_id )
757
+ wp_delete_attachment( $attachment_id, true );
758
+
759
+ // Remove listing fees.
760
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listings WHERE listing_id = %d", $this->id ) );
761
+
762
+ // Delete logs.
763
+ $wpdb->delete( $wpdb->prefix . 'wpbdp_logs', array( 'object_type' => 'listing', 'object_id' => $this->id ) );
764
+
765
+ // Remove payment information.
766
+ foreach ( $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id = %d", $this->id ) ) as $payment_id ) {
767
+ $payment = WPBDP_Payment::objects()->get( $payment_id );
768
+ $payment->delete();
769
  }
770
+ }
771
 
772
+ /**
773
+ * @since 5.0
774
+ */
775
+ public static function insert_or_update( $args = array(), $error = false ) {
776
  }
777
 
778
  public static function get( $id ) {
781
 
782
  $l = new self( $id );
783
  $l->new = false;
 
784
  return $l;
785
  }
786
 
includes/class-listings-api.php CHANGED
@@ -8,538 +8,39 @@ if ( ! class_exists( 'WPBDP_Listings_API' ) ) {
8
  class WPBDP_Listings_API {
9
 
10
  public function __construct() {
11
- add_filter( 'post_type_link', array( &$this, '_post_link' ), 10, 3 );
12
- add_filter( 'get_shortlink', array( &$this, '_short_link' ), 10, 4 );
13
- // add_filter('post_type_link', array($this, '_post_link_qtranslate'), 11, 2); // basic support for qTranslate
14
- add_filter('preview_post_link', array($this, '_preview_post_link'), 10, 2);
15
-
16
- add_filter('term_link', array($this, '_category_link'), 10, 3);
17
- add_filter('term_link', array($this, '_tag_link'), 10, 3);
18
-
19
- add_filter('comments_open', array($this, '_allow_comments'), 10, 2);
20
-
21
- add_action( 'WPBDP_Listing::listing_created', array( &$this, 'new_listing_admin_email' ) );
22
- add_action( 'WPBDP_Listing::listing_created', array( &$this, 'new_listing_confirmation_email' ) );
23
- add_action( 'wpbdp_edit_listing', array( &$this, 'edit_listing_admin_email' ) );
24
-
25
- add_action( 'WPBDP_Payment::status_change', array( &$this, 'setup_listing_after_payment' ) );
26
- add_action( 'WPBDP_Payment::status_change', array( &$this, 'auto_renewal_notification_email' ) );
27
-
28
- add_action( 'transition_post_status', array( &$this, 'listing_published_notification' ), 10, 3 );
29
-
30
- add_action( 'before_delete_post', array( &$this, 'after_listing_delete' ) );
31
- add_action( 'delete_term', array( &$this, 'handle_delete_term' ), 10, 3 );
32
-
33
- $this->upgrades = WPBDP_Listing_Upgrade_API::instance();
34
- }
35
-
36
- public function _category_link($link, $category, $taxonomy) {
37
- if ( WPBDP_CATEGORY_TAX != $taxonomy )
38
- return $link;
39
-
40
- if ( ! wpbdp_rewrite_on() ) {
41
- if ( wpbdp_get_option( 'disable-cpt' ) )
42
- return wpbdp_url( '/' ) . '&_' . wpbdp_get_option( 'permalinks-category-slug' ) . '=' . $category->slug;
43
-
44
- return $link;
45
- }
46
-
47
- $link = wpbdp_url( sprintf( '/%s/%s/', wpbdp_get_option( 'permalinks-category-slug' ), $category->slug ) );
48
-
49
- return apply_filters( 'wpbdp_category_link', $link, $category );
50
- }
51
-
52
- public function _tag_link($link, $tag, $taxonomy) {
53
- if ( WPBDP_TAGS_TAX != $taxonomy )
54
- return $link;
55
-
56
- if ( ! wpbdp_rewrite_on() ) {
57
- if ( wpbdp_get_option( 'disable-cpt' ) )
58
- $link = wpbdp_url( '/' ) . '&_' . wpbdp_get_option( 'permalinks-tags-slug' ) . '=' . $tag->slug;
59
-
60
- return $link;
61
- }
62
-
63
- $link = wpbdp_url( sprintf( '/%s/%s/', wpbdp_get_option( 'permalinks-tags-slug' ), $tag->slug ) );
64
-
65
- return $link;
66
- }
67
-
68
- public function _post_link( $link, $post = null, $leavename = false ) {
69
- if ( WPBDP_POST_TYPE != get_post_type( $post ) )
70
- return $link;
71
-
72
- if ( $querystring = parse_url( $link, PHP_URL_QUERY ) )
73
- $querystring = '?' . $querystring;
74
- else
75
- $querystring = '';
76
-
77
- if ( ! wpbdp_rewrite_on() ) {
78
- if ( wpbdp_get_option( 'disable-cpt' ) ) {
79
- $link = wpbdp_url( '/' ) . '&' . '_' . wpbdp_get_option( 'permalinks-directory-slug' ) . '=' . $post->post_name;
80
- }
81
- } else {
82
- if ( $leavename )
83
- return wpbdp_url( '/' . '%' . WPBDP_POST_TYPE . '%' . '/' . $querystring );
84
-
85
- if ( wpbdp_get_option( 'permalinks-no-id' ) ) {
86
- if ( $post->post_name ) {
87
- $link = wpbdp_url( '/' . $post->post_name . '/' );
88
- } else {
89
- // Use default $link.
90
- return $link;
91
- }
92
- } else {
93
- $link = wpbdp_url( '/' . $post->ID . '/' . ( $post->post_name ? $post->post_name : '' ) );
94
- }
95
-
96
- $link .= $querystring;
97
- }
98
-
99
- return apply_filters( 'wpbdp_listing_link', $link, $post->ID );
100
- }
101
-
102
- public function _short_link( $shortlink, $id = 0, $context = 'post', $allow_slugs = true ) {
103
- if ( 'post' !== $context || WPBDP_POST_TYPE != get_post_type( $id ) )
104
- return $shortlink;
105
-
106
- $post = get_post( $id );
107
- return $this->_post_link( $shortlink, $post );
108
  }
109
 
110
- public function _post_link_qtranslate( $url, $post ) {
111
- if ( is_admin() || !function_exists( 'qtrans_convertURL' ) )
112
- return $url;
113
-
114
- global $q_config;
115
-
116
- $lang = isset( $_GET['lang'] ) ? $_GET['lang'] : $q_config['language'];
117
- $default_lang = $q_config['default_language'];
118
-
119
- if ( $lang != $default_lang )
120
- return add_query_arg( 'lang', $lang, $url );
121
-
122
- return $url;
123
- }
124
-
125
- public function _preview_post_link( $url, $post = null ) {
126
- if ( is_null( $post ) && isset( $GLOBALS['post'] ) )
127
- $post = $GLOBALS['post'];
128
-
129
- if ( WPBDP_POST_TYPE != get_post_type( $post ) )
130
- return $url ;
131
-
132
- if ( wpbdp_rewrite_on() ) {
133
- if ( ! wpbdp_get_option( 'permalinks-no-id' ) || ! empty( $post->post_name ) ) {
134
- $url = remove_query_arg( array( 'post_type', 'p' ), $url );
135
- }
136
- }
137
-
138
- return $url;
139
- }
140
-
141
- public function _allow_comments($open, $post_id) {
142
- // comments on directory pages
143
- if ($post_id == wpbdp_get_page_id('main'))
144
- return false;
145
-
146
- // comments on listings
147
- if ( get_post_type( $post_id ) == WPBDP_POST_TYPE ) {
148
- return in_array(
149
- wpbdp_get_option( 'allow-comments-in-listings' ),
150
- array( 'allow-comments', 'allow-comments-and-insert-template' )
151
- );
152
- }
153
 
154
- return $open;
155
- }
156
-
157
- /**
158
- * @since 3.4
159
- */
160
- public function setup_listing_after_payment( &$payment ) {
161
- $listing = WPBDP_Listing::get( $payment->get_listing_id() );
162
-
163
- // TODO: handle some rejected payments (i.e. downgrade listing if pending upgrade, etc.)
164
-
165
- if ( ! $listing || ! $payment->is_completed() )
166
  return;
167
 
168
- $is_renewal = false;
169
 
170
- foreach ( $payment->get_items() as $item ) {
171
- switch ( $item->item_type ) {
172
- case 'recurring_fee':
173
- $listing->add_category( $item->rel_id_1, (object) $item->data, true, array( 'recurring_id' => $payment->get_data( 'recurring_id' ),
174
- 'payment_id' => $payment->get_id() ) );
 
175
 
176
- if ( ! empty( $item->data['is_renewal'] ) )
177
- $is_renewal = true;
178
-
179
- break;
180
- case 'fee':
181
- $listing->add_category( $item->rel_id_1, $item->rel_id_2, false );
182
-
183
- if ( ! empty( $item->data['is_renewal'] ) )
184
- $is_renewal = true;
185
-
186
- break;
187
-
188
- case 'upgrade':
189
- $upgrades_api = wpbdp_listing_upgrades_api();
190
- $sticky_info = $upgrades_api->get_info( $listing->get_id() );
191
-
192
- if ( $sticky_info->upgradeable )
193
- $upgrades_api->set_sticky( $listing->get_id(), $sticky_info->upgrade->id, true );
194
-
195
- break;
196
  }
197
  }
198
 
199
- $listing->save();
200
 
201
- if ( $is_renewal ) {
 
202
  $listing->set_post_status( 'publish' );
203
- } elseif ( 'initial' == $payment->tag ) {
204
- $listing->set_post_status( wpbdp_get_option( 'new-post-status' ) );
205
- }
206
- }
207
-
208
- /**
209
- * @since 3.5.2
210
- */
211
- public function auto_renewal_notification_email( &$payment ) {
212
- if ( ! $payment->is_completed() || ! $payment->has_item_type( 'recurring_fee' ) )
213
- return;
214
-
215
- if ( ! $payment->get_data( 'parent_payment_id' ) )
216
- return;
217
-
218
- global $wpbdp;
219
- if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
220
- return;
221
-
222
- $recurring_item = $payment->get_recurring_item();
223
-
224
- $replacements = array();
225
- $replacements['listing'] = sprintf( '<a href="%s">%s</a>',
226
- get_permalink( $payment->get_listing_id() ),
227
- get_the_title( $payment->get_listing_id() ) );
228
- $replacements['author'] = get_the_author_meta( 'display_name', get_post( $payment->get_listing_id() )->post_author );
229
- $replacements['category'] = wpbdp_get_term_name( $recurring_item->rel_id_1 );
230
- $replacements['date'] = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ),
231
- strtotime( $payment->get_processed_on() ) );
232
- $replacements['site'] = sprintf( '<a href="%s">%s</a>',
233
- get_bloginfo( 'url' ),
234
- get_bloginfo( 'name' ) );
235
-
236
- $email = wpbdp_email_from_template( 'listing-autorenewal-message', $replacements );
237
- $email->to[] = wpbusdirman_get_the_business_email( $payment->get_listing_id() );
238
- $email->template = 'businessdirectory-email';
239
- $email->send();
240
- }
241
-
242
- function listing_published_notification( $new_status, $old_status, $post ) {
243
- if ( ! in_array( 'listing-published', wpbdp_get_option( 'user-notifications' ), true ) )
244
- return;
245
-
246
- if ( WPBDP_POST_TYPE != get_post_type( $post ) )
247
- return;
248
-
249
- if ( $new_status == $old_status || 'publish' != $new_status || ( 'pending' != $old_status && 'draft' != $old_status ) )
250
- return;
251
-
252
- global $wpbdp;
253
- if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
254
- return;
255
-
256
- if ( isset( $_POST['original_post_status'] ) && 'auto-draft' == $_POST['original_post_status'] ) {
257
- add_action( 'save_post', array( $this, 'send_listing_published_notification' ), PHP_INT_MAX, 2 );
258
- add_action( 'save_post', array( $this, 'try_to_remove_listing_published_notification_action' ), PHP_INT_MAX );
259
- return;
260
- }
261
-
262
- $this->send_listing_published_notification( $post->ID, $post );
263
- }
264
-
265
- public function send_listing_published_notification( $post_id, $post ) {
266
- if ( ! isset( $post->post_type ) || WPBDP_POST_TYPE !== $post->post_type ) {
267
- return;
268
- }
269
-
270
- $email = wpbdp_email_from_template( 'email-templates-listing-published', array(
271
- 'listing' => get_the_title( $post->ID ),
272
- 'listing-url' => get_permalink( $post->ID )
273
- ) );
274
- $email->to[] = wpbusdirman_get_the_business_email( $post->ID );
275
- $email->template = 'businessdirectory-email';
276
- $email->send();
277
- }
278
-
279
- public function try_to_remove_listing_published_notification_action() {
280
- remove_action( 'save_post', array( $this, 'send_listing_published_notification' ), PHP_INT_MAX, 2 );
281
- remove_action( 'save_post', array( $this, 'try_to_remove_listing_published_notification_action' ), PHP_INT_MAX );
282
- }
283
-
284
- /**
285
- * Handles cleanup after a listing is deleted.
286
- * @since 3.4
287
- */
288
- public function after_listing_delete( $post_id ) {
289
- global $wpdb;
290
-
291
- if ( WPBDP_POST_TYPE != get_post_type( $post_id ) )
292
- return;
293
-
294
- // Remove attachments.
295
- $attachments = get_posts( array( 'post_type' => 'attachment', 'post_parent' => $post_id, 'numberposts' => -1, 'fields' => 'ids' ) );
296
- foreach ( $attachments as $attachment_id )
297
- wp_delete_attachment( $attachment_id, true );
298
-
299
- // Remove listing fees.
300
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d", $post_id ) );
301
-
302
- // Remove payment information.
303
- $wpdb->query( $wpdb->prepare( "DELETE pi.* FROM {$wpdb->prefix}wpbdp_payments_items pi WHERE pi.payment_id IN (SELECT p.id FROM {$wpdb->prefix}wpbdp_payments p WHERE p.listing_id = %d)", $post_id ) );
304
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_payments WHERE listing_id = %d", $post_id ) );
305
- }
306
-
307
- public function handle_delete_term( $term_id, $tt_id, $taxonomy ) {
308
- global $wpdb;
309
-
310
- if ( WPBDP_CATEGORY_TAX != $taxonomy )
311
- return;
312
-
313
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE category_id = %d", $term_id ) );
314
- }
315
-
316
- public function new_listing_confirmation_email( &$listing ) {
317
- if ( ! in_array( 'new-listing', wpbdp_get_option( 'user-notifications' ), true ) )
318
- return;
319
-
320
- global $wpbdp;
321
- if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
322
- return;
323
-
324
- $email = wpbdp_email_from_template( 'email-confirmation-message', array(
325
- 'listing' => $listing->get_title()
326
- ) );
327
- $email->to[] = wpbusdirman_get_the_business_email( $listing->get_id() );
328
- $email->template = 'businessdirectory-email';
329
- $email->send();
330
- }
331
-
332
- public function new_listing_admin_email( &$listing ) {
333
- if ( ! in_array( 'new-listing', wpbdp_get_option( 'admin-notifications' ), true ) )
334
- return;
335
-
336
- global $wpbdp;
337
- if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
338
- return;
339
-
340
- $email = new WPBDP_Email();
341
- $email->subject = sprintf( _x( '[%s] New listing notification', 'notify email', 'WPBDM' ), get_bloginfo( 'name' ) );
342
- $email->to[] = get_bloginfo( 'admin_email' );
343
-
344
- if ( wpbdp_get_option( 'admin-notifications-cc' ) )
345
- $email->cc[] = wpbdp_get_option( 'admin-notifications-cc' );
346
-
347
- $email->body = wpbdp_render( 'email/listing-added', array( 'listing' => $listing ), false );
348
- $email->send();
349
- }
350
-
351
- public function edit_listing_admin_email( &$listing ) {
352
- if ( ! in_array( 'listing-edit', wpbdp_get_option( 'admin-notifications' ), true ) )
353
- return;
354
-
355
- global $wpbdp;
356
- if ( isset( $wpbdp->_importing_csv_no_email ) && $wpbdp->_importing_csv_no_email )
357
- return;
358
-
359
- $email = new WPBDP_Email();
360
- $email->subject = sprintf( _x( '[%s] Listing edit notification', 'notify email', 'WPBDM' ), get_bloginfo( 'name' ) );
361
- $email->to[] = get_bloginfo( 'admin_email' );
362
-
363
- if ( wpbdp_get_option( 'admin-notifications-cc' ) )
364
- $email->cc[] = wpbdp_get_option( 'admin-notifications-cc' );
365
-
366
- $email->body = wpbdp_render( 'email/listing-edited', array( 'listing' => $listing ), false );
367
-
368
- $email->send();
369
- }
370
-
371
- public function get_thumbnail_id($listing_id) {
372
- if ( $thumbnail_id = get_post_meta($listing_id, '_wpbdp[thumbnail_id]', true ) ) {
373
- if ( false !== get_post_status( $thumbnail_id ) )
374
- return intval( $thumbnail_id );
375
- }
376
-
377
- if ( $images = $this->get_images( $listing_id ) ) {
378
- update_post_meta( $listing_id, '_wpbdp[thumbnail_id]', $images[0]->ID );
379
- return $images[0]->ID;
380
- }
381
-
382
- return 0;
383
- }
384
-
385
- /**
386
- * @since 3.4.1
387
- */
388
- public function calculate_sequence_id( $listing_id ) {
389
- $sequence_id = get_post_meta( $listing_id, '_wpbdp[import_sequence_id]', true );
390
-
391
- if ( ! $sequence_id ) {
392
- global $wpdb;
393
-
394
- $candidate = intval( $wpdb->get_var( $wpdb->prepare( "SELECT MAX(CAST(meta_value AS UNSIGNED INTEGER )) FROM {$wpdb->postmeta} WHERE meta_key = %s",
395
- '_wpbdp[import_sequence_id]' ) ) );
396
- $candidate++;
397
-
398
- if ( false == add_post_meta( $listing_id, '_wpbdp[import_sequence_id]', $candidate, true ) )
399
- $sequence_id = 0;
400
- else
401
- $sequence_id = $candidate;
402
- }
403
-
404
- return $sequence_id;
405
- }
406
-
407
- public function get_images($listing_id) {
408
- $attachments = get_posts(array(
409
- 'numberposts' => -1,
410
- 'post_type' => 'attachment',
411
- 'post_parent' => $listing_id
412
- ));
413
-
414
- $result = array();
415
-
416
- foreach ($attachments as $attachment) {
417
- if (wp_attachment_is_image($attachment->ID))
418
- $result[] = $attachment;
419
- }
420
-
421
- return $result;
422
- }
423
-
424
- public function get_listing_fees($listing_id) {
425
- global $wpdb;
426
- return $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d", $listing_id));
427
- }
428
-
429
- public function remove_category_info( $listing_id, $category_or_categories ) {
430
- global $wpdb;
431
-
432
- $categories = array_map( 'intval', is_array( $category_or_categories ) ? $category_or_categories : array( $category_or_categories ) );
433
- $current_terms = array_map( 'intval', wp_get_post_terms( $listing_id, WPBDP_CATEGORY_TAX, 'fields=ids' ) );
434
- $new_terms = array_diff( $current_terms, $categories );
435
-
436
- wp_set_post_terms( $listing_id, $new_terms, WPBDP_CATEGORY_TAX, false );
437
-
438
- foreach ( $categories as $cat_id ) {
439
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d AND category_id = %d",
440
- $listing_id,
441
- $cat_id ) );
442
- }
443
-
444
- return true;
445
- }
446
-
447
- public function get_expiration_time($listing_id, $fee) {
448
- if (is_array($fee)) return $this->get_expiration_time($listing_id, (object) $fee);
449
-
450
- if ($fee->days == 0)
451
- return null;
452
-
453
- $start_time = get_post_time('U', false, $listing_id);
454
- $expire_time = strtotime(sprintf('+%d days', $fee->days), $start_time);
455
- return $expire_time;
456
- }
457
-
458
- public function get_listing_fee_for_category($listing_id, $catid) {
459
- global $wpdb;
460
-
461
- $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE listing_id = %d AND category_id = %d", $listing_id, $catid));
462
-
463
- if ($row != null) {
464
- // $fee = unserialize($row->fee);
465
- $fee['expires_on'] = $row->expires_on;
466
- $fee['renewal_id'] = $row->id;
467
- $fee['category_id'] = $row->category_id;
468
- return (object) $fee;
469
  }
470
-
471
- return null;
472
- }
473
-
474
- /*
475
- * Featured listings.
476
- */
477
-
478
- // TODO: deprecate (move to ListingUpgrades)
479
- public function get_sticky_status( $listing_id ) {
480
- $listing = WPBDP_Listing::get( $listing_id );
481
-
482
- if ( ! $listing )
483
- return 'normal';
484
-
485
- return $listing->get_sticky_status( false );
486
  }
487
 
488
- /**
489
- * Automatically renews a listing in all of its expired categories using the same fee as before (if possible) or the first one available.
490
- * @param int $listing_id the listing ID
491
- * @since 3.1
492
- */
493
- public function auto_renew( $listing_id ) {
494
- global $wpdb;
495
-
496
- $listing = WPBDP_Listing::get( $listing_id );
497
- $expired = $listing->get_categories( 'expired' );
498
-
499
- if ( !$expired )
500
- return;
501
-
502
- foreach ( $expired as &$e ) {
503
- $available_fees = wpbdp_get_fees_for_category( $e->term_id );
504
- $old_fee_id = $e->fee_id;
505
- $new_fee = null;
506
-
507
- foreach ( $available_fees as &$fee_option ) {
508
- if ( $fee_option->id == $old_fee_id ) {
509
- $new_fee = $fee_option;
510
- break;
511
- }
512
- }
513
-
514
- if ( !$new_fee )
515
- $new_fee = $available_fees[0];
516
-
517
- $listing->add_category( $e->term_id, $new_fee );
518
- }
519
-
520
- wp_update_post( array( 'ID' => $listing_id, 'post_status' => 'publish' ) );
521
- }
522
-
523
- public function renew_listing($renewal_id, $fee) {
524
- global $wpdb;
525
-
526
- if ( $renewal = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d AND expires_on IS NOT NULL", $renewal_id, current_time( 'mysql' ) ) ) ) {
527
- // set payment status to not-paid
528
- // update_post_meta( $renewal->listing_id, '_wpbdp[payment_status]', 'not-paid' );
529
-
530
- // register the new transaction
531
- $transaction_id = wpbdp_payments_api()->save_transaction( array(
532
- 'listing_id' => $renewal->listing_id,
533
- 'amount' => $fee->amount,
534
- 'payment_type' => 'renewal',
535
- 'extra_data' => array( 'renewal_id' => $renewal_id, 'fee' => $fee )
536
- ));
537
-
538
- return $transaction_id;
539
- }
540
-
541
- return 0;
542
- }
543
 
544
  // {{{ Quick search.
545
 
@@ -576,7 +77,7 @@ class WPBDP_Listings_API {
576
  if ( ! $keywords && ! $location )
577
  return array();
578
 
579
- require_once( WPBDP_INC . 'helpers/class-search-helper.php' );
580
 
581
  $args = array( 'query' => $keywords,
582
  'mode' => 'quick-search',
@@ -589,212 +90,9 @@ class WPBDP_Listings_API {
589
 
590
  // }}}
591
 
592
- public function send_renewal_email( $renewal_id, $email_message_type = 'auto' ) {
593
- global $wpdb;
594
-
595
- $renewal_id = intval( $renewal_id );
596
- $fee_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d", $renewal_id ) );
597
-
598
- if ( !$fee_info || !$fee_info->expires_on )
599
- return false;
600
-
601
-
602
- $message_option = '';
603
-
604
- if ( $email_message_type == 'auto' ) {
605
- $expiration = strtotime( $fee_info->expires_on );
606
- $current_time = time();
607
-
608
- if ( $expiration > $current_time ) {
609
- $message_option = 'renewal-pending-message';
610
- } else {
611
- $message_option = 'listing-renewal-message';
612
- }
613
- } elseif ( $email_message_type ) {
614
- $message_option = $email_message_type;
615
- } else {
616
- $message_option = 'listing-renewal-message';
617
- }
618
-
619
- $listing = WPBDP_Listing::get( $fee_info->listing_id );
620
-
621
- $renewal_url = $listing->get_renewal_url( $fee_info->category_id );
622
- $message_replacements = array( 'site' => sprintf( '<a href="%s">%s</a>', get_bloginfo( 'url' ), get_bloginfo( 'name' ) ),
623
- 'listing' => esc_attr( get_the_title( $fee_info->listing_id ) ),
624
- 'category' => get_term( $fee_info->category_id, WPBDP_CATEGORY_TAX )->name,
625
- 'expiration' => date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $fee_info->expires_on ) ),
626
- 'link' => sprintf( '<a href="%1$s">%1$s</a>', $renewal_url )
627
- );
628
-
629
- $email = wpbdp_email_from_template( $message_option, $message_replacements );
630
- $email->to[] = wpbusdirman_get_the_business_email( $fee_info->listing_id );
631
- $email->template = 'businessdirectory-email';
632
- $email->send();
633
-
634
- return true;
635
- }
636
-
637
-
638
- /**
639
- * Notifies listings expiring soon. Despite its name this function also changes listings according to expiration rules (removing categories, unpublishing, etc.).
640
- * @param int $threshold A threshold (in days) to use for checking listing expiration times: 0 means already expired listings and a positive
641
- * value checks listings expiring between now and now + $threshold.
642
- * @param int $now Timestamp to use as current time. Defaults to the value of `current_time( 'timestamp' )`.
643
- * @since 3.1
644
- */
645
- public function notify_expiring_listings( $threshold=0, $now=null ) {
646
- global $wpdb;
647
-
648
- $threshold = intval( $threshold );
649
- $now = $now > 0 ? intval( $now ) : current_time( 'timestamp' );
650
-
651
- $query = '';
652
- $now_date = wpbdp_format_time( $now, 'mysql' );
653
-
654
- if ( $threshold == 0 ) {
655
- $this->notify_expired_listings_recurring( $now );
656
-
657
- $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE recurring = %d AND expires_on IS NOT NULL AND expires_on < %s AND email_sent <> %d AND email_sent <> %d ORDER BY expires_on LIMIT 100",
658
- 0,
659
- $now_date,
660
- 2,
661
- 3 );
662
- } else {
663
- if ( $threshold > 0 ) {
664
- $end_date = wpbdp_format_time( strtotime( sprintf( '+%d days', $threshold ), $now ), 'mysql' );
665
-
666
- if ( wpbdp_get_option( 'send-autorenewal-expiration-notice' ) ) {
667
- $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE expires_on IS NOT NULL AND expires_on >= %s AND expires_on <= %s AND email_sent = %d ORDER BY expires_on LIMIT 100",
668
- $now_date,
669
- $end_date,
670
- 0 );
671
- } else {
672
- $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE recurring = %d AND expires_on IS NOT NULL AND expires_on >= %s AND expires_on <= %s AND email_sent = %d ORDER BY expires_on LIMIT 100",
673
- 0,
674
- $now_date,
675
- $end_date,
676
- 0 );
677
- }
678
- } else {
679
- $exp_date = wpbdp_format_time( strtotime( sprintf( '%d days', $threshold ), $now ), 'mysql' );
680
-
681
- $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE recurring = %d AND expires_on IS NOT NULL AND expires_on < %s AND email_sent = %d",
682
- 0,
683
- $exp_date,
684
- 2 );
685
- }
686
- }
687
-
688
- $rs = $wpdb->get_results( $query );
689
-
690
- if ( !$rs )
691
- return;
692
-
693
- foreach ( $rs as &$r ) {
694
- $listing = WPBDP_Listing::get( $r->listing_id );
695
-
696
- if ( ! $listing || ! term_exists( absint( $r->category_id ), WPBDP_CATEGORY_TAX ) ) {
697
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_listing_fees WHERE id = %d", $r->id ) );
698
- continue;
699
- }
700
-
701
- $base_replacements = array( 'site' => sprintf( '<a href="%s">%s</a>', get_bloginfo( 'url' ), get_bloginfo( 'name' ) ),
702
- 'author' => get_the_author_meta( 'display_name', get_post( $r->listing_id )->post_author ),
703
- 'listing' => sprintf( '<a href="%s">%s</a>', $listing->get_permalink(), esc_attr( $listing->get_title() ) ),
704
- 'category' => wpbdp_get_term_name( $r->category_id ),
705
- 'expiration' => date_i18n( get_option( 'date_format' ), strtotime( $r->expires_on ) )
706
- );
707
-
708
- if ( ! $r->recurring ) {
709
- $renewal_url = $listing->get_renewal_url( $r->category_id );
710
- $message_replacements = array_merge( $base_replacements, array(
711
- 'link' => sprintf( '<a href="%1$s">%1$s</a>', $renewal_url )
712
- ) );
713
- } else {
714
- $message_replacements = array_merge( $base_replacements, array(
715
- 'date' => $base_replacements['expiration'],
716
- 'link' => sprintf( '<a href="%1$s">%1$s</a>', esc_url( wpbdp_url( 'manage_recurring' ) ) )
717
- ) );
718
- }
719
-
720
- if ( 0 == $threshold ) {
721
- // handle expired listings
722
-
723
- // remove expired category from post
724
- $listing->remove_category( $r->category_id, false );
725
-
726
- if ( ! $listing->get_categories( 'current' ) ) {
727
- // $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d", wpbdp_get_option( 'deleted-status' ), $r->listing_id ) );
728
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d", 'draft', $listing->get_id() ) );
729
- }
730
-
731
- if ( wpbdp_get_option( 'listing-renewal' ) ) {
732
- $email = wpbdp_email_from_template( 'listing-renewal-message', $message_replacements );
733
- $email->to[] = wpbusdirman_get_the_business_email( $listing->get_id() );
734
-
735
- if ( in_array( 'renewal', wpbdp_get_option( 'admin-notifications' ), true ) ) {
736
- $email->cc[] = get_option( 'admin_email' );
737
-
738
- if ( wpbdp_get_option( 'admin-notifications-cc' ) )
739
- $email->cc[] = wpbdp_get_option( 'admin-notifications-cc' );
740
- }
741
-
742
- $email->template = 'businessdirectory-email';
743
- $email->send();
744
- }
745
-
746
- $wpdb->update( "{$wpdb->prefix}wpbdp_listing_fees", array( 'email_sent' => 2 ), array( 'id' => $r->id ) );
747
- } elseif ( $threshold > 0 ) {
748
- // notify about coming expirations
749
- $email = wpbdp_email_from_template( ( $r->recurring ? 'listing-autorenewal-notice' : 'renewal-pending-message' ),
750
- $message_replacements );
751
- $email->to[] = wpbusdirman_get_the_business_email( $listing->get_id() );
752
- $email->template = 'businessdirectory-email';
753
- $email->send();
754
-
755
- $wpdb->update( "{$wpdb->prefix}wpbdp_listing_fees", array( 'email_sent' => 1 ), array( 'id' => $r->id ) );
756
- } elseif ( $threshold < 0 ) {
757
- // remind about expired listings
758
- $email = wpbdp_email_from_template( 'renewal-reminder-message', $message_replacements );
759
- $email->to[] = wpbusdirman_get_the_business_email( $listing->get_id() );
760
- $email->template = 'businessdirectory-email';
761
- $email->send();
762
-
763
- $wpdb->update( "{$wpdb->prefix}wpbdp_listing_fees", array( 'email_sent' => 3 ), array( 'id' => $r->id ) );
764
- }
765
- }
766
-
767
- }
768
-
769
- private function notify_expired_listings_recurring( $now ) {
770
- global $wpdb, $wpbdp;
771
-
772
- $now_date = wpbdp_format_time( $now, 'mysql' );
773
-
774
- $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_listing_fees WHERE recurring = %d AND expires_on IS NOT NULL AND expires_on < %s ORDER BY expires_on LIMIT 100",
775
- 1,
776
- $now_date );
777
- $rs = $wpdb->get_results( $query );
778
-
779
- foreach ( $rs as $r ) {
780
- $recurring_id = $r->recurring_id;
781
- $data = unserialize( $r->recurring_data );
782
-
783
- if ( ! isset( $data['payment_id'] ) )
784
- continue;
785
-
786
- $wpbdp->payments->process_recurring_expiration( $data['payment_id'] );
787
- }
788
- }
789
-
790
 
791
 
792
  }
793
 
794
- /*
795
- * For compatibility with other APIs (< 3.5.4).
796
- */
797
- class WPBDP_ListingsAPI extends WPBDP_Listings_API {}
798
-
799
  }
800
 
8
  class WPBDP_Listings_API {
9
 
10
  public function __construct() {
11
+ add_action( 'wpbdp_payment_completed', array( $this, 'update_listing_after_payment' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
13
 
14
+ public function update_listing_after_payment( $payment ) {
15
+ $listing = $payment->get_listing();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ if ( ! $listing )
 
 
 
 
 
 
 
 
 
 
 
18
  return;
19
 
20
+ $is_renewal = 'renewal' == $payment->payment_type;
21
 
22
+ foreach ( $payment->payment_items as $item ) {
23
+ switch ( $item['type'] ) {
24
+ case 'recurring_plan':
25
+ case 'plan':
26
+ case 'plan_renewal': // Do we really use/need this?
27
+ $listing->update_plan( $item );
28
 
29
+ if ( 'plan_renewal' == $item['type'] ) {
30
+ $is_renewal = true;
31
+ }
32
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
  }
35
 
36
+ $listing->set_status( 'complete' );
37
 
38
+ if ( $is_renewal) {
39
+ wpbdp_insert_log( array( 'log_type' => 'listing.renewal', 'object_id' => $payment->listing_id, 'message' => _x( 'Listing renewed', 'listings api', 'WPBDM' ) ) );
40
  $listing->set_post_status( 'publish' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  // {{{ Quick search.
46
 
77
  if ( ! $keywords && ! $location )
78
  return array();
79
 
80
+ require_once( WPBDP_PATH . 'core/helpers/class-search-helper.php' );
81
 
82
  $args = array( 'query' => $keywords,
83
  'mode' => 'quick-search',
90
 
91
  // }}}
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
 
95
  }
96
 
 
 
 
 
 
97
  }
98
 
includes/class-meta.php ADDED
@@ -0,0 +1,405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Meta {
6
+
7
+ public function __construct() {
8
+ add_action( 'wp_head', array( $this, '_rss_feed' ), 2 );
9
+ add_filter( 'feed_links_show_posts_feed', array( $this, 'should_show_posts_feed_links' ) );
10
+ add_filter( 'feed_links_show_comments_feed', array( $this, 'should_show_posts_feed_links' ) );
11
+
12
+ if ( wpbdp_get_option( 'disable-cpt' ) ) {
13
+ add_action( 'wp', array( &$this, '_meta_setup' ) );
14
+ add_filter( 'wp_title', array( &$this, '_meta_title' ), 10, 3 );
15
+ add_filter( 'pre_get_document_title', array( &$this, '_meta_title' ), 10, 3 );
16
+ } else {
17
+ add_filter( 'document_title_parts', array( &$this, 'set_view_title' ), 10 );
18
+ }
19
+ }
20
+
21
+ public function _rss_feed() {
22
+ $current_view = wpbdp_current_view();
23
+
24
+ if ( ! $current_view ) {
25
+ return;
26
+ }
27
+
28
+ if ( ! in_array( $current_view, array( 'main', 'show_category', 'all_listings' ), true ) ) {
29
+ return;
30
+ }
31
+
32
+ $main_page_title = get_the_title( wpbdp_get_page_id() );
33
+ $link_template = '<link rel="alternate" type="application/rss+xml" title="%s" href="%s" />' . PHP_EOL;
34
+ $feed_links = array();
35
+
36
+ if ( 'main' === $current_view || 'all_listings' === $current_view ) {
37
+ $feed_title = sprintf( _x( '%s Feed', 'rss feed', 'WPBDM'), $main_page_title );
38
+ $feed_url = esc_url( add_query_arg( 'post_type', WPBDP_POST_TYPE, get_bloginfo( 'rss2_url' ) ) );
39
+
40
+ $feed_links[] = sprintf( $link_template, $feed_title, $feed_url );
41
+ }
42
+
43
+ if ( 'show_category' === $current_view ) {
44
+ $term = _wpbpd_current_category();
45
+
46
+ if ( $term ) {
47
+ $taxonomy = get_taxonomy( $term->taxonomy );
48
+ $feed_title = sprintf( '%s &raquo; %s %s Feed', $main_page_title, $term->name, $taxonomy->labels->singular_name );
49
+ $query_args = array( 'post_type' => WPBDP_POST_TYPE, WPBDP_CATEGORY_TAX => $term->slug );
50
+ $feed_url = esc_url( add_query_arg( $query_args, get_bloginfo( 'rss2_url' ) ) );
51
+
52
+ $feed_links[] = sprintf( $link_template, $feed_title, $feed_url );
53
+
54
+ // Add dummy action to prevent https://core.trac.wordpress.org/ticket/40906
55
+ add_action( 'wp_head', '__return_null', 3 );
56
+ // Avoid two RSS URLs in Category pages.
57
+ remove_action( 'wp_head', 'feed_links_extra', 3 );
58
+ }
59
+ }
60
+
61
+ if ( $feed_links ) {
62
+ echo '<!-- Business Directory RSS feed -->' . PHP_EOL;
63
+ echo implode( '', $feed_links );
64
+ echo '<!-- /Business Directory RSS feed -->' . PHP_EOL;
65
+ }
66
+ }
67
+
68
+ public function should_show_posts_feed_links( $should ) {
69
+ $current_view = wpbdp_current_view();
70
+
71
+ if ( ! $current_view ) {
72
+ return $should;
73
+ }
74
+
75
+ if ( ! in_array( $current_view, array( 'main', 'show_category', 'all_listings' ), true ) ) {
76
+ return $should;
77
+ }
78
+
79
+ return false;
80
+ }
81
+
82
+ public function _meta_setup() {
83
+ $action = wpbdp_current_view();
84
+
85
+ $plugin_views_with_meta = array(
86
+ 'show_listing', 'show_category', 'show_tag',
87
+ 'all_listings', 'submit_listing', 'search'
88
+ );
89
+
90
+ if ( ! in_array( $action, $plugin_views_with_meta ) ) {
91
+ return;
92
+ }
93
+
94
+ require_once( WPBDP_PATH . 'includes/class-page-meta.php' );
95
+ $this->page_meta = new WPBDP_Page_Meta( $action );
96
+
97
+ $this->_do_wpseo = defined( 'WPSEO_VERSION' ) ? true : false;
98
+
99
+ if ( $this->_do_wpseo ) {
100
+ $wpseo_front = $this->_get_wpseo_frontend();
101
+
102
+ remove_filter( 'wp_title', array( $this, '_meta_title' ), 10, 3 );
103
+ add_filter( 'wp_title', array( $this, '_meta_title' ), 16, 3 );
104
+ add_filter( 'pre_get_document_title', array( $this, '_meta_title' ), 16 );
105
+
106
+ if ( is_object( $wpseo_front ) ) {
107
+ remove_filter( 'pre_get_document_title', array( &$wpseo_front, 'title' ), 15 );
108
+ remove_filter( 'wp_title', array( &$wpseo_front, 'title' ), 15, 3 );
109
+ remove_action( 'wp_head', array( &$wpseo_front, 'head' ), 1, 1 );
110
+ }
111
+
112
+ add_action( 'wp_head', array( $this, '_meta_keywords' ) );
113
+ }
114
+
115
+ remove_filter( 'wp_head', 'rel_canonical' );
116
+ add_filter( 'wp_head', array( $this, '_meta_rel_canonical' ) );
117
+
118
+ if ( 'show_listing' == $action && wpbdp_rewrite_on() ) {
119
+ add_action( 'wp_head', array( &$this, 'listing_opentags' ) );
120
+ }
121
+ }
122
+
123
+ private function _get_wpseo_frontend() {
124
+ if ( isset( $GLOBALS['wpseo_front'] ) ) {
125
+ return $GLOBALS['wpseo_front'];
126
+ } elseif ( class_exists( 'WPSEO_Frontend' ) && method_exists( 'WPSEO_Frontend', 'get_instance' ) ) {
127
+ return WPSEO_Frontend::get_instance();
128
+ }
129
+ }
130
+
131
+ public function set_view_title( $title ) {
132
+ global $wp_query;
133
+
134
+ if ( empty( $wp_query->wpbdp_view ) || ! is_array( $title ) )
135
+ return $title;
136
+
137
+ $current_view = wpbdp()->dispatcher->current_view_object();
138
+
139
+ if ( ! $current_view )
140
+ return $title;
141
+
142
+ if ( $view_title = $current_view->get_title() )
143
+ $title['title'] = $view_title;
144
+
145
+ return $title;
146
+ }
147
+
148
+ public function _meta_title( $title = '', $sep = '»', $seplocation = 'right' ) {
149
+ $wpseo_front = $this->_get_wpseo_frontend();
150
+
151
+ $current_view = wpbdp_current_view();
152
+
153
+ switch ( $current_view ) {
154
+ case 'submit_listing':
155
+ $view_title = _x( 'Submit A Listing', 'views', 'WPBDM' );
156
+ return $this->_maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation );
157
+ break;
158
+
159
+ case 'search':
160
+ $view_title = _x( 'Find a Listing', 'title', 'WPBDM' );
161
+ return $this->_maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation );
162
+ break;
163
+
164
+ case 'all_listings':
165
+ $view_title = _x( 'View All Listings', 'title', 'WPBDM' );
166
+ return $this->_maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation );
167
+ break;
168
+
169
+ case 'show_tag':
170
+ $term = get_term_by(
171
+ 'slug',
172
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-tags-slug' ) ),
173
+ WPBDP_TAGS_TAX
174
+ );
175
+
176
+ if ( ! $term ) {
177
+ return $title;
178
+ }
179
+
180
+ if ( $this->_do_wpseo ) {
181
+ if ( method_exists( 'WPSEO_Taxonomy_Meta', 'get_term_meta' ) ) {
182
+ $title = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'title' );
183
+ } else {
184
+ $title = trim( wpseo_get_term_meta( $term, $term->taxonomy, 'title' ) );
185
+ }
186
+
187
+ if ( !empty( $title ) )
188
+ return wpseo_replace_vars( $title, (array) $term );
189
+
190
+ if ( is_object( $wpseo_front ) )
191
+ return $wpseo_front->get_title_from_options( 'title-tax-' . $term->taxonomy, $term );
192
+ }
193
+
194
+ return sprintf( _x( 'Listings tagged: %s', 'title', 'WPBDM' ), $term->name ) . ' ' . $sep . ' ' . $title;
195
+
196
+ break;
197
+
198
+ case 'show_category':
199
+ $term = get_term_by(
200
+ 'slug',
201
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-category-slug' ) ),
202
+ WPBDP_CATEGORY_TAX
203
+ );
204
+
205
+ if ( ! $term && get_query_var( 'category_id' ) ) {
206
+ $term = get_term_by( 'id', get_query_var( 'category_id' ), WPBDP_CATEGORY_TAX );
207
+ }
208
+
209
+ if ( ! $term ) {
210
+ return $title;
211
+ }
212
+
213
+ if ( $this->_do_wpseo ) {
214
+ if ( method_exists( 'WPSEO_Taxonomy_Meta', 'get_term_meta' ) ) {
215
+ $title = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'title' );
216
+ } else {
217
+ $title = trim( wpseo_get_term_meta( $term, $term->taxonomy, 'title' ) );
218
+ }
219
+
220
+ if ( !empty( $title ) )
221
+ return wpseo_replace_vars( $title, (array) $term );
222
+
223
+ if ( is_object( $wpseo_front ) )
224
+ return $wpseo_front->get_title_from_options( 'title-tax-' . $term->taxonomy, $term );
225
+ }
226
+
227
+ return $term->name . ' ' . $sep . ' ' . $title;
228
+
229
+ break;
230
+
231
+ case 'show_listing':
232
+ $listing_id = wpbdp_get_post_by_id_or_slug(
233
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
234
+ 'id',
235
+ 'id'
236
+ );
237
+
238
+ if ( $this->_do_wpseo ) {
239
+ $title = $wpseo_front->get_content_title( get_post( $listing_id ) );
240
+ $title = esc_html( strip_tags( stripslashes( apply_filters( 'wpseo_title', $title ) ) ) );
241
+
242
+ return $title;
243
+ break;
244
+ } else {
245
+ $post_title = get_the_title($listing_id);
246
+ }
247
+
248
+ return $post_title . ' '. $sep . ' ' . $title;
249
+ break;
250
+
251
+ case 'main':
252
+ break;
253
+
254
+ default:
255
+ break;
256
+ }
257
+
258
+ return $title;
259
+ }
260
+
261
+ private function _maybe_do_wpseo_title( $view_title, $title, $sep, $seplocation ) {
262
+ $wpseo_front = $this->_get_wpseo_frontend();
263
+
264
+ if ( $this->_do_wpseo && is_object( $wpseo_front ) ) {
265
+ return $wpseo_front->get_title_from_options( 'title-page', array( 'post_title' => $view_title ) );
266
+ }
267
+
268
+ if ( 'left' == $seplocation ) {
269
+ return $title . ' ' . $sep . ' ' . $view_title;
270
+ } else {
271
+ return $view_title . ' ' . $sep . ' ' . $title;
272
+ }
273
+ }
274
+
275
+ public function _meta_keywords() {
276
+ $wpseo_front = $this->_get_wpseo_frontend();
277
+
278
+ $current_view = wpbdp_current_view();
279
+
280
+ switch ( $current_view ){
281
+ case 'show_listing':
282
+ global $post;
283
+
284
+ $listing_id = wpbdp_get_post_by_id_or_slug(
285
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
286
+ 'id',
287
+ 'id'
288
+ );
289
+
290
+ $prev_post = $post;
291
+ $post = get_post( $listing_id );
292
+
293
+ if ( is_object( $wpseo_front ) ) {
294
+ $wpseo_front->metadesc();
295
+ $wpseo_front->metakeywords();
296
+ $wpseo_front->webmaster_tools_authentication();
297
+ }
298
+
299
+ $post = $prev_post;
300
+
301
+ break;
302
+ case 'show_category':
303
+ case 'show_tag':
304
+ if ( $current_view == 'show_tag' ) {
305
+ $term = get_term_by(
306
+ 'slug',
307
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-tags-slug' ) ),
308
+ WPBDP_TAGS_TAX
309
+ );
310
+ } else {
311
+ $term = get_term_by(
312
+ 'slug',
313
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-category-slug' ) ),
314
+ WPBDP_CATEGORY_TAX
315
+ );
316
+
317
+ if ( ! $term && get_query_var( 'category_id' ) ) {
318
+ $term = get_term_by( 'id', get_query_var( 'category_id' ), WPBDP_CATEGORY_TAX );
319
+ }
320
+ }
321
+
322
+ if ( $term ) {
323
+ $metadesc = method_exists( 'WPSEO_Taxonomy_Meta', 'get_term_meta' ) ?
324
+ WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'desc' ) :
325
+ wpseo_get_term_meta( $term, $term->taxonomy, 'desc' );
326
+
327
+ if ( !$metadesc && is_object( $wpseo_front ) && isset( $wpseo_front->options['metadesc-tax-' . $term->taxonomy] ) )
328
+ $metadesc = wpseo_replace_vars( $wpseo_front->options['metadesc-tax-' . $term->taxonomy], (array) $term );
329
+
330
+ if ( $metadesc )
331
+ echo '<meta name="description" content="' . esc_attr( strip_tags( stripslashes( $metadesc ) ) ) . '"/>' . "\n";
332
+ }
333
+
334
+ break;
335
+
336
+ case 'main':
337
+ if ( is_object( $wpseo_front ) ) {
338
+ $wpseo_front->metadesc();
339
+ $wpseo_front->metakeywords();
340
+ $wpseo_front->webmaster_tools_authentication();
341
+ }
342
+
343
+ break;
344
+
345
+ default:
346
+ break;
347
+ }
348
+
349
+ }
350
+
351
+ public function _meta_rel_canonical() {
352
+ $action = wpbdp_current_view();
353
+
354
+ if ( !$action )
355
+ return rel_canonical();
356
+
357
+ $not_supported_views = array(
358
+ 'edit_listing', 'submit_listing', 'delete_listing', 'renew_listing',
359
+ 'listing_contact'
360
+ );
361
+
362
+ if ( in_array( $action, $not_supported_views ) )
363
+ return;
364
+
365
+ if ( $action == 'show_listing' ) {
366
+ $listing_id = wpbdp_get_post_by_id_or_slug(
367
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
368
+ 'id',
369
+ 'id'
370
+ );
371
+ $url = get_permalink( $listing_id );
372
+ } else {
373
+ $url = site_url( $_SERVER['REQUEST_URI'] );
374
+ }
375
+
376
+ echo sprintf( '<link rel="canonical" href="%s" />', esc_url( user_trailingslashit( $url ) ) );
377
+ }
378
+
379
+ function listing_opentags() {
380
+ $listing_id = wpbdp_get_post_by_id_or_slug(
381
+ get_query_var( '_' . wpbdp_get_option( 'permalinks-directory-slug' ) ),
382
+ 'id',
383
+ 'id'
384
+ );
385
+
386
+ $listing = WPBDP_Listing::get( $listing_id );
387
+
388
+ if ( ! $listing )
389
+ return;
390
+
391
+ echo '<meta property="og:type" content="website" />';
392
+ echo '<meta property="og:title" content="' . esc_attr( WPBDP_SEO::listing_title( $listing_id ) ) . '" />';
393
+ echo '<meta property="og:url" content="' . esc_url( user_trailingslashit( $listing->get_permalink() ) ) . '" />';
394
+ echo '<meta property="og:description" content="' . esc_attr( WPBDP_SEO::listing_og_description( $listing_id ) ) . '" />';
395
+
396
+ if ( $thumbnail_id = $listing->get_thumbnail_id() ) {
397
+ if ( $img = wp_get_attachment_image_src( $thumbnail_id, 'wpbdp-large' ) )
398
+ echo '<meta property="og:image" content="' . $img[0] . '" />';
399
+ } else {
400
+ $image_url = WPBDP_URL . 'assets/images/default-image-big.gif';
401
+ echo '<meta property="og:image" content="' . $image_url . '" />';
402
+ }
403
+ }
404
+
405
+ }
includes/class-module.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Lightweight wrapper for extension modules, ensuring all basic info is always available.
4
+ * @since 5.0
5
+ */
6
+ final class WPBDP__Module {
7
+
8
+ public $file;
9
+ public $title;
10
+ public $id;
11
+ public $version;
12
+ public $required_bd_version;
13
+
14
+ public $text_domain;
15
+ public $text_domain_path;
16
+
17
+ public $is_premium_module = true;
18
+
19
+ private $module;
20
+
21
+
22
+ public function __construct( $obj ) {
23
+ $this->module = $obj;
24
+
25
+ foreach ( array( 'file', 'id' ) as $required_prop ) {
26
+ if ( ! isset( $obj->{$required_prop} ) )
27
+ throw new Exception( sprintf( '%s is not a valid Business Directory module!', get_class( $obj ) ) );
28
+
29
+ $this->{$required_prop} = $obj->{$required_prop};
30
+ }
31
+
32
+ $plugin_data = get_file_data( $obj->file, array( 'Plugin Name', 'Version', 'Text Domain', 'Domain Path' ) );
33
+
34
+ $this->title = empty( $obj->title ) ? $plugin_data[0] : $obj->title;
35
+ $this->version = empty( $obj->version ) ? $plugin_data[1] : $obj->version;
36
+ $this->text_domain = empty( $obj->text_domain ) ? $plugin_data[2] : $obj->text_domain;
37
+ $this->text_domain_path = empty( $obj->domain_path ) ? $plugin_data[3] : $obj->domain_path;
38
+
39
+ $this->required_bd_version = isset( $obj->required_bd_version ) ? $obj->required_bd_version : '';
40
+ $this->is_premium_module = ! in_array( $this->id, array( 'categories' ), true );
41
+ }
42
+
43
+ public function __call( $name, $args ) {
44
+ if ( method_exists( $this->module, $name ) )
45
+ return call_user_func_array( array( $this->module, $name ), $args );
46
+ elseif ( in_array( $name, array( 'init' ), true ) )
47
+ return;
48
+
49
+ throw new Exception( 'Invalid method called!' );
50
+ }
51
+
52
+ }
53
+
includes/class-modules.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once( WPBDP_PATH . 'includes/class-module.php' );
3
+
4
+ // FIXME: replace all module support with branch issue/2708 before release.
5
+ class WPBDP__Modules {
6
+
7
+ private $modules = array();
8
+ private $valid = array();
9
+
10
+
11
+ public function __construct() {
12
+ $this->register_modules();
13
+
14
+ add_action( 'init', array( $this, 'load_i18n' ), 999 );
15
+ }
16
+
17
+ private function register_modules() {
18
+ // Allow modules to register themselves with this class.
19
+ do_action( 'wpbdp_load_modules', $this );
20
+
21
+ // Register modules with the Licensing API.
22
+ foreach ( $this->modules as $mod ) {
23
+ $valid = false;
24
+
25
+ if ( ! $mod->is_premium_module ) {
26
+ $valid = true;
27
+ } else {
28
+ $valid = wpbdp()->licensing->add_item_and_check_license( array( 'item_type' => 'module', 'name' => $mod->title, 'file' => $mod->file, 'version' => $mod->version ) );
29
+ }
30
+
31
+ if ( $valid ) {
32
+ $this->valid[] = $mod->id;
33
+ }
34
+ }
35
+ }
36
+
37
+ public function load( $module ) {
38
+ try {
39
+ if ( is_string( $module ) && class_exists( $module ) )
40
+ $module = new $module;
41
+
42
+ $wrapper = new WPBDP__Module( $module );
43
+ $this->modules[ $wrapper->id ] = $wrapper;
44
+ } catch ( Exception $e ) {
45
+ }
46
+ }
47
+
48
+ public function init() {
49
+ foreach ( $this->valid as $module_id ) {
50
+ $mod = $this->modules[ $module_id ];
51
+ $mod->init();
52
+ }
53
+ }
54
+
55
+ public function is_loaded( $module_id ) {
56
+ return array_key_exists( $module_id, $this->modules );
57
+ }
58
+
59
+ public function load_i18n() {
60
+ foreach ( $this->modules as $mod ) {
61
+ load_plugin_textdomain( $mod->text_domain, false, basename( dirname( $mod->file ) ) . $mod->text_domain_path );
62
+ }
63
+ }
64
+
65
+ }
includes/class-payment-gateway.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class WPBDP__Payment_Gateway {
4
+
5
+ public function __construct() {
6
+ }
7
+
8
+ public abstract function get_id();
9
+ public abstract function get_title();
10
+
11
+ public function enqueue_scripts() {
12
+ }
13
+
14
+ public function is_enabled( $no_errors = true ) {
15
+ $setting_on = wpbdp_get_option( $this->get_id() );
16
+ if ( ! $no_errors )
17
+ return $setting_on;
18
+
19
+ return $setting_on && ! $this->validate_settings();
20
+ }
21
+
22
+ public function in_test_mode() {
23
+ return wpbdp_get_option( 'payments-test-mode' );
24
+ }
25
+
26
+ public function get_option( $key ) {
27
+ return wpbdp_get_option( $this->get_id() . '-' . $key );
28
+ }
29
+
30
+ public abstract function get_integration_method();
31
+
32
+ public function supports( $feature ) {
33
+ return false;
34
+ }
35
+
36
+ public function supports_currency( $currency ) {
37
+ return false;
38
+ }
39
+
40
+ public function get_settings() {
41
+ return array();
42
+ }
43
+
44
+ public function get_settings_text() {
45
+ return '';
46
+ }
47
+
48
+ public function validate_settings() {
49
+ return array();
50
+ }
51
+
52
+ public function process_payment( $payment ) {
53
+ return false;
54
+ }
55
+
56
+ public function process_postback() {
57
+ }
58
+
59
+ public function refund( $payment, $data = array() ) {
60
+ }
61
+
62
+ public function render_form( $payment, $errors = array() ) {
63
+ $vars = array();
64
+
65
+ $vars['data'] = $_POST;
66
+
67
+ foreach ( $payment->get_payer_details() as $k => $v ) {
68
+ if ( empty( $_POST[ 'payer_' . $k ] ) && ! empty( $v ) ) {
69
+ $vars['data'][ 'payer_' . $k ] = $v;
70
+ }
71
+ }
72
+
73
+ $vars['gateway'] = $this;
74
+ $vars['errors'] = $errors;
75
+ $vars['payment'] = $payment;
76
+
77
+ if ( 'form' == $this->get_integration_method() ) {
78
+ $vars['show_cc_section'] = false;
79
+ $vars['show_details_section'] = false;
80
+ }
81
+
82
+ return wpbdp_x_render( 'checkout-billing-form', $vars );
83
+ }
84
+
85
+ public function validate_form( $payment ) {
86
+ $errors = array();
87
+
88
+ $required = array( 'payer_email', 'payer_first_name' );
89
+ if ( 'form' != $this->get_integration_method() ) {
90
+ $required = array_merge( $required, array( 'card_number', 'cvc', 'card_name', 'exp_month', 'exp_year', 'payer_address', 'payer_city', 'payer_zip', 'payer_country' ) );
91
+ }
92
+
93
+ foreach ( $required as $req_field ) {
94
+ $field_value = isset( $_POST[ $req_field ] ) ? $_POST[ $req_field ] : '';
95
+
96
+ if ( ! $field_value ) {
97
+ $errors[ $req_field ] = _x( 'This field is required (' . $req_field . ').', 'payment-gateway', 'WPBDM' );
98
+ }
99
+ }
100
+
101
+ return $errors;
102
+ }
103
+
104
+ public function save_billing_data( $payment ) {
105
+ $form = $_POST;
106
+
107
+ foreach ( array( 'payer_email', 'payer_first_name', 'payer_last_name' ) as $k ) {
108
+ if ( ! empty( $form[ $k ] ) )
109
+ $payment->{$k} = $form[ $k ];
110
+ }
111
+
112
+ if ( ! empty( $form['payer_address'] ) )
113
+ $payment->payer_data['address'] = $form['payer_address'];
114
+
115
+ if ( ! empty( $form['payer_address_2'] ) )
116
+ $payment->payer_data['address_2'] = $form['payer_address_2'];
117
+
118
+ if ( ! empty( $form['payer_city'] ) )
119
+ $payment->payer_data['city'] = $form['payer_city'];
120
+
121
+ if ( ! empty( $form['payer_state'] ) )
122
+ $payment->payer_data['state'] = $form['payer_state'];
123
+
124
+ if ( ! empty( $form['payer_zip'] ) )
125
+ $payment->payer_data['zip'] = $form['payer_zip'];
126
+
127
+ if ( ! empty( $form['payer_country'] ) )
128
+ $payment->payer_data['country'] = $form['payer_country'];
129
+
130
+ $payment->save();
131
+ }
132
+
133
+ public function get_listener_url() {
134
+ return add_query_arg( 'wpbdp-listener', $this->get_id(), home_url( 'index.php' ) );
135
+ }
136
+
137
+ }
includes/class-payment-gateways.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @since 5.0
4
+ */
5
+ class WPBDP__Payment_Gateways {
6
+
7
+ private $gateways = array();
8
+
9
+
10
+ public function __construct() {
11
+ add_action( 'wpbdp_modules_loaded', array( $this, 'load_gateways' ) );
12
+ add_action( 'wpbdp_loaded', array( $this, '_execute_listener' ) );
13
+ add_action( 'wpbdp_register_settings', array( $this, '_add_gateway_settings' ) );
14
+ add_action( 'wpbdp_admin_notices', array( $this, '_admin_warnings' ) );
15
+ }
16
+
17
+ public function load_gateways() {
18
+ $gateways = array();
19
+
20
+ // Add Authorize.net by default.
21
+ require_once( WPBDP_PATH . 'includes/gateways/class-gateway-authorize-net.php' );
22
+ $gateways[] = new WPBDP__Gateway__Authorize_Net();
23
+
24
+ // Allow modules to add gateways.
25
+ $gateways = apply_filters( 'wpbdp_payment_gateways', $gateways );
26
+
27
+ foreach ( $gateways as $gateway_ ) {
28
+ $gateway = is_string( $gateway_ ) ? new $gateway_() : $gateway_;
29
+ $this->gateways[ $gateway->get_id() ] = $gateway;
30
+ }
31
+ }
32
+
33
+ public function _execute_listener() {
34
+ $listener_id = ! empty( $_GET['wpbdp-listener'] ) ? $_GET['wpbdp-listener'] : '';
35
+
36
+ if ( ! $listener_id )
37
+ return;
38
+
39
+ if ( ! $this->can_use( $listener_id ) )
40
+ wp_die();
41
+
42
+ $gateway = $this->get( $listener_id );
43
+ $gateway->process_postback();
44
+ exit;
45
+ }
46
+
47
+ public function get_available_gateways( $conditions = array() ) {
48
+ $res = array();
49
+
50
+ foreach ( $this->gateways as $gateway ) {
51
+ if ( $gateway->is_enabled() ) {
52
+ if ( $conditions ) {
53
+ if ( isset( $conditions['currency_code'] ) && ! $gateway->supports_currency( $conditions['currency_code'] ) )
54
+ continue;
55
+ }
56
+
57
+ $res[ $gateway->get_id() ] = $gateway;
58
+ }
59
+ }
60
+
61
+ return $res;
62
+ }
63
+
64
+ public function can_use( $gateway_id ) {
65
+ return isset( $this->gateways[ $gateway_id ] ) && $this->gateways[ $gateway_id ]->is_enabled();
66
+ }
67
+
68
+ public function get( $gateway_id ) {
69
+ if ( isset( $this->gateways[ $gateway_id ] ) )
70
+ return $this->gateways[ $gateway_id ];
71
+
72
+ return false;
73
+ }
74
+
75
+ public function can_pay() {
76
+ return count( $this->get_available_gateways() ) > 0;
77
+ }
78
+
79
+ public function _add_gateway_settings( $api ) {
80
+ foreach ( $this->gateways as $gateway ) {
81
+ wpbdp_register_settings_group( 'gateway_' . $gateway->get_id(), $gateway->get_title(), 'payment', array( 'desc' => $gateway->get_settings_text() ) );
82
+ wpbdp_register_setting( array(
83
+ 'id' => $gateway->get_id(),
84
+ 'name' => sprintf( _x( 'Enable %s?', 'payment-gateways', 'WPBDM' ), $gateway->get_title() ),
85
+ 'type' => 'checkbox',
86
+ 'default' => false,
87
+ 'group' => 'gateway_' . $gateway->get_id(),
88
+ 'requirements' => array( 'payments-on' )
89
+ ) );
90
+ foreach ( $gateway->get_settings() as $setting ) {
91
+ $setting = array_merge( $setting, array( 'group' => 'gateway_' . $gateway->get_id() ) );
92
+ $setting['id'] = $gateway->get_id() . '-' . $setting['id'];
93
+ $setting['requirements'] = array( $gateway->get_id() );
94
+
95
+ wpbdp_register_setting( $setting );
96
+ }
97
+ }
98
+ }
99
+
100
+ // TODO: Maybe integrate all of these warnings into just one message?
101
+ public function _admin_warnings() {
102
+ if ( empty( $_GET['page'] ) || 'wpbdp_settings' != $_GET['page'] )
103
+ return;
104
+
105
+ if ( ! wpbdp_get_option( 'payments-on' ) )
106
+ return;
107
+
108
+ $at_least_one_gateway = false;
109
+ foreach ( $this->gateways as $gateway ) {
110
+ if ( $gateway->is_enabled( true ) ) {
111
+ $at_least_one_gateway = true;
112
+ } elseif ( $gateway->is_enabled( false ) ) {
113
+ $errors = rtrim( '&#149; ' . implode( ' &#149; ', $gateway->validate_settings() ), '.' );
114
+
115
+ $msg = _x( 'The <gateway> gateway is enabled but not properly configured. The gateway won\'t be available until the following problems are fixed: <problems>.', 'payment-gateways', 'WPBDM' );
116
+ $msg .= '<br />';
117
+ $msg .= _x( 'Please check the <link>payment settings</link>.', 'payment-gateways', 'WPBDM' );
118
+
119
+ $msg = str_replace( '<gateway>', '<b>' . $gateway->get_title() .'</b>', $msg );
120
+ $msg = str_replace( '<problems>', '<b>' . $errors . '</b>', $msg );
121
+ $msg = str_replace( array( '<link>', '</link>' ), array( '<a href="' . admin_url( 'admin.php?page=wpbdp_settings&tab=payment' ) . '">', '</a>' ), $msg );
122
+
123
+ wpbdp_admin_message( $msg, 'error' );
124
+ }
125
+ }
126
+
127
+ if ( ! $at_least_one_gateway ) {
128
+ $msg = _x( 'You have payments turned on but no gateway is active and properly configured. Go to <link>Manage Options - Payment</link> to change the payment settings. Until you change this, the directory will operate in <i>Free Mode</i>.', 'payment-gateways', 'WPBDM' );
129
+ $msg = str_replace( array( '<link>', '</link>' ), array( '<a href="' . admin_url( 'admin.php?page=wpbdp_settings&tab=payment' ) . '">', '</a>' ), $msg );
130
+ wpbdp_admin_message( $msg, 'error' );
131
+ }
132
+ }
133
+
134
+ }
includes/class-payment.php CHANGED
@@ -1,505 +1,282 @@
1
  <?php
2
- require_once( WPBDP_INC . 'db/class-db-model.php' );
3
-
4
- /**
5
- * This class represents a listing payment.
6
- *
7
- * @since 3.3
8
- */
9
- class WPBDP_Payment extends WPBDP_DB_Model {
10
-
11
- const STATUS_UNKNOWN = 'unknown';
12
- const STATUS_NEW = 'new';
13
- const STATUS_PENDING = 'pending';
14
- const STATUS_COMPLETED = 'completed';
15
- const STATUS_CANCELED = 'canceled';
16
- const STATUS_REJECTED = 'rejected';
17
-
18
- const HANDLER_GATEWAY = 'gateway';
19
- const HANDLER_ADMIN = 'admin';
20
- const HANDLER_SYSTEM = 'system';
21
-
22
- private $items = array();
23
-
24
- public function __construct( $data = array() ) {
25
- $this->fill_from_data( $data, array(
26
- 'id' => 0,
27
- 'listing_id' => 0,
28
- 'gateway' => '',
29
- 'currency_code' => wpbdp_get_option( 'currency' ),
30
- 'amount' => 0.0,
31
- 'status' => self::STATUS_PENDING,
32
- 'created_on' => current_time( 'mysql' ),
33
- 'processed_on' => '',
34
- 'processed_by' => '',
35
- 'payerinfo' => array(),
36
- 'extra_data' => array(),
37
- 'notes' => array(),
38
- 'tag' => ''
39
- ) );
40
-
41
- $this->amount = floatval( $this->amount );
42
 
43
- global $wpdb;
44
 
45
- if ( $this->id > 0 ) {
46
- foreach ( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wpbdp_payments_items WHERE payment_id = %d", $this->id ), ARRAY_A ) as $item ) {
47
- $item['data'] = maybe_unserialize( $item['data'] );
48
- $this->items[] = $item;
49
- }
50
- }
51
- }
52
-
53
- public function reset() {
54
- $this->gateway = '';
55
- $this->processed_by = '';
56
- $this->processed_on = '';
57
- $this->payerinfo = array();
58
- $this->status = self::STATUS_PENDING;
59
- }
60
 
 
61
 
62
- // TODO: when a payment is saved (and it's completed) all payments it superseeds should be removed/rejected (i.e. a payment for the same category or an already pending upgrade)
63
- public function save() {
64
- global $wpdb;
65
 
66
- // do_action_ref_array( 'WPBDP_Payment::before_save', array( &$this ) );
67
-
68
- $row = array(
69
- 'listing_id' => $this->listing_id,
70
- 'gateway' => $this->gateway,
71
- 'amount' => $this->amount,
72
- 'status' => $this->status,
73
- 'created_on' => $this->created_on,
74
- 'processed_on' => $this->processed_on,
75
- 'processed_by' => $this->processed_by,
76
- 'currency_code' => $this->currency_code,
77
- 'payerinfo' => serialize( is_array( $this->payerinfo ) ? $this->payerinfo : array() ),
78
- 'extra_data' => serialize( is_array( $this->extra_data ) ? $this->extra_data : array() ),
79
- 'notes' => serialize( is_array( $this->notes ) ? $this->notes : array() ),
80
- 'tag' => $this->tag
81
  );
82
-
83
- if ( ! $this->processed_on )
84
- unset( $row['processed_on'] );
85
-
86
- if ( $this->id )
87
- $row['id'] = $this->id;
88
-
89
- if ( false === $wpdb->replace( $wpdb->prefix . 'wpbdp_payments', $row ) )
90
- return false;
91
-
92
- $this->id = $this->id ? $this->id : $wpdb->insert_id;
93
-
94
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wpbdp_payments_items WHERE payment_id = %d", $this->id ) );
95
-
96
- foreach ( $this->items as &$item ) {
97
- $wpdb->insert( $wpdb->prefix . 'wpbdp_payments_items',
98
- array( 'item_type' => $item['item_type'],
99
- 'amount' => $item['amount'],
100
- 'description' => $item['description'],
101
- 'payment_id' => $this->id,
102
- 'rel_id_1' => $item['rel_id_1'],
103
- 'rel_id_2' => $item['rel_id_2'],
104
- 'data' => serialize( $item['data'] ) )
105
- );
106
- }
107
-
108
- do_action_ref_array( 'WPBDP_Payment::save', array( &$this ) );
109
-
110
- if ( $this->status != self::STATUS_COMPLETED && $this->amount == 0.0 ) {
111
- $this->set_status( self::STATUS_COMPLETED );
112
- $this->save();
113
- }
114
-
115
- return true;
116
  }
117
 
118
- public function delete() {
119
- }
120
 
121
- public function is_payment_due() {
122
- return $this->amount > 0.0 && $this->status != self::STATUS_COMPLETED;
123
- }
 
 
 
124
 
125
- public function is_pending() {
126
- return $this->status == self::STATUS_PENDING;
127
  }
128
 
129
- public function is_completed() {
130
- return $this->status == self::STATUS_COMPLETED;
131
- }
132
 
133
- public function is_canceled() {
134
- return $this->status == self::STATUS_CANCELED;
135
- }
136
-
137
- public function is_rejected() {
138
- return $this->status == self::STATUS_REJECTED;
139
- }
140
-
141
- public function has_been_processed() {
142
- return ! empty( $this->processed_by );
143
- }
144
 
145
- public function is_first_recurring_payment() {
146
- return $this->has_item_type( 'recurring_fee' ) && ( ! $this->get_data( 'recurring_id' ) );
147
- }
148
 
149
- public function generate_recurring_payment() {
150
- $recurring_item = $this->get_recurring_item();
151
-
152
- if ( ! $recurring_item )
153
- return null;
154
-
155
- $rp = new WPBDP_Payment( array( 'listing_id' => $this->get_listing_id(),
156
- 'gateway' => $this->get_gateway(),
157
- 'currency_code' => $this->get_currency_code(),
158
- 'amount' => 0.0,
159
- 'payerinfo' => $this->payerinfo,
160
- 'extra_data' => array( 'recurring_id' => $this->get_data( 'recurring_id' ),
161
- 'parent_payment_id' => $this->id )
162
- ) );
163
- $rp->add_item( 'recurring_fee',
164
- $recurring_item->amount,
165
- $recurring_item->description,
166
- $recurring_item->data,
167
- $recurring_item->rel_id_1,
168
- $recurring_item->rel_id_2 );
169
- $rp->save();
170
- return $rp;
171
  }
172
 
173
- public function get_handler() {
174
- return $this->processed_by;
175
- }
176
-
177
- public function get_processed_on() {
178
- return $this->processed_on;
179
- }
 
180
 
181
- public function cancel_recurring() {
182
- if ( ! $this->id )
183
  return;
184
 
185
- $listing = WPBDP_Listing::get( $this->get_listing_id() );
186
- $recurring_item = $this->get_recurring_item();
187
-
188
- if ( $recurring_item ) {
189
- $listing->make_category_non_recurring( $recurring_item->rel_id_1 );
190
- // $listing->remove_category( $recurring_item->rel_id_1 );
 
 
191
  }
192
- }
193
 
194
- public function get_recurring_item() {
195
- $items = $this->get_items( array( 'item_type' => 'recurring_fee' ) );
196
- return $items ? $items[0] : null;
197
  }
198
 
199
- public function add_item( $item_type = 'charge', $amount = 0.0, $description = '', $data = array(), $rel_id_1 = 0, $rel_id_2 = 0 ) {
200
- $item = array();
201
- $item['item_type'] = $item_type;
202
- $item['amount'] = floatval( $amount );
203
- $item['description'] = $description;
204
- $item['data'] = $data;
205
-
206
- $item['rel_id_1'] = $rel_id_1;
207
- $item['rel_id_2'] = $rel_id_2;
208
-
209
- $this->items[] = $item;
210
- $this->amount += $amount;
211
  }
212
 
213
- public function add_category_fee_item( $category_id, $fee, $recurring = false ) {
214
- if ( ! is_object( $fee ) ) {
215
- $fee = wpbdp_get_fee( intval( $fee ) );
216
 
217
- if ( ! $fee )
218
- return false;
219
  }
220
 
221
- $this->add_item( $recurring ? 'recurring_fee' : 'fee',
222
- $fee->amount,
223
- sprintf( _x( 'Fee "%s" for category "%s"%s', 'listings', 'WPBDM' ),
224
- $fee->label,
225
- wpbdp_get_term_name( $category_id ),
226
- $recurring ? ( ' ' . _x( '(recurring)', 'listings', 'WPBDM' ) ) : '' ),
227
- array( 'fee_id' => $fee->id, 'fee_days' => $fee->days, 'fee_images' => $fee->images, 'fee_sticky' => $fee->sticky ),
228
- $category_id,
229
- $fee->id );
230
- return true;
231
  }
232
 
233
- public function update_items( $items = array() ) {
234
- $this->amount = 0.0;
235
- $this->items = array();
236
-
237
- foreach ( $items as $item ) {
238
- $item = (array) $item;
239
- $this->items[] = $item;
240
- $this->amount += $item['amount'];
241
- }
242
  }
243
 
244
- public function delete_item( &$item ) {
245
- $index = array_search( (array) $item, $this->items, true );
246
 
247
- if ( false === $index )
248
- return;
 
 
 
 
 
 
 
 
249
 
250
- unset( $this->items[ $index ] );
251
- $this->amount -= $item->amount;
252
- }
 
253
 
254
- public function has_item_type( $item_type ) {
255
- foreach ( $this->items as &$item ) {
256
- if ( $item['item_type'] == $item_type )
257
- return true;
258
  }
259
 
260
- return false;
261
  }
262
 
263
- public function get_items( $args = array() ) {
264
- $items = array();
265
-
266
- if ( isset( $args['item_type'] ) )
267
- $args['item_type'] = is_array( $args['item_type'] ) ? $args['item_type'] : array( $args['item_type'] );
268
- else
269
- $args['item_type'] = null;
270
-
271
- foreach ( $this->items as &$item ) {
272
- if ( isset( $args['item_type'] ) && ! in_array( $item['item_type'], $args['item_type'], true ) )
273
- continue;
274
 
275
- if ( isset( $args['rel_id_1'] ) && $args['rel_id_1'] != $item['rel_id_1'] )
276
- continue;
277
-
278
- $items[] = $item;
279
- }
280
-
281
- return array_map( create_function( '$x', 'return (object) $x;' ), $items );
282
  }
283
 
284
- public function get_item( $args = array() ) {
285
- $items = $this->get_items( $args );
 
286
 
287
- if ( $items )
288
- return array_pop( $items );
289
-
290
- return null;
291
  }
292
 
293
- public function summarize() {
294
- $regular = 0.0;
295
- $discounts = 0.0;
296
- $recurring = 0.0;
297
- $recurring_days = 0;
298
-
299
- $res = array( 'trial' => false,
300
- 'trial_amount' => 0.0,
301
- 'recurring' => false,
302
- 'recurring_amount' => 0.0,
303
- 'recurring_days' => 0,
304
- 'recurring_description' => '',
305
- 'recurring_obj' => null,
306
- 'balance' => 0.0,
307
- 'description' => $this->get_short_description() );
308
-
309
- $recurring = $this->get_item( array( 'item_type' => 'recurring_fee' ) );
310
- $res['recurring_obj'] = $recurring;
311
-
312
- if ( ! $recurring ) {
313
- $res['balance'] = floatval( $this->get_total() );
314
- } else {
315
- $recurring_amt = floatval( $recurring->amount );
316
- $discounts_amt = abs( floatval( $this->get_total( 'coupon' ) ) );
317
- $others_amt = ( floatval( $this->get_total() ) + $discounts_amt ) - $recurring_amt;
318
-
319
- $res['recurring'] = true;
320
- $res['recurring_amount'] = $recurring_amt;
321
- $res['recurring_days'] = $recurring->data['fee_days'];
322
- $res['recurring_description'] = $recurring->description;
323
-
324
- if ( $discounts_amt > 0.0 ) {
325
- if ( $others_amt > 0.0 ) {
326
- $others_rem = $others_amt - $discounts_amt;
327
-
328
- if ( $others_rem > 0.0 ) {
329
- $res['balance'] = $others_rem;
330
- } else {
331
- $res['trial_amount'] = max( 0.0, $recurring_amt + $others_rem );
332
- $res['trial'] = true;
333
- }
334
- } else {
335
- $res['trial'] = true;
336
- $res['trial_amount'] = max( 0.0, $recurring_amt - $discounts_amt );
337
- }
338
- } else {
339
- $res['balance'] = $others_amt;
340
- }
341
- }
342
 
343
- return $res;
344
- }
345
 
346
- public function get_listing_id() {
347
- return $this->listing_id;
348
  }
349
 
350
- public function get_total( $item_type = 'all' ) {
351
- if ( $item_type && 'all' != $item_type ) {
352
- $res = 0.0;
353
- $items = $this->get_items( array( 'item_type' => $item_type ) );
354
-
355
- foreach ( $items as $i )
356
- $res += $i->amount;
357
 
358
- return $res;
 
359
  }
360
 
361
- return $this->amount;
362
  }
363
 
364
- public function get_status() {
365
- return $this->status;
 
366
  }
367
 
368
- public function set_status( $newstatus, $processed_by = 'system', $processed_on = null ) {
369
- $prev_status = $this->status;
370
- $this->status = $newstatus;
371
- $this->processed_by = $processed_by;
372
- $this->processed_on = ! $processed_on ? current_time( 'mysql' ) : $processed_on;
373
 
374
- if ( $prev_status != $newstatus )
375
- do_action_ref_array( 'WPBDP_Payment::status_change', array( &$this, $prev_status, $newstatus ) );
376
  }
377
 
378
- public function get_gateway() {
379
- return $this->gateway;
380
- }
 
 
 
381
 
382
- public function set_listing( $listing ) {
383
- if ( is_object( $listing ) )
384
- $this->listing_id = $listing->ID;
385
- else
386
- $this->listing_id = $listing;
387
  }
388
 
389
- public function set_payment_method( $method_id ) {
390
- $this->gateway = $method_id;
391
-
392
- do_action_ref_array( 'WPBDP_Payment::set_payment_method', array( &$this, $method_id ) );
393
  }
394
 
395
- public function get_currency_code() {
396
- return $this->currency_code;
397
  }
398
 
399
- public function get_short_description() {
400
- return $this->get_description();
401
- }
402
 
403
- // TODO
404
- public function get_description() {
405
- if ( count( $this->items ) == 1 )
406
- return $this->items[0]['description'];
407
 
408
- return sprintf( 'Listing Payment (ID: %s)', $this->id );
409
  }
410
 
411
- public function set_data( $key, $value ) {
412
- if ( !is_array( $this->extra_data ) )
413
- $this->extra_data = array();
414
-
415
- $this->extra_data[ $key ] = $value;
416
  }
417
 
418
- public function get_data( $key ) {
419
- if ( ! is_array( $this->extra_data ) || ! isset( $this->extra_data[ $key ] ) )
420
- return null;
421
-
422
- return $this->extra_data[ $key ];
423
  }
424
 
425
- public function set_submit_state_id( $id ) {
426
- $this->set_data( 'submit_state_id', $id );
427
- }
428
 
429
- public function get_submit_state_id() {
430
- return $this->get_data( 'submit_state_id' );
431
  }
432
 
433
- public function set_payer_info( $key, $value ) {
434
- $this->payerinfo[ $key ] = $value;
435
  }
436
 
437
- public function get_payer_info( $key ) {
438
- if ( isset( $this->payerinfo[ $key ] ) )
439
- return $this->payerinfo[ $key ];
440
-
441
- return '';
442
  }
443
 
444
- public function get_checkout_url( $force_http = false ) {
445
- $payment_id = $this->id;
446
- $payment_q = base64_encode('payment_id=' . $payment_id . '&verify=0' ); // TODO: add a 'verify' parameter to avoid false links being generated.
447
-
448
- $base_url = wpbdp_get_page_link( 'main' );
449
-
450
- if ( ! $force_http && ! is_ssl() && wpbdp_get_option( 'payments-use-https' ) ) {
451
- $base_url = set_url_scheme( $base_url, 'https' );
452
- }
453
-
454
- return add_query_arg( array( 'wpbdp_view' => 'checkout', 'payment' => urlencode( $payment_q ) ), $base_url );
455
- }
456
-
457
- public function get_redirect_url() {
458
- if ( $this->get_submit_state_id() ) {
459
- if ( $this->is_completed() )
460
- return add_query_arg( array( '_state' => $this->get_submit_state_id() ), wpbdp_get_page_link( 'submit' ) );
461
- }
462
-
463
- return $this->get_checkout_url( true );
464
  }
465
 
466
- public function get_created_on() {
467
- return $this->created_on;
468
  }
469
 
470
- public function tag( $tag ) {
471
- $this->tag = strtolower( trim( $tag ) );
472
  }
473
 
474
- public function add_error( $error_msg ) {
475
- // TODO: add datetime support.
476
- $errors = $this->get_data( 'errors' );
477
- $errors = ! $errors ? array() : $errors;
478
-
479
- $errors[] = $error_msg;
480
-
481
- $this->set_data( 'errors', $errors );
482
  }
483
 
484
- public function clear_errors() {
485
- $this->set_data( 'errors', array() );
486
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
 
488
- public function get_notes() {
489
- return $this->notes;
490
  }
491
 
492
- /* @override */
493
- public static function find( $args = array(), $lightweight = false ) {
494
- global $wpdb;
495
- return parent::_find( $args, $lightweight, $wpdb->prefix . 'wpbdp_payments', __CLASS__ );
496
  }
497
 
498
- /* @override */
499
- public static function get( $id ) {
500
- global $wpdb;
501
- return parent::_get( $id, $wpdb->prefix . 'wpbdp_payments', __CLASS__ );
 
502
  }
503
 
504
  }
505
- ?>
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
+ class WPBDP_Payment extends WPBDP__DB__Model {
4
 
5
+ static $serialized = array( 'payment_items', 'payer_data', 'data' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ private $old_status = '';
8
 
 
 
 
9
 
10
+ protected function get_defaults() {
11
+ return array(
12
+ 'parent_id' => 0,
13
+ 'payment_items' => array(),
14
+ 'payer_data' => array(),
15
+ 'gateway_data' => array(),
16
+ 'status' => 'pending',
17
+ 'currency_code' => wpbdp_get_option( 'currency', 'USD' ),
18
+ 'amount' => 0.0,
19
+ 'data' => array()
 
 
 
 
 
20
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
+ protected function prepare_row() {
24
+ $row = parent::prepare_row();
25
 
26
+ // Remove unnecessary columns.
27
+ // FIXME: In the future we should not use WPBDP__DB__Model at all. See #2945.
28
+ // FIXME: We also need to remove at least `created_on`, `processed_on` and `processed_by` which are not used anywhere.
29
+ unset( $row['created_on'] );
30
+ unset( $row['processed_on'] );
31
+ unset( $row['processed_by'] );
32
 
33
+ return $row;
 
34
  }
35
 
36
+ protected function before_save( $new = false ) {
37
+ if ( ! $this->payment_key )
38
+ $this->payment_key = strtolower( sha1( $this->listing_id . date( 'Y-m-d H:i:s' ) . ( defined( 'AUTH_KEY' ) ? AUTH_KEY : '' ) . uniqid( 'wpbdp', true ) ) );
39
 
40
+ $this->amount = 0.0;
 
 
 
 
 
 
 
 
 
 
41
 
42
+ foreach ( $this->payment_items as $item )
43
+ $this->amount += floatval( $item['amount'] );
 
44
 
45
+ if ( 0.0 == $this->amount && ! $this->has_item_type( 'recurring_plan' ) )
46
+ $this->status = 'completed';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
+ protected function after_save( $new = false ) {
50
+ if ( $new ) {
51
+ wpbdp_insert_log( array(
52
+ 'log_type' => 'listing.payment',
53
+ 'object_id' => $this->listing_id,
54
+ 'rel_object_id' => $this->id
55
+ ) );
56
+ }
57
 
58
+ if ( ! $this->old_status || ! $this->status )
 
59
  return;
60
 
61
+ if ( $this->old_status != $this->status ) {
62
+ wpbdp_insert_log( array(
63
+ 'log_type' => 'payment.status_change',
64
+ 'actor' => is_admin() ? 'user:' . get_current_user_id() : 'system',
65
+ 'object_id' => $this->id,
66
+ 'message' => sprintf( _x( 'Payment status changed from "%s" to "%s".', 'payment', 'WPBDM' ), $this->old_status, $this->status ) ) );
67
+ do_action_ref_array( 'WPBDP_Payment::status_change', array( &$this, $this->old_status, $this->status ) );
68
+ do_action( "wpbdp_payment_{$this->status}", $this );
69
  }
 
70
 
71
+ $this->old_status = $this->status;
 
 
72
  }
73
 
74
+ protected function after_delete() {
75
+ global $wpdb;
76
+ $wpdb->delete( $wpdb->prefix . 'wpbdp_logs', array( 'object_type' => 'payment', 'object_id' => $this->id ) );
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
+ protected function set_attr( $name, $value ) {
80
+ if ( in_array( $name, self::$serialized, true ) )
81
+ $value = is_array( $value ) ? $value : array();
82
 
83
+ if ( 'status' == $name ) {
84
+ $this->old_status = $this->status;
85
  }
86
 
87
+ return parent::set_attr( $name, $value );
 
 
 
 
 
 
 
 
 
88
  }
89
 
90
+ public function get_listing() {
91
+ return WPBDP_Listing::get( $this->listing_id );
 
 
 
 
 
 
 
92
  }
93
 
94
+ public function get_summary() {
95
+ $summary = '';
96
 
97
+ switch ( $this->payment_type ) {
98
+ case 'initial':
99
+ $summary = sprintf( _x( 'Initial payment ("%s")', 'payment', 'WPBDM' ), $this->get_listing()->get_title() );
100
+ break;
101
+ case 'renewal':
102
+ $summary = sprintf( _x( 'Renewal payment ("%s")', 'payment', 'WPBDM' ), $this->get_listing()->get_title() );
103
+ break;
104
+ default:
105
+ break;
106
+ }
107
 
108
+ if ( ! $summary ) {
109
+ $first_item = reset( $this->payment_items );
110
+ $summary = $first_item['description'];
111
+ }
112
 
113
+ if ( 'admin-submit' == $this->context ) {
114
+ $summary = sprintf( _x( '%s. Admin Posted.', 'payment summary', 'WPBDM' ), $summary );
 
 
115
  }
116
 
117
+ return $summary;
118
  }
119
 
120
+ public function get_created_at_date() {
121
+ $date = date_parse( $this->created_at );
122
+ extract( $date );
 
 
 
 
 
 
 
 
123
 
124
+ return compact( 'year', 'month', 'day' );
 
 
 
 
 
 
125
  }
126
 
127
+ public function get_created_at_time() {
128
+ $date = date_parse( $this->created_at );
129
+ extract( $date );
130
 
131
+ return compact( 'hour', 'minute' );
 
 
 
132
  }
133
 
134
+ public function get_payer_details() {
135
+ $data = array();
136
+ $data['email'] = $this->payer_email;
137
+ $data['first_name'] = $this->payer_first_name;
138
+ $data['last_name'] = $this->payer_last_name;
139
+ $data['country'] = '';
140
+ $data['state'] = '';
141
+ $data['city'] = '';
142
+ $data['address'] = '';
143
+ $data['address_2'] = '';
144
+ $data['zip'] = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
+ foreach ( (array) $this->payer_data as $k => $v )
147
+ $data[ $k ] = $v;
148
 
149
+ return $data;
 
150
  }
151
 
152
+ public function get_payer_address() {
153
+ $address = array();
 
 
 
 
 
154
 
155
+ foreach ( array( 'line_1', 'line_2', 'city', 'state', 'zip', 'country' ) as $k ) {
156
+ $address[ $k ] = ! empty( $this->payer_data[ 'address_' . $k ] ) ? $this->payer_data[ 'address_' . $k ] : '';
157
  }
158
 
159
+ return $address;
160
  }
161
 
162
+ public function has_item_type( $item_type ) {
163
+ $item_types = wp_list_pluck( $this->payment_items, 'type' );
164
+ return in_array( $item_type, $item_types, true );
165
  }
166
 
167
+ public function find_item( $item_type ) {
168
+ foreach ( $this->payment_items as $item ) {
169
+ if ( $item_type == $item['type'] )
170
+ return $item;
171
+ }
172
 
173
+ return null;
 
174
  }
175
 
176
+ public function process_as_admin() {
177
+ // $this->payment_items[0]['description'] .= ' ' . _x( '(admin, no charge)', 'submit listing', 'WPBDM' );
178
+ // $this->payment_items[0]['amount'] = 0.0;
179
+ $this->status = 'completed';
180
+ $this->context = 'admin-submit';
181
+ $this->save();
182
 
183
+ wpbdp_insert_log( array(
184
+ 'log_type' => 'payment.note',
185
+ 'object_id' => $this->id,
186
+ 'actor' => is_admin() ? 'user:' . get_current_user_id() : 'system',
187
+ 'message' => _x( 'Listing submitted by admin. Payment skipped.', 'submit listing', 'WPBDM' ) ) );
188
  }
189
 
190
+ public function is_completed() {
191
+ return 'completed' == $this->status;
 
 
192
  }
193
 
194
+ public function get_admin_url() {
195
+ return admin_url( 'admin.php?page=wpbdp_admin_payments&wpbdp-view=details&payment-id=' . $this->id );
196
  }
197
 
198
+ public function get_checkout_url( $force_http = false ) {
199
+ $url = wpbdp_url( 'checkout', $this->payment_key );
 
200
 
201
+ if ( ! $force_http && ! is_ssl() && wpbdp_get_option( 'payments-use-https' ) )
202
+ $url = set_url_scheme( $url, 'https' );
 
 
203
 
204
+ return $url;
205
  }
206
 
207
+ public function get_return_url() {
208
+ return $this->get_checkout_url();
 
 
 
209
  }
210
 
211
+ public function get_cancel_url() {
212
+ return add_query_arg( 'cancel-payment', '1', $this->get_checkout_url() );
 
 
 
213
  }
214
 
215
+ public function get_payment_notes() {
216
+ if ( ! $this->id )
217
+ return array();
218
 
219
+ return wpbdp_get_logs( array( 'object_id' => $this->id, 'object_type' => 'payment' ) );
 
220
  }
221
 
222
+ public function log( $msg ) {
223
+ return wpbdp_insert_log( array( 'object_id' => $this->id, 'object_type' => 'payment', 'log_type' => 'payment.note', 'message' => $msg ) );
224
  }
225
 
226
+ public function set_payment_method( $method ) {
227
+ $this->gateway = $method;
228
+ $this->save();
 
 
229
  }
230
 
231
+ public function is_pending() {
232
+ return $this->status == self::STATUS_PENDING;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
234
 
235
+ public function is_canceled() {
236
+ return $this->status == self::STATUS_CANCELED;
237
  }
238
 
239
+ public function is_rejected() {
240
+ return $this->status == self::STATUS_REJECTED;
241
  }
242
 
243
+ public function has_been_processed() {
244
+ return ! empty( $this->processed_by );
 
 
 
 
 
 
245
  }
246
 
247
+ /**
248
+ * Returns the list of supported payment statuses. By default, this is the list of statuses and their meaning:
249
+ * - Pending: Payment generated, but not paid.
250
+ * - Failed: Payment failed/was declined.
251
+ * - Completed: Payment was received successfuly and order is complete.
252
+ * - Canceled: Payment was canceled either by the user or the admin.
253
+ * - Refunded: Payment was refunded by admin.
254
+ * - On-hold: Not really used, but might be useful for manual payment gateways in the future.
255
+ * @return array Array of status => label items.
256
+ */
257
+ public static function get_stati() {
258
+ $stati = array();
259
+ $stati['pending'] = _x( 'Pending', 'payment', 'WPBDM' );
260
+ $stati['failed'] = _x( 'Failed', 'payment', 'WPBDM' );
261
+ $stati['completed'] = _x( 'Completed', 'payment', 'WPBDM' );
262
+ $stati['canceled'] = _x( 'Canceled', 'payment', 'WPBDM' );
263
+ $stati['on-hold'] = _x( 'On Hold', 'payment', 'WPBDM' );
264
+ $stati['refunded'] = _x( 'Refunded', 'payment', 'WPBDM' );
265
 
266
+ return $stati;
 
267
  }
268
 
269
+ public static function get_status_label( $status ) {
270
+ $stati = self::get_stati();
271
+ return $stati[ $status ];
 
272
  }
273
 
274
+ /**
275
+ * @override
276
+ */
277
+ public static function objects() {
278
+ return parent::_objects( get_class() );
279
  }
280
 
281
  }
282
+
includes/class-query-integration.php CHANGED
@@ -5,11 +5,38 @@
5
  class WPBDP__Query_Integration {
6
 
7
  public function __construct() {
 
 
8
  add_action( 'parse_query', array( $this, 'set_query_flags' ), 50 );
9
  add_action( 'template_redirect', array( $this, 'set_404_flag' ), 0 );
10
 
11
  add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10, 1 );
12
  add_filter( 'posts_clauses', array( $this, 'posts_clauses' ), 10, 2 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  }
14
 
15
  public function set_query_flags( $query ) {
@@ -45,6 +72,8 @@ class WPBDP__Query_Integration {
45
  $query->wpbdp_view = 'show_category';
46
  }
47
 
 
 
48
  $tags_slug = wpbdp_get_option( 'permalinks-tags-slug' );
49
  if ( ! empty( $query->query_vars[ WPBDP_TAGS_TAX ] ) ) {
50
  $query->wpbdp_is_tag = true;
@@ -111,25 +140,146 @@ class WPBDP__Query_Integration {
111
  $pieces = apply_filters( 'wpbdp_query_clauses', $pieces, $query );
112
 
113
  // Sticky listings.
114
- $is_sticky_query = "( SELECT 1 FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->prefix}wpbdp_listing_fees lf ON pm.post_id = lf.listing_id WHERE pm.post_id = {$wpdb->posts}.ID AND ( ( pm.meta_key = '_wpbdp[sticky]' AND pm.meta_value = 'sticky' ) OR lf.sticky = 1 ) LIMIT 1 ) AS wpbdp_is_sticky";
115
- $pieces['fields'] .= ', ' . $is_sticky_query . ' ';
116
-
117
- // Paid first query order.
118
- if ( in_array( $query->get( 'orderby' ), array( 'paid', 'paid-title' ), true ) ) {
119
- $is_paid_query = "(SELECT 1 FROM {$wpdb->prefix}wpbdp_fees f JOIN {$wpdb->prefix}wpbdp_listing_fees lf ON ( f.amount > 0 AND f.id = lf.fee_id ) WHERE lf.listing_id = {$wpdb->posts}.ID LIMIT 1 ) AS wpbdp_is_paid";
120
- $pieces['fields'] .= ', ' . $is_paid_query;
121
- } else {
122
- $pieces['fields'] .= ', (SELECT 0) AS wpbdp_is_paid';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  }
124
 
125
- if ( 'paid-title' == $query->get( 'orderby' ) )
126
- $pieces['orderby'] = "{$wpdb->posts}.post_title ASC, " . $pieces['orderby'];
127
-
128
- $pieces['orderby'] = 'wpbdp_is_sticky DESC, wpbdp_is_paid DESC ' . apply_filters( 'wpbdp_query_orderby', '' ) . ', ' . $pieces['orderby'];
129
  $pieces['fields'] = apply_filters('wpbdp_query_fields', $pieces['fields'] );
 
130
 
131
  return $pieces;
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  class WPBDP__Query_Integration {
6
 
7
  public function __construct() {
8
+ add_filter( 'query_vars', array( $this, 'add_query_vars' ) );
9
+
10
  add_action( 'parse_query', array( $this, 'set_query_flags' ), 50 );
11
  add_action( 'template_redirect', array( $this, 'set_404_flag' ), 0 );
12
 
13
  add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10, 1 );
14
  add_filter( 'posts_clauses', array( $this, 'posts_clauses' ), 10, 2 );
15
+
16
+ // Core sorting options.
17
+ add_filter( 'wpbdp_listing_sort_options', array( &$this, 'sortbar_sort_options' ) );
18
+ add_filter( 'wpbdp_query_fields', array( &$this, 'sortbar_query_fields' ) );
19
+ add_filter( 'wpbdp_query_orderby', array( &$this, 'sortbar_orderby' ) );
20
+ }
21
+
22
+ public function add_query_vars( $vars ) {
23
+ array_push( $vars, 'id' );
24
+ array_push( $vars, 'listing' );
25
+ array_push( $vars, 'category_id' ); // TODO: are we really using this var?
26
+ array_push( $vars, 'category' );
27
+ array_push( $vars, 'action' ); // TODO: are we really using this var?
28
+ array_push( $vars, 'wpbdpx' );
29
+ array_push( $vars, 'wpbdp-listener' );
30
+ array_push( $vars, 'region' );
31
+ array_push( $vars, 'wpbdp_view' );
32
+
33
+ if ( wpbdp_get_option( 'disable-cpt' ) ) {
34
+ array_push( $vars, '_' . wpbdp_get_option( 'permalinks-directory-slug' ) );
35
+ array_push( $vars, '_' . wpbdp_get_option( 'permalinks-category-slug' ) );
36
+ array_push( $vars, '_' . wpbdp_get_option( 'permalinks-tags-slug' ) );
37
+ }
38
+
39
+ return $vars;
40
  }
41
 
42
  public function set_query_flags( $query ) {
72
  $query->wpbdp_view = 'show_category';
73
  }
74
 
75
+ // wpbdp_debug_e( $query );
76
+
77
  $tags_slug = wpbdp_get_option( 'permalinks-tags-slug' );
78
  if ( ! empty( $query->query_vars[ WPBDP_TAGS_TAX ] ) ) {
79
  $query->wpbdp_is_tag = true;
140
  $pieces = apply_filters( 'wpbdp_query_clauses', $pieces, $query );
141
 
142
  // Sticky listings.
143
+ $is_sticky_query = "(SELECT is_sticky FROM {$wpdb->prefix}wpbdp_listings wls WHERE wls.listing_id = {$wpdb->posts}.ID LIMIT 1) AS wpbdp_is_sticky";
144
+ $pieces['fields'] .= ', ' . $is_sticky_query;
145
+
146
+ switch ( $query->get( 'orderby' ) ) {
147
+ case 'paid':
148
+ $pieces['fields'] .= ", (SELECT fee_price FROM {$wpdb->prefix}wpbdp_listings lp WHERE lp.listing_id = {$wpdb->posts}.ID LIMIT 1) AS wpbdp_plan_amount";
149
+ $pieces['orderby'] = "wpbdp_plan_amount " . $query->get( 'order' ) . ", {$wpdb->posts}.post_date DESC, " . $pieces['orderby'];
150
+
151
+ break;
152
+ case 'paid-title':
153
+ $pieces['fields'] .= ", (SELECT fee_price FROM {$wpdb->prefix}wpbdp_listings lp WHERE lp.listing_id = {$wpdb->posts}.ID LIMIT 1) AS wpbdp_plan_amount";
154
+ $pieces['orderby'] = "wpbdp_plan_amount " . $query->get( 'order' ) . ", {$wpdb->posts}.post_title ASC, " . $pieces['orderby'];
155
+
156
+ break;
157
+ case 'plan-order-date':
158
+ $plan_order = wpbdp_get_option( 'fee-order' );
159
+
160
+ if ( 'custom' == $plan_order['method'] ) {
161
+ $pieces['fields'] .= ", (SELECT po.weight FROM {$wpdb->prefix}wpbdp_plans po JOIN {$wpdb->prefix}wpbdp_listings pol ON po.id = pol.fee_id WHERE pol.listing_id = {$wpdb->posts}.ID ) AS wpbdp_plan_weight";
162
+ $pieces['orderby'] = "wpbdp_plan_weight DESC, {$wpdb->posts}.post_date " . $query->get( 'order' ) . ", " . $pieces['orderby'];
163
+ }
164
+
165
+ break;
166
+ case 'plan-order-title':
167
+ $plan_order = wpbdp_get_option( 'fee-order' );
168
+
169
+ if ( 'custom' == $plan_order['method'] ) {
170
+ $pieces['fields'] .= ", (SELECT po.weight FROM {$wpdb->prefix}wpbdp_plans po JOIN {$wpdb->prefix}wpbdp_listings pol ON po.id = pol.fee_id WHERE pol.listing_id = {$wpdb->posts}.ID ) AS wpbdp_plan_weight";
171
+ $pieces['orderby'] = "wpbdp_plan_weight DESC, {$wpdb->posts}.post_title " . $query->get( 'order' ) . ", " . $pieces['orderby'];
172
+ }
173
+
174
+ break;
175
+ default:
176
+ break;
177
  }
178
 
 
 
 
 
179
  $pieces['fields'] = apply_filters('wpbdp_query_fields', $pieces['fields'] );
180
+ $pieces['orderby'] = 'wpbdp_is_sticky DESC' . apply_filters( 'wpbdp_query_orderby', '' ) . ', ' . $pieces['orderby'];
181
 
182
  return $pieces;
183
  }
184
 
185
+ // {{ Sort bar.
186
+ public function sortbar_sort_options( $options ) {
187
+ $sortbar_fields = wpbdp_sortbar_get_field_options();
188
+ $sortbar = wpbdp_get_option( 'listings-sortbar-fields' );
189
+
190
+ foreach ( $sortbar as $field_id) {
191
+ if ( ! array_key_exists( $field_id, $sortbar_fields ) )
192
+ continue;
193
+ $options[ 'field-' . $field_id ] = array( $sortbar_fields[ $field_id ], '', 'ASC' );
194
+ }
195
+
196
+ return $options;
197
+ }
198
+
199
+ public function sortbar_query_fields( $fields ) {
200
+ global $wpdb;
201
+
202
+ $sort = wpbdp_get_current_sort_option();
203
+
204
+ if ( ! $sort || ! in_array( str_replace( 'field-', '', $sort->option ), wpbdp_get_option( 'listings-sortbar-fields' ) ) )
205
+ return $fields;
206
+
207
+ $sname = str_replace( 'field-', '', $sort->option );
208
+ $q = '';
209
+
210
+ switch ( $sname ) {
211
+ case 'user_login':
212
+ $q = "(SELECT user_login FROM {$wpdb->users} WHERE {$wpdb->users}.ID = {$wpdb->posts}.post_author) AS user_login";
213
+ break;
214
+ case 'user_registered':
215
+ $q = "(SELECT user_registered FROM {$wpdb->users} WHERE {$wpdb->users}.ID = {$wpdb->posts}.post_author) AS user_registered";
216
+ break;
217
+ case 'date':
218
+ case 'modified':
219
+ break;
220
+ default:
221
+ $field = wpbdp_get_form_field( $sname );
222
+
223
+ if ( ! $field || 'meta' != $field->get_association() )
224
+ break;
225
+
226
+ $q = $wpdb->prepare( "(SELECT {$wpdb->postmeta}.meta_value FROM {$wpdb->postmeta} WHERE {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID AND {$wpdb->postmeta}.meta_key = %s) AS field_{$sname}", '_wpbdp[fields][' . $field->get_id() . ']' );
227
+ break;
228
+ }
229
+
230
+ if ( $q )
231
+ return $fields . ', ' . $q;
232
+