Changeset 2973972
- Timestamp:
- 10/02/2023 06:25:57 PM (2 years ago)
- Location:
- constellation-client-portal
- Files:
-
- 156 added
- 6 deleted
- 7 edited
-
assets/screenshot-15.png (added)
-
assets/screenshot-16.png (added)
-
tags/1.0.10 (deleted)
-
tags/1.0.7 (deleted)
-
tags/1.5.4 (deleted)
-
tags/1.5.5 (deleted)
-
tags/1.5.6 (deleted)
-
tags/1.5.7 (deleted)
-
tags/1.7.0 (added)
-
tags/1.7.0/LICENSE.txt (added)
-
tags/1.7.0/README.txt (added)
-
tags/1.7.0/admin (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-admin.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-client-pages.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-company.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-core-authorization.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-core-file-checks.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-file.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-invoice.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-settings.php (added)
-
tags/1.7.0/admin/class-ars-constellation-client-portal-users.php (added)
-
tags/1.7.0/admin/css (added)
-
tags/1.7.0/admin/css/ars-constellation-client-portal-admin.css (added)
-
tags/1.7.0/admin/css/jquery-ui (added)
-
tags/1.7.0/admin/css/jquery-ui/1.11.1 (added)
-
tags/1.7.0/admin/css/jquery-ui/1.11.1/themes (added)
-
tags/1.7.0/admin/css/jquery-ui/1.11.1/themes/cupertino (added)
-
tags/1.7.0/admin/css/jquery-ui/1.11.1/themes/cupertino/jquery-ui.css (added)
-
tags/1.7.0/admin/css/select2.min.css (added)
-
tags/1.7.0/admin/index.php (added)
-
tags/1.7.0/admin/js (added)
-
tags/1.7.0/admin/js/ars-constellation-client-portal-admin.js (added)
-
tags/1.7.0/admin/js/i18n (added)
-
tags/1.7.0/admin/js/i18n/af.js (added)
-
tags/1.7.0/admin/js/i18n/ar.js (added)
-
tags/1.7.0/admin/js/i18n/az.js (added)
-
tags/1.7.0/admin/js/i18n/bg.js (added)
-
tags/1.7.0/admin/js/i18n/bs.js (added)
-
tags/1.7.0/admin/js/i18n/ca.js (added)
-
tags/1.7.0/admin/js/i18n/cs.js (added)
-
tags/1.7.0/admin/js/i18n/da.js (added)
-
tags/1.7.0/admin/js/i18n/de.js (added)
-
tags/1.7.0/admin/js/i18n/dsb.js (added)
-
tags/1.7.0/admin/js/i18n/el.js (added)
-
tags/1.7.0/admin/js/i18n/en.js (added)
-
tags/1.7.0/admin/js/i18n/es.js (added)
-
tags/1.7.0/admin/js/i18n/et.js (added)
-
tags/1.7.0/admin/js/i18n/eu.js (added)
-
tags/1.7.0/admin/js/i18n/fa.js (added)
-
tags/1.7.0/admin/js/i18n/fi.js (added)
-
tags/1.7.0/admin/js/i18n/fr.js (added)
-
tags/1.7.0/admin/js/i18n/gl.js (added)
-
tags/1.7.0/admin/js/i18n/he.js (added)
-
tags/1.7.0/admin/js/i18n/hi.js (added)
-
tags/1.7.0/admin/js/i18n/hr.js (added)
-
tags/1.7.0/admin/js/i18n/hsb.js (added)
-
tags/1.7.0/admin/js/i18n/hu.js (added)
-
tags/1.7.0/admin/js/i18n/hy.js (added)
-
tags/1.7.0/admin/js/i18n/id.js (added)
-
tags/1.7.0/admin/js/i18n/is.js (added)
-
tags/1.7.0/admin/js/i18n/it.js (added)
-
tags/1.7.0/admin/js/i18n/ja.js (added)
-
tags/1.7.0/admin/js/i18n/km.js (added)
-
tags/1.7.0/admin/js/i18n/ko.js (added)
-
tags/1.7.0/admin/js/i18n/lt.js (added)
-
tags/1.7.0/admin/js/i18n/lv.js (added)
-
tags/1.7.0/admin/js/i18n/mk.js (added)
-
tags/1.7.0/admin/js/i18n/ms.js (added)
-
tags/1.7.0/admin/js/i18n/nb.js (added)
-
tags/1.7.0/admin/js/i18n/nl.js (added)
-
tags/1.7.0/admin/js/i18n/pl.js (added)
-
tags/1.7.0/admin/js/i18n/ps.js (added)
-
tags/1.7.0/admin/js/i18n/pt-BR.js (added)
-
tags/1.7.0/admin/js/i18n/pt.js (added)
-
tags/1.7.0/admin/js/i18n/ro.js (added)
-
tags/1.7.0/admin/js/i18n/ru.js (added)
-
tags/1.7.0/admin/js/i18n/sk.js (added)
-
tags/1.7.0/admin/js/i18n/sl.js (added)
-
tags/1.7.0/admin/js/i18n/sr-Cyrl.js (added)
-
tags/1.7.0/admin/js/i18n/sr.js (added)
-
tags/1.7.0/admin/js/i18n/sv.js (added)
-
tags/1.7.0/admin/js/i18n/th.js (added)
-
tags/1.7.0/admin/js/i18n/tr.js (added)
-
tags/1.7.0/admin/js/i18n/uk.js (added)
-
tags/1.7.0/admin/js/i18n/vi.js (added)
-
tags/1.7.0/admin/js/i18n/zh-CN.js (added)
-
tags/1.7.0/admin/js/i18n/zh-TW.js (added)
-
tags/1.7.0/admin/js/select2.full.min.js (added)
-
tags/1.7.0/admin/js/select2.min.js (added)
-
tags/1.7.0/ars-constellation-client-portal.php (added)
-
tags/1.7.0/assets (added)
-
tags/1.7.0/assets/css (added)
-
tags/1.7.0/assets/css/font-awesome (added)
-
tags/1.7.0/assets/css/font-awesome/css (added)
-
tags/1.7.0/assets/css/font-awesome/css/all.css (added)
-
tags/1.7.0/assets/css/font-awesome/css/all.min.css (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-brands-400.eot (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-brands-400.svg (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-brands-400.ttf (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-brands-400.woff (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-brands-400.woff2 (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-regular-400.eot (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-regular-400.svg (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-regular-400.ttf (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-regular-400.woff (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-regular-400.woff2 (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-solid-900.eot (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-solid-900.svg (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-solid-900.ttf (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-solid-900.woff (added)
-
tags/1.7.0/assets/css/font-awesome/webfonts/fa-solid-900.woff2 (added)
-
tags/1.7.0/assets/img (added)
-
tags/1.7.0/assets/img/accp-full-logo.png (added)
-
tags/1.7.0/includes (added)
-
tags/1.7.0/includes/ars-constellation-client-portal-install-uninstall.php (added)
-
tags/1.7.0/includes/class-ars-constellation-client-portal-activator.php (added)
-
tags/1.7.0/includes/class-ars-constellation-client-portal-deactivator.php (added)
-
tags/1.7.0/includes/class-ars-constellation-client-portal-i18n.php (added)
-
tags/1.7.0/includes/class-ars-constellation-client-portal-loader.php (added)
-
tags/1.7.0/includes/class-ars-constellation-client-portal-utility-functions.php (added)
-
tags/1.7.0/includes/class-ars-constellation-client-portal.php (added)
-
tags/1.7.0/includes/index.php (added)
-
tags/1.7.0/index.php (added)
-
tags/1.7.0/languages (added)
-
tags/1.7.0/languages/ars-constellation-client-portal.pot (added)
-
tags/1.7.0/public (added)
-
tags/1.7.0/public/assets (added)
-
tags/1.7.0/public/assets/index.php (added)
-
tags/1.7.0/public/class-ars-constellation-client-portal-public.php (added)
-
tags/1.7.0/public/css (added)
-
tags/1.7.0/public/css/ars-constellation-client-portal-public.css (added)
-
tags/1.7.0/public/index.php (added)
-
tags/1.7.0/public/js (added)
-
tags/1.7.0/public/js/ars-constellation-client-portal-public.js (added)
-
tags/1.7.0/public/shortcodes (added)
-
tags/1.7.0/public/shortcodes/class-ars-constellation-client-portal-list-shortcodes.php (added)
-
tags/1.7.0/uninstall.php (added)
-
trunk/README.txt (modified) (6 diffs)
-
trunk/admin/class-ars-constellation-client-portal-admin.php (modified) (3 diffs)
-
trunk/admin/class-ars-constellation-client-portal-settings.php (modified) (8 diffs)
-
trunk/admin/css/ars-constellation-client-portal-admin.css (modified) (1 diff)
-
trunk/admin/js/select2.full.min.js (added)
-
trunk/ars-constellation-client-portal.php (modified) (2 diffs)
-
trunk/assets/css (added)
-
trunk/assets/css/font-awesome (added)
-
trunk/assets/css/font-awesome/css (added)
-
trunk/assets/css/font-awesome/css/all.css (added)
-
trunk/assets/css/font-awesome/css/all.min.css (added)
-
trunk/assets/css/font-awesome/webfonts (added)
-
trunk/assets/css/font-awesome/webfonts/fa-brands-400.eot (added)
-
trunk/assets/css/font-awesome/webfonts/fa-brands-400.svg (added)
-
trunk/assets/css/font-awesome/webfonts/fa-brands-400.ttf (added)
-
trunk/assets/css/font-awesome/webfonts/fa-brands-400.woff (added)
-
trunk/assets/css/font-awesome/webfonts/fa-brands-400.woff2 (added)
-
trunk/assets/css/font-awesome/webfonts/fa-regular-400.eot (added)
-
trunk/assets/css/font-awesome/webfonts/fa-regular-400.svg (added)
-
trunk/assets/css/font-awesome/webfonts/fa-regular-400.ttf (added)
-
trunk/assets/css/font-awesome/webfonts/fa-regular-400.woff (added)
-
trunk/assets/css/font-awesome/webfonts/fa-regular-400.woff2 (added)
-
trunk/assets/css/font-awesome/webfonts/fa-solid-900.eot (added)
-
trunk/assets/css/font-awesome/webfonts/fa-solid-900.svg (added)
-
trunk/assets/css/font-awesome/webfonts/fa-solid-900.ttf (added)
-
trunk/assets/css/font-awesome/webfonts/fa-solid-900.woff (added)
-
trunk/assets/css/font-awesome/webfonts/fa-solid-900.woff2 (added)
-
trunk/includes/class-ars-constellation-client-portal.php (modified) (4 diffs)
-
trunk/public/class-ars-constellation-client-portal-public.php (modified) (2 diffs)
-
trunk/public/shortcodes (added)
-
trunk/public/shortcodes/class-ars-constellation-client-portal-list-shortcodes.php (added)
Legend:
- Unmodified
- Added
- Removed
-
constellation-client-portal/trunk/README.txt
r2961762 r2973972 5 5 Requires at least: 5.0.0 6 6 Tested up to: 6.3 7 Stable tag: 1. 6.07 Stable tag: 1.7.0 8 8 Requires PHP: 7.4 9 9 License: GPLv3 or later … … 32 32 * Automatically send email notifications to clients when a new File or Invoice post is created. 33 33 * Automatically send reminder email notifications on a schedule. 34 * Easily generate, save, and edit file and invoice shortcodes within the plugin settings. 34 35 * Add due dates and past due notices to invoices and files. 35 36 * Further restrict file and invoice access within a company by user and role. … … 68 69 13. Admin Settings - Client Page Edit 69 70 14. Admin Settings - Pro Invoice Bulk Create 70 71 == Shortcodes == 71 15. Admin Settings - Pro List/Shortcode Settings 72 16. Admin Settings - Pro List/Shortcode Edit Settings 73 74 == Shortcodes (Core) == 75 76 The shortcode parameters, below, are for use with the core version of the plugin. The pro version allows for file and invoice shortcodes to be easily generated, saved, and edited within the plugin settings. 72 77 73 78 = Unpaid Invoice List = … … 91 96 * **align_thumbnail** this allows the thumbnail image alignment to be set if the “show_thumbnail” attribute is set to “true”. Accepted Values: “center”, “left”, “right”, “float-left”, or “float-right”. Default: null. 92 97 * **show_post_date** this allows for the WordPress post date to be displayed with each item in a list. Accepted Values: “true” or “false”. Default: “false”. 93 * **list_id** this can be useful for development when you have multiple lists on the same page (ex. this could be helpful when creatig paginated lists on the same page). Accepted Values: any whole positive number that is unique on the page. Default: null94 98 * **categories** Accepted Values: this can be entered as an Invoice Category Slug or ID, or a combination of those. Separate multiple values with a comma (ex. “21, category-a”). Default: null. 95 99 * **link_title** Accepted Values: “nolink”. Adding this parameter and setting the value to "nolink" will remove the href from post titles in the list and make them unclickable. Default: null. 96 * **id** Accepted Values: any valid HTML ID attribute name. Default: null.97 100 * **class** Accepted Values: any valid HTML class attribute name or names (separate multiple class names with a space). Default: null. 98 99 100 = Pro Invoice Shortcode Parameters =101 102 * **display_pay_btn** this will display a pay button if the “invoice_status” attribute is set to “unpaid” and a WooCommerce product id has been entered in the invoice. Accepted Values: “true” or “false”. Default: “false”.103 * **due_date** this will display the due date if a due date has been entered in the invoice. Accepted Values: “true” or “false”. Default: “false”.104 * **past_due_notice** this will display a “Past Due” label for each item that has a status of “unpaid” and the current date is after the “due_date”. Accepted Values: “true” or “false”. Default: “false”.105 * **exclude_user** this allows you to prevent specific users, within an assigned company, from viewing items in the list. Accepted Values: the WordPress user ID(s). Separate multiple values with a comma (ex. “21, 45”). Default: null.106 * **exclude_role** this allows you to prevent specific roles, within an assigned company, from viewing items in the list. Accepted Values: the WordPress role name. Separate multiple values with a comma (ex. “Subscriber, Editor”). Default: null.107 101 108 102 … … 123 117 * **align_thumbnail** this allows the thumbnail image alignment to be set if the “show_thumbnail” attribute is set to “true”. Accepted Values: “center”, “left”, “right”, “float-left”, or “float-right”. Default: null. 124 118 * **show_post_date** this allows for the WordPress post date to be displayed with each item in a list. Accepted Values: “true” or “false”. Default: “false”. 125 * **list_id** this can be useful for development when you have multiple lists on the same page (ex. this could be helpful when creatig paginated lists on the same page). Accepted Values: any whole positive number that is unique on the page. Default: null.126 119 * **link_title** Accepted Values: “nolink”. Adding this parameter and setting the value to "nolink" will remove the href from post titles in the list and make them unclickable. Default: null. 127 * **id** Accepted Values: any valid HTML ID attribute name. Default: null.128 120 * **class** Accepted Values: any valid HTML class attribute name or names (separate multiple class names with a space). Default: null. 129 121 130 = Pro File Shortcode Parameters =131 132 * **due_date** this will display the due date if a due date has been entered in the file. Accepted Values: “true” or “false”. Default: “false”.133 * **past_due_notice** this will display a “Past Due” label a due date has been entered, and the current date is after the “due_date”. Accepted Values: “true” or “false”. Default: “false”.134 * **exclude_user** this allows you to prevent specific users, within an assigned company, from viewing items in the list. Accepted Values: the WordPress user ID(s). Separate multiple values with a comma (ex. “21, 45”). Default: null.135 * **exclude_role** this allows you to prevent specific roles, within an assigned company, from viewing items in the list. Accepted Values: the WordPress role name. Separate multiple values with a comma (ex. “Subscriber, Editor”). Default: null.136 122 137 123 = Company Menu (Pro) = … … 207 193 208 194 == Changelog == 195 196 = 1.7.0 (Pro) - 2023-10-2 = 197 * Update: Updated the invoice pay all functionality to leave the button disabled on AJAX success (through redirection to the cart). 198 * Update: Deprecated accp-file-list-shortcode-atts.php. 199 * Update: Deprecated accp-file-list-shortcode-vars.php. 200 * Update: Deprecated accp-invoice-list-shortcode-atts.php. 201 * Update: Deprecated ars-constellation-invoice-list-shortcode-vars.php. 202 * Update: Deprecated accp-file-list-due-date-past-due.php. 203 * Update: Deprecated accp-file-list-loop-vars.php. 204 * Update: Deprecated accp-file-list-pay-button.php. 205 * Update: Deprecated accp-invoice-list-due-date-past-due.php. 206 * Update: Deprecated accp-invoice-list-loop-vars.php. 207 * Update: Deprecated accp-invoice-list-pay-all-button.php. 208 * Update: Deprecated accp-invoice-list-pay-button.php. 209 * Update: Deprecated the accp-invoice-list-shortcode-includes dir. 210 * Update: Deprecated the accp-file-list-shortcode-includes dir. 211 * Update: Deprecated the premium admin dir is this will not be used. 212 * Feature: Added functionality to allow shortcodes to be genarated and saved as settings for easier implementation and editing. 213 * Update: Overhauled the pro file and invoice list shortcode framework for better maintainability and scalability, and for forthcoming features. 214 215 = 1.7.0 (Core) - 2023-10-2 = 216 * Improvement: Updated the sanitize strings in array function to account for incorrect and null values. 217 * Update: Overhauled the core file and invoice list shortcode framework for better maintainability and scalability. 218 * Update: Deprecated the “list_id” shortcode param. This now uses the auto-generated “data-list-id" value. This is also not needed in the new pro saved shortcode framework. 219 * Update: Updated select2 to select2.full. 220 * Update: Updated Font Awesome to enqueue from a local plugin dir instead of via the CDN. Also updated the Font Awesome version. 221 * Update: Updated the add settings sub page function to exit early for non-admin users to prevent notices on WP Admin for non-admin users. 209 222 210 223 = 1.6.0 (Pro) - 2023-9-1 = -
constellation-client-portal/trunk/admin/class-ars-constellation-client-portal-admin.php
r2961762 r2973972 72 72 * Enqueue Admin Styles 73 73 */ 74 75 74 wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/ars-constellation-client-portal-admin.css', array(), $this->version, 'all' ); 76 75 wp_enqueue_style( $this->plugin_name.'-jquery-ui', plugin_dir_url( __FILE__ ) . 'css/jquery-ui/1.11.1/themes/cupertino/jquery-ui.css', array(), $this->version, 'all' ); 77 76 78 wp_enqueue_style( $this->plugin_name.'-selec2-css', plugin_dir_url( __FILE__ ) . 'css/select2.min.css', array(), $this->version, 'all' ); 79 80 // Font Awesome 81 if (!wp_style_is( 'fontawesome', 'enqueued' )) { 82 wp_register_style( 'fontawesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css', false, '4.6.1' ); 83 wp_enqueue_style( 'fontawesome' ); 84 } 77 wp_enqueue_style( $this->plugin_name.'-selec2-css', plugin_dir_url( __FILE__ ) . 'css/select2.min.css', array(), $this->version, 'all' ); 78 79 /** 80 * Conditionally enqueue Font Awesome CSS. 81 */ 82 if( !wp_style_is('font-awesome', 'registered') ){ 83 84 wp_enqueue_style( 'accp-font-awesome-css', dirname( plugin_dir_url( __FILE__ ) ) . '/assets/css/font-awesome/css/all.min.css', array(), $this->version, 'all' ); 85 86 } 87 85 88 } 86 89 … … 96 99 wp_enqueue_script( 'jquery-ui-datepicker' ); 97 100 98 wp_enqueue_script( $this->plugin_name . '-select2-js', plugin_dir_url( __FILE__ ) . 'js/select2. min.js', array( 'jquery' ), $this->version, false );101 wp_enqueue_script( $this->plugin_name . '-select2-js', plugin_dir_url( __FILE__ ) . 'js/select2.full.min.js', array( 'jquery' ), $this->version, false ); 99 102 100 103 } … … 2136 2139 2137 2140 wp_die(); 2141 2138 2142 } 2139 2143 -
constellation-client-portal/trunk/admin/class-ars-constellation-client-portal-settings.php
r2961762 r2973972 70 70 function add_accp_settings_pages_to_wp_admin(){ 71 71 72 if( !is_admin() || !is_user_logged_in() || !current_user_can('manage_options') ) 73 return; 74 72 75 $defined_settings_pages = $this->get_defined_settings_pages(); 76 77 if( !$defined_settings_pages || empty($defined_settings_pages) ) 78 return; 73 79 74 80 foreach( $defined_settings_pages as $slug => $settings_page ){ … … 126 132 $html .= '<div class="accp-admin-main-content-header">'; 127 133 128 $html .= '<h1>'.esc_html( $this->get_settings_page_title _from_url() ).'</h1>';134 $html .= '<h1>'.esc_html( $this->get_settings_page_title() ).'</h1>'; 129 135 130 136 $html .= '</div>'; … … 244 250 * @return string $page_title - The title of the settings page. 245 251 */ 246 function get_settings_page_title _from_url(){252 function get_settings_page_title(){ 247 253 248 254 /** … … 253 259 if( $title && !empty($title) ) 254 260 return $title; 261 262 $is_pro = $this->utilities->is_pro_plugin($this->plugin_name); 255 263 256 264 if( $title == 'Settings' ){ … … 259 267 $page_title = 'Settings'; 260 268 } 269 261 270 262 271 /** … … 466 475 467 476 477 function get_list_settings_page_content(){ 478 479 if( !is_admin() || !is_user_logged_in() || !current_user_can('manage_options') ) 480 return; 481 482 $allowed_html = $this->get_customized_allowed_html_for_wp_kses(); 483 $is_pro = $this->utilities->is_pro_plugin($this->plugin_name); 484 $html = ''; 485 486 /** 487 * Section html filter. 488 */ 489 if( true === $is_pro ){ 490 491 $html = apply_filters('accp_list_settings_page_section_html', $html); 492 493 } 494 495 if( !empty($html) ){ 496 497 echo wp_kses( $this->generate_settings_page_html($html, false, false, false, false), $allowed_html ); 498 499 } 500 501 } 502 503 468 504 function get_documentation_settings_page_content(){ 469 505 … … 847 883 $page_list['accp-company-settings'] = 'Companies'; 848 884 $page_list['accp-email-settings'] = 'Email'; 885 $page_list['accp-list-settings'] = 'Lists'; 849 886 850 887 } … … 1093 1130 'multiple' => array(), 1094 1131 'required' => array(), 1132 'disabled' => array(), 1133 'size' => array(), 1134 'data-term-slug' => array(), 1095 1135 ); 1096 1136 -
constellation-client-portal/trunk/admin/css/ars-constellation-client-portal-admin.css
r2961762 r2973972 409 409 } 410 410 411 #accp-shorcode-list-table-container{ 412 display: table; 413 width: 100%; 414 border-collapse: collapse; 415 } 416 417 .accp-shortcode-col-heading-row, 418 .accp-saved-shortcode-item-row{ 419 display: table-row; 420 height: 60px; 421 border-bottom: 1px solid #eee; 422 } 423 424 .accp-shortcode-col-heading { 425 font-weight: bold; 426 color: #777; 427 } 428 429 .accp-add-shortcode-btn-container{ 430 text-align: right; 431 margin-top: 15px; 432 } 433 434 .accp-row-action-col-heading{ 435 visibility: hidden; 436 } 437 438 .accp-shortcode-item-cell{ 439 display: table-cell; 440 padding: 5px; 441 vertical-align: middle; 442 } 443 444 .accp-shortcode-item-cell a{ 445 text-decoration: none; 446 } 447 448 input.accp-copy-text-enabled { 449 cursor: pointer; 450 background-color: #eee; 451 padding: 5px 7px 7px 7px; 452 border-radius: 3px; 453 border: none; 454 text-align: center; 455 } 456 457 .accp-shortcode-input-container{ 458 position: relative; 459 } 460 461 .accp-shortcode-input-container:hover::after { 462 display: block; 463 } 464 465 .accp-shortcode-input-container::after { 466 content: "\f0c5"; 467 font-family: "Font Awesome 5 Free"; 468 font-weight: 400; 469 position: absolute; 470 right: 5px; 471 display: none; 472 } 473 474 .accp-shortcode-input-container.accp-element-copied::after { 475 content: "\f00c"; 476 font-family: "Font Awesome 5 Free"; 477 font-weight: 600; 478 position: absolute; 479 right: 5px; 480 top: 0; 481 color: #259d25; 482 } 483 411 484 .accp-settings-tabs li:hover { 412 485 background-color: #fff; -
constellation-client-portal/trunk/ars-constellation-client-portal.php
r2961762 r2973972 5 5 * Plugin URI: https://adrianrodriguezstudios.com/constellation-client-portal/ 6 6 * Description: Create private pages for each of your clients, post private files, and protect your client files from unauthorized users and search engines. <strong>Important:</strong> All Site-level File Protection features will cease to function if the plugin is disabled or uninstalled. 7 * Version: 1. 6.07 * Version: 1.7.0 8 8 * Author: ARS 9 9 * Author URI: https://adrianrodriguezstudios.com … … 55 55 */ 56 56 define('ACCP_PLUGIN_NAME', 'ARS_CONSTELLATION_CLIENT_PORTAL'); 57 define('ACCP_PLUGIN_VERSION', '1. 6.0'); // Change the version in the header as well.57 define('ACCP_PLUGIN_VERSION', '1.7.0'); // Change the version in the header as well. 58 58 define( ACCP_PLUGIN_NAME, ACCP_PLUGIN_VERSION ); 59 59 define('ACCP_PLUGIN_FILE_NAME', __FILE__); -
constellation-client-portal/trunk/includes/class-ars-constellation-client-portal.php
r2961762 r2973972 127 127 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-ars-constellation-client-portal-settings.php'; 128 128 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-ars-constellation-client-portal-utility-functions.php'; 129 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/shortcodes/class-ars-constellation-client-portal-list-shortcodes.php'; 129 130 130 131 … … 201 202 $plugin_authorization = new ARS_Constellation_Client_Portal_Core_Authorization( $this->get_plugin_name(), $this->get_version() ); 202 203 $plugin_users = new ARS_Constellation_Client_Portal_Users( $this->get_plugin_name(), $this->get_version() ); 203 $core_settings = new ARS_Constellation_Client_Portal_Settings(); 204 $core_settings = new ARS_Constellation_Client_Portal_Settings(); 204 205 205 206 /* Core (Basic tier) hooks */ … … 495 496 496 497 $plugin_public = new ARS_Constellation_Client_Portal_Public( $this->get_plugin_name(), $this->get_version() ); 498 $list_shortcodes = new ARS_Constellation_Client_Portal_List_Shortcodes; 497 499 498 500 $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' ); 499 $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' ); 500 501 $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' ); 501 502 502 503 // Client File List shortcode - [accp_clientfiles] 503 $this->loader->add_shortcode( 'accp_clientfiles', $ plugin_public, 'accp_client_files' );504 $this->loader->add_shortcode( 'accp_clientfiles', $list_shortcodes, 'get_client_files_shortcode' ); 504 505 505 506 // Client Invoice List shortcode - [accp_clientinvoices] 506 $this->loader->add_shortcode( 'accp_clientinvoices', $ plugin_public, 'accp_client_invoices' );507 $this->loader->add_shortcode( 'accp_clientinvoices', $list_shortcodes, 'get_client_invoices_shortcode' ); 507 508 508 509 … … 519 520 } 520 521 521 /* Premium tier hooks */ 522 if ( $this->plugin_name == 'ars-constellation-client-portal-premium' ){ 523 524 // Include the Pro hooks 525 $plugin_pro_public = new ARS_Constellation_Client_Portal_Pro_Public( $this->get_plugin_name(), $this->get_version() ); 526 require_once ( dirname(__DIR__) . '/pro/public/ars-constellation-client-portal-pro-public-hooks.php' ); 527 528 } 529 522 530 523 } 531 524 -
constellation-client-portal/trunk/public/class-ars-constellation-client-portal-public.php
r2961762 r2973972 73 73 74 74 } 75 76 77 /**78 * Set up Client File List shortcode.79 *80 * Shortcode: [accp_clientfiles]81 *82 * @param array $atts - array of atts passed in via the shortcode.83 * @return string $html - the shortcode result.84 */85 function accp_client_files( $atts, $content = null ) {86 87 /**88 * Exit if the user is not logged in89 * or if this is WP Admin.90 */91 if ( !is_user_logged_in() || is_admin() )92 return;93 94 global $post;95 96 $post_id = get_the_ID();97 $user = wp_get_current_user();98 $user_id = get_current_user_id();99 $roles_array = (array)$user->roles;100 $roles = array_map('strtolower', $roles_array);101 $list_instance = filter_var( $this->accp_generate_list_instance_id(), FILTER_SANITIZE_NUMBER_INT);102 $paged_param = 'paged' . $list_instance;103 $paged = isset( $_GET[$paged_param] ) ? (int)$_GET[$paged_param] : 1;104 $authorized_company_id = $this->get_client_page_authorized_company_id_by_user_id($user_id, $post_id);105 106 /**107 * Exit if the $authorized_company_id is false.108 */109 if( false === $authorized_company_id || !$authorized_company_id )110 return;111 112 $current_date = date('Y-m-d');113 114 115 /**116 * Set up the core atts for the clientfile shortcode.117 */118 $atts_list_array = $this->accp_clientfile_core_shortcode_atts();119 120 121 /**122 * Conditionally add Pro Tier shortcode attributes.123 */124 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' ){125 include dirname(__DIR__) . '/pro/public/accp-file-list-shortcode-atts.php';126 }127 128 /**129 * Output the shortcode attributes.130 */131 $atts = shortcode_atts($atts_list_array, $atts);132 133 134 /**135 * List vars.136 */137 138 // File Status139 if( $atts['file_status'] != null){140 141 $file_status = strtolower($atts['file_status']);142 143 }else{144 145 $file_status = '';146 147 }148 149 // List ID150 $list_id = $this->accp_list_id_var($atts);151 152 // Category Filter153 $taxonomy = 'accp_file_categories';154 $categories = $this->accp_categories_var($atts, $taxonomy);155 156 // Posts per page157 $number_of_posts = $this->accp_number_of_posts_var($atts);158 159 // Order posts by160 $order_by = $this->accp_order_by_var($atts);161 162 // Post order163 $order = $this->accp_order_var($atts);164 165 // Exerpt length166 $excerpt_length = $this->accp_excerpt_length_var($atts);167 168 // Thumbnail size169 $thumbnail_size = $this->accp_thumbnail_size_var($atts);170 171 // Thumbnail alignment172 $align_thumbnail = $this->accp_align_thumbnail_var($atts) ? $this->accp_align_thumbnail_var($atts) : '';173 174 // Link title175 $link_title = '';176 177 if( isset($atts['link_title']) &&178 !empty($atts['link_title']) &&179 trim( strtolower($atts['link_title']) ) === 'nolink'180 ){181 182 $link_title = 'nolink';183 184 }185 186 // Container ID187 $container_id = '';188 189 if( isset($atts['id']) && !empty($atts['id']) ){190 191 $container_id = trim($atts['id']);192 $container_id = str_replace(' ', '', $container_id);193 194 }195 196 // Container Classes197 $container_classes = '';198 199 if( isset($atts['class']) && !empty($atts['class']) ){200 201 $container_classes = trim($atts['class']);202 203 }204 205 /**206 * Set up Pro Tier vars207 */208 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' || $this->plugin_name == 'ars-constellation-client-portal-premium' ){209 include dirname(__DIR__) . '/pro/public/accp-file-list-shortcode-vars.php';210 }211 212 213 /**214 * Hook - Allow content to be added before215 * the file list.216 *217 * @param $post_id - ID of the page that contains the client file shortcode.218 */219 $before_loop_content = do_action('accp_before_file_list', $post_id);220 221 if($before_loop_content){222 echo wp_kses_post($before_loop_content);223 }224 225 /**226 * File List227 */228 ob_start();229 ?>230 231 <div <?php echo !empty($container_id) ? 'id="'. esc_attr($container_id).'"' : ''; ?> class="accp_documents_filelist <?php echo !empty($container_classes) ? esc_attr($container_classes) : ''; ?>" <?php echo ( $list_id != null ? ' data-accp-rel-list="' . esc_attr($list_id) . '"' : '' ); ?> data-list-id="<?php echo esc_attr($list_instance); ?>">232 <?php233 234 /**235 * Generate the file query.236 */237 $args = $this->accp_generate_file_query_args($categories, $number_of_posts, $paged, $order_by, $order, $authorized_company_id, $file_status);238 $query = new WP_Query( $args );239 240 $html = '';241 242 if ($query->have_posts()):243 244 while ( $query->have_posts() ):245 246 $query->the_post();247 248 $accp_file = get_post_meta($post->ID, 'accp_file', true);249 $file_post_id = get_the_ID();250 251 /**252 * Get the Company ID associated with the file.253 */254 $file_post_company_id = get_post_meta($file_post_id, 'accp_user', true );255 256 257 /**258 * Check if pro access checks need to be instantiated.259 */260 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' ){261 262 $authorization = new ARS_Constellation_Client_Portal_Pro_Authorization( $this->plugin_name, $this->version );263 $check_authorization = $authorization->verify_page_or_post_authorization_pro($file_post_id, $user_id);264 265 }else{266 267 /**268 * Use the default file check if this is the Core version269 * to determine if access should be granted.270 */271 $authorization = new ARS_Constellation_Client_Portal_Core_Authorization( $this->plugin_name, $this->version );272 $check_authorization = $authorization->verify_page_or_post_authorization($file_post_id, $user_id);273 274 }275 276 if( $check_authorization === true ){277 278 /**279 * Hook - Allow content to be added before280 * the file list item.281 *282 * @param $item_id - The ID of the file post in the loop.283 */284 $item_id = $file_post_id;285 $before_item_content = do_action('accp_before_file_list_item', $item_id);286 287 if($before_item_content){288 echo wp_kses_post($before_item_content);289 }290 ?>291 292 <div class="accp-item-container clearfix">293 294 <?php295 /**296 * Hook - Allow content to be added to297 * the top of the file list item.298 *299 * @param $item_id - ID of the file post in the loop.300 */301 $item_id = $file_post_id;302 $top_item_content = do_action('accp_file_list_item_top_inside', $item_id);303 304 if($top_item_content){305 echo wp_kses_post($top_item_content);306 }307 308 if($link_title !== 'nolink'):309 ?>310 311 <span class="accp-file-list-item-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></span>312 313 <?php314 else:315 ?>316 317 <span class="accp-file-list-item-title"><?php the_title(); ?></span>318 319 <?php320 endif;321 ?>322 323 <div class="accp-list-item-meta">324 325 <?php // Post Date ?>326 327 <?php328 if( $atts['show_post_date'] == true && $atts['show_post_date'] !== null){329 330 ?>331 <div class="accp-file-post-date">332 <?php echo esc_html(get_the_date()); ?>333 </div>334 <?php335 336 }337 ?>338 339 <?php // Pro - Due Date and Past Due Elements ?>340 341 <?php342 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' || $this->plugin_name == 'ars-constellation-client-portal-premium' ){343 include dirname(__DIR__) . '/pro/public/accp-file-list-shortcode-includes/accp-file-list-due-date-past-due.php';344 }345 ?>346 347 </div>348 349 <? // Thumbnail ?>350 351 <div class="file-loop-thumbnail file-thumb-align<?php echo esc_attr($align_thumbnail); ?>">352 <?php353 354 if( $atts['show_thumbnail'] == true){355 356 if ($thumbnail_size != null){357 358 echo wp_kses_post( get_the_post_thumbnail($post->ID, $thumbnail_size) );359 360 }else{361 362 echo wp_kses_post( get_the_post_thumbnail() );363 364 }365 366 }367 ?>368 369 </div>370 371 <?php // Excerpt ?>372 373 <?php374 $excerpt_html = $this->accp_file_and_invoice_excerpt_html($file_post_id, $atts, $excerpt_length);375 376 echo wp_kses_post($excerpt_html);377 378 // Prepare list of term slugs - TODO: allow for categories to be displayed in the loop.379 $get_post_terms = get_the_terms($post->ID, 'accp_file_categories');380 381 if( $get_post_terms ){382 383 foreach ( $get_post_terms as $term) {384 385 $term_list_array[] = $term->slug;386 387 }388 389 }390 ?>391 392 <div class="accp-view-dl-link-container">393 394 <?php395 $file_dl_nonce = wp_create_nonce('file_download');396 $url_params = get_site_url() . '/?accp-dl-id=' . $file_post_id;397 ?>398 399 <?php if( $accp_file && $accp_file['url'] ): ?>400 401 <a href="<?php echo esc_url($accp_file['url']);?>" class="view-print accp-file-view-print" target="_blank">View and Print</a> <span class="accp-view-download-separator">|</span>402 403 <a href="<?php echo esc_url($url_params);?>" class="download accp-file-download" data-file-id="<?php echo esc_attr($file_post_id); ?>" data-nonce="<?php echo esc_attr($file_dl_nonce); ?>" target="_blank" download>Download</a>404 405 <?php endif; ?>406 407 </div>408 409 410 <?php411 /**412 * Hook - Allow content to be added to413 * the bottom of the file list item.414 *415 * @param $item_id - ID of the file post in the loop.416 */417 $item_id = $file_post_id;418 $bottom_item_content = do_action('accp_file_list_item_bottom_inside', $item_id);419 420 if($bottom_item_content){421 echo wp_kses_post($bottom_item_content);422 }423 ?>424 425 </div>426 <?php427 428 /**429 * Hook - Allow content to be added after430 * the file list item.431 *432 * @param $item_id - ID of the file post in the loop.433 */434 $item_id = $file_post_id;435 $after_item_content = do_action('accp_after_file_list_item', $item_id);436 437 if($after_item_content){438 echo wp_kses_post($after_item_content);439 }440 441 }442 443 endwhile;444 445 wp_reset_postdata();446 447 endif;448 449 /**450 * Hook - Allow content to be added after451 * the file list.452 *453 * @param $post_id - ID of the page that contains the client file shortcode.454 */455 $after_loop_content = do_action('accp_after_file_list', $post_id);456 457 if($after_loop_content){458 echo wp_kses_post($after_loop_content);459 }460 461 462 /**463 * Page Nav464 */465 $page_args = array(466 'format' => '?'.$paged_param.'=%#%',467 'current' => $paged,468 'total' => $query->max_num_pages,469 );470 471 if ( paginate_links( $page_args) ){472 473 ?>474 <div class="accp-page-nav-container" <?php echo ( $list_id != null ? 'data-accp-rel-list="' . esc_attr($list_id) . '"' : '' ); ?>>475 476 <?php477 echo wp_kses_post(paginate_links( $page_args ));478 ?>479 480 </div>481 <?php482 483 }484 485 /**486 * Hook - Allow content to be added after487 * the file list pagination element.488 *489 * This is added whether the the pagination element exists or not.490 *491 * @param $post_id - ID of the page that contains the client file shortcode.492 */493 $after_loop_pagination = do_action('accp_after_file_list_pagination', $post_id);494 495 if($after_loop_pagination){496 echo wp_kses_post($after_loop_pagination);497 }498 499 $html .= ob_get_clean();500 501 $html .= '</div>';502 503 return $html;504 }505 506 507 /**508 * Generate file query args.509 *510 * @param array $categories - array of category ID's.511 * @param int $number_of_posts - number of posts to show in the shortcode loop.512 * @param int $paged - the query args paged value.513 * @param string $order_by - the query args order_by value.514 * @param string $order - the query args order value.515 * @param int $authorized_company_id - post ID for the authorized company.516 * @param string $file_status - file status value.517 * @return array $args - array of args for the file query.518 */519 function accp_generate_file_query_args($categories, $number_of_posts, $paged, $order_by, $order, $authorized_company_id, $file_status){520 521 /**522 * Add a tax_query if the 'categories' att is not empty.523 */524 $tax_query = array();525 526 if(!empty($categories)){527 528 $tax_query[] = array(529 'taxonomy' => 'accp_file_categories',530 'field' => 'id',531 'terms' => $categories,532 );533 534 }535 536 $meta_query = array();537 538 /**539 * Add the file status to the meta_query540 * if it's not empty.541 */542 if(!empty($file_status)){543 544 $meta_query['relation'] = 'AND';545 546 $meta_query[] = array(547 'key' => 'file_status',548 'value' => $file_status549 );550 551 }552 553 $meta_query[] = array(554 'key' => 'accp_user',555 'value' => $authorized_company_id556 );557 558 $args = array(559 'post_type' => 'accp_clientfile',560 'posts_per_page' => $number_of_posts,561 'paged' => $paged,562 'orderby' => $order_by,563 'order' => $order,564 'meta_query' => $meta_query,565 'tax_query' => $tax_query,566 );567 568 return $args;569 570 }571 572 /**573 * Set up the core atts for the clientfile shortcode.574 *575 * @return array $atts_list_array - array of defined shortcode atts.576 */577 function accp_clientfile_core_shortcode_atts(){578 579 $atts_list_array = array(580 'id' => '', // Optional ID for the accp_documents_filelist list div. Defaults to null.581 'class' => '', // Optional additional class(es) for the accp_documents_filelist list div. Defaults to null.582 'categories' => '', // Category atts can be entered as the Slug or ID in the shortcode583 'file_status' => '', // File status to show - file status slug or null. Defaults to null.584 'display_number' => '', // This is the number of posts per page585 'order_by' => '', // This allows ordering by post title - default is post date - options "title" or "date"586 'order' => '', // This can be set as ASC or DESC - default is DESC587 'show_excerpt' => '', // Displays truncated text from the post content field588 'show_thumbnail' => '', // Displays the posts featured image in the loop589 'excerpt_length' => '', // Accepts the number of words for the excerpt590 'thumbnail_size' => '', // Enter the thumbnail slug defined in the theme591 'align_thumbnail' => '', // center, left, right, float-left, float-right592 'show_post_date' => '', // Display the post date - default is false593 'list_id' => '', // Integer - Useful when there are multiple shortcode lists on the same page - default is null594 'link_title' => '' // nolink or empty. Used to disable post link titles - default is null.595 );596 597 return $atts_list_array;598 599 }600 601 /* End client file list shortcode */602 603 604 /**605 * Set up Client Invoice List shortcode.606 *607 * Shortcode: [accp_clientinvoices]608 *609 * @param array $atts - array of atts passed in via the shortcode.610 * @return string $html - the shortcode result.611 */612 function accp_client_invoices( $atts, $content = null ) {613 614 /**615 * Exit if the user is not logged in616 * or if this is WP Admin.617 */618 if ( !is_user_logged_in() || is_admin() )619 return;620 621 global $post;622 623 $post_id = get_the_ID();624 $user = wp_get_current_user();625 $user_id = get_current_user_id();626 $roles_array = ( array ) $user->roles;627 $roles = array_map('strtolower', $roles_array);628 $list_instance = filter_var( $this->accp_generate_list_instance_id(), FILTER_SANITIZE_NUMBER_INT);629 $paged_param = 'paged' . $list_instance;630 $paged = isset( $_GET[$paged_param] ) ? (int)$_GET[$paged_param] : 1;631 632 $authorized_company_id = $this->get_client_page_authorized_company_id_by_user_id($user_id, $post_id);633 634 /**635 * Exit if the $authorized_company_id is false.636 */637 if( false === $authorized_company_id || !$authorized_company_id )638 return;639 640 $current_date = date('Y-m-d');641 642 643 /**644 * Set up the Basic Tier File List shortcode attributes.645 */646 $atts_list_array = $this->accp_clientinvoice_core_shortcode_atts();647 648 649 /**650 * Conditionally add Pro Tier shortcode attributes.651 */652 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' ){653 include dirname(__DIR__) . '/pro/public/accp-invoice-list-shortcode-atts.php';654 }655 656 657 /**658 * Output the shortcode attributes659 */660 $atts = shortcode_atts($atts_list_array, $atts);661 662 663 /**664 * List vars.665 */666 667 // Invoice Status668 if( $atts['invoice_status'] != null){669 670 $invoice_status = strtolower($atts['invoice_status']);671 672 }else{673 674 $invoice_status = 'unpaid';675 676 }677 678 // List ID679 $list_id = $this->accp_list_id_var($atts);680 681 // Category Filter682 $taxonomy = 'accp_invoice_categories';683 $categories = $this->accp_categories_var($atts, $taxonomy);684 685 // Posts per page686 $number_of_posts = $this->accp_number_of_posts_var($atts);687 688 // Order posts by689 $order_by = $this->accp_order_by_var($atts);690 691 // Post order692 $order = $this->accp_order_var($atts);693 694 // Exerpt length695 $excerpt_length = $this->accp_excerpt_length_var($atts);696 697 // Thumbnail size698 $thumbnail_size = $this->accp_thumbnail_size_var($atts);699 700 // Thumbnail alignment701 $align_thumbnail = $this->accp_align_thumbnail_var($atts) ? $this->accp_align_thumbnail_var($atts) : '';702 703 // Link title704 $link_title = '';705 706 if( isset($atts['link_title']) &&707 !empty($atts['link_title']) &&708 trim( strtolower($atts['link_title']) ) === 'nolink'709 ){710 711 $link_title = 'nolink';712 713 }714 715 // Container ID716 $container_id = '';717 718 if( isset($atts['id']) && !empty($atts['id']) ){719 720 $container_id = trim($atts['id']);721 $container_id = str_replace(' ', '', $container_id);722 723 }724 725 // Container Classes726 $container_classes = '';727 728 if( isset($atts['class']) && !empty($atts['class']) ){729 730 $container_classes = trim($atts['class']);731 732 }733 734 /**735 * Set up Pro Tier vars736 */737 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' || $this->plugin_name == 'ars-constellation-client-portal-premium' ){738 include dirname(__DIR__) . '/pro/public/ars-constellation-invoice-list-shortcode-vars.php';739 }740 741 742 /**743 * Hook - Allow content to be added before744 * the invoice list.745 *746 * @param $post_id - ID of the page that contains the client invoice shortcode.747 */748 $before_loop_content = do_action('accp_before_invoice_list', $post_id);749 750 if($before_loop_content){751 echo wp_kses_post($before_loop_content);752 }753 754 /**755 * Invoice List756 */757 ob_start();758 ?>759 760 <div <?php echo !empty($container_id) ? 'id="'. esc_attr($container_id).'"' : ''; ?> class="accp_documents_filelist <?php echo !empty($container_classes) ? esc_attr($container_classes) : ''; ?>" <?php echo ( $list_id != null ? ' data-accp-rel-list="' . esc_attr($list_id) . '"' : '' ); ?> data-list-id="<?php echo esc_attr($list_instance); ?>">761 <?php762 763 /**764 * Generate invoice query.765 */766 $args = $this->accp_generate_invoice_query_args($categories, $number_of_posts, $paged, $order_by, $order, $authorized_company_id, $invoice_status);767 $query = new WP_Query( $args );768 $html = '';769 770 if ($query->have_posts()):771 772 $invoice_id_list = array();773 774 while ( $query->have_posts()):775 776 $query->the_post();777 778 $accp_file = get_post_meta($post->ID, 'accp_file', true);779 $file_post_id = get_the_ID();780 $invoice_woo_product_id = get_post_meta($file_post_id, 'accp_woo_inv_id', true);781 782 /**783 * Only add the invoice post id to the list of payable invoices784 * if the post has a WooCommerce product ID saved to it.785 */786 if($invoice_woo_product_id){787 $invoice_id_list[] = $file_post_id;788 }789 790 791 /**792 * Get the Company ID associated with the file.793 */794 $file_post_company_id = get_post_meta($file_post_id, 'accp_user', true );795 796 797 /**798 * Check if pro access checks need to be instantiated.799 */800 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' ){801 802 $authorization = new ARS_Constellation_Client_Portal_Pro_Authorization( $this->plugin_name, $this->version );803 $check_authorization = $authorization->verify_page_or_post_authorization_pro($file_post_id, $user_id);804 805 }else{806 807 /**808 * Use the default file check if this is the Core version809 * to determine if access should be granted.810 */811 $authorization = new ARS_Constellation_Client_Portal_Core_Authorization( $this->plugin_name, $this->version );812 $check_authorization = $authorization->verify_page_or_post_authorization($file_post_id, $user_id);813 814 }815 816 if( $check_authorization === true ){817 818 /**819 * Hook - Allow content to be added before820 * the invoice list item.821 *822 * @param $item_id - ID of the invoice post in the loop.823 */824 $item_id = $file_post_id;825 $before_item_content = do_action('accp_before_invoice_list_item', $item_id);826 827 if($before_item_content){828 echo wp_kses_post($before_item_content);829 }830 831 ?>832 <div class="accp-item-container clearfix">833 834 <?php835 /**836 * Hook - Allow content to be added to837 * the top of the invoice list item.838 *839 * @param $item_id - ID of the invoice post in the loop.840 */841 $item_id = $file_post_id;842 $top_item_content = do_action('accp_invoice_list_item_top_inside', $item_id);843 844 if($top_item_content){845 echo wp_kses_post($top_item_content);846 }847 848 if($link_title !== 'nolink'):849 ?>850 851 <span class="accp-file-list-item-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></span>852 853 <?php854 else:855 ?>856 857 <span class="accp-file-list-item-title"><?php the_title(); ?></span>858 859 <?php860 endif;861 ?>862 863 <div class="accp-list-item-meta">864 865 <?php // Post Date ?>866 867 <?php868 if( $atts['show_post_date'] == true && $atts['show_post_date'] !== null){869 ?>870 <div class="accp-file-post-date">871 <?php echo esc_html(get_the_date()); ?>872 </div>873 <?php874 }875 ?>876 877 <?php // Pro - Due Date and Past Due Elements ?>878 <?php879 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' || $this->plugin_name == 'ars-constellation-client-portal-premium' ){880 include dirname(__DIR__) . '/pro/public/accp-invoice-list-shortcode-includes/accp-invoice-list-due-date-past-due.php';881 }882 ?>883 884 </div>885 886 <? // Thumbnail ?>887 <div class="file-loop-thumbnail file-thumb-align<?php echo esc_attr($align_thumbnail); ?>">888 <?php889 890 if( $atts['show_thumbnail'] == true){891 892 if ($thumbnail_size != null){893 894 echo wp_kses_post( get_the_post_thumbnail($post->ID, $thumbnail_size) );895 896 }else{897 898 echo wp_kses_post( get_the_post_thumbnail() );899 900 }901 902 }903 ?>904 905 </div>906 907 <?php // Excerpt ?>908 909 <?php910 $excerpt_html = $this->accp_file_and_invoice_excerpt_html($file_post_id, $atts, $excerpt_length);911 912 echo wp_kses_post($excerpt_html);913 914 /**915 * Display 'Invoice - Paid' if the invoice status is paid.916 */917 $saved_invoice_status = get_post_meta($post->ID, 'invoice_status', true);918 919 if($saved_invoice_status === 'paid'){920 921 ?>922 <span class="report-status">Paid</span>923 <?php924 925 }926 927 // Post Terms928 $get_post_terms = get_the_terms($post->ID, 'accp_invoice_categories');929 930 if($get_post_terms){931 932 foreach ( $get_post_terms as $term) {933 934 $term_list_array[] = $term->slug;935 936 }937 938 if($saved_invoice_status === 'paid'){939 940 /*941 ?>942 <span class="accp-post-terms">943 944 <ul><?php echo wp_kses_post( get_the_term_list( $post->ID, 'accp_invoice_categories', '<li>', ', ', '</li>' ) ); ?></ul>945 946 </span>947 <?php948 */949 950 }951 952 }953 ?>954 955 <div class="accp-view-dl-link-container">956 957 <?php958 $invoice_dl_nonce = wp_create_nonce('invoice_download');959 $url_params = get_site_url() . '/?accp-dl-id=' . $file_post_id;960 ?>961 962 <?php if($accp_file && $accp_file['url']): ?>963 964 <a href="<?php echo esc_url($accp_file['url']);?>" class="view-print" target="_blank">View and Print</a> <span class="accp-view-download-separator">|</span>965 966 <a href="<?php echo esc_url($url_params);?>" class="download accp-file-download" data-file-id="<?php echo esc_attr($file_post_id); ?>" data-nonce="<?php echo esc_attr($invoice_dl_nonce); ?>" target="_blank" download>Download</a>967 968 <?php endif; ?>969 970 </div>971 972 <?php // Pro - Pay Button Element ?>973 <?php974 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' || $this->plugin_name == 'ars-constellation-client-portal-premium' ){975 976 if($saved_invoice_status === 'unpaid'){977 include dirname(__DIR__) . '/pro/public/accp-invoice-list-shortcode-includes/accp-invoice-list-pay-button.php';978 }979 980 }981 ?>982 983 <?php984 /**985 * Hook - Allow content to be added to986 * the bottom of the invoice list item.987 *988 * @param $item_id - ID of the invoice post in the loop.989 */990 $item_id = $file_post_id;991 $bottom_item_content = do_action('accp_invoice_list_item_bottom_inside', $item_id);992 993 if($bottom_item_content){994 echo wp_kses_post($bottom_item_content);995 }996 ?>997 998 </div>999 <?php1000 1001 /**1002 * Hook - Allow content to be added after1003 * the invoice list item.1004 *1005 * @param $item_id - ID of the invoice post in the loop.1006 */1007 $item_id = $file_post_id;1008 $after_item_content = do_action('accp_after_invoice_list_item', $item_id);1009 1010 if($after_item_content){1011 echo wp_kses_post($after_item_content);1012 }1013 1014 }1015 1016 endwhile;1017 1018 // Pro - Pay-All Button Element1019 if ( $this->plugin_name == 'ars-constellation-client-portal-pro' || $this->plugin_name == 'ars-constellation-client-portal-premium' ){1020 include dirname(__DIR__) . '/pro/public/accp-invoice-list-shortcode-includes/accp-invoice-list-pay-all-button.php';1021 }1022 1023 wp_reset_postdata();1024 1025 endif;1026 1027 1028 /**1029 * Hook - Allow content to be added after1030 * the invoice list.1031 *1032 * @param $post_id - ID of the page that contains the client invoice shortcode.1033 */1034 $after_loop_content = do_action('accp_after_invoice_list', $post_id);1035 1036 if($after_loop_content){1037 echo wp_kses_post($after_loop_content);1038 }1039 1040 1041 /**1042 * Page Nav1043 */1044 $page_args1 = array(1045 'format' => '?'.$paged_param.'=%#%',1046 'current' => $paged,1047 'total' => $query->max_num_pages1048 );1049 1050 if ( paginate_links($page_args1) ){1051 1052 ?>1053 <div class="accp-page-nav-container" <?php echo ( $list_id != null ? 'data-accp-rel-list="' . esc_attr($list_id) . '"' : '' ); ?>>1054 1055 <?php1056 echo wp_kses_post(paginate_links( $page_args1 ));1057 ?>1058 1059 </div>1060 <?php1061 1062 }1063 1064 /**1065 * Hook - Allow content to be added after1066 * the invoice list pagination element.1067 *1068 * This is added whether the the pagination element exists or not.1069 *1070 * @param $post_id - ID of the page that contains the client file shortcode.1071 */1072 $after_loop_pagination = do_action('accp_after_invoice_list_pagination', $post_id);1073 1074 if($after_loop_pagination){1075 echo wp_kses_post($after_loop_pagination);1076 }1077 1078 $html .= ob_get_clean();1079 1080 $html .= '</div>';1081 1082 return $html;1083 1084 }1085 1086 1087 /**1088 * Get the authorized company ID for a given user.1089 *1090 * This ID is used for generating file and invoice1091 * post loops for the specified company(ID).1092 *1093 * @param int $user_id - The user ID of the respective user.1094 * @param int $post_id - The ID of the current Client Page.1095 *1096 * @return int|bool $authorized_company_id|false - The post ID of the company that the user has1097 * access to.1098 */1099 function get_client_page_authorized_company_id_by_user_id($user_id, $post_id){1100 1101 if( !$user_id || !$post_id)1102 return false;1103 1104 /**1105 * Get the primary Company ID associated with the current user.1106 */1107 $user_primary_company_id = get_user_meta( $user_id, 'client_company', true );1108 1109 /**1110 * Get additonal companies assigned to the user (if any).1111 */1112 $additional_assigned_companies = get_user_meta($user_id, 'client_additional_company', true);1113 1114 /**1115 * Check if this is a Client page set to global1116 * access before checking for a saved company.1117 *1118 * Only valid for Client Page post types,1119 * and not Client Files, Client Invoices, or1120 * direct file access.1121 */1122 $core_authorization = new ARS_Constellation_Client_Portal_Core_Authorization( $this->plugin_name, $this->version );1123 $is_global_page = $core_authorization->is_global_company_page($post_id);1124 1125 if( true === $is_global_page ){1126 1127 /**1128 * If this is a global page, verify that the current user1129 * only has a single company assigned, otherwise return false.1130 *1131 * Global pages are only suitable for users that have a single1132 * company assigned.1133 */1134 if( $user_primary_company_id && $additional_assigned_companies && !empty($additional_assigned_companies) )1135 return false;1136 1137 if( !$user_primary_company_id && $additional_assigned_companies && count($additional_assigned_companies) > 1 )1138 return false;1139 1140 /**1141 * Otherwise set the $authorized_company_id to the1142 * user primary company ID, or a single additonal company1143 * if the primary company is not set, and only a single1144 * additional company is set.1145 */1146 if($user_primary_company_id){1147 1148 $authorized_company_id = (int)$user_primary_company_id;1149 1150 return $authorized_company_id;1151 1152 }1153 1154 if( !empty($additional_assigned_companies) && is_array($additional_assigned_companies) && count($additional_assigned_companies) === 1 ){1155 1156 $authorized_company_id = (int)$additional_assigned_companies[0];1157 1158 return $authorized_company_id;1159 1160 }1161 1162 }1163 1164 1165 /**1166 * Get the Company id of the current page if1167 * this is not a global page.1168 */1169 $page_company_id = get_post_meta($post_id, 'accp_user', true);1170 1171 if(!$page_company_id)1172 return false;1173 1174 if ( $additional_assigned_companies && !empty($additional_assigned_companies) && in_array($page_company_id, $additional_assigned_companies) ){1175 1176 $additional_company_id = $page_company_id;1177 1178 }else{1179 1180 $additional_company_id = '';1181 $additional_assigned_companies = array();1182 1183 }1184 1185 if ( $additional_company_id && !empty($additional_company_id) ){1186 1187 $authorized_company_id = (int)$additional_company_id;1188 1189 }else{1190 1191 $authorized_company_id = $user_primary_company_id ? (int)$user_primary_company_id : false;1192 1193 }1194 1195 /**1196 * Admins have access to all companies, so just1197 * return the current Client Page ID as the authorized1198 * company ID if the current user is an admin.1199 */1200 if( current_user_can('manage_options') ){1201 1202 $authorized_company_id = $page_company_id;1203 $additional_assigned_companies = array();1204 1205 return $authorized_company_id;1206 1207 }1208 1209 return $authorized_company_id;1210 1211 }1212 1213 1214 /**1215 * Generate invoice query args.1216 *1217 * @param array $categories - array of category ID's.1218 * @param int $number_of_posts - number of posts to show in the shortcode loop.1219 * @param int $paged - the query args paged value.1220 * @param string $order_by - the query args order_by value.1221 * @param string $order - the query args order value.1222 * @param int $authorized_company_id - post ID for the authorized company.1223 * @param string $invoice_status - invoice status value.1224 * @return array $args - array of args for the invoice query.1225 */1226 function accp_generate_invoice_query_args($categories, $number_of_posts, $paged, $order_by, $order, $authorized_company_id, $invoice_status){1227 1228 /**1229 * Add a tax_query if the 'categories' att is not empty.1230 */1231 $tax_query = array();1232 1233 if(!empty($categories)){1234 1235 $tax_query[] = array(1236 'taxonomy' => 'accp_invoice_categories',1237 'field' => 'id',1238 'terms' => $categories,1239 );1240 1241 }1242 1243 $args = array(1244 'post_type' => 'accp_clientinvoice',1245 'posts_per_page' => $number_of_posts,1246 'paged' => $paged,1247 'orderby' => $order_by,1248 'order' => $order,1249 'meta_query' => array(1250 'relation' => 'AND',1251 array(1252 'key' => 'accp_user',1253 'value' => $authorized_company_id1254 ),1255 array(1256 'key' => 'invoice_status',1257 'value' => $invoice_status1258 )1259 ),1260 'tax_query' => $tax_query1261 );1262 1263 return $args;1264 1265 }1266 1267 1268 /**1269 * Set up the core atts for the clientinvoice shortcode.1270 *1271 * @return array $atts_list_array - array of defined shortcode atts.1272 */1273 function accp_clientinvoice_core_shortcode_atts(){1274 1275 $atts_list_array = array(1276 'id' => '', // Optional ID for the accp_documents_filelist list div. Defaults to null.1277 'class' => '', // Optional additional class(es) for the accp_documents_filelist list div. Defaults to null.1278 'categories' => '', // Category atts can be entered as the Slug or ID in the shortcode1279 'invoice_status' => '', // Invoice status to show - 'paid' or 'unpaid'. Defaults to 'unpaid.'1280 'display_number' => '', // This is the number of posts per page1281 'order_by' => '', // This allows ordering by post title - default is post date - options "title" or "date"1282 'order' => '', // This can be set as ASC or DESC - default is DESC1283 'show_excerpt' => '', // Displays truncated text from the post content field1284 'show_thumbnail' => '', // Displays the posts featured image in the loop1285 'excerpt_length' => '', // Accepts the number of words for the excerpt1286 'thumbnail_size' => '', // Enter the thumbnail slug defined in the theme1287 'align_thumbnail' => '', // center, left, right, float-left, float-right1288 'show_post_date' => '', // Display the post date - default is false1289 'list_id' => '', // Integer - Useful when there are multiple shortcode lists on the same page - default is null1290 'link_title' => '' // nolink or empty. Used to disable post link titles - default is null.1291 );1292 1293 return $atts_list_array;1294 1295 }1296 1297 /* End client invoice list shortcode */1298 75 1299 76 … … 1414 191 1415 192 1416 /**1417 * Generate excerpt html for File and Invoice shortcodes.1418 *1419 * @param int $file_post_id - the post ID of the file in the loop.1420 * @param array $atts - array of atts passed in via the shortcode.1421 * @param int $excerpt_length - value to use to constrain the exerpt length.1422 * @return string $html - the html for the excerpt element.1423 */1424 function accp_file_and_invoice_excerpt_html($file_post_id, $atts, $excerpt_length = null){1425 1426 if(!$file_post_id || !$atts) return;1427 1428 $excerpt = get_the_excerpt($file_post_id);1429 1430 if($excerpt){1431 1432 $html = '<div class="file-loop-description">';1433 1434 if( $atts['show_excerpt'] == true){1435 1436 if ($excerpt_length != null){1437 1438 $html .= wp_trim_words( wp_kses_post($excerpt), $excerpt_length, $more = '...' );1439 1440 }else{1441 1442 $html .= wp_kses_post($excerpt);1443 1444 }1445 1446 }1447 1448 $html .= '</div>';1449 1450 return $html;1451 1452 }1453 1454 return;1455 1456 }1457 1458 /**1459 * Set up the $list_id var.1460 *1461 * @param array $atts - array of atts passed in via the shortcode.1462 * @return int $list_id - integer.1463 */1464 function accp_list_id_var($atts){1465 1466 if(!$atts) return null;1467 1468 if( $atts['list_id'] != null){1469 1470 $list_id_input = (int)preg_replace('/[^0-9]/', '', $atts['list_id']);1471 1472 $list_id = filter_var($list_id_input, FILTER_SANITIZE_NUMBER_INT);1473 1474 }else{1475 1476 $list_id = null;1477 }1478 1479 return $list_id;1480 1481 }1482 1483 1484 /**1485 * Set up the $categories var.1486 *1487 * @param array $atts - array of atts passed in via the shortcode.1488 * @param string $taxonomy - either 'accp_file_categories' or 'accp_invoice_categories'.1489 * @return array $categories - array of category ID's.1490 */1491 function accp_categories_var($atts, $taxonomy){1492 1493 $categories = array();1494 1495 if( isset($atts['categories']) ){1496 1497 $categories_list = explode(',', trim($atts['categories']) );1498 $categories = array();1499 1500 foreach($categories_list as $category_item){1501 1502 $category_item = filter_var(trim($category_item), FILTER_SANITIZE_STRING);1503 1504 // We accept either a category ID or slug, so let's try1505 // to determine what has been entered.1506 if (!ctype_digit($category_item)) {1507 1508 // We assume this is a slug, get the term by the slug.1509 $category = get_term_by('slug', $category_item, $taxonomy);1510 1511 if($category){1512 1513 $categories[] = $category->term_id;1514 1515 }1516 1517 }else{1518 1519 $category = get_term_by('ID', (int)$category_item, $taxonomy);1520 1521 if($category){1522 1523 $categories[] = $category_item;1524 1525 }else{1526 1527 // Account for a category name/slug that is all numerical characters.1528 $category = get_term_by('slug', $category_item, $taxonomy);1529 1530 if($category){1531 1532 $categories[] = $category->term_id;1533 1534 }1535 1536 }1537 1538 1539 }1540 1541 }1542 1543 }1544 1545 return $categories;1546 1547 }1548 1549 1550 /**1551 * Set up $number_of_posts shortcode var.1552 *1553 * @param array $atts - array of atts passed in via the shortcode.1554 * @return int $number_of_posts - integer.1555 */1556 function accp_number_of_posts_var($atts){1557 1558 if ($atts['display_number'] != null){1559 1560 $att_input = preg_replace('/[^0-9]/', '', $atts['display_number']);1561 $number_of_posts = (int)$att_input;1562 1563 }else{1564 1565 $number_of_posts = 20;1566 1567 }1568 1569 return $number_of_posts;1570 1571 }1572 1573 1574 /**1575 * Set up $order_by shortcode var.1576 *1577 * @param array $atts - array of atts passed in via the shortcode.1578 * @return string $order_by - order_by value (ex. "date").1579 */1580 function accp_order_by_var($atts){1581 1582 if( $atts['order_by'] != null){1583 1584 $order_by = filter_var(trim($atts['order_by']), FILTER_SANITIZE_STRING);1585 1586 }else{1587 1588 $order_by = 'date';1589 1590 }1591 1592 return $order_by;1593 1594 }1595 1596 /**1597 * Set up $order shortcode var.1598 *1599 * @param array $atts - array of atts passed in via the shortcode.1600 * @return string $order - the order value (ASC or DESC).1601 */1602 function accp_order_var($atts){1603 1604 if( $atts['order'] != null){1605 1606 $order = filter_var(trim($atts['order']), FILTER_SANITIZE_STRING);1607 1608 }else{1609 1610 $order = 'DESC';1611 1612 }1613 1614 return $order;1615 1616 }1617 1618 1619 /**1620 * Set up $excerpt_length shortcode var.1621 *1622 * @param array $atts - array of atts passed in via the shortcode.1623 * @return int $excerpt_length - integer.1624 */1625 function accp_excerpt_length_var($atts){1626 1627 if($atts['excerpt_length'] != null){1628 1629 $att_input = preg_replace('/[^0-9]/', '', $atts['excerpt_length']);1630 1631 if(!empty($att_input) ){1632 1633 $excerpt_length = (int)$atts['excerpt_length'];1634 1635 }else{1636 1637 $excerpt_length = null;1638 1639 }1640 1641 }else{1642 1643 $excerpt_length = null;1644 1645 }1646 1647 return $excerpt_length;1648 1649 }1650 1651 /**1652 * Set up $thumbnail_size shortcode var.1653 *1654 * @param array $atts - array of atts passed in via the shortcode.1655 * @return string $thumbnail_size - the thumbnail slug.1656 */1657 function accp_thumbnail_size_var($atts){1658 1659 if($atts['thumbnail_size'] != null){1660 1661 $thumbnail_size = filter_var( trim($atts['thumbnail_size']), FILTER_SANITIZE_STRING);1662 1663 }else{1664 1665 $thumbnail_size = null;1666 1667 }1668 1669 return $thumbnail_size;1670 1671 }1672 1673 1674 /**1675 * Set up $align_thumbnail shortcode var.1676 *1677 * @param array $atts - array of atts passed in via the shortcode.1678 * @return string|false $align_thumbnail - the thumbnail CSS class suffix.1679 */1680 function accp_align_thumbnail_var($atts){1681 1682 if( !array_key_exists('align_thumbnail', $atts) )1683 return false;1684 1685 $att_input = trim( strtolower($atts['align_thumbnail']) );1686 1687 switch($att_input){1688 1689 case 'left':1690 $align_thumbnail = '-left';1691 break;1692 1693 case 'right':1694 $align_thumbnail = '-right';1695 break;1696 1697 case 'center':1698 $align_thumbnail = '-cetner';1699 break;1700 1701 case 'float-left':1702 $align_thumbnail = '-float-left';1703 break;1704 1705 case 'float-right':1706 $align_thumbnail = '-float-right';1707 break;1708 1709 default:1710 $align_thumbnail = false;1711 1712 }1713 1714 return $align_thumbnail;1715 1716 }1717 1718 1719 /**1720 * Generate a list instance ID by posting1721 * and incrementing a number that can be assigned1722 * to lists that are added to the page via file and1723 * invoice shortcodes.1724 *1725 * This allows for accurate pagination functionality1726 * when multiple lists are added to the same page, and1727 * can allow for better css and/or script targetting.1728 *1729 * @return int $list_instance_id - a unique number to be used1730 * for a file or invoice list.1731 */1732 function accp_generate_list_instance_id(){1733 1734 /**1735 * If $_POST['accp_list_count'] is not set,1736 * this should be the first (or only) list on the page,1737 * so let's set $_POST['accp_list_count'] to "1".1738 */1739 if( !isset($_POST['accp_list_count']) ){1740 1741 $_POST['accp_list_count'] = 1;1742 1743 }else{1744 1745 /**1746 * If we've gotten this far and $_POST['accp_list_count']1747 * is already set, There's more than one list on the page.1748 * So, let's increment $_POST['accp_list_count'] by 1 and1749 * use that for the current list's ID (and repeat until1750 * all lists on the page have a unique list ID). *1751 */1752 $_POST['accp_list_count'] = (int)$_POST['accp_list_count'] + 1;1753 1754 }1755 1756 $list_instance_id = filter_var( $_POST['accp_list_count'], FILTER_SANITIZE_NUMBER_INT );1757 1758 return $list_instance_id;1759 1760 }1761 1762 1763 193 } // END ARS_Constellation_Client_Portal_Public class
Note: See TracChangeset
for help on using the changeset viewer.