Esempio n. 1
0
def metadata_exists(meta_type, object_id, meta_key):
    ''' Determine if a meta key is set for a given object
  @param string meta_type Type of object metadata is for (e.g., comment, post, or user)
  @param int    object_id ID of the object metadata is for
  @param string meta_key  Metadata key.
  @return bool True of the key is set, False if not.
  '''
    if not meta_type or not Php.is_numeric(object_id):
        return False

    object_id = xFn.AbsInt(object_id)
    if not object_id:
        return False

    # This filter is documented in wp-includes/meta.php */
    check = WiPg.apply_filters("get_{}_metadata".format(meta_type), None,
                               object_id, meta_key, True)
    if None is not check:
        return bool(check)

    meta_cache = WiCa.wp_cache_get(object_id, meta_type + '_meta')

    if not meta_cache:
        meta_cache = update_meta_cache(meta_type, array(object_id))
        meta_cache = meta_cache[object_id]

    if Php.isset(meta_cache, meta_key):
        return True
    return False
Esempio n. 2
0
    def parse_orderby(self, orderby_raw):
        ''' Parse and sanitize 'orderby' keys passed to the term query.
    @global wpdb wpdb WordPress database abstraction object.
    @param string orderby_raw Alias for the field to order by.
    @return string|False Value to used in the ORDER clause. False otherwise.
    '''
        _orderby = Php.strtolower(orderby_raw)
        maybe_orderby_meta = False

        if Php.in_array(_orderby, array('term_id', 'name', 'slug',
                                        'term_group'), True):
            orderby = "t.$_orderby"
        elif Php.in_array(
                _orderby,
                array('count', 'parent', 'taxonomy', 'term_taxonomy_id',
                      'description'), True):
            orderby = "tt." + _orderby
        elif 'term_order' == _orderby:
            orderby = 'tr.term_order'
        if 'count' == _orderby:
            orderby = 'tt.count'
        elif 'name' == _orderby:
            orderby = 't.name'
        elif 'slug' == _orderby:
            orderby = 't.slug'

        elif 'include' == _orderby and not Php.empty(self.query_vars,
                                                     'include'):
            include = Php.implode(
                ',', WiFc.wp_parse_id_list(self.query_vars['include']))
            orderby = "FIELD( t.term_id, {} )".format(include)
        elif 'none' == _orderby:
            orderby = ''  # elif Php.empty(locals(), '_orderby') or ...
        elif not _orderby or 'id' == _orderby or 'term_id' == _orderby:
            orderby = 't.term_id'
        else:
            orderby = 't.name'

            # This may be a value of orderby related to meta.
            maybe_orderby_meta = True

        # Filters the ORDERBY clause of the terms query.
        # @param string orderby    `ORDERBY` clause of the terms query.
        # @param array  args       An array of terms query arguments.
        # @param array  taxonomies An array of taxonomies.
        orderby = WiPg.apply_filters('get_terms_orderby', orderby,
                                     self.query_vars,
                                     self.query_vars['taxonomy'])

        # Run after the 'get_terms_orderby' filter for backward compatibility.
        if maybe_orderby_meta:
            maybe_orderby_meta = self.parse_orderby_meta(_orderby)
            if maybe_orderby_meta:
                orderby = maybe_orderby_meta

        return orderby
Esempio n. 3
0
 def wp_doing_ajax(self):
     ''' Determines whether the current request is a WordPress Ajax request.
 @return bool True if it's a WordPress Ajax request, false otherwise.
 '''
     import wp.i.plugin as WiPg
     # Filters whether the current request is a WordPress Ajax request.
     # @param bool wp_doing_ajax Whether the current request is a WP Ajax request
     return WiPg.apply_filters(
         'wp_doing_ajax',
         self.defined('DOING_AJAX') and self.DOING_AJAX)
Esempio n. 4
0
    def parse_query(self, query=''):
        ''' Parse arguments passed to the term query with default query parameters
    @param string|array query WP_Term_Query arguments. See WP_Term_Query::__construct()
    '''
        if not query:  # if Php.empty(locals(), 'query'):
            query = self.query_vars

        print("WcTQ.parse_query: query=", query)
        taxonomies = Php.Array(query['taxonomy']) if Php.isset(
            query, 'taxonomy') else None
        print("WcTQ.parse_query: taxonomies=", taxonomies)

        # Filters the terms query default arguments.
        # Use {@see 'get_terms_args'} to filter the passed arguments.
        # @param array defaults   An array of default get_terms() arguments.
        # @param array taxonomies An array of taxonomies.
        self.query_var_defaults = WiPg.apply_filters('get_terms_defaults',
                                                     self.query_var_defaults,
                                                     taxonomies)

        query = WiFc.wp_parse_args(query, self.query_var_defaults)
        print("WcTQ.parse_query: query=", query)

        query['number'] = Php.absint(query['number'])
        query['offset'] = Php.absint(query['offset'])

        # 'parent' overrides 'child_of'.
        #must use Php.intval or int(''): invalid literal for int() with base 10: ''
        if 0 < Php.intval(query['parent']):
            query['child_of'] = False

        if 'all' == query['get']:
            query['childless'] = False
            query['child_of'] = 0
            query['hide_empty'] = 0
            query['hierarchical'] = False
            query['pad_counts'] = False

        query['taxonomy'] = taxonomies
        print("WcTQ.parse_query: taxonomies=", taxonomies)

        self.query_vars = query

        # Fires after term query vars have been parsed.
        # @param WP_Term_Query self Current instance of WP_Term_Query.
        WiPg.do_action('parse_term_query', self)
Esempio n. 5
0
def sanitize_meta(meta_key, meta_value, object_type):
    ''' Sanitize meta value.
  @param string meta_key   Meta key
  @param mixed  meta_value Meta value to sanitize
  @param string meta_type  Type of meta
  @return mixed Sanitized meta_value
  '''
    # Filter the sanitization of a specific meta key of a specific meta type.
    # The dynamic portions of the hook name, `meta_type`, and `meta_key`,
    # refer to the metadata object type (comment, post, or user) and the meta
    # key value, respectively.
    # @param mixed  meta_value   Meta value to sanitize.
    # @param string meta_key     Meta key.
    # @param string object_type  Object type.
    return WiPg.apply_filters(
        "sanitize_{}_meta_{}".format(object_type, meta_key), meta_value,
        meta_key, object_type)
