Plugin Directory

Changeset 2722706


Ignore:
Timestamp:
05/12/2022 12:54:36 PM (4 years ago)
Author:
tangibleinc
Message:

2.4.3

Location:
tangible-loops-and-logic
Files:
8 added
1 deleted
23 edited
137 copied

Legend:

Unmodified
Added
Removed
  • tangible-loops-and-logic/tags/2.4.3/includes/features/index.php

    r2715426 r2722706  
    66
    77require_once __DIR__.'/hyperdb/index.php';
     8require_once __DIR__.'/mobile-detect/index.php';
    89require_once __DIR__.'/vidstack-player/index.php';
  • tangible-loops-and-logic/tags/2.4.3/readme.txt

    r2717702 r2722706  
    11=== Loops & Logic ===
    2 Stable tag: 2.4.2
     2Stable tag: 2.4.3
    33Requires at least: 5.6
    4 Tested up to: 5.9
     4Tested up to: 6.0
    55Requires PHP: 7.0
    66License: GPLv2
     
    131131
    132132== Changelog ==
     133
     134= 2.4.3 =
     135
     136Release Date: 2022-05-12
     137
     138- Add Mobile Detect module
     139  - Variable type "device"
     140    - `<Get device=type />` is mobile, tablet, or desktop
     141  - Device conditions
     142    - `<If device=mobile>`
     143    - `<If device=tablet>`
     144    - `<If device=desktop>`
     145    - `<If not device=desktop>`
     146- Attachment loop: Add field for file "size" and "type"
     147- Base loop
     148  - Filter by field - For `field_compare` parameter, use the same common comparison operators as If tag
     149  - Set default loop context on author and taxonomy term archive pages
     150- Format tag
     151  - Add case "lower" and "upper"
     152  - Consolidate case conversions: camel, kebab, snake, pascal
     153- Post loop: Taxonomy query
     154  - Add parameter `child_terms=true` to include child terms for hierarchical taxonomies
     155  - Improve `terms=current` to support taxonomy term loop as well as archive page
     156- Taxonomy term loop
     157  - Add alias "terms" for "include"
     158  - Field `posts` gets posts of any post type that belong to current term
     159- Test compatibility with WordPress 6.0
    133160
    134161= 2.4.2 =
  • tangible-loops-and-logic/tags/2.4.3/tangible-loops-and-logic.php

    r2717702 r2722706  
    44 * Plugin URI: https://loop.tangible.one
    55 * Description: A template system with content type loops and conditions.
    6  * Version: 2.4.2
     6 * Version: 2.4.3
    77 * Author: Team Tangible
    88 * Author URI: https://teamtangible.com
     
    1010 */
    1111
    12 define( 'TANGIBLE_LOOPS_AND_LOGIC_VERSION', '2.4.2' );
     12define( 'TANGIBLE_LOOPS_AND_LOGIC_VERSION', '2.4.3' );
    1313
    1414require_once __DIR__ . '/vendor/tangible/plugin-framework/index.php';
  • tangible-loops-and-logic/tags/2.4.3/vendor/autoload.php

    r2717702 r2722706  
    1010require_once __DIR__ . '/composer/autoload_real.php';
    1111
    12 return ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24::getLoader();
     12return ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b::getLoader();
  • tangible-loops-and-logic/tags/2.4.3/vendor/composer/autoload_real.php

    r2717702 r2722706  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24
     5class ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b
    66{
    77    private static $loader;
     
    2323        }
    2424
    25         spl_autoload_register(array('ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24', 'loadClassLoader'), true, true);
     25        spl_autoload_register(array('ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b', 'loadClassLoader'), true, true);
    2626        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    27         spl_autoload_unregister(array('ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24', 'loadClassLoader'));
     27        spl_autoload_unregister(array('ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b', 'loadClassLoader'));
    2828
    2929        require __DIR__ . '/autoload_static.php';
    30         call_user_func(\Composer\Autoload\ComposerStaticInit5f136ea332e66fb1c0b5a02f96f2ca24::getInitializer($loader));
     30        call_user_func(\Composer\Autoload\ComposerStaticInitc7682a24ebe8ba3f0ac243b5dabd518b::getInitializer($loader));
    3131
    3232        $loader->register(true);
  • tangible-loops-and-logic/tags/2.4.3/vendor/composer/autoload_static.php

    r2717702 r2722706  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit5f136ea332e66fb1c0b5a02f96f2ca24
     7class ComposerStaticInitc7682a24ebe8ba3f0ac243b5dabd518b
    88{
    99    public static $classMap = array (
     
    1414    {
    1515        return \Closure::bind(function () use ($loader) {
    16             $loader->classMap = ComposerStaticInit5f136ea332e66fb1c0b5a02f96f2ca24::$classMap;
     16            $loader->classMap = ComposerStaticInitc7682a24ebe8ba3f0ac243b5dabd518b::$classMap;
    1717
    1818        }, null, ClassLoader::class);
  • tangible-loops-and-logic/tags/2.4.3/vendor/composer/installed.json

    r2717702 r2722706  
    3838                "type": "git",
    3939                "url": "git@bitbucket.org:/tangibleinc/tangible-loop-module.git",
    40                 "reference": "46e2251b40557f8ddc1e6a1e2163f63d80cd598f"
     40                "reference": "d68303b1abffcd796d9c9cc9f31162f8c906a7a4"
    4141            },
    42             "time": "2022-04-25T19:32:53+00:00",
     42            "time": "2022-05-12T12:10:25+00:00",
    4343            "default-branch": true,
    4444            "type": "library",
     
    6767                "type": "git",
    6868                "url": "git@bitbucket.org:/tangibleinc/tangible-template-module.git",
    69                 "reference": "1e15cdee6bedee066529a9ad8cb00c5c71b0f5dc"
     69                "reference": "3825fe4b1f92c111225ce523e963a0738ede6081"
    7070            },
    71             "time": "2022-05-03T17:33:27+00:00",
     71            "time": "2022-05-12T11:50:56+00:00",
    7272            "default-branch": true,
    7373            "type": "library",
  • tangible-loops-and-logic/tags/2.4.3/vendor/composer/installed.php

    r2717702 r2722706  
    66        'install_path' => __DIR__ . '/../../',
    77        'aliases' => array(),
    8         'reference' => '08b114502d541b906958c5102e7141f7807cc02f',
     8        'reference' => '603ee93de91b0f16d4bf6f366380706b40dbbf61',
    99        'name' => '__root__',
    1010        'dev' => false,
     
    1717            'install_path' => __DIR__ . '/../../',
    1818            'aliases' => array(),
    19             'reference' => '08b114502d541b906958c5102e7141f7807cc02f',
     19            'reference' => '603ee93de91b0f16d4bf6f366380706b40dbbf61',
    2020            'dev_requirement' => false,
    2121        ),
     
    5050                0 => '9999999-dev',
    5151            ),
    52             'reference' => '46e2251b40557f8ddc1e6a1e2163f63d80cd598f',
     52            'reference' => 'd68303b1abffcd796d9c9cc9f31162f8c906a7a4',
    5353            'dev_requirement' => false,
    5454        ),
     
    7070                0 => '9999999-dev',
    7171            ),
    72             'reference' => '1e15cdee6bedee066529a9ad8cb00c5c71b0f5dc',
     72            'reference' => '3825fe4b1f92c111225ce523e963a0738ede6081',
    7373            'dev_requirement' => false,
    7474        ),
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/context/index.php

    r2675945 r2722706  
    4141      if ($context && $context->get_name()===$type) {
    4242        return $context;
     43      }
     44    }
     45
     46    if ($type==='taxonomy_term') {
     47
     48      $context = $loop->get_context();
     49
     50      // Taxonomy term loop
     51      if (!empty($context) && $context->get_name()===$type) {
     52        return $context;
     53      }
     54
     55      // Taxonomy archive
     56      if (is_category() || is_tag() || is_tax()) {
     57        $object = get_queried_object();
     58        return $loop('taxonomy_term', [
     59          'taxonomy' => $object->taxonomy,
     60          'id' => $object->term_id
     61        ]);
    4362      }
    4463    }
     
    115134
    116135  return $loop($post_type, [
    117     'query' => clone $wp_the_query, // Assumes this loop type supports "query"
     136    'query' => clone $wp_the_query,
    118137  ]);
    119138};
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/index.php

    r2715426 r2722706  
    2626
    2727  public $name    = 'tangible_loop';
    28   public $version = '20220425';
     28  public $version = '20220512';
    2929  public $url     = '';
    3030  public $state   = [];
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/types/attachment/field.php

    r2595024 r2722706  
    6868      $value = $attachment->post_status;
    6969    break;
     70    case 'type':
    7071    case 'mime':
    7172      $value = $attachment->post_mime_type;
     
    9798      $value = pathinfo(wp_get_attachment_url($id), PATHINFO_EXTENSION);
    9899    break;
     100    case 'size':
     101      $metadata = wp_get_attachment_metadata($id);
     102      if (isset($metadata['filesize'])) return $metadata['filesize'];
     103      if (!isset($metadata['file'])) return;
     104
     105      $upload_dir = wp_upload_dir();
     106      $upload_base_dir = $upload_dir['basedir'];
     107      $size = filesize( $upload_base_dir . '/' . $metadata['file'] );
     108
     109      if (isset($args['raw'])) return $size;
     110
     111      if ( $size >= 1<<30 )
     112        return number_format($size/(1<<30),2).' GB';
     113      if ( $size >= 1<<20 )
     114        return number_format($size/(1<<20),2).' MB';
     115      if ( $size >= 1<<10 )
     116        return number_format($size/(1<<10),2).' KB';
     117
     118      return number_format($size).' bytes';
     119    break;
     120
    99121    case 'srcset':
    100122
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/types/attachment/index.php

    r2552244 r2722706  
    5757      'filename' => [ 'description' => 'File name' ],
    5858      'extension' => [ 'description' => 'File extension' ],
     59      'size' => [ 'description' => 'File size' ],
     60      'type' => [ 'description' => 'File type' ],
    5961
    6062      'srcset' => [ 'description' => 'Responsive image attribute "srcset" for img tag - Accepts optional attribute "size" for image size name (default is "medium"), or width and height values in pixels separated by comma like "400,300"' ],
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/types/base/index.php

    r2715426 r2722706  
    7474      'field_compare' => [
    7575        'target_name' => false,
    76         'description' => 'Compare using one of: "equal" (default), "not", "before", "before_inclusive", "after", "after_inclusive", "in", "not_in", "exists", "not exists"',
     76        'description' => 'Compare using one of: "is" (default), "is_not", "before", "before_inclusive", "after", "after_inclusive", "in", "not_in", "exists", "not_exists"',
    7777        'type'        => 'string',
    7878      ],
     
    243243        unset($args['field_value' . $postfix]);
    244244
    245         // Default compare is "equal", not "exists", if value is set
     245        // Default compare is "is", not "exists", if value is set
    246246        if (!isset($args['field_compare' . $postfix])) {
    247           $field['compare'] = '=';
     247          $field['compare'] = 'is';
    248248        }
    249249      }
     
    458458
    459459    // Ensure that current item exists
    460     if (empty( $this->current )) return;
     460    if (empty( $this->current )) {
     461      if ($this->index!==-1) return;
     462
     463      // Start loop if it hasn't yet
     464      $this->next();
     465      if (empty( $this->current )) return;
     466    }
    461467
    462468    // If field name is empty, return the whole item
     
    616622  // Filter
    617623
    618   function filter_by_field( $field_name, $field_compare = '=', $field_value = '', $field_type = 'string' ) {
     624  function filter_by_field( $field_name, $field_compare = 'is', $field_value = '', $field_type = 'string' ) {
    619625
    620626    $filtered_items = [];
    621627
    622628    $field_compare = strtolower( $field_compare );
     629
     630    $html = self::$loop->html;
    623631
    624632    foreach ($this->total_items as $item) {
     
    629637      $keep = false;
    630638
    631       // Evaluate comparison
     639      /**
     640       * Evaluate comparison using same logic as If tag
     641       * @see /vendor/tangible/template/logic/comparison.php
     642       */
    632643
    633644      switch ($field_compare) {
    634         case 'greater_than':
    635         case 'after':
    636         case '>':      $keep = $current_value > $field_value; break;
    637         case 'less_than':
    638         case 'before':
    639         case '<':      $keep = $current_value < $field_value; break;
    640         case 'greater_than_or_equal':
    641         case 'after_inclusive':
    642         case '>=':     $keep = $current_value >= $field_value; break;
    643         case 'less_than_or_equal':
    644         case 'before_inclusive':
    645         case '<=':     $keep = $current_value <= $field_value; break;
    646         case 'equal':
    647         case '=':      $keep = $current_value === $field_value; break;
    648 
     645        /**
     646         * For array comparisons, flip current field value and given value
     647         * because it's the opposite of how If tag works: field=X in value=X,Y,Z
     648         */
    649649        case 'in':
    650           $keep = is_array($current_value) && in_array($field_value, $current_value);
     650        case 'not_in':
     651          $keep = $html->evaluate_logic_comparison(
     652            $field_compare, $current_value, $field_value
     653          );
    651654        break;
    652         case 'not_in':
    653           $keep = is_array($current_value) && !in_array($field_value, $current_value);
    654         break;
    655 
    656         /**
    657          * For exists (and not_exists), the following are considered "empty".
    658          *
    659          * - Empty string, array, or false
    660          * - Loop instance with no items
    661          *
    662          * Notably, the number 0 *exists*.
    663          */
    664         case 'exists':
    665         case 'not_exists':
    666           $exists = self::$loop->is_instance($current_value)
    667             ? $current_value->has_next()
    668             : ($current_value===0 || !empty( $current_value ))
    669           ;
    670 
    671           $keep = $field_compare==='exists' ? $exists : !$exists;
    672         break;
     655        default:
     656          $keep = $html->evaluate_logic_comparison(
     657            $field_compare, $field_value, $current_value
     658          );
    673659      }
    674660
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/types/post/index.php

    r2715426 r2722706  
    127127
    128128      'taxonomy' => [
    129         'description' => 'Include by taxonomy ID or slug<br>Use with "term" and "taxonomy_compare" attributes',
     129        'description' => 'Include by taxonomy ID, slug, or "current" for taxonomy archive<br>Use with "term" and "taxonomy_compare" attributes',
    130130        'type'        => ['string', 'number'],
    131131      ],
     
    134134        'type'        => ['string', 'number', 'array'],
    135135      ],
     136      'child_terms' => [
     137        'description' => 'Set "true" to include child terms for hierarchical taxonomies',
     138        'type'        => ['string'],
     139      ],
     140
    136141      'taxonomy_compare' => [
    137142        'description' => 'One of "in" (default), "not", "and", "exists", and "not exists"<br>Use with "taxonomy" attribute',
     
    666671      $terms_key = 'terms' . $postfix;
    667672      $compare_key = 'taxonomy_compare' . $postfix;
     673      $include_child_terms_key = 'child_terms' . $postfix;
    668674
    669675      if (!isset($query_args[ $key ])) continue;
     
    702708      if ($compare==='NOT') $compare = 'NOT IN';
    703709
     710      // Include child terms - false by default
     711      $include_child_terms = isset($query_args[ $include_child_terms_key ]) &&
     712        $query_args[ $include_child_terms_key ]==='true'
     713      ;
     714
    704715      // Don't pass to WP_Query
    705716      unset( $query_args[ $key ] );
    706717      unset( $query_args[ $terms_key ] );
    707718      unset( $query_args[ $compare_key ] );
     719      unset( $query_args[ $include_child_terms_key ] );
    708720
    709721      // Separate IDs and slugs
     
    718730          $value_types['id'] []= $value;
    719731        } elseif (is_string($value)) {
    720           $value_types['slug'] []= $value;
     732
     733          if ($value==='current') {
     734
     735            // Current term inside taxonomy term loop or archive
     736
     737            $context = self::$loop->get_context('taxonomy_term');
     738
     739            $value_types['id'] []= !empty($context)
     740              ? $context->get_field('id')
     741              : 0 // Force empty
     742            ;
     743
     744          } else {
     745            $value_types['slug'] []= $value;
     746          }
    721747        }
    722748      }
     
    737763
    738764          'terms' => $values,
    739           'include_children' => false,
     765          'include_children' => $include_child_terms,
    740766          'operator' => $compare,
    741767        ];
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/types/taxonomy-term/field.php

    r2715426 r2722706  
    2121  if (empty( $item )) return;
    2222
    23   $id    = $item->term_id;
     23  $id = $item->term_id;
    2424
    2525  switch ( $field_name ) {
     
    133133      ], $args); // Other loop parameters
    134134
    135       return $loop('post', $loop_args);
     135      return $loop('any', $loop_args);
    136136
    137137    default:
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/loop/types/taxonomy-term/index.php

    r2715426 r2722706  
    6060        'description' => 'Exclude terms by ID(s) or slug(s)',
    6161        'type'        => ['string', 'array'],
     62      ],
     63      'terms' => [
     64        'description' => 'Alias for "include"',
     65        'type'        => ['string', 'array'],
     66        'target_name' => 'include',
    6267      ],
    6368
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/template/format/text.php

    r2715426 r2722706  
    22
    33/**
    4  * Case conversion - camel, snake, kebab, pascal
    5  *
    6  * Using utility methods in plugin framework.
     4 * Case conversion - camel, snake, kebab, pascal, lower, upper
    75 */
    8 $html->format_case = function( $content, $options = [] ) use ($html) {
     6$html->format_case = function( $content, $options = [] ) {
    97
    108  if (!isset($options['case'])) return $content;
    119
    1210  $case = $options['case'];
    13   $callback_name = "{$case}_case";
    1411
    15   if (!isset($html->framework->$callback_name)) return $content;
     12  switch ($case) {
     13    case 'kebab':
     14    case 'snake':
     15      // Snake case: hello_world - Used for PHP array keys and variable names
     16      $content = strtolower(
     17        preg_replace('/\s+/', '_',
     18          preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2',
     19            preg_replace('/[^a-zA-Z0-9]+/', '', $content)
     20          )
     21        )
     22      );
     23      if ($case==='snake') return $content;
    1624
    17   return $html->framework->$callback_name( $content );
     25      // Kebab case: hello-world - Used for post slugs and URL routes
     26      return str_replace('_', '-', $content);
     27    break;
     28    case 'camel':
     29    case 'pascal':
     30      /**
     31       * Pascal case: HelloWorld - Used for PHP and JS classes
     32       *
     33       * This will take any dash or underscore turn it into a space,
     34       * run ucwords against it so it capitalizes the first letter in
     35       * all words separated by a space then it turns and deletes all
     36       * spaces.
     37       */
     38      $content = str_replace(' ', '', ucwords(
     39        strtolower(preg_replace('/[^a-zA-Z0-9]+/', ' ', $content))
     40      ));
     41      if ($case==='pascal') return $content;
     42      // Camel case: helloWorld - Used for JS object keys and variable names
     43      return lcfirst( $content );
     44    break;
     45    case 'lower': return strtolower( $content );
     46    case 'upper': return strtoupper( $content );
     47  }
     48
     49  // Unknown case
     50  return $content;
    1851};
    1952
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/template/index.php

    r2717702 r2722706  
    2727
    2828  public $name    = 'tangible_template';
    29   public $version = '20220430';
     29  public $version = '20220512';
    3030
    3131  function load_latest_version() {
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/template/logic/comparison.php

    r2715426 r2722706  
    149149      $condition = $operand==='not_exists' ? !$c : $c;
    150150    break;
    151     case 'more_than': $condition = $current_value > $value; break;
    152     case 'more_than_or_equal': $condition = $current_value >= $value; break;
    153     case 'less_than': $condition = $current_value < $value; break;
    154     case 'less_than_or_equal': $condition = $current_value <= $value; break;
     151    case 'more_than':
     152    case 'after':
     153      $condition = $current_value > $value;
     154    break;
     155    case 'more_than_or_equal':
     156    case 'after_inclusive':
     157      $condition = $current_value >= $value;
     158    break;
     159    case 'less_than':
     160    case 'before':
     161      $condition = $current_value < $value;
     162    break;
     163    case 'less_than_or_equal':
     164    case 'before_inclusive':
     165      $condition = $current_value <= $value;
     166    break;
    155167
    156168    case 'starts_with':
     
    220232            isset($value[0]) && $value[0]==='['
    221233              ? $framework->hjson()->parse( $value )
    222               : array_map('trim', explode(',', $value)) // Command separated list
     234              : array_map('trim', explode(',', $value)) // Comma-separated list
    223235          )
    224236        )
  • tangible-loops-and-logic/tags/2.4.3/vendor/tangible/template/tags/term.php

    r2717702 r2722706  
    3737
    3838  $taxonomy_term_loop = $loop->get_context('taxonomy_term');
    39   if (!empty($taxonomy_term_loop)) {
     39  if (empty($taxonomy_term_loop)) return;
    4040
    41     // Set current loop context to taxonomy term loop
    42     $previous_context = $loop->current_context;
    43     $loop->current_context = $taxonomy_term_loop;
     41  // Set current loop context to taxonomy term loop
     42  $previous_context = $loop->current_context;
     43  $loop->current_context = $taxonomy_term_loop;
    4444
    45     $value = $html->field_tag($atts);
     45  $value = $html->field_tag($atts);
    4646
    47     // Restore loop context
    48     $loop->current_context = $previous_context;
    49     return $value;
    50   }
     47  // Restore loop context
     48  $loop->current_context = $previous_context;
     49  return $value;
    5150};
    5251
  • tangible-loops-and-logic/trunk/includes/features/index.php

    r2715426 r2722706  
    66
    77require_once __DIR__.'/hyperdb/index.php';
     8require_once __DIR__.'/mobile-detect/index.php';
    89require_once __DIR__.'/vidstack-player/index.php';
  • tangible-loops-and-logic/trunk/readme.txt

    r2717702 r2722706  
    11=== Loops & Logic ===
    2 Stable tag: 2.4.2
     2Stable tag: 2.4.3
    33Requires at least: 5.6
    4 Tested up to: 5.9
     4Tested up to: 6.0
    55Requires PHP: 7.0
    66License: GPLv2
     
    131131
    132132== Changelog ==
     133
     134= 2.4.3 =
     135
     136Release Date: 2022-05-12
     137
     138- Add Mobile Detect module
     139  - Variable type "device"
     140    - `<Get device=type />` is mobile, tablet, or desktop
     141  - Device conditions
     142    - `<If device=mobile>`
     143    - `<If device=tablet>`
     144    - `<If device=desktop>`
     145    - `<If not device=desktop>`
     146- Attachment loop: Add field for file "size" and "type"
     147- Base loop
     148  - Filter by field - For `field_compare` parameter, use the same common comparison operators as If tag
     149  - Set default loop context on author and taxonomy term archive pages
     150- Format tag
     151  - Add case "lower" and "upper"
     152  - Consolidate case conversions: camel, kebab, snake, pascal
     153- Post loop: Taxonomy query
     154  - Add parameter `child_terms=true` to include child terms for hierarchical taxonomies
     155  - Improve `terms=current` to support taxonomy term loop as well as archive page
     156- Taxonomy term loop
     157  - Add alias "terms" for "include"
     158  - Field `posts` gets posts of any post type that belong to current term
     159- Test compatibility with WordPress 6.0
    133160
    134161= 2.4.2 =
  • tangible-loops-and-logic/trunk/tangible-loops-and-logic.php

    r2717702 r2722706  
    44 * Plugin URI: https://loop.tangible.one
    55 * Description: A template system with content type loops and conditions.
    6  * Version: 2.4.2
     6 * Version: 2.4.3
    77 * Author: Team Tangible
    88 * Author URI: https://teamtangible.com
     
    1010 */
    1111
    12 define( 'TANGIBLE_LOOPS_AND_LOGIC_VERSION', '2.4.2' );
     12define( 'TANGIBLE_LOOPS_AND_LOGIC_VERSION', '2.4.3' );
    1313
    1414require_once __DIR__ . '/vendor/tangible/plugin-framework/index.php';
  • tangible-loops-and-logic/trunk/vendor/autoload.php

    r2717702 r2722706  
    1010require_once __DIR__ . '/composer/autoload_real.php';
    1111
    12 return ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24::getLoader();
     12return ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b::getLoader();
  • tangible-loops-and-logic/trunk/vendor/composer/autoload_real.php

    r2717702 r2722706  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24
     5class ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b
    66{
    77    private static $loader;
     
    2323        }
    2424
    25         spl_autoload_register(array('ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24', 'loadClassLoader'), true, true);
     25        spl_autoload_register(array('ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b', 'loadClassLoader'), true, true);
    2626        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
    27         spl_autoload_unregister(array('ComposerAutoloaderInit5f136ea332e66fb1c0b5a02f96f2ca24', 'loadClassLoader'));
     27        spl_autoload_unregister(array('ComposerAutoloaderInitc7682a24ebe8ba3f0ac243b5dabd518b', 'loadClassLoader'));
    2828
    2929        require __DIR__ . '/autoload_static.php';
    30         call_user_func(\Composer\Autoload\ComposerStaticInit5f136ea332e66fb1c0b5a02f96f2ca24::getInitializer($loader));
     30        call_user_func(\Composer\Autoload\ComposerStaticInitc7682a24ebe8ba3f0ac243b5dabd518b::getInitializer($loader));
    3131
    3232        $loader->register(true);
  • tangible-loops-and-logic/trunk/vendor/composer/autoload_static.php

    r2717702 r2722706  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit5f136ea332e66fb1c0b5a02f96f2ca24
     7class ComposerStaticInitc7682a24ebe8ba3f0ac243b5dabd518b
    88{
    99    public static $classMap = array (
     
    1414    {
    1515        return \Closure::bind(function () use ($loader) {
    16             $loader->classMap = ComposerStaticInit5f136ea332e66fb1c0b5a02f96f2ca24::$classMap;
     16            $loader->classMap = ComposerStaticInitc7682a24ebe8ba3f0ac243b5dabd518b::$classMap;
    1717
    1818        }, null, ClassLoader::class);
  • tangible-loops-and-logic/trunk/vendor/composer/installed.json

    r2717702 r2722706  
    3838                "type": "git",
    3939                "url": "git@bitbucket.org:/tangibleinc/tangible-loop-module.git",
    40                 "reference": "46e2251b40557f8ddc1e6a1e2163f63d80cd598f"
     40                "reference": "d68303b1abffcd796d9c9cc9f31162f8c906a7a4"
    4141            },
    42             "time": "2022-04-25T19:32:53+00:00",
     42            "time": "2022-05-12T12:10:25+00:00",
    4343            "default-branch": true,
    4444            "type": "library",
     
    6767                "type": "git",
    6868                "url": "git@bitbucket.org:/tangibleinc/tangible-template-module.git",
    69                 "reference": "1e15cdee6bedee066529a9ad8cb00c5c71b0f5dc"
     69                "reference": "3825fe4b1f92c111225ce523e963a0738ede6081"
    7070            },
    71             "time": "2022-05-03T17:33:27+00:00",
     71            "time": "2022-05-12T11:50:56+00:00",
    7272            "default-branch": true,
    7373            "type": "library",
  • tangible-loops-and-logic/trunk/vendor/composer/installed.php

    r2717702 r2722706  
    66        'install_path' => __DIR__ . '/../../',
    77        'aliases' => array(),
    8         'reference' => '08b114502d541b906958c5102e7141f7807cc02f',
     8        'reference' => '603ee93de91b0f16d4bf6f366380706b40dbbf61',
    99        'name' => '__root__',
    1010        'dev' => false,
     
    1717            'install_path' => __DIR__ . '/../../',
    1818            'aliases' => array(),
    19             'reference' => '08b114502d541b906958c5102e7141f7807cc02f',
     19            'reference' => '603ee93de91b0f16d4bf6f366380706b40dbbf61',
    2020            'dev_requirement' => false,
    2121        ),
     
    5050                0 => '9999999-dev',
    5151            ),
    52             'reference' => '46e2251b40557f8ddc1e6a1e2163f63d80cd598f',
     52            'reference' => 'd68303b1abffcd796d9c9cc9f31162f8c906a7a4',
    5353            'dev_requirement' => false,
    5454        ),
     
    7070                0 => '9999999-dev',
    7171            ),
    72             'reference' => '1e15cdee6bedee066529a9ad8cb00c5c71b0f5dc',
     72            'reference' => '3825fe4b1f92c111225ce523e963a0738ede6081',
    7373            'dev_requirement' => false,
    7474        ),
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/context/index.php

    r2675945 r2722706  
    4141      if ($context && $context->get_name()===$type) {
    4242        return $context;
     43      }
     44    }
     45
     46    if ($type==='taxonomy_term') {
     47
     48      $context = $loop->get_context();
     49
     50      // Taxonomy term loop
     51      if (!empty($context) && $context->get_name()===$type) {
     52        return $context;
     53      }
     54
     55      // Taxonomy archive
     56      if (is_category() || is_tag() || is_tax()) {
     57        $object = get_queried_object();
     58        return $loop('taxonomy_term', [
     59          'taxonomy' => $object->taxonomy,
     60          'id' => $object->term_id
     61        ]);
    4362      }
    4463    }
     
    115134
    116135  return $loop($post_type, [
    117     'query' => clone $wp_the_query, // Assumes this loop type supports "query"
     136    'query' => clone $wp_the_query,
    118137  ]);
    119138};
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/index.php

    r2715426 r2722706  
    2626
    2727  public $name    = 'tangible_loop';
    28   public $version = '20220425';
     28  public $version = '20220512';
    2929  public $url     = '';
    3030  public $state   = [];
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/types/attachment/field.php

    r2595024 r2722706  
    6868      $value = $attachment->post_status;
    6969    break;
     70    case 'type':
    7071    case 'mime':
    7172      $value = $attachment->post_mime_type;
     
    9798      $value = pathinfo(wp_get_attachment_url($id), PATHINFO_EXTENSION);
    9899    break;
     100    case 'size':
     101      $metadata = wp_get_attachment_metadata($id);
     102      if (isset($metadata['filesize'])) return $metadata['filesize'];
     103      if (!isset($metadata['file'])) return;
     104
     105      $upload_dir = wp_upload_dir();
     106      $upload_base_dir = $upload_dir['basedir'];
     107      $size = filesize( $upload_base_dir . '/' . $metadata['file'] );
     108
     109      if (isset($args['raw'])) return $size;
     110
     111      if ( $size >= 1<<30 )
     112        return number_format($size/(1<<30),2).' GB';
     113      if ( $size >= 1<<20 )
     114        return number_format($size/(1<<20),2).' MB';
     115      if ( $size >= 1<<10 )
     116        return number_format($size/(1<<10),2).' KB';
     117
     118      return number_format($size).' bytes';
     119    break;
     120
    99121    case 'srcset':
    100122
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/types/attachment/index.php

    r2552244 r2722706  
    5757      'filename' => [ 'description' => 'File name' ],
    5858      'extension' => [ 'description' => 'File extension' ],
     59      'size' => [ 'description' => 'File size' ],
     60      'type' => [ 'description' => 'File type' ],
    5961
    6062      'srcset' => [ 'description' => 'Responsive image attribute "srcset" for img tag - Accepts optional attribute "size" for image size name (default is "medium"), or width and height values in pixels separated by comma like "400,300"' ],
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/types/base/index.php

    r2715426 r2722706  
    7474      'field_compare' => [
    7575        'target_name' => false,
    76         'description' => 'Compare using one of: "equal" (default), "not", "before", "before_inclusive", "after", "after_inclusive", "in", "not_in", "exists", "not exists"',
     76        'description' => 'Compare using one of: "is" (default), "is_not", "before", "before_inclusive", "after", "after_inclusive", "in", "not_in", "exists", "not_exists"',
    7777        'type'        => 'string',
    7878      ],
     
    243243        unset($args['field_value' . $postfix]);
    244244
    245         // Default compare is "equal", not "exists", if value is set
     245        // Default compare is "is", not "exists", if value is set
    246246        if (!isset($args['field_compare' . $postfix])) {
    247           $field['compare'] = '=';
     247          $field['compare'] = 'is';
    248248        }
    249249      }
     
    458458
    459459    // Ensure that current item exists
    460     if (empty( $this->current )) return;
     460    if (empty( $this->current )) {
     461      if ($this->index!==-1) return;
     462
     463      // Start loop if it hasn't yet
     464      $this->next();
     465      if (empty( $this->current )) return;
     466    }
    461467
    462468    // If field name is empty, return the whole item
     
    616622  // Filter
    617623
    618   function filter_by_field( $field_name, $field_compare = '=', $field_value = '', $field_type = 'string' ) {
     624  function filter_by_field( $field_name, $field_compare = 'is', $field_value = '', $field_type = 'string' ) {
    619625
    620626    $filtered_items = [];
    621627
    622628    $field_compare = strtolower( $field_compare );
     629
     630    $html = self::$loop->html;
    623631
    624632    foreach ($this->total_items as $item) {
     
    629637      $keep = false;
    630638
    631       // Evaluate comparison
     639      /**
     640       * Evaluate comparison using same logic as If tag
     641       * @see /vendor/tangible/template/logic/comparison.php
     642       */
    632643
    633644      switch ($field_compare) {
    634         case 'greater_than':
    635         case 'after':
    636         case '>':      $keep = $current_value > $field_value; break;
    637         case 'less_than':
    638         case 'before':
    639         case '<':      $keep = $current_value < $field_value; break;
    640         case 'greater_than_or_equal':
    641         case 'after_inclusive':
    642         case '>=':     $keep = $current_value >= $field_value; break;
    643         case 'less_than_or_equal':
    644         case 'before_inclusive':
    645         case '<=':     $keep = $current_value <= $field_value; break;
    646         case 'equal':
    647         case '=':      $keep = $current_value === $field_value; break;
    648 
     645        /**
     646         * For array comparisons, flip current field value and given value
     647         * because it's the opposite of how If tag works: field=X in value=X,Y,Z
     648         */
    649649        case 'in':
    650           $keep = is_array($current_value) && in_array($field_value, $current_value);
     650        case 'not_in':
     651          $keep = $html->evaluate_logic_comparison(
     652            $field_compare, $current_value, $field_value
     653          );
    651654        break;
    652         case 'not_in':
    653           $keep = is_array($current_value) && !in_array($field_value, $current_value);
    654         break;
    655 
    656         /**
    657          * For exists (and not_exists), the following are considered "empty".
    658          *
    659          * - Empty string, array, or false
    660          * - Loop instance with no items
    661          *
    662          * Notably, the number 0 *exists*.
    663          */
    664         case 'exists':
    665         case 'not_exists':
    666           $exists = self::$loop->is_instance($current_value)
    667             ? $current_value->has_next()
    668             : ($current_value===0 || !empty( $current_value ))
    669           ;
    670 
    671           $keep = $field_compare==='exists' ? $exists : !$exists;
    672         break;
     655        default:
     656          $keep = $html->evaluate_logic_comparison(
     657            $field_compare, $field_value, $current_value
     658          );
    673659      }
    674660
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/types/post/index.php

    r2715426 r2722706  
    127127
    128128      'taxonomy' => [
    129         'description' => 'Include by taxonomy ID or slug<br>Use with "term" and "taxonomy_compare" attributes',
     129        'description' => 'Include by taxonomy ID, slug, or "current" for taxonomy archive<br>Use with "term" and "taxonomy_compare" attributes',
    130130        'type'        => ['string', 'number'],
    131131      ],
     
    134134        'type'        => ['string', 'number', 'array'],
    135135      ],
     136      'child_terms' => [
     137        'description' => 'Set "true" to include child terms for hierarchical taxonomies',
     138        'type'        => ['string'],
     139      ],
     140
    136141      'taxonomy_compare' => [
    137142        'description' => 'One of "in" (default), "not", "and", "exists", and "not exists"<br>Use with "taxonomy" attribute',
     
    666671      $terms_key = 'terms' . $postfix;
    667672      $compare_key = 'taxonomy_compare' . $postfix;
     673      $include_child_terms_key = 'child_terms' . $postfix;
    668674
    669675      if (!isset($query_args[ $key ])) continue;
     
    702708      if ($compare==='NOT') $compare = 'NOT IN';
    703709
     710      // Include child terms - false by default
     711      $include_child_terms = isset($query_args[ $include_child_terms_key ]) &&
     712        $query_args[ $include_child_terms_key ]==='true'
     713      ;
     714
    704715      // Don't pass to WP_Query
    705716      unset( $query_args[ $key ] );
    706717      unset( $query_args[ $terms_key ] );
    707718      unset( $query_args[ $compare_key ] );
     719      unset( $query_args[ $include_child_terms_key ] );
    708720
    709721      // Separate IDs and slugs
     
    718730          $value_types['id'] []= $value;
    719731        } elseif (is_string($value)) {
    720           $value_types['slug'] []= $value;
     732
     733          if ($value==='current') {
     734
     735            // Current term inside taxonomy term loop or archive
     736
     737            $context = self::$loop->get_context('taxonomy_term');
     738
     739            $value_types['id'] []= !empty($context)
     740              ? $context->get_field('id')
     741              : 0 // Force empty
     742            ;
     743
     744          } else {
     745            $value_types['slug'] []= $value;
     746          }
    721747        }
    722748      }
     
    737763
    738764          'terms' => $values,
    739           'include_children' => false,
     765          'include_children' => $include_child_terms,
    740766          'operator' => $compare,
    741767        ];
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/types/taxonomy-term/field.php

    r2715426 r2722706  
    2121  if (empty( $item )) return;
    2222
    23   $id    = $item->term_id;
     23  $id = $item->term_id;
    2424
    2525  switch ( $field_name ) {
     
    133133      ], $args); // Other loop parameters
    134134
    135       return $loop('post', $loop_args);
     135      return $loop('any', $loop_args);
    136136
    137137    default:
  • tangible-loops-and-logic/trunk/vendor/tangible/loop/types/taxonomy-term/index.php

    r2715426 r2722706  
    6060        'description' => 'Exclude terms by ID(s) or slug(s)',
    6161        'type'        => ['string', 'array'],
     62      ],
     63      'terms' => [
     64        'description' => 'Alias for "include"',
     65        'type'        => ['string', 'array'],
     66        'target_name' => 'include',
    6267      ],
    6368
  • tangible-loops-and-logic/trunk/vendor/tangible/template/format/text.php

    r2715426 r2722706  
    22
    33/**
    4  * Case conversion - camel, snake, kebab, pascal
    5  *
    6  * Using utility methods in plugin framework.
     4 * Case conversion - camel, snake, kebab, pascal, lower, upper
    75 */
    8 $html->format_case = function( $content, $options = [] ) use ($html) {
     6$html->format_case = function( $content, $options = [] ) {
    97
    108  if (!isset($options['case'])) return $content;
    119
    1210  $case = $options['case'];
    13   $callback_name = "{$case}_case";
    1411
    15   if (!isset($html->framework->$callback_name)) return $content;
     12  switch ($case) {
     13    case 'kebab':
     14    case 'snake':
     15      // Snake case: hello_world - Used for PHP array keys and variable names
     16      $content = strtolower(
     17        preg_replace('/\s+/', '_',
     18          preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2',
     19            preg_replace('/[^a-zA-Z0-9]+/', '', $content)
     20          )
     21        )
     22      );
     23      if ($case==='snake') return $content;
    1624
    17   return $html->framework->$callback_name( $content );
     25      // Kebab case: hello-world - Used for post slugs and URL routes
     26      return str_replace('_', '-', $content);
     27    break;
     28    case 'camel':
     29    case 'pascal':
     30      /**
     31       * Pascal case: HelloWorld - Used for PHP and JS classes
     32       *
     33       * This will take any dash or underscore turn it into a space,
     34       * run ucwords against it so it capitalizes the first letter in
     35       * all words separated by a space then it turns and deletes all
     36       * spaces.
     37       */
     38      $content = str_replace(' ', '', ucwords(
     39        strtolower(preg_replace('/[^a-zA-Z0-9]+/', ' ', $content))
     40      ));
     41      if ($case==='pascal') return $content;
     42      // Camel case: helloWorld - Used for JS object keys and variable names
     43      return lcfirst( $content );
     44    break;
     45    case 'lower': return strtolower( $content );
     46    case 'upper': return strtoupper( $content );
     47  }
     48
     49  // Unknown case
     50  return $content;
    1851};
    1952
  • tangible-loops-and-logic/trunk/vendor/tangible/template/index.php

    r2717702 r2722706  
    2727
    2828  public $name    = 'tangible_template';
    29   public $version = '20220430';
     29  public $version = '20220512';
    3030
    3131  function load_latest_version() {
  • tangible-loops-and-logic/trunk/vendor/tangible/template/logic/comparison.php

    r2715426 r2722706  
    149149      $condition = $operand==='not_exists' ? !$c : $c;
    150150    break;
    151     case 'more_than': $condition = $current_value > $value; break;
    152     case 'more_than_or_equal': $condition = $current_value >= $value; break;
    153     case 'less_than': $condition = $current_value < $value; break;
    154     case 'less_than_or_equal': $condition = $current_value <= $value; break;
     151    case 'more_than':
     152    case 'after':
     153      $condition = $current_value > $value;
     154    break;
     155    case 'more_than_or_equal':
     156    case 'after_inclusive':
     157      $condition = $current_value >= $value;
     158    break;
     159    case 'less_than':
     160    case 'before':
     161      $condition = $current_value < $value;
     162    break;
     163    case 'less_than_or_equal':
     164    case 'before_inclusive':
     165      $condition = $current_value <= $value;
     166    break;
    155167
    156168    case 'starts_with':
     
    220232            isset($value[0]) && $value[0]==='['
    221233              ? $framework->hjson()->parse( $value )
    222               : array_map('trim', explode(',', $value)) // Command separated list
     234              : array_map('trim', explode(',', $value)) // Comma-separated list
    223235          )
    224236        )
  • tangible-loops-and-logic/trunk/vendor/tangible/template/tags/term.php

    r2717702 r2722706  
    3737
    3838  $taxonomy_term_loop = $loop->get_context('taxonomy_term');
    39   if (!empty($taxonomy_term_loop)) {
     39  if (empty($taxonomy_term_loop)) return;
    4040
    41     // Set current loop context to taxonomy term loop
    42     $previous_context = $loop->current_context;
    43     $loop->current_context = $taxonomy_term_loop;
     41  // Set current loop context to taxonomy term loop
     42  $previous_context = $loop->current_context;
     43  $loop->current_context = $taxonomy_term_loop;
    4444
    45     $value = $html->field_tag($atts);
     45  $value = $html->field_tag($atts);
    4646
    47     // Restore loop context
    48     $loop->current_context = $previous_context;
    49     return $value;
    50   }
     47  // Restore loop context
     48  $loop->current_context = $previous_context;
     49  return $value;
    5150};
    5251
Note: See TracChangeset for help on using the changeset viewer.