woothemes /
sensei
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
|
0 ignored issues
–
show
|
|||
| 2 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
||
| 3 | /** |
||
| 4 | * |
||
| 5 | * Renders the [sensei_unpurchased_courses] shortcode when a user is logged in. If the user is not logged in |
||
| 6 | * it will show all courses. |
||
| 7 | * This class is loaded int WP by the shortcode loader class. |
||
| 8 | * |
||
| 9 | * @class Sensei_Shortcode_Unpurchased_Courses |
||
| 10 | * |
||
| 11 | * @package Content |
||
| 12 | * @subpackage Shortcode |
||
| 13 | * @author Automattic |
||
| 14 | * |
||
| 15 | * @since 1.9.0 |
||
| 16 | */ |
||
| 17 | class Sensei_Shortcode_Unpurchased_Courses implements Sensei_Shortcode_Interface { |
||
| 18 | |||
| 19 | /** |
||
| 20 | * @var WP_Query to help setup the query needed by the render method. |
||
| 21 | */ |
||
| 22 | protected $query; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var string number of items to show on the current page |
||
| 26 | * Default: all. |
||
| 27 | */ |
||
| 28 | protected $number; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * @var string ordery by course field |
||
| 32 | * Default: date |
||
| 33 | */ |
||
| 34 | protected $orderby; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * @var string ASC or DESC |
||
| 38 | * Default: 'DESC' |
||
| 39 | */ |
||
| 40 | protected $order; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * Setup the shortcode object |
||
| 44 | * |
||
| 45 | * @since 1.9.0 |
||
| 46 | * @param array $attributes |
||
| 47 | * @param string $content |
||
| 48 | * @param string $shortcode the shortcode that was called for this instance |
||
| 49 | */ |
||
| 50 | public function __construct( $attributes, $content, $shortcode ){ |
||
| 51 | |||
| 52 | // set up all argument need for constructing the course query |
||
| 53 | $this->number = isset( $attributes['number'] ) ? $attributes['number'] : '10'; |
||
| 54 | $this->orderby = isset( $attributes['orderby'] ) ? $attributes['orderby'] : 'title'; |
||
| 55 | |||
| 56 | // set the default for menu_order to be ASC |
||
| 57 | if( 'menu_order' == $this->orderby && !isset( $attributes['order'] ) ){ |
||
| 58 | |||
| 59 | $this->order = 'ASC'; |
||
| 60 | |||
| 61 | }else{ |
||
| 62 | |||
| 63 | // for everything else use the value passed or the default DESC |
||
| 64 | $this->order = isset( $attributes['order'] ) ? $attributes['order'] : 'DESC'; |
||
| 65 | |||
| 66 | } |
||
| 67 | |||
| 68 | // setup the course query that will be used when rendering |
||
| 69 | $this->setup_course_query(); |
||
| 70 | } |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Sets up the object course query |
||
| 74 | * that will be used int he render method. |
||
| 75 | * |
||
| 76 | * @since 1.9.0 |
||
| 77 | */ |
||
| 78 | protected function setup_course_query(){ |
||
| 79 | |||
| 80 | |||
| 81 | // course query parameters to be used for all courses |
||
| 82 | $query_args = array( |
||
| 83 | 'post_type' => 'course', |
||
| 84 | 'post_status' => 'publish', |
||
| 85 | // the number specified by the user will be used later in this function |
||
| 86 | 'posts_per_page' => 1000, |
||
| 87 | 'orderby' => $this->orderby, |
||
| 88 | 'order' => $this->order |
||
| 89 | ); |
||
| 90 | |||
| 91 | // get all the courses that has a product attached |
||
| 92 | $all_courses_query = new WP_Query( $query_args ); |
||
| 93 | |||
| 94 | $paid_courses_not_taken = array(); |
||
| 95 | // look through all course and find the purchasable ones that user has not purchased |
||
| 96 | foreach( $all_courses_query->posts as $course ){ |
||
| 97 | |||
| 98 | // only keep the courses with a product including only courses that the user not taking |
||
| 99 | $course_product_id = get_post_meta( $course->ID, '_course_woocommerce_product',true ); |
||
| 100 | if( is_numeric( $course_product_id ) |
||
| 101 | && |
||
| 102 | ! Sensei_Utils::user_started_course( $course->ID , get_current_user_id() ) |
||
| 103 | ){ |
||
| 104 | |||
| 105 | $paid_courses_not_taken[] = $course->ID; |
||
| 106 | |||
| 107 | } |
||
| 108 | |||
| 109 | } // end foreach |
||
| 110 | |||
| 111 | // setup the course query again and only use the course the user has not purchased. |
||
| 112 | // this query will be loaded into the global WP_Query in the render function. |
||
| 113 | $query_args[ 'post__in' ] = $paid_courses_not_taken; |
||
| 114 | $query_args[ 'posts_per_page' ] = $this->number; |
||
| 115 | |||
| 116 | $this->query = new WP_Query( $query_args ); |
||
| 117 | |||
| 118 | }// end setup _course_query |
||
| 119 | |||
| 120 | /** |
||
| 121 | * Rendering the shortcode this class is responsible for. |
||
| 122 | * |
||
| 123 | * @return string $content |
||
| 124 | */ |
||
| 125 | public function render(){ |
||
| 126 | |||
| 127 | global $wp_query; |
||
| 128 | |||
| 129 | if ( ! is_user_logged_in() ) { |
||
| 130 | |||
| 131 | $anchor_before = '<a href="' . esc_url( sensei_user_login_url() ) . '" >'; |
||
| 132 | $anchor_after = '</a>'; |
||
| 133 | $notice = sprintf( |
||
| 134 | __('You must be logged in to view the non-purchased courses. Click here to %slogin%s.'), |
||
| 135 | $anchor_before, |
||
| 136 | $anchor_after |
||
| 137 | ); |
||
| 138 | |||
| 139 | Sensei()->notices->add_notice( $notice, 'info' ); |
||
| 140 | Sensei()->notices->maybe_print_notices(); |
||
| 141 | |||
| 142 | return ''; |
||
| 143 | |||
| 144 | } |
||
| 145 | |||
| 146 | // keep a reference to old query |
||
| 147 | $current_global_query = $wp_query; |
||
| 148 | // assign the query setup in $this-> setup_course_query |
||
| 149 | $wp_query = $this->query; |
||
| 150 | |||
| 151 | ob_start(); |
||
| 152 | Sensei()->notices->maybe_print_notices(); |
||
| 153 | Sensei_Templates::get_template('loop-course.php'); |
||
| 154 | $shortcode_output = ob_get_clean(); |
||
| 155 | |||
| 156 | //restore old query |
||
| 157 | $wp_query = $current_global_query; |
||
| 158 | |||
| 159 | return $shortcode_output; |
||
| 160 | |||
| 161 | }// end render |
||
| 162 | |||
| 163 | } |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.