Esempio n. 6
0
    def find_compatible_table_alias(self, clause, parent_query):
        alias = False

        for sibling in parent_query:
            # If the sibling has no alias yet, there's nothing to check.
            if Php.empty(sibling, 'alias'):
                continue

            # We're only interested in siblings that are first-order clauses.
            if not Php.is_array(sibling) or not self.is_first_order_clause(
                    sibling):
                continue

            compatible_compares = array()

            # Clauses connected by OR can share joins as long as they have "positive" operators.
            if 'OR' == parent_query['relation']:
                compatible_compares = array('=', 'IN', 'BETWEEN', 'LIKE',
                                            'REGEXP', 'RLIKE', '>', '>=', '<',
                                            '<=')

            # Clauses joined by AND with "negative" operators share a join only if they also share a key.
            elif (Php.isset(sibling, 'key') and Php.isset(clause, 'key')
                  and sibling['key'] == clause['key']):
                compatible_compares = array('!=', 'NOT IN', 'NOT LIKE')

            clause_compare = clause['compare'].upper()
            sibling_compare = sibling['compare'].upper()
            if (Php.in_array(clause_compare, compatible_compares)
                    and Php.in_array(sibling_compare, compatible_compares)):
                alias = sibling['alias']
                break

        # Filters the table alias identified as compatible with the current clause.
        # @param string|bool alias        Table alias, or False if none was found.
        # @param array       clause       First-order query clause.
        # @param array       parent_query Parent of clause.
        # @param object      self         WP_Meta_Query object.
        return WiPg.apply_filters('meta_query_find_compatible_table_alias',
                                  alias, clause, parent_query, self)
