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
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
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)
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)
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)
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)
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
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
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()
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
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
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