List category posts - Version 0.83

Version Description

This is a big release since @zymeth25 and I have been doing lots of refactoring based on maintainability, code quality and testing. It means the code is much cleaner and easier to maintain. So fixing bugs or adding new features should be easier now. If you find any issues, please report them on GitHub (https://github.com/picandocodigo/List-Category-Posts/issues).

  • Development: We've refactored a lot of the code in include, updated the build, bumped versions, added tests, and more.
  • Bugfix: An issue where customfield_display_glue was shown even when the custom field values were empty - https://wordpress.org/support/topic/hide-the-glue-content-if-costum-fields-are-empty
  • Bugfix: Fixed excluded categories when using an and relationship.
  • New parameter: ol_offset, when you use an ordered list, you can set an offset so the posts will start from that number instead of 1.
  • Templates system refactor - The plugin now uses the template system by default. There should be no changes on how the plugin works, but please do let us know if you have any issues. Building templates should be easier now. You can use the included template as an example to start. It's in the plugin's template folder under the name default.php. Be warned, however, that this is the default template the plugin uses to create output so if you change it, you will change the plugin's default behavior. When you update the plugin this file will be overwritten so it's best not to edit it but copy it over to another file to create your custom template. More information on templates:
  • Pull Request: https://github.com/picandocodigo/List-Category-Posts/pull/411
  • Official docs: https://github.com/picandocodigo/List-Category-Posts/wiki/HTML-&-CSS-Customization#templates
Download this release

Release Info

Developer fernandobt
Plugin Icon 128x128 List category posts
Version 0.83
Comparing to
See all releases

Code changes from version 0.82 to 0.83

include/lcp-category.php CHANGED
@@ -15,49 +15,165 @@ class LcpCategory{
15
  return self::$instance;
16
  }
17
 
18
- /*
19
- * When the category is set using the `name` parameter.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  */
21
- public function with_name($name){
22
- $lcp_category_id = null;
23
- // AND relationship
24
- if ( preg_match('/\+/', $name) ){
25
- $categories = array();
26
- $cat_array = explode("+", $name);
27
-
28
- foreach ($cat_array as $category){
29
- $categories[] = $this->get_category_id_by_name($category);
30
- }
31
- $lcp_category_id = $categories;
32
- // OR relationship
33
- } elseif (preg_match('/,/', $name )){
34
- $categories = '';
35
- $cat_array = explode(",", $name);
36
-
37
- foreach ($cat_array as $category){
38
- $id = $this->get_category_id_by_name($category);
39
- $categories .= $id . ",";
 
 
 
40
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- $lcp_category_id = $categories;
 
 
 
 
 
 
 
43
  } else {
44
- $lcp_category_id = $this->get_category_id_by_name($name);
45
  }
46
- return $lcp_category_id;
47
  }
48
 
49
- public function with_id($id){
50
- if (preg_match('/\+/', $id)){
51
- if ( preg_match('/(-[0-9]+)+/', $id, $matches) ){
52
- $this->exclude = implode(',', explode("-", ltrim($matches[0], '-') ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
- $lcp_category_id = array_map( 'intval', explode( "+", $id ) );
55
- } else {
56
- $lcp_category_id = $id;
57
  }
58
- return $lcp_category_id;
 
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  public function current_category($mode){
62
  // Only single post pages with assigned category and
63
  // category archives have a 'current category',
@@ -93,18 +209,60 @@ class LcpCategory{
93
  return $category->cat_ID;
94
  }
95
 
 
96
  /**
97
- * Get the category id from its name
98
- * by Eric Celeste / http://eric.clst.org
 
 
 
 
99
  */
100
- private function get_category_id_by_name($cat_name){
101
- //TODO: Support multiple names (this used to work, but not anymore)
102
- //We check if the name gets the category id, if not, we check the slug.
103
- $term = get_term_by('slug', $cat_name, 'category');
104
- if (!$term){
105
- $term = get_term_by('name', $cat_name, 'category');
106
  }
107
  return ($term) ? $term->term_id : 0;
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  }
15
  return self::$instance;
16
  }
17
 
18
+ /**
19
+ * Parses category related shortcode parameters and returns
20
+ * WP_Query compatible $args array. Also sets $lcp_category_id.
21
+ *
22
+ * This method is the main interface of the LcpCategory class. It
23
+ * is currently only used by the CatList class and servers as its helper.
24
+ * $params expects all category related shortcode parameters.
25
+ * $lcp_category_id is **passed by reference** so that it can be
26
+ * changed here. CatList::$lcp_category_id relies on this value heavily.
27
+ *
28
+ * @param array $params {
29
+ * Category related shortcode parameter values.
30
+ *
31
+ * @type string $id
32
+ * @type string $name
33
+ * @type string $categorypage
34
+ * @type string $child_categories
35
+ * }
36
+ * @param mixed &$lcp_category_id Optional. Updated by this method if necessary.
37
+ * @return array WP_Query $args array, @see lcp_categories.
38
  */
39
+ public function get_lcp_category($params, &$lcp_category_id=0) {
40
+ // Only used when excluded categories are combined with 'and' relationship.
41
+ $exclude = [];
42
+ // This will be the value of lcp_category_id which is passed by reference.
43
+ $categories = $lcp_category_id;
44
+
45
+ // In a category page:
46
+ if ($params['categorypage'] &&
47
+ in_array($params['categorypage'], ['yes', 'all', 'other']) ||
48
+ $params['id'] == -1) {
49
+ // Use current category
50
+ $categories = $this->current_category($params['categorypage']);
51
+ } elseif ($params['name']) {
52
+ // Using the category name:
53
+ $categories = $this->with_name($params['name']);
54
+ } elseif ($params['id']) {
55
+ // Using the id:
56
+ $categories = $this->with_id($params['id']);
57
+ // If the 'exclude' array was added, excract it.
58
+ if (is_array($categories) && array_key_exists('exclude', $categories)) {
59
+ $exclude = $categories['exclude'];
60
+ unset($categories['exclude']);
61
  }
62
+ }
63
+
64
+ // This is where the lcp_category_id property of CatList is changed.
65
+ $lcp_category_id = $categories;
66
+
67
+ return $this->lcp_categories(
68
+ $categories, $params['child_categories'], $exclude);
69
+ }
70
+
71
+ /**
72
+ * Formats the $args array in compliance with WP_Query.
73
+ *
74
+ * This method assigns input category IDs to proper WP_Query $args array.
75
+ * $categories expects an int, string or an array following the logic:
76
+ * - int -> single category
77
+ * - array -> 'and' relationship
78
+ * - string -> 'or' relationship (or single cateogry as a string)
79
+ *
80
+ * $child_categories is the value of `child_categories` shortcode param.
81
+ * $exclude is only used when combining 'and' relationship with excluded IDs.
82
+ *
83
+ * @param int|string|array $categories Category IDs.
84
+ * @param string $child_categories 'no' or 'false' disables child cats.
85
+ * @param array $exclude Accepts an array of IDs.
86
+ * @return array WP_Query $args array.
87
+ */
88
+ private function lcp_categories($categories, $child_categories, $exclude) {
89
+ $args = array();
90
 
91
+ if (is_array($categories)) {
92
+ // Handle excluded categories for the 'and' relationship.
93
+ if ($exclude) {
94
+ $args['category__not_in'] = $exclude;
95
+ }
96
+ $args['category__and'] = $categories;
97
+ } else if (in_array($child_categories, ['no', 'false'])) {
98
+ $args['category__in']= $categories;
99
  } else {
100
+ $args['cat'] = $categories;
101
  }
102
+ return $args;
103
  }
104
 
105
+ /**
106
+ * Used when the category is set using the `name` shortcode parameter.
107
+ *
108
+ * This method returns a category ID when a single category is specified,
109
+ * a string containing comma separated category IDs when using the 'or'
110
+ * relationship, an array of category IDs when using the 'and' relationship.
111
+ *
112
+ * If $name does not resolve to an existing name or slug, `0` will be returned.
113
+ * Similarly, the returned comma separated string or an array will have `0`
114
+ * for any name/slug that could not be found.
115
+ *
116
+ * @param string $name Accepts valid `name` shortcode parameter values.
117
+ * @return int|string|array Int for single category, string for 'or' relationsip,
118
+ * array for 'and' relationship.
119
+ */
120
+ public function with_name($name) {
121
+ if (false !== strpos($name, '+')) { // AND relationship
122
+ return $this->and_relationship($name);
123
+ } elseif (false !== strpos($name, ',')) { // OR relationship
124
+ return $this->or_relationship($name);
125
+ }
126
+ return $this->get_category_id_by_name($name);
127
+ }
128
+
129
+ /**
130
+ * Used when the category is set using the `id` shortcode parameter.
131
+ *
132
+ * Accepts all valid `id` parameter values. If $cat_id is a single category
133
+ * ID or comma separated IDs (for the 'or' relationship), this method does not
134
+ * perfom any parsing and returns the string as is. If the 'and' relationship
135
+ * is used (eg. `id=1+2+3`), returns an array of IDs. If the 'and' relationship is
136
+ * used together with excluded categories (`id=1+2-3-4`), returns an array of
137
+ * included IDs that also contains the 'exclude' key that is an array of excluded
138
+ * IDs.
139
+ *
140
+ * @param string $name Accepts valid `id` shortcode parameter values.
141
+ * @return string|array Array of IDs for 'and' relationship, string otherwise.
142
+ */
143
+ public function with_id($cat_id) {
144
+ if (false !== strpos($cat_id, '+')) {
145
+ if (false !== strpos($cat_id, '-')) {
146
+ /*
147
+ * If the 'and' relationship is used together with excluded
148
+ * categories (eg. 1+2+3-4-5) we parse it with regex and append an
149
+ * array of excluded IDs to the returned array.
150
+ */
151
+ preg_match('/(?P<in>(\+?[0-9]+)+)(?P<ex>(-[0-9]+)+)/', $cat_id, $matches);
152
+
153
+ $cat_id = array_map('intval', explode("+", $matches['in']));
154
+ $cat_id['exclude'] = explode('-', ltrim($matches['ex'], '-'));
155
+ } else {
156
+ // Simple 'and' relationship, just convert input into an array.
157
+ $cat_id = array_map('intval', explode("+", $cat_id));
158
  }
 
 
 
159
  }
160
+ // In all other cases leave user input as is.
161
+ return $cat_id;
162
  }
163
 
164
+ /**
165
+ * Handles the `categorypage` shortcode parameter with all its modes.
166
+ *
167
+ * This method accepts all valid `categorypage` shortcode parameters.
168
+ * Also accepts an empty string for compatibility with the widget.
169
+ * Returns a single category ID when used on category archive page,
170
+ * a comma separated string of IDs for the 'or' relationship,
171
+ * an array of IDs for the 'and' relationship. When no posts should be
172
+ * displayed it returns `[0]`.
173
+ *
174
+ * @param string $mode Accepts 'all', 'yes', 'other' and empty string.
175
+ * @return int|string|array Category ID(s).
176
+ */
177
  public function current_category($mode){
178
  // Only single post pages with assigned category and
179
  // category archives have a 'current category',
209
  return $category->cat_ID;
210
  }
211
 
212
+
213
  /**
214
+ * Gets the category id from its name.
215
+ *
216
+ * @author Eric Celeste / http://eric.clst.org
217
+ *
218
+ * @param string $category_name Accepts category name or slug.
219
+ * @return int Category ID or 0 if none found.
220
  */
221
+ private function get_category_id_by_name($category_name) {
222
+ //We check if the slug gets the category id, if not, we check the name.
223
+ $term = get_term_by('slug', $category_name, 'category');
224
+ if (!$term) {
225
+ $term = get_term_by('name', $category_name, 'category');
 
226
  }
227
  return ($term) ? $term->term_id : 0;
228
  }
229
 
230
+ /**
231
+ * Handles 'and' relationship when categories are specified by name.
232
+ *
233
+ * Parses the input string and returns an array of corresponding
234
+ * category IDs.
235
+ *
236
+ * @param string $name Accepts category names or slugs separated by the '+' sign.
237
+ * @return array Category IDs.
238
+ */
239
+ private function and_relationship($name) {
240
+ $categories = array();
241
+ $cat_array = explode("+", $name);
242
+
243
+ foreach ($cat_array as $category) {
244
+ $categories[] = $this->get_category_id_by_name($category);
245
+ }
246
+ return $categories;
247
+ }
248
+
249
+ /**
250
+ * Handles 'or' relationship when categories are specified by name.
251
+ *
252
+ * Parses the input string and returns comma separated
253
+ * category IDs.
254
+ *
255
+ * @param string $name Accepts category names or slugs separated by the ',' sign.
256
+ * @return string Comma separated category IDs.
257
+ */
258
+ private function or_relationship($name) {
259
+ $categories = array();
260
+ $catArray = explode(",", $name);
261
+
262
+ foreach ($catArray as $category) {
263
+ $categories[] = $this->get_category_id_by_name($category);
264
+ }
265
+
266
+ return implode(',',$categories);
267
+ }
268
  }
include/lcp-catlist.php CHANGED
@@ -14,7 +14,6 @@ require_once ( LCP_PATH . 'lcp-paginator.php' );
14
  class CatList{
15
  private $params = array();
16
  private $lcp_category_id = 0;
17
- private $exclude;
18
  private $page = 1;
19
  private $posts_count = 0;
20
  private $instance = 0;
@@ -42,7 +41,6 @@ class CatList{
42
  * Determine the categories of posts and execute the WP_query
43
  */
44
  public function get_posts() {
45
- $this->get_lcp_category();
46
  $this->set_lcp_parameters();
47
  }
48
 
@@ -74,7 +72,12 @@ class CatList{
74
  * Order the parameters and query the DB for posts
75
  */
76
  private function set_lcp_parameters(){
77
- $args = $this->lcp_categories();
 
 
 
 
 
78
  $processed_params = LcpParameters::get_instance()->get_query_params($this->params);
79
  $args = array_merge($args, $processed_params);
80
  $args = $this->check_pagination($args);
@@ -114,43 +117,6 @@ class CatList{
114
  return $args;
115
  }
116
 
117
- /**
118
- * Check if there's one or more categories.
119
- * Used in the beginning when setting up the parameters.
120
- */
121
- private function lcp_categories(){
122
- if ( is_array($this->lcp_category_id) ){
123
- return array('category__and' => $this->lcp_category_id);
124
- } else {
125
- if($this->utils->lcp_not_empty('child_categories') &&
126
- (($this->params['child_categories'] === 'no' ) ||
127
- ($this->params['child_categories'] === 'false') )){
128
- return array('category__in'=> $this->lcp_category_id);
129
- }
130
- return array('cat'=> $this->lcp_category_id);
131
- }
132
- }
133
-
134
- private function get_lcp_category(){
135
- // In a category page:
136
- if ( $this->utils->lcp_not_empty('categorypage') &&
137
- in_array($this->params['categorypage'], ['yes', 'all', 'other']) ||
138
- $this->params['id'] == -1){
139
- // Use current category
140
- $this->lcp_category_id = LcpCategory::get_instance()->current_category(
141
- $this->params['categorypage']
142
- );
143
- } elseif ( $this->utils->lcp_not_empty('name') ){
144
- // Using the category name:
145
- $this->lcp_category_id = LcpCategory::get_instance()->with_name( $this->params['name'] );
146
- $this->params['name'] = null;
147
- } elseif ( isset($this->params['id']) && $this->params['id'] != '0' ){
148
- // Using the id:
149
- $this->lcp_category_id = LcpCategory::get_instance()->with_id( $this->params['id'] );
150
- }
151
-
152
- }
153
-
154
  public function get_category_id(){
155
  return $this->lcp_category_id;
156
  }
@@ -218,7 +184,17 @@ class CatList{
218
  endif;
219
  }
220
 
221
-
 
 
 
 
 
 
 
 
 
 
222
 
223
  public function get_category_count(){
224
  if($this->utils->lcp_not_empty('category_count') && $this->params['category_count'] == 'yes'):
@@ -257,17 +233,26 @@ class CatList{
257
  $custom_fields = get_post_custom( $post_id );
258
 
259
  //Loop on custom fields and if there's a value, add it:
260
- foreach ( $custom_array as $user_customfield ) :
261
  // Check that the custom field is wanted:
262
- if ( isset( $custom_fields[$user_customfield] ) ) :
263
  //Browse through the custom field values:
264
- foreach ( $custom_fields[$user_customfield] as $key => $value ) :
265
- if ( $this->params['customfield_display_name'] != 'no' )
266
  $value = $user_customfield . $this->params['customfield_display_name_glue'] . $value;
267
- $lcp_customs[] = $value;
268
- endforeach;
269
- endif;
270
- endforeach;
 
 
 
 
 
 
 
 
 
271
 
272
  return $lcp_customs;
273
  else:
@@ -307,6 +292,11 @@ class CatList{
307
  return $this->page;
308
  }
309
 
 
 
 
 
 
310
  public function get_posts_count(){
311
  return $this->posts_count;
312
  }
@@ -322,7 +312,7 @@ class CatList{
322
  public function get_date_to_show($single){
323
  if ($this->params['date'] == 'yes'):
324
  //by Verex, great idea!
325
- return get_the_time($this->params['dateformat'], $single);
326
  else:
327
  return null;
328
  endif;
@@ -330,12 +320,25 @@ class CatList{
330
 
331
  public function get_modified_date_to_show($single){
332
  if ($this->params['date_modified'] == 'yes'):
333
- return get_the_modified_time($this->params['dateformat'], $single);
334
  else:
335
  return null;
336
  endif;
337
  }
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  public function get_content($single){
340
  if (isset($this->params['content']) &&
341
  ($this->params['content'] =='yes' || $this->params['content'] == 'full') &&
@@ -428,6 +431,52 @@ class CatList{
428
  $lcp_thumb_class);
429
  }
430
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  public function get_pagination(){
432
  $paginator_params = array(
433
  'bookmarks' => $this->params['pagination_bookmarks'],
14
  class CatList{
15
  private $params = array();
16
  private $lcp_category_id = 0;
 
17
  private $page = 1;
18
  private $posts_count = 0;
19
  private $instance = 0;
41
  * Determine the categories of posts and execute the WP_query
42
  */
43
  public function get_posts() {
 
44
  $this->set_lcp_parameters();
45
  }
46
 
72
  * Order the parameters and query the DB for posts
73
  */
74
  private function set_lcp_parameters(){
75
+ $args = LcpCategory::get_instance()->get_lcp_category([
76
+ 'id' => $this->params['id'],
77
+ 'name' => $this->params['name'],
78
+ 'categorypage' => $this->params['categorypage'],
79
+ 'child_categories' => $this->params['child_categories'],
80
+ ], $this->lcp_category_id);
81
  $processed_params = LcpParameters::get_instance()->get_query_params($this->params);
82
  $args = array_merge($args, $processed_params);
83
  $args = $this->check_pagination($args);
117
  return $args;
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  public function get_category_id(){
121
  return $this->lcp_category_id;
122
  }
184
  endif;
185
  }
186
 
187
+ public function get_posts_morelink($single, $css_class) {
188
+ if(!empty($this->params['posts_morelink'])){
189
+ $href = 'href="' . get_permalink($single->ID) . '"';
190
+ $class = $css_class ?: "";
191
+ if ( $class ):
192
+ $class = 'class="' . $class . '" ';
193
+ endif;
194
+ $readmore = $this->params['posts_morelink'];
195
+ return ' <a ' . $href . ' ' . $class . ' >' . $readmore . '</a>';
196
+ }
197
+ }
198
 
199
  public function get_category_count(){
200
  if($this->utils->lcp_not_empty('category_count') && $this->params['category_count'] == 'yes'):
233
  $custom_fields = get_post_custom( $post_id );
234
 
235
  //Loop on custom fields and if there's a value, add it:
236
+ foreach ( $custom_array as $user_customfield ) {
237
  // Check that the custom field is wanted:
238
+ if ( isset( $custom_fields[$user_customfield] )) {
239
  //Browse through the custom field values:
240
+ foreach ( $custom_fields[$user_customfield] as $key => $value ) {
241
+ if ( $this->params['customfield_display_name'] != 'no' && $value !== '' ){
242
  $value = $user_customfield . $this->params['customfield_display_name_glue'] . $value;
243
+ }
244
+ if($value != ''){
245
+ $lcp_customs[] = $value;
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ // Return a string instead of array if custom fields
252
+ // are not displayed separately.
253
+ if ($this->params['customfield_display_separately'] === 'no') {
254
+ $lcp_customs = implode($this->params['customfield_display_glue'], $lcp_customs);
255
+ }
256
 
257
  return $lcp_customs;
258
  else:
292
  return $this->page;
293
  }
294
 
295
+ // Helper method for tests.
296
+ public function update_page($page) {
297
+ $this->page = $page;
298
+ }
299
+
300
  public function get_posts_count(){
301
  return $this->posts_count;
302
  }
312
  public function get_date_to_show($single){
313
  if ($this->params['date'] == 'yes'):
314
  //by Verex, great idea!
315
+ return ' ' . get_the_time($this->params['dateformat'], $single);
316
  else:
317
  return null;
318
  endif;
320
 
321
  public function get_modified_date_to_show($single){
322
  if ($this->params['date_modified'] == 'yes'):
323
+ return " " . get_the_modified_time($this->params['dateformat'], $single);
324
  else:
325
  return null;
326
  endif;
327
  }
328
 
329
+ public function get_display_id($single) {
330
+ if (!empty($this->params['display_id']) && $this->params['display_id'] == 'yes'){
331
+ $lcp_display_output .= $single->ID;
332
+ }
333
+ }
334
+
335
+ public function get_no_posts_text() {
336
+ if ( ($this->get_posts_count() == 0) &&
337
+ ($this->params["no_posts_text"] != '') ) {
338
+ return $this->params["no_posts_text"];
339
+ }
340
+ }
341
+
342
  public function get_content($single){
343
  if (isset($this->params['content']) &&
344
  ($this->params['content'] =='yes' || $this->params['content'] == 'full') &&
431
  $lcp_thumb_class);
432
  }
433
 
434
+ public function get_outer_tag($tag, $css_class) {
435
+ $css_class = $this->params['class'] ?: $css_class;
436
+
437
+ $tag_string = '<' . $tag;
438
+ if ($tag == 'ol' && !empty($this->params['ol_offset'])) {
439
+ $tag_string .= ' start="' . $this->params['ol_offset'] . '"';
440
+ }
441
+
442
+ // Follow the number of posts in an ordered list with pagination.
443
+ if( 'ol' === $tag && $this->page > 1 ) {
444
+ $start = $this->get_number_posts() * ( $this->page - 1 ) + 1;
445
+ $tag_string .= ' start="' . $start . '"';
446
+ }
447
+ //Give a class to wrapper tag
448
+ $tag_string .= ' class="' . $css_class . '"';
449
+
450
+ //Give id to wrapper tag
451
+ $tag_string .= ' id="lcp_instance_' . $this->instance . '"';
452
+
453
+ $tag_string .= '>';
454
+
455
+ return $tag_string;
456
+ }
457
+
458
+ public function get_inner_tag( $single, $parent, $tag, $css_class='' ) {
459
+ $class = $css_class;
460
+ $tag_css = '';
461
+ if ( is_object( $parent ) && is_object( $single ) &&
462
+ $parent->ID === $single->ID ) {
463
+ $class .= 'current';
464
+ }
465
+
466
+ if ( $this->params['tags_as_class'] === 'yes' ) {
467
+ $post_tags = wp_get_post_Tags( $single->ID );
468
+ if ( !empty( $post_tags ) ) {
469
+ foreach ( $post_tags as $post_tag ) {
470
+ $class .= " $post_tag->slug ";
471
+ }
472
+ }
473
+ }
474
+ if ( !empty($class) ) {
475
+ $tag_css = 'class="' . $class . '"';
476
+ }
477
+ return '<'. $tag . ' ' . $tag_css . '>';
478
+ }
479
+
480
  public function get_pagination(){
481
  $paginator_params = array(
482
  'bookmarks' => $this->params['pagination_bookmarks'],
include/lcp-catlistdisplayer.php CHANGED
@@ -5,279 +5,97 @@
5
  * @author fernando@picandocodigo.net
6
  */
7
  require_once 'lcp-catlist.php';
 
 
8
 
9
  class CatListDisplayer {
10
  public $catlist;
 
 
11
  private $params = array();
12
  private $lcp_output;
13
 
14
- public static function getTemplatePaths(){
15
- $template_path = TEMPLATEPATH . "/list-category-posts/";
16
- $stylesheet_path = STYLESHEETPATH . "/list-category-posts/";
17
- return array($template_path, $stylesheet_path);
18
- }
19
-
20
  public function __construct($atts) {
21
  $this->params = $atts;
22
  $this->catlist = new CatList($atts);
 
23
  global $post;
24
  $this->parent = $post;
 
25
  }
26
 
27
  public function display(){
28
  $this->catlist->save_wp_query();
29
  $this->catlist->get_posts();
30
- $this->select_template();
31
  $this->catlist->restore_wp_query();
32
  wp_reset_query();
33
  return $this->lcp_output;
34
  }
35
 
36
- private function select_template(){
37
- // Check if we got a template param:
38
- if (isset($this->params['template']) &&
39
- !empty($this->params['template'])){
40
- // The default values for ul, ol and div:
41
- if (preg_match('/^ul$|^div$|^ol$/i', $this->params['template'], $matches)){
42
- $this->build_output($matches[0]);
43
- } else {
44
- // Else try an actual template from the params
45
- $this->template();
46
- }
47
- } else {
48
- // Default:
49
- $this->build_output('ul');
50
- }
51
  }
52
 
53
  /**
54
- * Template code
55
  */
56
- private function template(){
57
- $tplFileName = null;
58
- $template_param = $this->params['template'];
59
- $templates = array();
60
-
61
- // Get templates paths and add the incoming parameter to search
62
- // for the php file:
63
- if($template_param){
64
- $paths = self::getTemplatePaths();
65
- foreach($paths as $path){
66
- $templates[] = $path . $template_param . '.php';
67
- }
68
- }
69
 
70
- // Check if we can read the template file:
71
- foreach ($templates as $file) :
72
- if ( is_file($file) && is_readable($file) ) :
73
- $tplFileName = $file;
74
- endif;
75
- endforeach;
76
 
77
- if($tplFileName){
78
- require($tplFileName);
79
- } else {
80
- $this->build_output('ul');
81
- }
82
  }
83
 
84
- public static function get_templates($param = null){
85
- $templates = array();
86
- $paths = self::getTemplatePaths();
87
- foreach ($paths as $templatePath){
88
- if (is_dir($templatePath) && scandir($templatePath)){
89
- foreach (scandir($templatePath) as $file){
90
- // Check that the files found are well formed
91
- if ( ($file[0] != '.') && (substr($file, -4) == '.php') &&
92
- is_file($templatePath.$file) && is_readable($templatePath.$file) ){
93
- $templateName = substr($file, 0, strlen($file)-4);
94
- // Add the template only if necessary
95
- if (!in_array($templateName, $templates)){
96
- $templates[] = $templateName;
97
- }
98
- }
99
- }
100
- }
101
- }
102
- return $templates;
103
  }
104
 
105
- private function build_output($tag){
106
- $this->category_title();
107
-
108
- $this->get_category_description();
109
-
110
- $this->lcp_output .= $this->get_conditional_title();
111
-
112
- $this->lcp_output .= '<' . $tag;
113
-
114
- // Follow the numner of posts in an ordered list with pagination
115
- if( $tag == 'ol' && $this->catlist->get_page() > 1 ){
116
- $start = $this->catlist->get_number_posts() * ($this->catlist->get_page() - 1) + 1;
117
- $this->lcp_output .= ' start="' . $start . '" ';
118
- }
119
- //Give a class to wrapper tag
120
- if (isset($this->params['class'])):
121
- $this->lcp_output .= ' class="' . $this->params['class'] . '"';
122
- endif;
123
-
124
- //Give id to wrapper tag
125
- if (isset($this->params['instance'])){
126
- $this->lcp_output .= ' id="lcp_instance_' . $this->params['instance'] . '"';
127
- }
128
-
129
- $this->lcp_output .= '>';
130
- $inner_tag = ( ($tag == 'ul') || ($tag == 'ol') ) ? 'li' : 'p';
131
-
132
- //Posts loop
133
- global $post;
134
- while ( have_posts() ) : the_post();
135
- if ( !post_password_required($post) ||
136
- ( post_password_required($post) && (
137
- isset($this->params['show_protected']) &&
138
- $this->params['show_protected'] == 'yes' ) )):
139
- $this->lcp_output .= $this->lcp_build_post($post, $inner_tag);
140
- endif;
141
- endwhile;
142
-
143
- if ( ($this->catlist->get_posts_count() == 0) &&
144
- ($this->params["no_posts_text"] != '') ) {
145
- $this->lcp_output .= $this->params["no_posts_text"];
146
- }
147
-
148
- //Close wrapper tag
149
- $this->lcp_output .= '</' . $tag . '>';
150
-
151
- // More link
152
- $this->lcp_output .= $this->get_morelink();
153
-
154
- $this->lcp_output .= $this->catlist->get_pagination();
155
  }
156
 
157
- /**
158
- * This function should be overriden for template system.
159
- * @param post $single
160
- * @param HTML tag to display $tag
161
- * @return string
162
- */
163
- private function lcp_build_post($single, $tag){
164
- $class ='';
165
- $tag_css = '';
166
- if ( is_object($this->parent) && is_object($single) && $this->parent->ID == $single->ID ){
167
- $class = 'current';
168
- }
169
-
170
- if ( array_key_exists('tags_as_class', $this->params) && $this->params['tags_as_class'] == 'yes' ) {
171
- $post_tags = wp_get_post_Tags($single->ID);
172
- if ( !empty($post_tags) ){
173
- foreach ($post_tags as $post_tag) {
174
- $class .= " $post_tag->slug ";
175
- }
176
- }
177
- }
178
- if ( !empty($class) ){
179
- $tag_css = 'class="' . $class . '"';
180
- }
181
- $lcp_display_output = '<'. $tag . ' ' . $tag_css . '>';
182
-
183
- if ( empty($this->params['no_post_titles']) || !empty($this->params['no_post_titles']) && $this->params['no_post_titles'] !== 'yes' ) {
184
- $lcp_display_output .= $this->get_post_title($single);
185
- }
186
-
187
- // Comments count
188
- $lcp_display_output .= $this->get_stuff_with_tags_and_classes('comments', $single);
189
-
190
- // Date
191
- if (!empty($this->params['date_tag']) || !empty($this->params['date_class'])):
192
- $lcp_display_output .= $this->get_date($single,
193
- $this->params['date_tag'],
194
- $this->params['date_class']);
195
- else:
196
- $lcp_display_output .= $this->get_date($single);
197
- endif;
198
-
199
- // Date Modified
200
- if (!empty($this->params['date_modified_tag']) || !empty($this->params['date_modified_class'])):
201
- $lcp_display_output .= $this->get_modified_date($single,
202
- $this->params['date_modified_tag'],
203
- $this->params['date_modified_class']);
204
- else:
205
- $lcp_display_output .= $this->get_modified_date($single);
206
- endif;
207
-
208
- // Author
209
- $lcp_display_output .= $this->get_stuff_with_tags_and_classes('author', $single);
210
-
211
- // Display ID
212
- if (!empty($this->params['display_id']) && $this->params['display_id'] == 'yes'){
213
- $lcp_display_output .= $single->ID;
214
- }
215
-
216
- // Custom field display
217
- $lcp_display_output .= $this->get_custom_fields($single);
218
-
219
- $lcp_display_output .= $this->get_thumbnail($single);
220
 
221
- $lcp_display_output .= $this->get_stuff_with_tags_and_classes('content', $single);
 
 
222
 
223
- $lcp_display_output .= $this->get_stuff_with_tags_and_classes('excerpt', $single);
 
 
224
 
225
- $lcp_display_output .= $this->get_posts_morelink($single);
 
 
226
 
227
- $lcp_display_output .= '</' . $tag . '>';
228
- return $lcp_display_output;
229
  }
230
 
231
- /**
232
- * Several checks going on here:
233
- * - Tag provided, no class - wrap content with tag
234
- * - Tag and class provided - wrap content with tag and class
235
- * - Class provided, no tag - wrap content with span and class
236
- */
237
- private function get_stuff_with_tags_and_classes($entity, $single){
238
- $result = '';
239
- $stuffFunction = 'get_' . $entity;
240
- if (!empty($this->params[$entity . '_class'])){
241
- if (empty($this->params[$entity . '_tag'])){
242
- $result = $this->$stuffFunction($single, 'span', $this->params[$entity . '_class']);
243
- } else {
244
- $result = $this->$stuffFunction($single, $this->params[$entity . '_tag'], $this->params[$entity . '_class']);
245
- }
246
- } else {
247
- if (!empty($this->params[$entity . '_tag'])){
248
- $result = $this->$stuffFunction($single, $this->params[$entity . '_tag']);
249
- } else {
250
- $result = $this->$stuffFunction($single);
251
- }
252
- }
253
- return $result;
254
  }
255
 
256
- private function category_title(){
257
- // More link
258
- if (!empty($this->params['catlink_tag'])):
259
- if (!empty($this->params['catlink_class'])):
260
- $this->lcp_output .= $this->get_category_link(
261
- $this->params['catlink_tag'],
262
- $this->params['catlink_class']
263
- );
264
- else:
265
- $this->lcp_output .= $this->get_category_link($this->params['catlink_tag']);
266
- endif;
267
- else:
268
- $this->lcp_output .= $this->get_category_link("strong");
269
- endif;
270
  }
271
 
272
- public function get_category_description(){
273
- if(!empty($this->params['category_description']) && $this->params['category_description'] == 'yes'){
274
- $this->lcp_output .= $this->catlist->get_category_description();
275
- }
276
  }
277
 
278
- /**
279
- * Auxiliary functions for templates
280
- */
281
  private function get_comments($single, $tag = null, $css_class = null){
282
  return $this->content_getter('comments', $single, $tag, $css_class);
283
  }
@@ -294,8 +112,28 @@ class CatListDisplayer {
294
  return $this->content_getter('excerpt', $single, $tag, $css_class);
295
  }
296
 
297
- private function get_pagination(){
298
- return $this->catlist->get_pagination();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
300
 
301
  /*
@@ -303,6 +141,11 @@ class CatListDisplayer {
303
  * in the same function for less repetition.
304
  */
305
  private function content_getter($type, $post, $tag = null, $css_class = null) {
 
 
 
 
 
306
  $info = '';
307
  switch( $type ){
308
  case 'comments':
@@ -317,79 +160,42 @@ class CatListDisplayer {
317
  case 'excerpt':
318
  $info = $this->catlist->get_excerpt($post);
319
  $info = preg_replace('/\[.*\]/', '', $info);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  }
321
- return $this->assign_style($info, $tag, $css_class);
322
- }
323
-
324
- private function get_conditional_title(){
325
- if(!empty($this->params['conditional_title_tag']))
326
- $tag = $this->params['conditional_title_tag'];
327
- else
328
- $tag = 'h3';
329
- if(!empty($this->params['conditional_title_class']))
330
- $class = $this->params['conditional_title_class'];
331
- else
332
- $class = '';
333
-
334
- return $this->assign_style($this->catlist->get_conditional_title(), $tag, $class);
335
- }
336
-
337
- private function get_custom_fields($single){
338
- if(!empty($this->params['customfield_display'])){
339
- $info = $this->catlist->get_custom_fields($this->params['customfield_display'], $single->ID);
340
- if(empty($this->params['customfield_tag']) || $this->params['customfield_tag'] == null){
341
- $tag = 'div';
342
- } else {
343
- $tag = $this->params['customfield_tag'];
344
- }
345
-
346
- if(empty($this->params['customfield_class']) || $this->params['customfield_class'] == null){
347
- $css_class = 'lcp_customfield';
348
- } else {
349
- $css_class = $this->params['customfield_class'];
350
- }
351
-
352
- $final_info = '';
353
- if(!is_array($info)){
354
- $final_info = $this->assign_style($info, $tag, $css_class);
355
- }else{
356
- if($this->params['customfield_display_separately'] != 'no'){
357
- foreach($info as $i)
358
- $final_info .= $this->assign_style($i, $tag, $css_class);
359
- }else{
360
- $one_info = implode($this->params['customfield_display_glue'], $info);
361
- $final_info = $this->assign_style($one_info, $tag, $css_class);
362
- }
363
- }
364
- return $final_info;
365
- }
366
- }
367
-
368
- private function get_date($single, $tag = null, $css_class = null){
369
- $info = $this->catlist->get_date_to_show($single);
370
-
371
- if ( !empty($this->params['link_dates']) && ( 'yes' === $this->params['link_dates'] || 'true' === $this->params['link_dates'] ) ):
372
- $info = $this->get_post_link($single, $info);
373
- endif;
374
-
375
- $info = ' ' . $info;
376
- return $this->assign_style($info, $tag, $css_class);
377
- }
378
-
379
- private function get_modified_date($single, $tag = null, $css_class = null){
380
- $info = " " . $this->catlist->get_modified_date_to_show($single);
381
- return $this->assign_style($info, $tag, $css_class);
382
- }
383
-
384
- private function get_thumbnail($single, $tag = null){
385
- if ( !empty($this->params['thumbnail_class']) ) :
386
- $lcp_thumb_class = $this->params['thumbnail_class'];
387
- $info = $this->catlist->get_thumbnail($single, $lcp_thumb_class);
388
- else:
389
- $info = $this->catlist->get_thumbnail($single);
390
- endif;
391
-
392
- return $this->assign_style($info, $tag);
393
  }
394
 
395
  private function get_post_link($single, $text, $class = null){
@@ -414,6 +220,11 @@ class CatListDisplayer {
414
  // Link is a parameter here in case you want to use it on a template
415
  // and not show the links for all the shortcodes using this template:
416
  private function get_post_title($single, $tag = null, $css_class = null, $link = true){
 
 
 
 
 
417
  $lcp_post_title = apply_filters('the_title', $single->post_title, $single->ID);
418
 
419
  $lcp_post_title = $this->lcp_title_limit( $lcp_post_title );
@@ -443,7 +254,7 @@ class CatListDisplayer {
443
  $info = $pre . $info . $post;
444
 
445
  if( $tag !== null || $css_class !== null){
446
- $info = $this->assign_style($info, $tag, $css_class);
447
  }
448
 
449
  return $info;
@@ -464,66 +275,15 @@ class CatListDisplayer {
464
  return $lcp_post_title;
465
  }
466
 
467
- private function get_posts_morelink($single){
468
- if(!empty($this->params['posts_morelink'])){
469
- $href = 'href="' . get_permalink($single->ID) . '"';
470
- $class = "";
471
- if ( !empty($this->params['posts_morelink_class']) ):
472
- $class = 'class="' . $this->params['posts_morelink_class'] . '" ';
473
- endif;
474
- $readmore = $this->params['posts_morelink'];
475
- return ' <a ' . $href . ' ' . $class . ' >' . $readmore . '</a>';
476
- }
477
- }
478
-
479
- private function get_category_link($tag = null, $css_class = null){
480
- $info = $this->catlist->get_category_link();
481
- return $this->assign_style($info, $tag, $css_class);
482
- }
483
-
484
- private function get_morelink(){
485
- $info = $this->catlist->get_morelink();
486
- if ( !empty($this->params['morelink_tag'])){
487
- if( !empty($this->params['morelink_class']) ){
488
- return "<" . $this->params['morelink_tag'] . " class='" .
489
- $this->params['morelink_class'] . "'>" . $info .
490
- "</" . $this->params["morelink_tag"] . ">";
491
- } else {
492
- return "<" . $this->params['morelink_tag'] . ">" .
493
- $info . "</" . $this->params["morelink_tag"] . ">";
494
- }
495
- } else{
496
- if ( !empty($this->params['morelink_class']) ){
497
- return str_replace("<a", "<a class='" . $this->params['morelink_class'] . "' ", $info);
498
- }
499
- }
500
- return $info;
501
- }
502
-
503
- public function get_category_count(){
504
- return $this->catlist->get_category_count();
505
- }
506
-
507
  /**
508
- * Assign style to the info delivered by CatList. Tag is an HTML tag
509
- * which is passed and will sorround the info. Css_class is the css
510
- * class we want to assign to this tag.
511
- * @param string $info
512
- * @param string $tag
513
- * @param string $css_class
514
- * @return string
515
  */
516
- private function assign_style($info, $tag = null, $css_class = null){
517
- if (!empty($info)):
518
- if (empty($tag) && !empty($css_class)):
519
- $tag = "span";
520
- elseif (empty($tag)):
521
- return $info;
522
- elseif (!empty($tag) && empty($css_class)) :
523
- return '<' . $tag . '>' . $info . '</' . $tag . '>';
524
- endif;
525
- $css_class = sanitize_html_class($css_class);
526
- return '<' . $tag . ' class="' . $css_class . '">' . $info . '</' . $tag . '>';
527
- endif;
528
  }
529
  }
5
  * @author fernando@picandocodigo.net
6
  */
7
  require_once 'lcp-catlist.php';
8
+ require_once 'lcp-wrapper.php';
9
+ require_once 'lcp-templater.php';
10
 
11
  class CatListDisplayer {
12
  public $catlist;
13
+ private $wrapper;
14
+ private $templater;
15
  private $params = array();
16
  private $lcp_output;
17
 
 
 
 
 
 
 
18
  public function __construct($atts) {
19
  $this->params = $atts;
20
  $this->catlist = new CatList($atts);
21
+ $this->wrapper = LcpWrapper::get_instance();
22
  global $post;
23
  $this->parent = $post;
24
+ $this->templater = new LcpTemplater($atts['template']);
25
  }
26
 
27
  public function display(){
28
  $this->catlist->save_wp_query();
29
  $this->catlist->get_posts();
30
+ $this->create_output();
31
  $this->catlist->restore_wp_query();
32
  wp_reset_query();
33
  return $this->lcp_output;
34
  }
35
 
36
+ private function create_output() {
37
+ require $this->templater->get_template();
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
  /**
41
+ * Auxiliary functions for templates
42
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
+ /* Use outside The Loop */
 
 
 
 
 
45
 
46
+ private function open_outer_tag($tag='ul', $css_class='lcp_catlist') {
47
+ $this->templater->update_outer_tag($tag);
48
+ return $this->catlist->get_outer_tag($this->templater->outer_tag, $css_class);
 
 
49
  }
50
 
51
+ private function close_outer_tag() {
52
+ return '</' . $this->templater->outer_tag . '>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
+ private function get_morelink($tag = null, $css_class = null){
56
+ return $info = $this->content_getter('morelink', null, $tag, $css_class);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
 
59
+ private function get_category_link($tag = 'strong', $css_class = null){
60
+ return $this->content_getter('catlink', null, $tag, $css_class);
61
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
+ private function get_conditional_title($tag = 'h3', $css_class = null){
64
+ return $this->content_getter('conditional_title', null, $tag, $css_class);
65
+ }
66
 
67
+ private function get_pagination(){
68
+ return $this->catlist->get_pagination();
69
+ }
70
 
71
+ public function get_category_count(){
72
+ return $this->catlist->get_category_count();
73
+ }
74
 
75
+ public function get_category_description(){
76
+ return $this->catlist->get_category_description();
77
  }
78
 
79
+ private function get_no_posts_text() {
80
+ return $this->catlist->get_no_posts_text();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
+ /* Use within The Loop */
84
+
85
+ private function open_inner_tag($single, $tag, $css_class='') {
86
+ $this->templater->update_inner_tag( $tag );
87
+ return $this->catlist->get_inner_tag(
88
+ $single,
89
+ $this->parent,
90
+ $this->templater->inner_tag,
91
+ $css_class
92
+ );
 
 
 
 
93
  }
94
 
95
+ private function close_inner_tag() {
96
+ return '</' . $this->templater->inner_tag . '>';
 
 
97
  }
98
 
 
 
 
99
  private function get_comments($single, $tag = null, $css_class = null){
100
  return $this->content_getter('comments', $single, $tag, $css_class);
101
  }
112
  return $this->content_getter('excerpt', $single, $tag, $css_class);
113
  }
114
 
115
+ private function get_modified_date($single, $tag = null, $css_class = null){
116
+ return $info = $this->content_getter('date_modified', $single, $tag, $css_class);
117
+ }
118
+
119
+ private function get_custom_fields($single, $tag='div', $css_class='lcp-customfield'){
120
+ return $this->content_getter('customfield', $single, $tag, $css_class);
121
+ }
122
+
123
+ private function get_date($single, $tag=null, $css_class=null) {
124
+ return $this->content_getter('date', $single, $tag, $css_class);
125
+ }
126
+
127
+ private function get_thumbnail($single, $tag=null, $css_class=null) {
128
+ return $this->content_getter('thumbnail', $single, $tag, $css_class);
129
+ }
130
+
131
+ private function get_posts_morelink($single, $css_class=null) {
132
+ return $this->content_getter('posts_morelink', $single, null, $css_class);
133
+ }
134
+
135
+ private function get_display_id($single) {
136
+ return $this->catlist->get_display_id($single);
137
  }
138
 
139
  /*
141
  * in the same function for less repetition.
142
  */
143
  private function content_getter($type, $post, $tag = null, $css_class = null) {
144
+ // Shortcode parameters take precedence over function arguments
145
+ // for tags and classes. 'posts_morelink_tag' param doesn't exist
146
+ if ($type !== 'posts_morelink') $tag = $this->params[$type . '_tag'] ?: $tag;
147
+ $css_class = $this->params[$type . '_class'] ?: $css_class;
148
+
149
  $info = '';
150
  switch( $type ){
151
  case 'comments':
160
  case 'excerpt':
161
  $info = $this->catlist->get_excerpt($post);
162
  $info = preg_replace('/\[.*\]/', '', $info);
163
+ break;
164
+ case 'date_modified':
165
+ $info = $this->catlist->get_modified_date_to_show($post);
166
+ break;
167
+ case 'morelink':
168
+ $info = $this->catlist->get_morelink();
169
+ break;
170
+ case 'catlink':
171
+ $info = $this->catlist->get_category_link();
172
+ break;
173
+ case 'conditional_title':
174
+ $info = $this->catlist->get_conditional_title();
175
+ break;
176
+ case 'customfield':
177
+ $info = $this->catlist->get_custom_fields($this->params['customfield_display'], $post->ID);
178
+ break;
179
+ case 'date':
180
+ $info = $this->catlist->get_date_to_show($post);
181
+ if ( !empty($this->params['link_dates']) && ( 'yes' === $this->params['link_dates'] || 'true' === $this->params['link_dates'] ) ):
182
+ $info = $this->get_post_link($post, $info);
183
+ endif;
184
+ ($info) ? ($info = ' ' . $info) : null;
185
+ break;
186
+ case 'thumbnail':
187
+ $info = $this->catlist->get_thumbnail($post, $css_class);
188
+ // Default wrapper behavior not supported here,
189
+ // class is only used inside the <img> element.
190
+ $css_class = null;
191
+ break;
192
+ case 'posts_morelink':
193
+ $info = $this->catlist->get_posts_morelink($post, $css_class);
194
+ // Default wrapper behavior not supported here,
195
+ // class is only used inside the <a> element.
196
+ $css_class = null;
197
  }
198
+ return $this->wrapper->wrap($info, $tag, $css_class);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
200
 
201
  private function get_post_link($single, $text, $class = null){
220
  // Link is a parameter here in case you want to use it on a template
221
  // and not show the links for all the shortcodes using this template:
222
  private function get_post_title($single, $tag = null, $css_class = null, $link = true){
223
+ // Don't do anything if no_post_titles is specified.
224
+ if ( 'yes' === $this->params['no_post_titles'] ) {
225
+ return;
226
+ }
227
+
228
  $lcp_post_title = apply_filters('the_title', $single->post_title, $single->ID);
229
 
230
  $lcp_post_title = $this->lcp_title_limit( $lcp_post_title );
254
  $info = $pre . $info . $post;
255
 
256
  if( $tag !== null || $css_class !== null){
257
+ $info = $this->wrapper->wrap($info, $tag, $css_class);
258
  }
259
 
260
  return $info;
275
  return $lcp_post_title;
276
  }
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  /**
279
+ * Checks if a protected post should be included in the LCP output.
280
+ *
281
+ *
282
+ * @param object $post A post to be checked.
283
+ * @return bool Whether a post should be included in the LCP output.
 
 
284
  */
285
+ private function check_show_protected($post) {
286
+ return ! post_password_required($post) ||
287
+ post_password_required($post) && 'yes' === $this->params['show_protected'];
 
 
 
 
 
 
 
 
 
288
  }
289
  }
include/lcp-date-query.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ trait LcpDateQuery{
4
+ // Parameters that are set to build the argument array
5
+ function params_set(){
6
+ return array(
7
+ 'after' => false,
8
+ 'after_year' => false,
9
+ 'after_month' => false,
10
+ 'after_day' => false,
11
+ 'before' => false,
12
+ 'before_year' => false,
13
+ 'before_month' => false,
14
+ 'before_day' => false,
15
+ );
16
+ }
17
+
18
+ /*
19
+ * Create date_query args according to https://codex.wordpress.org/Class_Reference/WP_Query#Date_Parameters
20
+ */
21
+ public function create_date_query_args($args, $params) {
22
+ $date_query = array();
23
+ // Booleans to track which subarrays should be created.
24
+ $after = false;
25
+ $before = false;
26
+ $time_periods = array('before', 'after');
27
+ $params_set = $this->set_params_values($params);
28
+
29
+ /*
30
+ * Build the subarrays.
31
+ * The after parameter takes priority over after_* parameters.
32
+ * Similarly, the before parameter takes priority over before_* parameters.
33
+ */
34
+ foreach ($time_periods as $period){
35
+ if ($params_set[$period]) {
36
+ $date_query[$period] = $params[$period];
37
+ } else {
38
+ if ( $params_set[$period . '_year'] ) $date_query[$period]['year'] = $params_set[$period . '_year'];
39
+ if ( $params_set[$period . '_month'] ) $date_query[$period]['month'] = $params_set[$period . '_month'];
40
+ if ( $params_set[$period . '_day'] ) $date_query[$period]['day'] = $params_set[$period . '_day'];
41
+ }
42
+ }
43
+
44
+ if(!empty($date_query)){
45
+ $args = array_merge($args, array('date_query' => $date_query));
46
+ }
47
+ return $args;
48
+ }
49
+
50
+ /*
51
+ * Check which paramaters are set save the values
52
+ */
53
+ private function set_params_values($params){
54
+ $params_set = $this->params_set();
55
+ foreach ($params_set as $key => $value){
56
+ if ( array_key_exists($key, $params) && $params[$key] != false){
57
+ $params_set[$key] = $params[$key];
58
+ }
59
+ }
60
+ return $params_set;
61
+ }
62
+ }
include/lcp-parameters.php CHANGED
@@ -1,15 +1,17 @@
1
  <?php
2
  require_once ( LCP_PATH . 'lcp-utils.php' );
 
3
 
4
  class LcpParameters{
5
  // Singleton implementation
6
  private static $instance = null;
7
  private $starting_with = null;
8
- // $date_query tells us if we need to generate date_query args
9
- private $date_query = false;
10
  private $utils;
11
  private $params;
12
 
 
 
 
13
  public static function get_instance(){
14
  if( !isset( self::$instance ) ){
15
  self::$instance = new self;
@@ -23,21 +25,11 @@ class LcpParameters{
23
  # Essential parameters:
24
  $args = array(
25
  'numberposts' => $params['numberposts'],
26
- 'orderby' => $params['orderby'],
27
- 'order' => $params['order'],
28
  'offset' => $params['offset']
29
  );
30
 
31
- if( get_option('lcp_orderby') && $params['orderby'] === ''){
32
- $orderby = array('orderby' => get_option('lcp_orderby'));
33
- $args = array_merge($args, $orderby);
34
- }
35
-
36
- if( get_option('lcp_order') && $params['order'] === ''){
37
- $order = array('order' => get_option('lcp_order'));
38
- $args = array_merge($args, $order);
39
- }
40
-
41
  $this->utils = new LcpUtils($params);
42
 
43
  // Check posts to exclude
@@ -46,9 +38,9 @@ class LcpParameters{
46
  // Check type, status, parent params
47
  $args = $this->lcp_types_and_statuses($args);
48
 
49
- if($this->utils->lcp_not_empty('search')):
50
  $args['s'] = $params['search'];
51
- endif;
52
 
53
  if($this->utils->lcp_not_empty('author_posts')):
54
  $authors = $params['author_posts'];
@@ -67,67 +59,8 @@ class LcpParameters{
67
  // final return array ($args)
68
  $args = $this->lcp_check_basic_params($args);
69
 
70
- // Posts within given date range:
71
- if ( $this->utils->lcp_not_empty('after') ) {
72
- $this->after = $params['after'];
73
- $date_query = true;
74
- }
75
-
76
- if ( $this->utils->lcp_not_empty('after_year') ) {
77
- $this->after_year = $params['after_year'];
78
- $date_query = true;
79
- }
80
-
81
- if ( $this->utils->lcp_not_empty('after_month') ) {
82
- // after_month should be in the range [1, 12]
83
- if ($params['after_month'] >= 1 && $params['after_month'] <= 12) {
84
- $this->after_month = $params['after_month'];
85
- $date_query = true;
86
- }
87
- }
88
-
89
- if ( $this->utils->lcp_not_empty('after_day') ) {
90
- // after_day should be in the range [1, 31]
91
- if ($params['after_day'] >= 1 && $params['after_day'] <= 31) {
92
- $this->after_day = $params['after_day'];
93
- $date_query = true;
94
- }
95
- }
96
-
97
- if ( $this->utils->lcp_not_empty('before') ) {
98
- if('today' === strtolower($params['before'])) {
99
- $this->before = date("Y/m/d");
100
- } else {
101
- $this->before = $params['before'];
102
- }
103
- $date_query = true;
104
- }
105
-
106
- if ( $this->utils->lcp_not_empty('before_year') ) {
107
- $this->before_year = $params['before_year'];
108
- $date_query = true;
109
- }
110
-
111
- if ( $this->utils->lcp_not_empty('before_month') ) {
112
- // before_month should be in the range [1, 12]
113
- if ($params['before_month'] >= 1 && $params['before_month'] <= 12) {
114
- $this->before_month = $params['before_month'];
115
- $date_query = true;
116
- }
117
- }
118
-
119
- if ( $this->utils->lcp_not_empty('before_day') ) {
120
- // before_day should be in the range [1, 31]
121
- if ($params['before_day'] >= 1 && $params['before_day'] <= 31) {
122
- $this->before_day = $params['before_day'];
123
- $date_query = true;
124
- }
125
- }
126
-
127
  // Only generate date_query args if a before/after paramater was found
128
- if (isset($date_query) ){
129
- $args['date_query'] = $this->create_date_query_args();
130
- }
131
 
132
  /*
133
  * Custom fields 'customfield_name' & 'customfield_value'
@@ -345,61 +278,19 @@ class LcpParameters{
345
  return $post->ID;
346
  }
347
 
348
- /*
349
- * Create date_query args according to https://codex.wordpress.org/Class_Reference/WP_Query#Date_Parameters
350
- * There's probably a better way to check if values exist.
351
- * Code should be cleaned up (this is first attempt at a solution).
352
- */
353
- private function create_date_query_args() {
354
- $date_query = array();
355
-
356
- // Keep track of parameters that are set to build the argument array.
357
- $params_set = array(
358
- 'after' => false,
359
- 'after_year' => false,
360
- 'after_month' => false,
361
- 'after_day' => false,
362
- 'before' => false,
363
- 'before_year' => false,
364
- 'before_month' => false,
365
- 'before_day' => false,
366
- );
367
 
368
- // Booleans to track which subarrays should be created.
369
- $after = false;
370
- $before = false;
371
 
372
- /*
373
- * Check which paramaters are set and find out which subarrays
374
- * should be created.
375
- */
376
- foreach ($params_set as $key=>$value){
377
- if ( property_exists($this, $key) ){
378
- $params_set[$key] = true;
379
- $trutify = explode('_', $key);
380
- $trutify = $trutify[0];
381
- ${$trutify} = true;
382
- }
383
  }
 
 
384
 
385
- /*
386
- * Build the subarrays.
387
- * The after parameter takes priority over after_* parameters.
388
- * Similarly, the before parameter takes priority over before_* parameters.
389
- */
390
- $time_periods = array('before', 'after');
391
- foreach ($time_periods as $period){
392
- if (${$period}){
393
- if ($params_set[$period]) {
394
- $date_query[$period] = $this->$period;
395
- } else {
396
- if ( $params_set[$period . '_year'] ) $date_query[$period]['year'] = $this->{$period . '_year'};
397
- if ( $params_set[$period . '_month'] ) $date_query[$period]['month'] = $this->{$period . '_month'};
398
- if ( $params_set[$period . '_day'] ) $date_query[$period]['day'] = $this->{$period . '_day'};
399
- }
400
- }
401
  }
402
-
403
- return $date_query;
404
  }
405
  }
1
  <?php
2
  require_once ( LCP_PATH . 'lcp-utils.php' );
3
+ require_once ( LCP_PATH . 'lcp-date-query.php' );
4
 
5
  class LcpParameters{
6
  // Singleton implementation
7
  private static $instance = null;
8
  private $starting_with = null;
 
 
9
  private $utils;
10
  private $params;
11
 
12
+ // Use Trait for before/after date queries:
13
+ use LcpDateQuery;
14
+
15
  public static function get_instance(){
16
  if( !isset( self::$instance ) ){
17
  self::$instance = new self;
25
  # Essential parameters:
26
  $args = array(
27
  'numberposts' => $params['numberposts'],
28
+ 'orderby' => $this->lcp_order_by($params['orderby']),
29
+ 'order' => $this->lcp_order($params['order']),
30
  'offset' => $params['offset']
31
  );
32
 
 
 
 
 
 
 
 
 
 
 
33
  $this->utils = new LcpUtils($params);
34
 
35
  // Check posts to exclude
38
  // Check type, status, parent params
39
  $args = $this->lcp_types_and_statuses($args);
40
 
41
+ if($this->utils->lcp_not_empty('search')){
42
  $args['s'] = $params['search'];
43
+ }
44
 
45
  if($this->utils->lcp_not_empty('author_posts')):
46
  $authors = $params['author_posts'];
59
  // final return array ($args)
60
  $args = $this->lcp_check_basic_params($args);
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  // Only generate date_query args if a before/after paramater was found
63
+ $args = $this->create_date_query_args($args, $params);
 
 
64
 
65
  /*
66
  * Custom fields 'customfield_name' & 'customfield_value'
278
  return $post->ID;
279
  }
280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
 
 
 
 
282
 
283
+ private function lcp_order_by($orderby) {
284
+ if( get_option('lcp_orderby') && $orderby === ''){
285
+ return get_option('lcp_orderby');
 
 
 
 
 
 
 
 
286
  }
287
+ return $orderby;
288
+ }
289
 
290
+ private function lcp_order($order) {
291
+ if( get_option('lcp_order') && $params['order'] === ''){
292
+ return get_option('lcp_order');
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  }
294
+ return $order;
 
295
  }
296
  }
include/lcp-templater.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Defines the LcpTemplater class
4
+ */
5
+
6
+ /**
7
+ * Contains and manages all template-related logic.
8
+ *
9
+ * This class is used to choose the correct template file,
10
+ * either the default one or one that corresponds to the `template` parameter
11
+ * supplied by the user.
12
+ *
13
+ * It also stores and manages:
14
+ *
15
+ * - the list's outer tag
16
+ * - the list's inner tags
17
+ */
18
+ class LcpTemplater {
19
+
20
+ /**
21
+ * Paths to template directory.
22
+ *
23
+ * @var array
24
+ */
25
+ private static $paths = null;
26
+
27
+ /**
28
+ * Path to the template file being used.
29
+ *
30
+ * @var string
31
+ */
32
+ private $template_file;
33
+
34
+ /**
35
+ * List's outer tag.
36
+ *
37
+ * @var string
38
+ */
39
+ public $outer_tag = null;
40
+
41
+ /**
42
+ * List's inner tag.
43
+ *
44
+ * @var null
45
+ */
46
+ public $inner_tag = null;
47
+
48
+ /**
49
+ * Instance constructor.
50
+ *
51
+ * Sets the proper template to be used. Either the default one or one
52
+ * specified by the user, if set. If $param is ul, div, or ul this method
53
+ * will also set proper outer and inner tags.
54
+ *
55
+ * @param string $param 'template' shortcode parameter.
56
+ */
57
+ public function __construct($param) {
58
+ // Default plugin template.
59
+ $this->template_file = plugin_dir_path(__DIR__) . 'templates/default.php';
60
+
61
+ if (empty($param)) {
62
+ // Use default plugin template.
63
+ ;
64
+ } else if ( preg_match('/^ul$|^div$|^ol$/i', $param, $matches)) {
65
+ // Use default plugin template, set outer and inner tags.
66
+ $this->outer_tag = ($matches[0]);
67
+ if ('div' === $this->outer_tag) {
68
+ $this->inner_tag = 'p';
69
+ }
70
+ } else {
71
+ // Try user's template.
72
+ $this->select_template($param);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Gets the possible template direcotry paths.
78
+ *
79
+ * The paths are stored in the $paths variable and returned.
80
+ *
81
+ * @return array Paths to template directory.
82
+ */
83
+ private static function get_template_paths() {
84
+ if (null === self::$paths) {
85
+ self::$paths = array_unique(
86
+ [
87
+ get_stylesheet_directory() . '/list-category-posts/',
88
+ get_template_directory() . '/list-category-posts/',
89
+ ]
90
+ );
91
+ }
92
+ return self::$paths;
93
+ }
94
+
95
+ /**
96
+ * Gets and returns all available template names.
97
+ *
98
+ * THis method scans the template directory and outputs all available
99
+ * template names in an array. This is currently only used by the widget.
100
+ *
101
+ * @return array All available template names (without .php extension).
102
+ */
103
+ public static function get_templates() {
104
+ $templates = [];
105
+ $paths = self::get_template_paths();
106
+
107
+ foreach ($paths as $path) {
108
+ foreach (scandir($path) as $file) {
109
+ if (! self::validate_template($path, $file)) {
110
+ continue;
111
+ }
112
+
113
+ $template_name = substr($file, 0, strlen($file) - 4);
114
+
115
+ // Add the template only if necessary
116
+ if (! in_array( $template_name, $templates)) {
117
+ $templates[] = $template_name;
118
+ }
119
+ }
120
+ }
121
+ return $templates;
122
+ }
123
+
124
+ /**
125
+ * Checks whether specified template files are formatted properly.
126
+ *
127
+ * @param string $path Path to the template directory.
128
+ * @param string $file Template file name.
129
+ * @return bool Is the template a proper php file.
130
+ */
131
+ private static function validate_template($path, $file) {
132
+ return (substr($file, -4) == '.php' ) && is_file($path . $file) &&
133
+ is_readable($path . $file);
134
+ }
135
+
136
+ /**
137
+ * Determine template path.
138
+ *
139
+ * Checks if the user specified template file exists and if so,
140
+ * sets the $template_file member variable to the template file's path.
141
+ *
142
+ * @param string $param 'template' shortcode paramter.
143
+ */
144
+ private function select_template($param) {
145
+ // Path to a proper template file.
146
+ $template = null;
147
+
148
+ // Get templates paths and search for the php file.
149
+ $paths = self::get_template_paths();
150
+ foreach($paths as $path) {
151
+ if (self::validate_template($path, $param . '.php')) {
152
+ $template = $path . $param . '.php';
153
+ break;
154
+ }
155
+ }
156
+
157
+ if ($template) {
158
+ $this->template_file = $template;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Updates the list's outer tag.
164
+ *
165
+ * @param string $tag Outer tag, ex. ul.
166
+ */
167
+ public function update_outer_tag($tag) {
168
+ $this->outer_tag = $this->outer_tag ?: $tag;
169
+ }
170
+
171
+ /**
172
+ * Updates the list's inner tag.
173
+ *
174
+ * @param string $tag Inner tag, ex. li.
175
+ */
176
+ public function update_inner_tag($tag) {
177
+ $this->inner_tag = $this->inner_tag ?: $tag;
178
+ }
179
+
180
+ /**
181
+ * Getter method for the template path.
182
+ *
183
+ * @return string $template_file value.
184
+ */
185
+ public function get_template() {
186
+ return $this->template_file;
187
+ }
188
+ }
include/lcp-widget-form.php CHANGED
@@ -259,7 +259,7 @@
259
  <br/>
260
  <select id="<?php echo $this->get_field_id('template'); ?>" name="<?php echo $this->get_field_name('template'); ?>">
261
  <?php
262
- $templates = CatListDisplayer::get_templates();
263
  $templates[] = 'default';
264
  foreach ($templates as $tmp) :
265
  $option = '<option value="' . $tmp . '" ';
259
  <br/>
260
  <select id="<?php echo $this->get_field_id('template'); ?>" name="<?php echo $this->get_field_name('template'); ?>">
261
  <?php
262
+ $templates = LcpTemplater::get_templates();
263
  $templates[] = 'default';
264
  foreach ($templates as $tmp) :
265
  $option = '<option value="' . $tmp . '" ';
include/lcp-wrapper.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class handles HTML customizations
4
+ * defined by the user, both in shortcode parameters (e.g. comments_tag)
5
+ * and in template method calls.
6
+ */
7
+ class LcpWrapper {
8
+
9
+ // Singleton implementation
10
+ private static $instance = null;
11
+ public static function get_instance(){
12
+ if( !isset( self::$instance ) ){
13
+ self::$instance = new self;
14
+ }
15
+ return self::$instance;
16
+ }
17
+
18
+ /**
19
+ * Several checks going on here:
20
+ * - Tag provided, no class - wrap content with tag
21
+ * - Tag and class provided - wrap content with tag and class
22
+ * - Class provided, no tag - wrap content with span and class
23
+ * @param string $info
24
+ * @param string $tag
25
+ * @param string $css_class
26
+ * @return string
27
+ */
28
+ private function assign_style($info, $tag = null, $css_class = null){
29
+ if (!empty($info)):
30
+ if (empty($tag) && !empty($css_class)):
31
+ $tag = "span";
32
+ elseif (empty($tag)):
33
+ return $info;
34
+ elseif (!empty($tag) && empty($css_class)) :
35
+ return '<' . $tag . '>' . $info . '</' . $tag . '>';
36
+ endif;
37
+ $css_class = sanitize_html_class($css_class);
38
+ return '<' . $tag . ' class="' . $css_class . '">' . $info . '</' . $tag . '>';
39
+ endif;
40
+ }
41
+
42
+ /**
43
+ * Assign style to the info delivered by CatList. Tag is an HTML tag
44
+ * which is passed and will sorround the info. Css_class is the css
45
+ * class we want to assign to this tag. If an array is passed to $info
46
+ * each element will be wrapped separately and added to the returned string.
47
+ * @param string|array $info
48
+ * @param string $tag
49
+ * @param string $css_class
50
+ * @return string
51
+ */
52
+ public function wrap($info, $tag=null, $css_class=null) {
53
+
54
+ $wrapped = '';
55
+
56
+ if (is_array($info)) {
57
+ foreach ($info as $i) {
58
+ $wrapped .= $this->assign_style($i, $tag, $css_class);
59
+ }
60
+ } else {
61
+ $wrapped = $this->assign_style($info, $tag, $css_class);
62
+ }
63
+ return $wrapped;
64
+ }
65
+ }
list-category-posts.php CHANGED
@@ -3,14 +3,14 @@
3
  Plugin Name: List category posts
4
  Plugin URI: https://github.com/picandocodigo/List-Category-Posts
5
  Description: List Category Posts allows you to list posts by category in a post/page using the [catlist] shortcode. This shortcode accepts a category name or id, the order in which you want the posts to display, the number of posts to display and many more parameters. You can use [catlist] as many times as needed with different arguments. Usage: [catlist argument1=value1 argument2=value2].
6
- Version: 0.82
7
  Author: Fernando Briano
8
  Author URI: http://fernandobriano.com
9
 
10
  Text Domain: list-category-posts
11
  Domain Path: /languages/
12
 
13
- Copyright 2008-2016 Fernando Briano (email : fernando@picandocodigo.net)
14
 
15
  This program is free software; you can redistribute it and/or modify
16
  it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@ require_once 'include/lcp-catlistdisplayer.php';
34
 
35
  class ListCategoryPosts{
36
  private static $default_params = null;
 
37
  public static function default_params(){
38
  if (self::$default_params === null) {
39
  self::$default_params = array(
@@ -83,6 +84,7 @@ class ListCategoryPosts{
83
  'starting_with' => '',
84
  'thumbnail' => 'no',
85
  'thumbnail_size' => 'thumbnail',
 
86
  'thumbnail_class' => '',
87
  'force_thumbnail' => '',
88
  'title_tag' => '',
@@ -93,7 +95,7 @@ class ListCategoryPosts{
93
  'post_parent' => '0',
94
  'post_suffix' => '',
95
  'show_protected' => 'no',
96
- 'class' => 'lcp_catlist',
97
  'conditional_title' => '',
98
  'conditional_title_tag' => '',
99
  'conditional_title_class' => '',
@@ -142,6 +144,7 @@ class ListCategoryPosts{
142
  'before_day' => '',
143
  'tags_as_class' => 'no',
144
  'pagination_bookmarks' => '',
 
145
  );
146
  }
147
  return self::$default_params;
@@ -152,7 +155,7 @@ class ListCategoryPosts{
152
  * @param $atts
153
  * @param $content
154
  */
155
- static function catlist_func($atts, $content = null) {
156
  $atts = shortcode_atts(self::default_params(), $atts);
157
 
158
  if($atts['numberposts'] == ''){
@@ -173,14 +176,14 @@ add_shortcode( 'catlist', array('ListCategoryPosts', 'catlist_func') );
173
  function lpc_meta($links, $file) {
174
  $plugin = plugin_basename(__FILE__);
175
 
176
- if ($file == $plugin):
177
  return array_merge(
178
  $links,
179
  array( sprintf('<a href="http://wordpress.org/extend/plugins/list-category-posts/other_notes/">%s</a>', __('How to use','list-category-posts')) ),
180
  array( sprintf('<a href="http://picandocodigo.net/programacion/wordpress/list-category-posts-wordpress-plugin-english/#support">%s</a>', __('Donate','list-category-posts')) ),
181
  array( sprintf('<a href="https://github.com/picandocodigo/List-Category-Posts">%s</a>', __('Fork on Github','list-category-posts')) )
182
  );
183
- endif;
184
 
185
  return $links;
186
  }
@@ -194,18 +197,22 @@ function set_default_numberposts() {
194
  register_activation_hook( __FILE__, 'set_default_numberposts' );
195
 
196
  function load_i18n(){
197
- load_plugin_textdomain( 'list-category-posts', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
 
 
 
 
198
  }
199
  add_action( 'plugins_loaded', 'load_i18n' );
200
 
201
  function lcp_pagination_css(){
202
- if ( @file_exists( get_stylesheet_directory() . '/lcp_paginator.css' ) ):
203
  $css_file = get_stylesheet_directory_uri() . '/lcp_paginator.css';
204
- elseif ( @file_exists( get_template_directory() . '/lcp_paginator.css' ) ):
205
  $css_file = get_template_directory_uri() . '/lcp_paginator.css';
206
- else:
207
  $css_file = plugin_dir_url(__FILE__) . '/lcp_paginator.css';
208
- endif;
209
 
210
  wp_enqueue_style( 'lcp_paginator', $css_file);
211
  }
3
  Plugin Name: List category posts
4
  Plugin URI: https://github.com/picandocodigo/List-Category-Posts
5
  Description: List Category Posts allows you to list posts by category in a post/page using the [catlist] shortcode. This shortcode accepts a category name or id, the order in which you want the posts to display, the number of posts to display and many more parameters. You can use [catlist] as many times as needed with different arguments. Usage: [catlist argument1=value1 argument2=value2].
6
+ Version: 0.83
7
  Author: Fernando Briano
8
  Author URI: http://fernandobriano.com
9
 
10
  Text Domain: list-category-posts
11
  Domain Path: /languages/
12
 
13
+ Copyright 2008-2020 Fernando Briano (email : fernando@picandocodigo.net)
14
 
15
  This program is free software; you can redistribute it and/or modify
16
  it under the terms of the GNU General Public License as published by
34
 
35
  class ListCategoryPosts{
36
  private static $default_params = null;
37
+
38
  public static function default_params(){
39
  if (self::$default_params === null) {
40
  self::$default_params = array(
84
  'starting_with' => '',
85
  'thumbnail' => 'no',
86
  'thumbnail_size' => 'thumbnail',
87
+ 'thumbnail_tag' => '',
88
  'thumbnail_class' => '',
89
  'force_thumbnail' => '',
90
  'title_tag' => '',
95
  'post_parent' => '0',
96
  'post_suffix' => '',
97
  'show_protected' => 'no',
98
+ 'class' => '',
99
  'conditional_title' => '',
100
  'conditional_title_tag' => '',
101
  'conditional_title_class' => '',
144
  'before_day' => '',
145
  'tags_as_class' => 'no',
146
  'pagination_bookmarks' => '',
147
+ 'ol_offset' => ''
148
  );
149
  }
150
  return self::$default_params;
155
  * @param $atts
156
  * @param $content
157
  */
158
+ static function catlist_func($atts) {
159
  $atts = shortcode_atts(self::default_params(), $atts);
160
 
161
  if($atts['numberposts'] == ''){
176
  function lpc_meta($links, $file) {
177
  $plugin = plugin_basename(__FILE__);
178
 
179
+ if ($file == $plugin) {
180
  return array_merge(
181
  $links,
182
  array( sprintf('<a href="http://wordpress.org/extend/plugins/list-category-posts/other_notes/">%s</a>', __('How to use','list-category-posts')) ),
183
  array( sprintf('<a href="http://picandocodigo.net/programacion/wordpress/list-category-posts-wordpress-plugin-english/#support">%s</a>', __('Donate','list-category-posts')) ),
184
  array( sprintf('<a href="https://github.com/picandocodigo/List-Category-Posts">%s</a>', __('Fork on Github','list-category-posts')) )
185
  );
186
+ }
187
 
188
  return $links;
189
  }
197
  register_activation_hook( __FILE__, 'set_default_numberposts' );
198
 
199
  function load_i18n(){
200
+ load_plugin_textdomain(
201
+ 'list-category-posts',
202
+ false,
203
+ dirname( plugin_basename( __FILE__ ) ) . '/languages/'
204
+ );
205
  }
206
  add_action( 'plugins_loaded', 'load_i18n' );
207
 
208
  function lcp_pagination_css(){
209
+ if ( @file_exists( get_stylesheet_directory() . '/lcp_paginator.css' ) ) {
210
  $css_file = get_stylesheet_directory_uri() . '/lcp_paginator.css';
211
+ } elseif ( @file_exists( get_template_directory() . '/lcp_paginator.css' ) ) {
212
  $css_file = get_template_directory_uri() . '/lcp_paginator.css';
213
+ } else {
214
  $css_file = plugin_dir_url(__FILE__) . '/lcp_paginator.css';
215
+ }
216
 
217
  wp_enqueue_style( 'lcp_paginator', $css_file);
218
  }
readme.txt CHANGED
@@ -1,11 +1,11 @@
1
  === List category posts ===
2
- Contributors: fernandobt
3
  Donate Link: http://picandocodigo.net/programacion/wordpress/list-category-posts-wordpress-plugin-english/#support
4
  Tags: list, categories, posts, cms
5
  Requires at least: 3.3
6
- Tested up to: 5.4.1
7
  Requires PHP: 5.4
8
- Stable tag: 0.82
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -60,7 +60,10 @@ Some users have made videos on how to use the plugin (thank you, you are awesome
60
 
61
  **Support the plugin**
62
 
63
- If you've found the plugin useful, consider making a [donation via PayPal](http://picandocodigo.net/programacion/wordpress/list-category-posts-wordpress-plugin-english/#support "Donate via PayPal").
 
 
 
64
 
65
  **Development**
66
 
@@ -179,7 +182,7 @@ Then just add a new text widget to your blog and use the shortcode there as the
179
 
180
  **TEMPLATE SYSTEM**
181
 
182
- How to customize the way the posts are shown: [Template System](https://github.com/picandocodigo/List-Category-Posts/wiki/Template-System). I am aware the Template System is not the friendliest right now, I'll work on improving this if I ever get the time to work on it.
183
 
184
  **NEW FEATURE REQUESTS, BUG FIXES, ENHANCEMENTS**
185
 
@@ -229,6 +232,19 @@ Template system has changed. Custom templates should be stored in WordPress them
229
 
230
  == Changelog ==
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  = 0.82 =
233
 
234
  * Adds support for several authors. To select posts from one author, you can use the **author_posts** parameter and use 'user_nicename' (NOT name). Example: `[catlist author_posts="fernando"]`. If you want to select posts from several authors, you need to use the author id instead. You can find the id for each author in `wp-admin/users.php`. It needs to be a comma separated value, example: `[catlist author_posts="1,2"]`
1
  === List category posts ===
2
+ Contributors: fernandobt, zymeth25
3
  Donate Link: http://picandocodigo.net/programacion/wordpress/list-category-posts-wordpress-plugin-english/#support
4
  Tags: list, categories, posts, cms
5
  Requires at least: 3.3
6
+ Tested up to: 5.4.2
7
  Requires PHP: 5.4
8
+ Stable tag: 0.83
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
60
 
61
  **Support the plugin**
62
 
63
+ Klemens Starybrat has been writing lots of amazing code for this plugin, so if you've found it useful and want to pay it forward, consider sponsoring him on GitHub: https://github.com/sponsors/zymeth25
64
+
65
+ I have a [PayPal account](http://picandocodigo.net/programacion/wordpress/list-category-posts-wordpress-plugin-english/#support "Donate via PayPal") where you can donate too.
66
+
67
 
68
  **Development**
69
 
182
 
183
  **TEMPLATE SYSTEM**
184
 
185
+ How to customize the way the posts are shown: [Template System](https://github.com/picandocodigo/List-Category-Posts/wiki/Template-System).
186
 
187
  **NEW FEATURE REQUESTS, BUG FIXES, ENHANCEMENTS**
188
 
232
 
233
  == Changelog ==
234
 
235
+ = 0.83 =
236
+
237
+ This is a big release since @zymeth25 and I have been doing lots of refactoring based on maintainability, code quality and testing. It means the code is much cleaner and easier to maintain. So fixing bugs or adding new features should be easier now. If you find any issues, please report them on GitHub (https://github.com/picandocodigo/List-Category-Posts/issues).
238
+
239
+ * Development: We've refactored a lot of the code in `include`, updated the build, bumped versions, added tests, and more.
240
+ * Bugfix: An issue where `customfield_display_glue` was shown even when the custom field values were empty - https://wordpress.org/support/topic/hide-the-glue-content-if-costum-fields-are-empty
241
+ * Bugfix: Fixed excluded categories when using an `and` relationship.
242
+ * New parameter: `ol_offset`, when you use an ordered list, you can set an offset so the posts will start from that number instead of 1.
243
+ * *Templates system refactor* - The plugin now uses the template system by default. There should be no changes on how the plugin works, but please do let us know if you have any issues. Building templates should be easier now. You can use the included template as an example to start. It's in the plugin's template folder under the name default.php. Be warned, however, that this is the default template the plugin uses to create output so if you change it, you *will change* the plugin's default behavior. When you update the plugin this file will be overwritten so it's best not to edit it but copy it over to another file to create your custom template.
244
+ More information on templates:
245
+ - Pull Request: https://github.com/picandocodigo/List-Category-Posts/pull/411
246
+ - Official docs: https://github.com/picandocodigo/List-Category-Posts/wiki/HTML-&-CSS-Customization#templates
247
+
248
  = 0.82 =
249
 
250
  * Adds support for several authors. To select posts from one author, you can use the **author_posts** parameter and use 'user_nicename' (NOT name). Example: `[catlist author_posts="fernando"]`. If you want to select posts from several authors, you need to use the author id instead. You can find the id for each author in `wp-admin/users.php`. It needs to be a comma separated value, example: `[catlist author_posts="1,2"]`
templates/default.php CHANGED
@@ -40,11 +40,14 @@ $lcp_display_output = '';
40
  // Show category link:
41
  $lcp_display_output .= $this->get_category_link('strong');
42
 
 
 
 
43
  // Show the conditional title:
44
  $lcp_display_output .= $this->get_conditional_title();
45
 
46
  //Add 'starting' tag. Here, I'm using an unordered list (ul) as an example:
47
- $lcp_display_output .= '<ul class="lcp_catlist">';
48
 
49
  /* Posts Loop
50
  *
@@ -61,24 +64,30 @@ global $post;
61
  while ( have_posts() ):
62
  the_post();
63
 
 
 
 
64
  //Start a List Item for each post:
65
- $lcp_display_output .= "<li>";
66
 
67
  //Show the title and link to the post:
68
- $lcp_display_output .= $this->get_post_title($post, 'h3', 'lcp_post');
69
 
70
  //Show comments:
71
  $lcp_display_output .= $this->get_comments($post);
72
 
73
  //Show date:
74
- $lcp_display_output .= ' ' . $this->get_date($post);
75
 
76
  //Show date modified:
77
- $lcp_display_output .= ' ' . $this->get_modified_date($post);
78
 
79
  //Show author
80
  $lcp_display_output .= $this->get_author($post);
81
 
 
 
 
82
  //Custom fields:
83
  $lcp_display_output .= $this->get_custom_fields($post);
84
 
@@ -101,11 +110,14 @@ while ( have_posts() ):
101
  $lcp_display_output .= $this->get_posts_morelink($post);
102
 
103
  //Close li tag
104
- $lcp_display_output .= '</li>';
105
  endwhile;
106
 
 
 
 
107
  // Close the wrapper I opened at the beginning:
108
- $lcp_display_output .= '</ul>';
109
 
110
  // If there's a "more link", show it:
111
  $lcp_display_output .= $this->get_morelink();
@@ -116,4 +128,4 @@ $lcp_display_output .= $this->get_category_count();
116
  //Pagination
117
  $lcp_display_output .= $this->get_pagination();
118
 
119
- $this->lcp_output = $lcp_display_output;
40
  // Show category link:
41
  $lcp_display_output .= $this->get_category_link('strong');
42
 
43
+ // Show category description:
44
+ $lcp_display_output .= $this->get_category_description();
45
+
46
  // Show the conditional title:
47
  $lcp_display_output .= $this->get_conditional_title();
48
 
49
  //Add 'starting' tag. Here, I'm using an unordered list (ul) as an example:
50
+ $lcp_display_output .= $this->open_outer_tag('ul', 'lcp_catlist');
51
 
52
  /* Posts Loop
53
  *
64
  while ( have_posts() ):
65
  the_post();
66
 
67
+ // Check if protected post should be displayed
68
+ if (!$this->check_show_protected($post)) continue;
69
+
70
  //Start a List Item for each post:
71
+ $lcp_display_output .= $this->open_inner_tag($post, 'li');
72
 
73
  //Show the title and link to the post:
74
+ $lcp_display_output .= $this->get_post_title($post);
75
 
76
  //Show comments:
77
  $lcp_display_output .= $this->get_comments($post);
78
 
79
  //Show date:
80
+ $lcp_display_output .= $this->get_date($post);
81
 
82
  //Show date modified:
83
+ $lcp_display_output .= $this->get_modified_date($post);
84
 
85
  //Show author
86
  $lcp_display_output .= $this->get_author($post);
87
 
88
+ // Show post ID
89
+ $lcp_display_output .= $this->get_display_id($post);
90
+
91
  //Custom fields:
92
  $lcp_display_output .= $this->get_custom_fields($post);
93
 
110
  $lcp_display_output .= $this->get_posts_morelink($post);
111
 
112
  //Close li tag
113
+ $lcp_display_output .= $this->close_inner_tag();
114
  endwhile;
115
 
116
+ // Show no posts text if there are no posts
117
+ $lcp_display_output .= $this->get_no_posts_text();
118
+
119
  // Close the wrapper I opened at the beginning:
120
+ $lcp_display_output .= $this->close_outer_tag();
121
 
122
  // If there's a "more link", show it:
123
  $lcp_display_output .= $this->get_morelink();
128
  //Pagination
129
  $lcp_display_output .= $this->get_pagination();
130
 
131
+ $this->lcp_output = $lcp_display_output;