Esempio n. 7
0
    def get_terms(self):
        ''' Get terms, based on query_vars.
    @global wpdb wpdb WordPress database abstraction object.
    @return array
    '''
        import wp.i.taxonomy as WiTx
        wpdb = WpC.WB.Wj.wpdb  # global wpdb

        self.parse_query(self.query_vars)
        args = self.query_vars
        #pprint(self.query_vars)  # TypeError: unhashable type: 'instancemethod'
        # userdata is array, inspect.ismethod(A.__repr__) is True
        print('WP_Term_Query.get_terms: self.query_vars=', self.query_vars)

        # Set up meta_query so it's available to 'pre_get_terms'.
        self.meta_query = WcMQ.WP_Meta_Query()
        self.meta_query.parse_query_vars(args)

        # Fires before terms are retrieved.
        # @param WP_Term_Query self Current instance of WP_Term_Query.
        WiPg.do_action('pre_get_terms', self)

        taxonomies = args['taxonomy']
        print("WcTQ.get_terms: taxonomies=", taxonomies)

        # Save queries by not crawling the tree in the case of multiple taxes or a flat tax.
        has_hierarchical_tax = False
        if taxonomies:
            for _tax in taxonomies:
                if WiTx.is_taxonomy_hierarchical(_tax):
                    has_hierarchical_tax = True

        if not has_hierarchical_tax:
            args['hierarchical'] = False
            args['pad_counts'] = False

        # 'parent' overrides 'child_of'.
        if 0 < Php.intval(args['parent']):
            args['child_of'] = False

        if 'all' == args['get']:
            args['childless'] = False
            args['child_of'] = 0
            args['hide_empty'] = 0
            args['hierarchical'] = False
            args['pad_counts'] = False

        # Filters the terms query arguments.
        # @param array args       An array of get_terms() arguments.
        # @param array taxonomies An array of taxonomies.
        args = WiPg.apply_filters('get_terms_args', args, taxonomies)
        #pprint(args)  # TypeError: unhashable type: 'instancemethod'
        # userdata is array, inspect.ismethod(A.__repr__) is True
        print('WP_Term_Query.get_terms: args=', args)

        # Avoid the query if the queried parent/child_of term has no descendants.
        child_of = args['child_of']
        parent = args['parent']

        if child_of:
            _parent = child_of
        elif parent:
            _parent = parent
        else:
            _parent = False

        if _parent:
            in_hierarchy = False
            for _tax in taxonomies:
                hierarchy = WiTx._get_term_hierarchy(_tax)

                if Php.isset(hierarchy, _parent):
                    in_hierarchy = True

            if not in_hierarchy:
                return array()

        # 'term_order' is a legal sort order only when joining the relationship
        #    table.
        _orderby = self.query_vars['orderby']
        if 'term_order' == _orderby and Php.empty(self.query_vars,
                                                  'object_ids'):
            _orderby = 'term_id'
        orderby = self.parse_orderby(_orderby)

        if orderby:
            orderby = "ORDER BY " + orderby

        order = self.parse_order(self.query_vars['order'])

        if taxonomies:
            self.sql_clauses['where']['taxonomy'] = (
                "tt.taxonomy IN ('" +
                Php.implode("', '", Php.array_map(WiF.esc_sql, taxonomies)) +
                "')")

        exclude = args['exclude']
        exclude_tree = args['exclude_tree']
        include = args['include']

        inclusions = ''
        if include:  # if not Php.empty(locals(), 'include'):
            exclude = ''
            exclude_tree = ''
            inclusions = Php.implode(',', WiFc.wp_parse_id_list(include))

        if inclusions:  # if not Php.empty(locals(), 'inclusions'):
            self.sql_clauses['where']['inclusions'] = ('t.term_id IN ( ' +
                                                       inclusions + ' )')

        exclusions = array()  # Php.array_map( int, exclusions=List)
        if exclude_tree:  # if not Php.empty(locals(), 'exclude_tree'):
            exclude_tree = WiFc.wp_parse_id_list(exclude_tree)
            excluded_children = exclude_tree
            for extrunk in exclude_tree:
                excluded_children = Php.array_merge(
                    excluded_children,
                    Php.Array(
                        get_terms(
                            taxonomies[0],
                            array(
                                ('child_of', Php.intval(extrunk)),
                                ('fields', 'ids'),
                                ('hide_empty', 0),
                            ))))
            exclusions = Php.array_merge(excluded_children, exclusions)

        if exclude:  # if not Php.empty(locals(), 'exclude'):
            exclusions = Php.array_merge(WiFc.wp_parse_id_list(exclude),
                                         exclusions)

        # 'childless' terms are those without an entry in the flattened term hierarchy.
        childless = bool(args['childless'])
        if childless:
            for _tax in taxonomies:
                term_hierarchy = WiTx._get_term_hierarchy(_tax)
                exclusions = Php.array_merge(Php.array_keys(term_hierarchy),
                                             exclusions)

        if exclusions:  # if not Php.empty(locals(), 'exclusions'):
            exclusions = 't.term_id NOT IN (' + Php.implode(
                ',', Php.array_map(Php.intval, exclusions)) + ')'
        else:
            exclusions = ''

        # Filters the terms to exclude from the terms query.
        # @param string exclusions `NOT IN` clause of the terms query.
        # @param array  args       An array of terms query arguments.
        # @param array  taxonomies An array of taxonomies.
        exclusions = WiPg.apply_filters('list_terms_exclusions', exclusions,
                                        args, taxonomies)

        if exclusions:  # if not Php.empty(locals(), 'exclusions'):
            # Must do string manipulation here for backward compatibility with filter.
            self.sql_clauses['where']['exclusions'] = preg_replace(
                '/^\s*AND\s*/', '', exclusions)

        print("\n WcTQ.get_terms: args['name'] =", args['name'])

        print("WcTQ.get_terms: taxonomies=", taxonomies)
        if not Php.empty(args, 'name'):
            names = Php.Array(args['name'])
            print("WcTQ.get_terms: names=", names, taxonomies)
            #foreach ( names as &_name ) {
            #modify list entries during for loop stackoverflow.com/questions/4081217
            for k, _name in names.items(
            ):  #use enumerate(names) if type(names)=list
                # `sanitize_term_field()` returns slashed data.
                #_name = Php.stripslashes( WiTx.sanitize_term_field(
                #                      'name', _name, 0, Php.reset(taxonomies), 'db'))
                names[k] = Php.stripslashes(
                    WiTx.sanitize_term_field('name', _name, 0,
                                             Php.reset(taxonomies), 'db'))

            print("WcTQ.get_terms: names=", names, taxonomies)
            self.sql_clauses['where']['name'] = "t.name IN ('" + Php.implode(
                "', '", Php.array_map(WiF.esc_sql, names)) + "')"

        if not Php.empty(args, 'slug'):
            if Php.is_array(args['slug']):
                slug = Php.array_map(WiF.sanitize_title, args['slug'])
                self.sql_clauses['where'][
                    'slug'] = "t.slug IN ('" + Php.implode("', '", slug) + "')"
            else:
                slug = WiF.sanitize_title(args['slug'])
                self.sql_clauses['where']['slug'] = "t.slug = 'slug'"

        if not Php.empty(args, 'term_taxonomy_id'):
            if Php.is_array(args['term_taxonomy_id']):
                tt_ids = Php.implode(
                    ',', Php.array_map(Php.intval, args['term_taxonomy_id']))
                self.sql_clauses['where']['term_taxonomy_id'] = \
                                            "tt.term_taxonomy_id IN ({})".format(tt_ids)
            else:
                self.sql_clauses['where']['term_taxonomy_id'] = wpdb.prepare(
                    "tt.term_taxonomy_id = %s",
                    args['term_taxonomy_id'])  # PyMySQL %d->%s

        if not Php.empty(args, 'name__like'):
            self.sql_clauses['where']['name__like'] = wpdb.prepare(
                "t.name LIKE %s",
                '%' + wpdb.esc_like(args['name__like']) + '%')

        if not Php.empty(args, 'description__like'):
            self.sql_clauses['where']['description__like'] = wpdb.prepare(
                "tt.description LIKE %s",
                '%' + wpdb.esc_like(args['description__like']) + '%')

        if not Php.empty(args, 'object_ids'):
            object_ids = args['object_ids']
            if not Php.is_array(object_ids):
                object_ids = array(object_ids)

            object_ids = Php.implode(', ',
                                     Php.array_map(Php.intval, object_ids))
            self.sql_clauses['where'][
                'object_ids'] = "tr.object_id IN ({})".format(object_ids)

        # When querying for object relationships, the 'count > 0' check
        # added by 'hide_empty' is superfluous.
        if not Php.empty(args['object_ids']):
            args['hide_empty'] = False

        if '' != parent:
            parent = Php.intval(parent)
            self.sql_clauses['where']['parent'] = "tt.parent = 'parent'"

        hierarchical = args['hierarchical']
        if 'count' == args['fields']:
            hierarchical = False
        if args['hide_empty'] and not hierarchical:
            self.sql_clauses['where']['count'] = 'tt.count > 0'

        number = args['number']
        offset = args['offset']

        # Don't limit the query results when we have to descend the family tree.
        if number and not hierarchical and not child_of and '' == parent:
            if offset:
                limits = 'LIMIT ' + offset + ',' + number
            else:
                limits = 'LIMIT ' + number
        else:
            limits = ''

        if not Php.empty(args, 'search'):
            self.sql_clauses['where']['search'] = self.get_search_sql(
                args['search'])

        # Meta query support.
        join = ''
        distinct = ''

        # Reparse meta_query query_vars, in case they were modified in a 'pre_get_terms' callback.
        self.meta_query.parse_query_vars(self.query_vars)
        mq_sql = self.meta_query.get_sql('term', 't', 'term_id')
        meta_clauses = self.meta_query.get_clauses()

        if not Php.empty(args, 'meta_clauses'):
            join += mq_sql['join']
            self.sql_clauses['where']['meta_query'] = preg_replace(
                '/^\s*AND\s*/', '', mq_sql['where'])
            distinct += "DISTINCT"

        selects = array()
        #switch ( args['fields'] ) {
        #  case 'all':
        AF = args['fields']
        if AF in ('all', 'all_with_object_id', 'tt_ids', 'slugs'):
            selects = array('t.*', 'tt.*')
            if ('all_with_object_id' == args['fields']
                    and not Php.empty(args, 'object_ids')):
                selects[None] = 'tr.object_id'

        #elif AF in ('ids', 'id=>parent'):
        elif AF in ('ids', 'id=>parent', 'id.parent'):
            selects = array('t.term_id', 'tt.parent', 'tt.count',
                            'tt.taxonomy')
        elif AF == 'names':
            selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name',
                            'tt.taxonomy')
        elif AF == 'count':
            orderby = ''
            order = ''
            selects = array('COUNT(*)', )
        #elif AF == 'id=>name':
        elif AF in ('id=>name', 'id.name'):
            selects = array('t.term_id', 't.name', 'tt.count', 'tt.taxonomy')
        #elif AF == 'id=>slug':
        elif AF in ('id=>slug', 'id.slug'):
            selects = array('t.term_id', 't.slug', 'tt.count', 'tt.taxonomy')

        _fields = args['fields']

        # Filters the fields to select in the terms query.
        # Field lists modified using this filter will only modify the term fields returned
        # by the function when the `fields` parameter set to 'count' or 'all'. In all other
        # cases, the term fields in the results array will be determined by the `fields`
        # parameter alone.
        # Use of this filter can result in unpredictable behavior, and is not recommended.
        # @param array selects    An array of fields to select for the terms query.
        # @param array args       An array of term query arguments.
        # @param array taxonomies An array of taxonomies.
        fields = Php.implode(
            ', ',
            WiPg.apply_filters('get_terms_fields', selects, args, taxonomies))
        join += (" INNER JOIN " + wpdb.term_taxonomy +
                 " AS tt ON t.term_id = tt.term_id")

        if not Php.empty(self.query_vars, 'object_ids'):
            join += (" INNER JOIN {} AS tr ON tr.term_taxonomy_id = "
                     "tt.term_taxonomy_id".format(wpdb.term_relationships))
        where = Php.implode(' AND ', self.sql_clauses['where'])

        # Filters the terms query SQL clauses.
        # @param array pieces     Terms query SQL clauses.
        # @param array taxonomies An array of taxonomies.
        # @param array args       An array of terms query arguments.
        pieces = ('fields', 'join', 'where', 'distinct', 'orderby', 'order',
                  'limits')
        clauses = WiPg.apply_filters('terms_clauses',
                                     Php.compact(locals(), pieces), taxonomies,
                                     args)

        #fields = isset( clauses[ 'fields' ] ) ? clauses[ 'fields' ] : ''
        fields = clauses.get('fields', '')
        join = clauses.get('join', '')
        where = clauses.get('where', '')
        distinct = clauses.get('distinct', '')
        orderby = clauses.get('orderby', '')
        order = clauses.get('order', '')
        limits = clauses.get('limits', '')

        if where:
            where = "WHERE " + where

        self.sql_clauses['select'] = "SELECT {} {}".format(distinct, fields)
        self.sql_clauses['from'] = "FROM {} AS t {}".format(wpdb.terms, join)
        self.sql_clauses['orderby'] = orderby + " " + order if orderby else ''
        self.sql_clauses['limits'] = limits

        #self.request = "{self.sql_clauses['select']} {self.sql_clauses['from']} {where} {self.sql_clauses['orderby']} {self.sql_clauses['limits']}"
        self.request = "{} {} {} {} {}".format(self.sql_clauses['select'],
                                               self.sql_clauses['from'], where,
                                               self.sql_clauses['orderby'],
                                               self.sql_clauses['limits'])

        # args can be anything. Only use the args defined in defaults to compute the key.
        key = Php.md5(
            Php.serialize(
                WiFc.wp_array_slice_assoc(
                    args, Php.array_keys(self.query_var_defaults))) +
            Php.serialize(taxonomies) + self.request)
        last_changed = WiFc.wp_cache_get_last_changed('terms')
        cache_key = "get_terms:{}:{}".format(key, last_changed)
        cache = WiCa.wp_cache_get(cache_key, 'terms')
        if False != cache:
            if 'all' == _fields:
                cache = Php.array_map(WiTx.get_term, cache)

            self.terms = cache
            print("WcTQ get_terms 1 self.terms=", self.terms)
            return self.terms

        if 'count' == _fields:
            count = wpdb.get_var(self.request)
            WiCa.wp_cache_set(cache_key, count, 'terms')
            return count

        terms = wpdb.get_results(self.request)
        print("WcTQ get_terms 2 terms=", terms)
        if 'all' == _fields or 'all_with_object_id' == _fields:
            WiTx.update_term_cache(terms)
        print("WcTQ get_terms 3 terms=", terms)

        # Prime termmeta cache.
        if args['update_term_meta_cache']:
            term_ids = WiFc.wp_list_pluck(terms, 'term_id')
            WiTx.update_termmeta_cache(term_ids)

        print("WcTQ get_terms 4 terms=", terms)
        if not terms:  # if Php.empty(locals(), 'terms'):
            WiCa.wp_cache_add(cache_key, array(), 'terms',
                              WpC.WB.Wj.DAY_IN_SECONDS)
            return array()

        print("WcTQ get_terms 5 terms=", terms)
        if child_of:
            for _tax in taxonomies:
                children = WiTx._get_term_hierarchy(_tax)
                if children:  # if not Php.empty(locals(), 'children'):
                    terms = _get_term_children(child_of, terms, _tax)
                    print("WcTQ get_terms 6 terms=", terms)

        # Update term counts to include children.
        if args['pad_counts'] and 'all' == _fields:
            for _tax in taxonomies:
                _pad_term_counts(terms, _tax)

        # Make sure we show empty categories that have children.
        if hierarchical and args['hide_empty'] and Php.is_array(terms):
            for k, term in terms.items():
                Continue2 = False  #VT added to translate php: continue 2
                if not term.count:
                    children = get_term_children(term.term_id, term.taxonomy)
                    if Php.is_array(children):
                        for child_id in children:
                            child = WiTx.get_term(child_id, term.taxonomy)
                            if child.count:
                                #continue 2
                                Continue2 = True  #VT added to translate php: continue 2
                                continue  #VT added to translate php: continue 2
                    # It really is empty.
                    del terms[k]
                if Continue2:  #VT added to translate php: continue 2
                    continue  #VT added to translate php: continue 2

        print("WcTQ get_terms 7 terms=", terms)

        # When querying for terms connected to objects, we may get
        # duplicate results. The duplicates should be preserved if
        # `fields` is 'all_with_object_id', but should otherwise be
        # removed.
        if not Php.empty(args,
                         'object_ids') and 'all_with_object_id' != _fields:
            _tt_ids = array()  # need to be sperate mutable obj
            _terms = array()  # need to be sperate mutable obj
            for term in terms:
                if Php.isset(_tt_ids, getattr(term, 'term_id', None)):
                    continue
                _tt_ids[term.term_id] = 1
                _terms[None] = term

            terms = _terms

        _terms = array()  # array()
        #if 'id=>parent' == _fields:
        if _fields in ('id=>parent', 'id.parent'):
            for term in terms:
                _terms[term.term_id] = term.parent
        elif 'ids' == _fields:
            #for i,term in enumerate(terms):
            #  _terms[i] = int(term.term_id)
            for term in terms:
                _terms[None] = int(term.term_id)
        elif 'tt_ids' == _fields:
            for term in terms:
                _terms[None] = int(term.term_taxonomy_id)
        elif 'names' == _fields:
            #for i,term in enumerate(terms):
            #  _terms[i] = term.name
            for term in terms:
                _terms[None] = term.name
        elif 'slug' == _fields:
            for term in terms:
                _terms[None] = term.slug
        #elif 'id=>name' == _fields:
        elif _fields in ('id=>name', 'id.name'):
            for term in terms:
                _terms[term.term_id] = term.name
        #elif 'id=>slug' == _fields:
        elif _fields in ('id=>slug', 'id.slug'):
            for term in terms:
                _terms[term.term_id] = term.slug

        if _terms:  # if not Php.empty(locals(), '_terms'):
            terms = _terms

        # Hierarchical queries are not limited, so 'offset' and 'number' must be handled now.
        if hierarchical and number and Php.is_array(terms):
            if offset >= len(terms):
                terms = array()  # array()
            else:
                terms = Php.array_slice(terms, offset, number, True)

        WiCa.wp_cache_add(cache_key, terms, 'terms', WpC.WB.Wj.DAY_IN_SECONDS)

        if 'all' == _fields or 'all_with_object_id' == _fields:
            terms = Php.array_map(WiTx.get_term, terms)

        self.terms = terms
        return self.terms
Esempio n. 8
0
    def set_props(self, object_type, args):
        ''' Sets taxonomy properties.
    @access public
    @param array|str object_type Name of the object type for the taxonomy obj
    @param array|str args        Array or query string of arguments for
                                 registering a taxonomy.
    '''
        Wj = self.Wj
        import wp.i.taxonomy as WiTx
        args = WiFc.wp_parse_args(args)

        # Filters the arguments for registering a taxonomy.
        # @param array args        Array of arguments for registering a taxonomy.
        # @param str   taxonomy    Taxonomy key.
        # @param array object_type Array of names of object types for the taxonomy
        args = WiPg.apply_filters('register_taxonomy_args',
                                  args,
                                  self.name,
                                  Php.Array(object_type),
                                  Wj=self.Wj)

        defaults = array(
            ('labels', array()),
            ('description', ''),
            ('public', True),
            ('publicly_queryable', None),
            ('hierarchical', False),
            ('show_ui', None),
            ('show_in_menu', None),
            ('show_in_nav_menus', None),
            ('show_tagcloud', None),
            ('show_in_quick_edit', None),
            ('show_admin_column', False),
            ('meta_box_cb', None),
            ('capabilities', array()),
            ('rewrite', True),
            ('query_var', self.name),
            ('update_count_callback', ''),
            ('_builtin', False),
        )

        args = Php.array_merge(defaults, args)

        # If not set, default to the setting for public.
        if None is args['publicly_queryable']:
            args['publicly_queryable'] = args['public']

        if False is not args['query_var'] and (
                Wj.is_admin() or False is not args['publicly_queryable']):
            if True is args['query_var']:
                args['query_var'] = self.name
            else:
                args['query_var'] = WiF.sanitize_title_with_dashes(
                    args['query_var'])
        else:
            # Force query_var to False for non-public taxonomies.
            args['query_var'] = False

        if False is not args['rewrite'] and (
                Wj.is_admin() or '' != WiO.get_option('permalink_structure')):
            args['rewrite'] = WiFc.wp_parse_args(
                args['rewrite'],
                array(
                    ('with_front', True),
                    ('hierarchical', False),
                    ('ep_mask', 'EP_NONE'),
                ))

            if Php.empty(args['rewrite'], 'slug'):
                args['rewrite']['slug'] = WiF.sanitize_title_with_dashes(
                    self.name)

        # If not set, default to the setting for public.
        if None is args['show_ui']:
            args['show_ui'] = args['public']

        # If not set, default to the setting for show_ui.
        if None is args['show_in_menu'] or not args['show_ui']:
            args['show_in_menu'] = args['show_ui']

        # If not set, default to the setting for public.
        if None is args['show_in_nav_menus']:
            args['show_in_nav_menus'] = args['public']

        # If not set, default to the setting for show_ui.
        if None is args['show_tagcloud']:
            args['show_tagcloud'] = args['show_ui']

        # If not set, default to the setting for show_ui.
        if None is args['show_in_quick_edit']:
            args['show_in_quick_edit'] = args['show_ui']

        default_caps = array(
            ('manage_terms', 'manage_categories'),
            ('edit_terms', 'manage_categories'),
            ('delete_terms', 'manage_categories'),
            ('assign_terms', 'edit_posts'),
        )

        args['cap'] = Php.Object(
            Php.array_merge(default_caps, args['capabilities']))
        Php.unset(args, 'capabilities')

        args['object_type'] = Php.array_unique(Php.Array(object_type))

        # If not set, use the default meta box
        if None is args['meta_box_cb']:
            if args['hierarchical']:
                args['meta_box_cb'] = 'post_categories_meta_box'
            else:
                args['meta_box_cb'] = 'post_tags_meta_box'

        for property_name, property_value in args.items():
            setattr(self, property_name, property_value)

        self.labels = WiTx.get_taxonomy_labels(self)  # pass self.Wj
        self.label = self.labels.name
Esempio n. 9
0
def get_metadata(meta_type, object_id, meta_key='', single=False):
    '''
   Retrieve metadata for the specified object.
   @param string meta_type Type of object metadata is for
                           (e.g., comment, post, or user)
   @param int    object_id ID of the object metadata is for
   @param string meta_key  Optional. Metadata key. If not specified,
                           retrieve all metadata for the specified object.
   @param bool   single    Optional, default is False.
                           If True, return only the first value of the
                           specified meta_key. This parameter has no effect
                           if meta_key is not specified.
   @return mixed Single metadata value, or array of values = list = [] !!!
  '''
    if not meta_type or not isinstance(object_id, int):
        return False
    object_id = abs(object_id)
    if not object_id:
        return False
    print('get_metadata meta_type={}, object_id ={}, meta_key={}'.format(
        meta_type, object_id, meta_key))

    # Filter whether to retrieve metadata of a specific type.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user). Returning a non-None value
    # will effectively short-circuit the function.
    # @param None|array|string value  The value get_metadata() should return -
    #                           a single metadata value, or an array of values.
    # @param int     object_id Object ID.
    # @param string  meta_key  Meta key.
    # @param bool    single    Whether to return only the first value of the
    #                          specified meta_key.
    check = WiPg.apply_filters("get_{}_metadata".format(meta_type), None,
                               object_id, meta_key, single)
    if check is not None:
        if single and Php.is_array(check):
            return check[0]
        else:
            return check
    meta_cache = WiCa.wp_cache_get(object_id, meta_type + '_meta')

    if not meta_cache:
        meta_cache = update_meta_cache(meta_type, array(object_id))
        # wp> $m = false; wp> $m[1] => NULL
        meta_cache = meta_cache[object_id]
        # The folllowing is BAD! since meta_cache = array( (object_id, array))
        #   so object_id in meta_cache is always False!
        #meta_cache  = meta_cache[object_id] if object_id in meta_cache else None
        # Can use array_key_exists or object_id in meta_cache.keys()

    if not meta_key:
        print('\n get_metadata not meta_key, return meta_cache =', meta_cache)
        return meta_cache

    #if meta_cache.get(meta_key, None) is not None:
    if Php.isset(meta_cache, meta_key):
        mkey = meta_cache[meta_key]
        print('get_metadata:', meta_type, object_id, meta_key, single, mkey)
        if single:
            return WiFc.maybe_unserialize(mkey[0])
        else:
            #print('get_metadata return:', Php.array_map(WiFc.maybe_unserialize, mkey))
            #return [ WiFc.maybe_unserialize(v) for v in mkey ]
            return Php.array_map(WiFc.maybe_unserialize, mkey)  #same as:

    #print('\n get_metadata not isset(meta_cache, meta_key)', meta_cache, meta_key)
    if single:
        return ''
    else:
        return array()
Esempio n. 10
0
def add_metadata(meta_type, object_id, meta_key, meta_value, unique=False):
    '''
  Add metadata for the specified object.
  @global wpdb wpdb WordPress database abstraction object.
  @param string meta_type  Type of object metadata is for
                           (e.g., comment, post, or user)
  @param int    object_id  ID of the object metadata is for
  @param string meta_key   Metadata key
  @param mixed  meta_value Metadata value. Must be serializable if non-scalar
  @param bool   unique     Optional, default is False.
                           Whether the specified metadata key should be
                           unique for the object. If True, and the object
                           already has a value for the specified metadata
                           key, no change will be made.
  @return int|False The meta ID on success, False on failure.
  '''
    wpdb = WpC.WB.Wj.wpdb  # global wpdb

    if not meta_type or not meta_key or not isinstance(object_id, int):
        return False

    object_id = abs(object_id)
    if not object_id:
        return False

    table = _get_meta_table(meta_type)
    if not table:
        return False

    print("add_metadata: ", meta_type, object_id, meta_key, meta_value, unique)
    column = WiF.sanitize_key(meta_type + '_id')

    # expected_slashed (meta_key)
    meta_key = WiF.wp_unslash(meta_key)
    meta_value = WiF.wp_unslash(meta_value)
    meta_value = sanitize_meta(meta_key, meta_value, meta_type)

    # Filter whether to add metadata of a specific type.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user). Returning a non-None value
    # will effectively short-circuit the function.
    # @param None|bool check      Whether to allow adding metadata for
    #                             given type.
    # @param int       object_id  Object ID.
    # @param string    meta_key   Meta key.
    # @param mixed     meta_value Meta val. Must be serializable if non-scalar.
    # @param bool      unique     Whether the specified meta key should be
    #                             unique for the object. Optional.Default False
    check = WiPg.apply_filters("add_{}_metadata".format(meta_type), None,
                               object_id, meta_key, meta_value, unique)
    print("add_metadata: ", column, meta_key, meta_value, check)
    if check is not None:
        return check

    #Sql = "SELECT COUNT(*) FROM {} WHERE meta_key = %s AND {} = %d".format(
    # PyMySQL convert int & all to formatted quoted str. Can only use %s!!
    Sql = "SELECT COUNT(*) FROM {} WHERE meta_key = %s AND {} = %s".format(
        table, column)
    #RowDict = wDB.GetDB(MetaC,table).Exec(Sql,(meta_key,object_id,),'fetchone')
    #if unique and RowDict: # RowDict is only 1 dict
    if unique and wpdb.get_var(wpdb.prepare(Sql, meta_key, object_id)):
        return False

    _meta_value = meta_value
    print("add_metadata: ", column, meta_key, meta_value, type(meta_value))
    meta_value = WiFc.maybe_serialize(meta_value)

    # Fires immediately before meta of a specific type is added.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user).
    # @param int    object_id  Object ID.
    # @param string meta_key   Meta key.
    # @param mixed  meta_value Meta value.
    WiPg.do_action("add_{}_meta".format(meta_type), object_id, meta_key,
                   _meta_value)

    mid = wpdb.insert(
        table,
        array((column, object_id), ('meta_key', meta_key),
              ('meta_value', meta_value)))
    if not mid:
        return False
    mid = int(mid)

    WiCa.wp_cache_delete(object_id, meta_type + '_meta')

    # Fires immediately after meta of a specific type is added.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user).
    # @param int    mid        The meta ID after successful update.
    # @param int    object_id  Object ID.
    # @param string meta_key   Meta key.
    # @param mixed  meta_value Meta value.
    WiPg.do_action("added_{}_meta".format(meta_type), mid, object_id, meta_key,
                   _meta_value)
    return mid
Esempio n. 11
0
def delete_metadata(meta_type,
                    object_id,
                    meta_key,
                    meta_value='',
                    delete_all=False):
    ''' Delete metadata for the specified object.
  @global wpdb wpdb WordPress database abstraction object.
  @param string meta_type  Type of object metadata is for (e.g., comment, post, or user)
  @param int    object_id  ID of the object metadata is for
  @param string meta_key   Metadata key
  @param mixed  meta_value Optional. Metadata value. Must be serializable if
                           non-scalar. If specified, only delete metadata
                           entries with this value. Otherwise, delete all
                           entries with the specified meta_key.
                           Pass `None, `False`, or an empty string to skip
                           this check.
  @param bool   delete_all Optional, default is False. If True, delete
                           matching metadata entries for all objects,
                           ignoring the specified object_id. Otherwise, only
                           delete matching metadata entries for
                           the specified object_id.
  @return bool True on successful delete, False on failure.
  '''
    #global var==>WpC.WB.Wj.var, except: var=WpC.WB.Wj.var=same Obj,mutable array
    wpdb = WpC.WB.Wj.wpdb  # global wpdb

    if (not meta_type or not meta_key
            or not isinstance(object_id, int) and not delete_all):
        return False

    object_id = abs(object_id)
    if not object_id and not delete_all:
        return False

    table = _get_meta_table(meta_type)
    if not table:
        return False

    type_column = WiF.sanitize_key(meta_type + '_id')
    id_column = 'umeta_id' if 'user' == meta_type else 'meta_id'
    # expected_slashed (meta_key)
    meta_key = WiF.wp_unslash(meta_key)
    meta_value = WiF.wp_unslash(meta_value)

    # Filter whether to delete metadata of a specific type.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user). Returning a non-None value
    # will effectively short-circuit the function.
    # @param None|bool delete  Whether to allow metadata deletion of given type
    # @param int    object_id  Object ID.
    # @param string meta_key   Meta key.
    # @param mixed  meta_value Meta value. Must be serializable if non-scalar.
    # @param bool   delete_all Whether to delete the matching metadata entries
    #         for all objects, ignoring the specified object_id.  Default False
    check = WiPg.apply_filters("delete_{}_metadata".format(meta_type), None,
                               object_id, meta_key, meta_value, delete_all)
    if check is not None:
        return bool(check)

    _meta_value = meta_value
    meta_value = WiFc.maybe_serialize(meta_value)

    Sql = "SELECT {} FROM {} WHERE meta_key = %s".format(id_column, table)
    #SqlDict= (meta_key,)
    query = wpdb.prepare(Sql, meta_key)

    if not delete_all:
        # PyMySQL convert int & all to formatted quoted str. Can only use %s!!
        #Sql    += " AND {} = %s".format(type_column)   # changed from %d to %s
        query += wpdb.prepare(" AND {} = %s".format(type_column), object_id)
        #SqlDict+= (object_id, )
    #if '' != meta_value and meta_value is not None and False is not meta_value:
    if meta_value:
        Sql += wpdb.prepare(" AND meta_value = %s", meta_value)
        #SqlDict+= (meta_value, )

    #RowDicts = wDB.GetDB(MetaC, table).Exec(Sql, SqlDict)
    #meta_ids = [ Row(id_column) for Row in RowDicts ]
    meta_ids = wpdb.get_col(query)
    print(RowDicts, "\n meta_ids=", meta_ids)
    if not Php.count(meta_ids):  #if not meta_ids:
        return False

    if delete_all:
        value_clause = ''
        #value_tuple  = ()
        #if '' != meta_value and meta_value is not None and False != meta_value:
        if meta_value:
            value_clause = wpdb.prepare(" AND meta_value = %s", meta_value)
            #value_tuple  = (meta_value, )

        Sql = ("SELECT {} FROM {} WHERE meta_key = %s {}".format(
            type_column, table, value_clause))
        #RowDicts = wDB.GetDB(MetaC, table).Exec(Sql, (meta_key,)+ value_tuple )
        #object_ids = [ Row(id_column) for Row in RowDicts ]
        object_ids = wpdb.get_col(wpdb.prepare(Sql, meta_key))

    # Fires immediately before deleting metadata of a specific type.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user).
    # @param array  meta_ids   An array of metadata entry IDs to delete.
    # @param int    object_id  Object ID.
    # @param string meta_key   Meta key.
    # @param mixed  meta_value Meta value.
    WiPg.do_action("delete_{}_meta".format(meta_type), Php.Array(meta_ids),
                   object_id, meta.meta_key, meta._meta_value)

    # Old-style action.
    if 'post' == meta_type:
        # Fires immediately before deleting metadata for a post.
        # @since 2.9.0
        # @param array meta_ids An array of post metadata entry IDs to delete.
        WiPg.do_action('delete_postmeta', meta_ids)

    query = ("DELETE FROM {} WHERE {} IN( {} )".format(table, id_column,
                                                       ','.join(meta_ids)))
    #count= wDB.GetDB(MetaC, table).Exec(query)
    count = wpdb.query(query)

    if not count:
        return False

    if delete_all:
        for o_id in Php.Array(object_ids):
            WiCa.wp_cache_delete(o_id, meta_type + '_meta')
    else:
        WiCa.wp_cache_delete(object_id, meta_type + '_meta')

    # Fires immediately after deleting metadata of a specific type.
    # The dynamic portion of the hook name, `meta_type`, refers to the meta
    # object type (comment, post, or user).
    # @param array  meta_ids   An array of deleted metadata entry IDs.
    # @param int    object_id  Object ID.
    # @param string meta_key   Meta key.
    # @param mixed  meta_value Meta value.
    WiPg.do_action("deleted_{}_meta".format(meta_type), Php.Array(meta_ids),
                   object_id, meta.meta_key, meta._meta_value)
    return True
Esempio n. 12
0
def update_metadata(meta_type, object_id, meta_key, meta_value, prev_value=''):
    '''Update metadata for the specified object.
       If no value already exists for the specified object
  ID and metadata key, the metadata will be added.
  @global wpdb wpdb WordPress database abstraction object.
  @param string meta_type  Type of object metadata is for
                             (e.g., comment, post, or user)
  @param int    object_id  ID of the object metadata is for
  @param string meta_key   Metadata key
  @param mixed  meta_value Metadata value.Must be serializable if non-scalar.
  @param mixed  prev_value Optional. If specified, only update existing
                           metadata entries with the specified value.
                           Otherwise, update all entries.
  @return int|bool Meta ID if the key didn't exist, True on successful
                           update, False on failure.
  '''
    #global var==>WpC.WB.Wj.var, except: var=WpC.WB.Wj.var=same Obj,mutable array
    wpdb = WpC.WB.Wj.wpdb  # global wpdb

    if not meta_type or not meta_key or not isinstance(object_id, int):
        return False

    object_id = abs(object_id)
    if not object_id:
        return False

    table = _get_meta_table(meta_type)
    if not table:
        return False

    print("update_metadata:", meta_type, object_id, meta_key, meta_value,
          prev_value)
    column = WiF.sanitize_key(meta_type + '_id')
    id_column = 'umeta_id' if 'user' == meta_type else 'meta_id'

    # expected_slashed (meta_key)
    raw_meta_key = meta_key
    meta_key = WiF.wp_unslash(meta_key)
    passed_value = meta_value
    meta_value = WiF.wp_unslash(meta_value)
    meta_value = sanitize_meta(meta_key, meta_value, meta_type)

    # Filter whether to update metadata of a specific type.
    # The dynamic portion of the hook, `meta_type`, refers to the meta
    # object type (comment, post, or user). Returning a non-None value
    # will effectively short-circuit the function.
    # @param None|bool check     Whether to allow updating metadata for the
    #                              given type.
    # @param int      object_id  Object ID.
    # @param string   meta_key   Meta key.
    # @param mixed    meta_value Meta value. Must be serializable if non-scalar
    # @param mixed    prev_value Optional. If specified, only update existing
    #                            metadata entries with the specified value.
    #                            Otherwise, update all entries.
    check = WiPg.apply_filters("update_{}_metadata".format(meta_type), None,
                               object_id, meta_key, meta_value, prev_value)
    if check is not None:
        return bool(check)

    # Compare existing value to new value if no prev value given and
    #     the key exists only once.
    if not prev_value:  # if Php.empty(locals(), 'prev_value'):
        old_value = get_metadata(meta_type, object_id, meta_key)
        if len(old_value) == 1:
            if old_value[0] == meta_value:
                return False

    # meta_ids = wpdb->get_col( wpdb->prepare("SELECT $id_column FROM
    #    $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ))
    # meta_ids = wpdb->get_col( wpdb->prepare(
    #Sql = ("SELECT {} FROM {} WHERE meta_key = %s AND {} = %d"
    # PyMySQL convert int & all to formatted quoted str. Can only use %s!!

    Sql = ("SELECT {} FROM {} WHERE meta_key = %s AND {} = %s".format(
        id_column, table, column))
    meta_ids = wpdb.get_col(wpdb.prepare(Sql, meta_key, object_id))
    #RowDicts = wDB.GetDB(MetaC, table).Exec(Sql, (meta_key, object_id,) )
    #if RowDicts:
    #  meta_ids = [ Row[id_column] for Row in RowDicts ]
    #  print("\nupdate_metadata meta_ids=", meta_ids)
    #else:
    if not meta_ids:  # if Php.empty(locals(), 'meta_ids'):
        return add_metadata(meta_type, object_id, raw_meta_key, passed_value)

    _meta_value = meta_value
    meta_value = WiFc.maybe_serialize(meta_value)

    data = {'meta_value': meta_value}  # compact(locals(), 'meta_value' )
    where = array((column, object_id), ('meta_key', meta_key))

    if prev_value:  # if not Php.empty(locals(), 'prev_value'):
        prev_value = WiFc.maybe_serialize(prev_value)
        where['meta_value'] = prev_value

    for meta_id in meta_ids:
        # Fires immediately before updating metadata of a specific type.
        # The dynamic portion of the hook, `meta_type`, refers to the meta
        # object type (comment, post, or user).
        # @param int    meta_id    ID of the metadata entry to update.
        # @param int    object_id  Object ID.
        # @param string meta_key   Meta key.
        # @param mixed  meta_value Meta value.
        WiPg.do_action("update_{}_meta".format(meta_type), meta_id, object_id,
                       meta_key, _meta_value)

        if 'post' == meta_type:
            # Fires immediately before updating a post's metadata.
            # @param int    meta_id    ID of metadata entry to update.
            # @param int    object_id  Object ID.
            # @param string meta_key   Meta key.
            # @param mixed  meta_value Meta value.
            WiPg.do_action('update_postmeta', meta_id, object_id, meta_key,
                           meta_value)

    result = wpdb.update(table, data, where)
    if not result:
        return False

    WiCa.wp_cache_delete(object_id, meta_type + '_meta')

    for meta_id in meta_ids:
        # Fires immediately after updating metadata of a specific type.
        # The dynamic portion of the hook, `meta_type`, refers to the meta
        # object type (comment, post, or user).
        # @param int    meta_id    ID of updated metadata entry.
        # @param int    object_id  Object ID.
        # @param string meta_key   Meta key.
        # @param mixed  meta_value Meta value.
        WiPg.do_action("updated_{}_meta".format(meta_type), meta_id, object_id,
                       meta_key, _meta_value)

        if 'post' == meta_type:
            # Fires immediately after updating a post's metadata.
            # @param int    meta_id    ID of updated metadata entry.
            # @param int    object_id  Object ID.
            # @param string meta_key   Meta key.
            # @param mixed  meta_value Meta value.
            WiPg.do_action('updated_postmeta', meta_id, object_id, meta_key,
                           meta_value)

    return True