/**
	 * Respond to Javascript callbacks
	 * The name of this method is action_ajax_ followed by what you passed to the context parameter above.
	 */
	public function action_ajax_auto_tags( $handler )
	{
		$selected = array();
		if( isset( $handler->handler_vars['selected'] ) ) {
			$selected = Utils::single_array( $handler->handler_vars['selected'] );
		}
		if( isset( $handler->handler_vars['term'] ) && MultiByte::strlen( $handler->handler_vars['term'] ) ) {
			$search = $handler->handler_vars['term'] . '%';
			$tags = new Terms( DB::get_results( "SELECT * FROM {terms} WHERE vocabulary_id = :vid and LOWER(term_display) LIKE LOWER(:crit) ORDER BY term_display ASC", array( 'vid' => Tags::vocabulary()->id, 'crit' => $search ), 'Term' ) );
		}
		else {
			$tags = Tags::vocabulary()->get_tree( 'term_display ASC' );
		}

		$resp = array();
		foreach ( $tags as $tag ) {
			$resp[] = MultiByte::strpos( $tag->term_display, ',' ) === false ? $tag->term_display : $tag->tag_text_searchable;
		}

		if( count( $selected ) ) {
			$resp = array_diff($resp, $selected );
		}
		// Send the response
//		$ar = new AjaxResponse();
//		$ar->data = $resp;
//		$ar->out();
		echo json_encode( $resp );
	}
Esempio n. 2
0
 /**
  * Match the stub against this rule
  * Also sets internal structures based on a successful match
  * @param string $stub The URL stub to match against
  * @return boolean True if this rule matches the stub, false if not
  */
 public function match($stub)
 {
     if (preg_match($this->parse_regex, $stub, $pattern_matches) > 0) {
         $this->entire_match = array_shift($pattern_matches);
         // The entire matched string is returned at index 0
         $named_args = $this->named_args;
         // Direct call shows a PHP notice
         $result = true;
         if (is_string($this->parameters) && ($parameters = unserialize($this->parameters)) || is_array($this->parameters) && ($parameters = $this->parameters)) {
             $this->named_arg_values = array_merge($this->named_arg_values, $parameters);
         }
         foreach ($named_args as $keys) {
             foreach ($keys as $key) {
                 if (!empty($pattern_matches[$key])) {
                     $this->named_arg_values[$key] = urldecode(str_replace('%252F', '%2F', $pattern_matches[$key]));
                 }
             }
         }
         if (preg_match('/^\\{\\$(\\w+)\\}$/u', $this->action, $matches) > 0) {
             $this->action = $this->named_arg_values[$matches[1]];
         }
         if (isset($parameters['require_match'])) {
             $result = call_user_func($parameters['require_match'], $this, $stub, $parameters);
         }
         if ($result && isset($parameters['require_permission'])) {
             foreach ($parameters['require_permission'] as $token => $access) {
                 $access = Utils::single_array($access);
                 foreach ($access as $mask) {
                     if (is_bool($mask) && User::identify()->can($token)) {
                         $result = true;
                         break;
                     } elseif (User::identify()->can($token, $mask)) {
                         $result = true;
                         break 2;
                     }
                 }
             }
         }
         return $result;
     }
     return false;
 }
Esempio n. 3
0
 /**
  * Checks if the currently logged in user has access to a page and post type.
  */
 private function access_allowed($page, $type)
 {
     $user = User::identify();
     $require_any = array();
     $result = false;
     switch ($page) {
         case 'comment':
         case 'comments':
         case 'ajax_comments':
         case 'ajax_in_edit':
         case 'ajax_update_comment':
             $require_any = array('manage_all_comments' => true, 'manage_own_post_comments' => true);
             break;
         case 'tags':
         case 'ajax_tags':
             $require_any = array('manage_tags' => true);
             break;
         case 'options':
             $require_any = array('manage_options' => true);
             break;
         case 'themes':
             $require_any = array('manage_themes' => true, 'manage_theme_config' => true);
             break;
         case 'activate_theme':
             $require_any = array('manage_themes' => true);
             break;
         case 'preview_theme':
             $require_any = array('manage_themes' => true);
             break;
         case 'plugins':
             $require_any = array('manage_plugins' => true, 'manage_plugins_config' => true);
             break;
         case 'plugin_toggle':
             $require_any = array('manage_plugins' => true);
             break;
         case 'import':
             $require_any = array('manage_import' => true);
             break;
         case 'users':
         case 'ajax_update_users':
         case 'ajax_users':
             $require_any = array('manage_users' => true);
             break;
         case 'user':
             $require_any = array('manage_users' => true, 'manage_self' => true);
             break;
         case 'groups':
         case 'group':
         case 'ajax_update_groups':
         case 'ajax_groups':
             $require_any = array('manage_groups' => true);
             break;
         case 'logs':
         case 'ajax_delete_logs':
         case 'ajax_logs':
             $require_any = array('manage_logs' => true);
             break;
         case 'publish':
         case 'ajax_media':
         case 'ajax_media_panel':
             $type = Post::type_name($type);
             $require_any = array('post_any' => array(ACL::get_bitmask('create'), ACL::get_bitmask('edit')), 'post_' . $type => array(ACL::get_bitmask('create'), ACL::get_bitmask('edit')), 'own_posts' => array(ACL::get_bitmask('create'), ACL::get_bitmask('edit')));
             break;
         case 'delete_post':
             $type = Post::type_name($type);
             $require_any = array('post_any' => ACL::get_bitmask('delete'), 'post_' . $type => ACL::get_bitmask('delete'), 'own_posts' => ACL::get_bitmask('delete'));
             break;
         case 'posts':
         case 'ajax_posts':
         case 'ajax_delete_entries':
         case 'ajax_update_entries':
             $require_any = array('post_any' => array(ACL::get_bitmask('delete'), ACL::get_bitmask('edit')), 'own_posts' => array(ACL::get_bitmask('delete'), ACL::get_bitmask('edit')));
             foreach (Post::list_active_post_types() as $type => $type_id) {
                 $require_any['post_' . $type] = array(ACL::get_bitmask('delete'), ACL::get_bitmask('edit'));
             }
             break;
         case 'sysinfo':
             $require_any = array('super_user' => true);
             break;
         case 'dashboard':
         case 'ajax_dashboard':
             $result = true;
             break;
         case 'ajax_add_block':
             $result = true;
             break;
         case 'ajax_delete_block':
             $result = true;
             break;
         case 'configure_block':
             $result = true;
             break;
         case 'ajax_save_areas':
             $result = true;
             break;
         default:
             break;
     }
     $require_any = Plugins::filter('admin_access_tokens', $require_any, $page, $type);
     foreach ($require_any as $token => $access) {
         $access = Utils::single_array($access);
         foreach ($access as $mask) {
             if (is_bool($mask) && $user->can($token)) {
                 $result = true;
                 break;
             } elseif ($user->can($token, $mask)) {
                 $result = true;
                 break 2;
             }
         }
     }
     $result = Plugins::filter('admin_access', $result, $page, $type);
     return $result;
 }
Esempio n. 4
0
 /**
  * Returns a LogEntry or EventLog array based on supplied parameters.
  * By default,fetch as many entries as pagination allows and order them in a descending fashion based on timestamp.
  *
  * @todo Cache query results.
  * @param array $paramarray An associated array of parameters, or a querystring
  * The following keys are supported:
  * - id => an entry id or array of post ids
  * - user_id => id of the logged in user for which to return entries
  * - severity => severity level for which to return entries
  * - type_id => the numeric id or array of ids for the type of entries for which which to return entries
  * - module => a name or array of names of modules for which to return entries
  * - type => a single type name or array of type names for which to return entries
  * - ip => the IP number for which to return entries
  * - criteria => a literal search string to match entry message content or a special search
  * - day => a day of entry creation, ignored if month and year are not specified
  * - month => a month of entry creation, ignored if year isn't specified
  * - year => a year of entry creation
  * - orderby => how to order the returned entries
  * - fetch_fn => the function used to fetch data, one of 'get_results', 'get_row', 'get_value'
  * - count => return the number of entries that would be returned by this request
  * - month_cts => return the number of entries created in each month
  * - nolimit => do not implicitly set limit
  * - limit => the maximum number of entries to return, implicitly set for many queries
  * - index => 
  * - offset => amount by which to offset returned entries, used in conjunction with limit
  * - where => manipulate the generated WHERE clause
  * - return_data => set to return the data associated with the entry
  * 
  * @return array An array of LogEntry objects, or a single LogEntry object, depending on request
  */
 public static function get($paramarray = array())
 {
     $params = array();
     $fns = array('get_results', 'get_row', 'get_value');
     $select_ary = array();
     $select_distinct = array();
     // Put incoming parameters into the local scope
     $paramarray = Utils::get_params($paramarray);
     if ($paramarray instanceof \ArrayIterator) {
         $paramarray = $paramarray->getArrayCopy();
     }
     $select_fields = LogEntry::default_fields();
     if (!isset($paramarray['return_data'])) {
         unset($select_fields['data']);
     }
     foreach ($select_fields as $field => $value) {
         if (preg_match('/(?:(?P<table>[\\w\\{\\}]+)\\.)?(?P<field>\\w+)(?:(?:\\s+as\\s+)(?P<alias>\\w+))?/i', $field, $fielddata)) {
             if (empty($fielddata['table'])) {
                 $fielddata['table'] = '{log}';
             }
             if (empty($fielddata['alias'])) {
                 $fielddata['alias'] = $fielddata['field'];
             }
         }
         $select_ary[$fielddata['alias']] = "{$fielddata['table']}.{$fielddata['field']} AS {$fielddata['alias']}";
         $select_distinct[$fielddata['alias']] = "{$fielddata['table']}.{$fielddata['field']}";
     }
     // Transact on possible multiple sets of where information that is to be OR'ed
     if (isset($paramarray['where']) && is_array($paramarray['where'])) {
         $wheresets = $paramarray['where'];
     } else {
         $wheresets = array(array());
     }
     $query = Query::create('{log}');
     $query->select($select_ary);
     if (isset($paramarray['where']) && is_string($paramarray['where'])) {
         $query->where()->add($paramarray['where']);
     }
     foreach ($wheresets as $paramset) {
         $where = new QueryWhere();
         $paramset = array_merge((array) $paramarray, (array) $paramset);
         if (isset($paramset['id'])) {
             $where->in('{log}.id', $paramset['id'], 'log_id', 'intval');
         }
         if (isset($paramset['user_id'])) {
             $where->in('{log}.user_id', $paramset['user_id'], 'log_user_id', 'intval');
         }
         if (isset($paramset['severity']) && 'any' != LogEntry::severity_name($paramset['severity'])) {
             $where->in('{log}.severity_id', $paramset['severity'], 'log_severity_id', function ($a) {
                 return LogEntry::severity($a);
             });
         }
         if (isset($paramset['type_id'])) {
             $where->in('{log}.type_id', $paramset['type_id'], 'log_type_id', 'intval');
         }
         if (isset($paramset['module'])) {
             $paramset['module'] = Utils::single_array($paramset['module']);
             $qry = Query::create('{log_types}');
             $qry->select('{log_types}.id')->distinct();
             $qry->where()->in('{log_types}.module', $paramset['module'], 'log_subquery_module');
             $where->in('{log}.type_id', $qry, 'log_module');
         }
         if (isset($paramset['type'])) {
             $paramset['type'] = Utils::single_array($paramset['type']);
             $qry = Query::create('{log_types}');
             $qry->select('{log_types}.id')->distinct();
             $qry->where()->in('{log_types}.type', $paramset['type'], 'log_subquery_type');
             $where->in('{log}.type_id', $qry, 'log_type');
         }
         if (isset($paramset['ip'])) {
             $where->in('{log}.ip', $paramset['ip']);
         }
         /* do searching */
         if (isset($paramset['criteria'])) {
             // this regex matches any unicode letters (\p{L}) or numbers (\p{N}) inside a set of quotes (but strips the quotes) OR not in a set of quotes
             preg_match_all('/(?<=")(\\w[^"]*)(?=")|([:\\w]+)/u', $paramset['criteria'], $matches);
             foreach ($matches[0] as $word) {
                 if (preg_match('%^id:(\\d+)$%i', $word, $special_crit)) {
                     $where->in('{log}.id', $special_crit[1], 'log_special_criteria');
                 } else {
                     $crit_placeholder = $query->new_param_name('criteria');
                     $where->add("( LOWER( {log}.message ) LIKE :{$crit_placeholder}", array($crit_placeholder => '%' . MultiByte::strtolower($word) . '%'));
                 }
             }
         }
         /**
          * Build the pubdate
          * If we've got the day, then get the date.
          * If we've got the month, but no date, get the month.
          * If we've only got the year, get the whole year.
          *
          * @todo Ensure that we've actually got all the needed parts when we query on them
          */
         if (isset($paramset['day']) && isset($paramset['month']) && isset($paramset['year'])) {
             $start_date = sprintf('%d-%02d-%02d', $paramset['year'], $paramset['month'], $paramset['day']);
             $start_date = DateTime::create($start_date);
             $where->add('timestamp BETWEEN :start_date AND :end_date', array('start_date' => $start_date->sql, 'end_date' => $start_date->modify('+1 day -1 second')->sql));
         } elseif (isset($paramset['month']) && isset($paramset['year'])) {
             $start_date = sprintf('%d-%02d-%02d', $paramset['year'], $paramset['month'], 1);
             $start_date = DateTime::create($start_date);
             $where->add('timestamp BETWEEN :start_date AND :end_date', array('start_date' => $start_date->sql, 'end_date' => $start_date->modify('+1 month -1 second')->sql));
         } elseif (isset($paramset['year'])) {
             $start_date = sprintf('%d-%02d-%02d', $paramset['year'], 1, 1);
             $start_date = DateTime::create($start_date);
             $where->add('timestamp BETWEEN :start_date AND :end_date', array('start_date' => $start_date->sql, 'end_date' => $start_date->modify('+1 year -1 second')->sql));
         }
         // Concatenate the WHERE clauses
         $query->where()->add($where);
     }
     // Default parameters.
     $orderby = 'timestamp DESC, id DESC';
     //		$limit = Options::get( 'pagination' );
     // Get any full-query parameters
     $paramarray = new SuperGlobal($paramarray);
     $extract = $paramarray->filter_keys('orderby', 'fetch_fn', 'count', 'month_cts', 'nolimit', 'index', 'limit', 'offset');
     foreach ($extract as $key => $value) {
         ${$key} = $value;
     }
     if (isset($index) && is_numeric($index)) {
         $offset = (intval($index) - 1) * intval($limit);
     }
     if (isset($fetch_fn)) {
         if (!in_array($fetch_fn, $fns)) {
             $fetch_fn = $fns[0];
         }
     } else {
         $fetch_fn = $fns[0];
     }
     if (isset($count)) {
         $query->set_select("COUNT({$count})");
         $fetch_fn = isset($paramarray['fetch_fn']) ? $fetch_fn : 'get_value';
         $orderby = null;
         $groupby = null;
         $having = null;
     }
     // If the month counts are requested, replace the select clause
     if (isset($paramset['month_cts'])) {
         // @todo shouldn't this hand back to habari to convert to DateTime so it reflects the right timezone?
         $query->set_select('MONTH(FROM_UNIXTIME(timestamp)) AS month, YEAR(FROM_UNIXTIME(timestamp)) AS year, COUNT(*) AS ct');
         $groupby = 'year, month';
         if (!isset($paramarray['orderby'])) {
             $orderby = 'year, month';
         }
     }
     if (isset($nolimit) || isset($month_cts)) {
         $limit = null;
     }
     // Define the LIMIT, OFFSET, ORDER BY, GROUP BY if they exist
     if (isset($limit)) {
         $query->limit($limit);
     }
     if (isset($offset)) {
         $query->offset($offset);
     }
     if (isset($orderby)) {
         $query->orderby($orderby);
     }
     if (isset($groupby)) {
         $query->groupby($groupby);
     }
     /*
     if(isset($paramarray['type'])) {
     	print_r($query->params());
     	print_r($query->get());die();
     }
     */
     /* All SQL parts are constructed, on to real business! */
     DB::set_fetch_mode(\PDO::FETCH_CLASS);
     DB::set_fetch_class('LogEntry');
     $results = DB::$fetch_fn($query->get(), $query->params(), 'LogEntry');
     // If the fetch callback function is not get_results,
     // return an EventLog ArrayObject filled with the results as LogEntry objects.
     if ('get_results' != $fetch_fn) {
         return $results;
     } elseif (is_array($results)) {
         $c = __CLASS__;
         $return_value = new $c($results);
         $return_value->get_param_cache = $paramarray;
         return $return_value;
     }
 }
Esempio n. 5
0
 /**
  * A theme function for outputting CSS classes based on the requested content
  * @param Theme $theme A Theme object instance
  * @param mixed $args Additional classes that should be added to the ones generated
  * @return string The resultant classes
  */
 function theme_body_class($theme, $args = array())
 {
     $body_class = array();
     foreach (get_object_vars($this->request) as $key => $value) {
         if ($value) {
             $body_class[$key] = $key;
         }
     }
     $body_class = array_unique(array_merge($body_class, Stack::get_named_stack('body_class'), Utils::single_array($args)));
     $body_class = Plugins::filter('body_class', $body_class, $theme);
     return implode(' ', $body_class);
 }
Esempio n. 6
0
 /**
  * Produce a form with the contained fields.
  *
  * @param boolean $process_for_success Set to true to display the form as it would look if the submission succeeded, but do not execute success methods.
  * @return string HTML form generated from all controls assigned to this form
  */
 public function get($use_theme = null, $process_for_success = true)
 {
     $forvalidation = false;
     Plugins::act('modify_form_' . Utils::slugify($this->formtype, '_'), $this);
     Plugins::act('modify_form', $this);
     if (isset($use_theme)) {
         $theme = $use_theme;
     } else {
         $theme = $this->get_theme($forvalidation, $this);
     }
     $theme->start_buffer();
     $theme->success = false;
     $this->success = false;
     $this->submitted = false;
     $this->properties['id'] = isset($this->properties['id']) ? $this->properties['id'] : Utils::slugify($this->name);
     // Should we be validating?
     if (isset($_POST['FormUI']) && $_POST['FormUI'] == $this->salted_name()) {
         $this->submitted = true;
         $validate = $this->validate();
         if (count($validate) == 0) {
             if ($process_for_success) {
                 $result = $this->success();
                 if ($result) {
                     return $result;
                 }
             }
             $theme->success = true;
             $this->success = true;
             $theme->message = $this->options['success_message'];
         } else {
             $forvalidation = true;
             if (!isset($_SESSION['forms'][$this->salted_name()]['url'])) {
                 $_SESSION['forms'][$this->salted_name()]['url'] = Site::get_url('habari', true) . Controller::get_stub() . '#' . $this->properties['id'];
             }
         }
     } else {
         $_SESSION['forms'][$this->salted_name()]['url'] = Site::get_url('habari', true) . Controller::get_stub() . '#' . $this->properties['id'];
     }
     if (isset($_SESSION['forms'][$this->salted_name()]['error_data'])) {
         foreach ($_SESSION['forms'][$this->salted_name()]['error_data'] as $key => $value) {
             $_POST[$key] = $value;
         }
         unset($_SESSION['forms'][$this->salted_name()]['error_data']);
         $forvalidation = true;
     }
     $out = '';
     $theme->controls = $this->output_controls($forvalidation);
     $theme->form = $this;
     foreach ($this->properties as $prop => $value) {
         $theme->{$prop} = $value;
     }
     $theme->class = Utils::single_array($this->class);
     $this->action = $this->options['form_action'];
     $theme->salted_name = $this->salted_name();
     $theme->pre_out = $this->pre_out_controls();
     $out = $this->prefix . $theme->display_fallback($this->options['template'], 'fetch') . $this->postfix;
     $theme->end_buffer();
     return $out;
 }
Esempio n. 7
0
	/**
	 * Remove one or more permissions from a group
	 * @param mixed a permission ID, name, or array of the same
	 */
	public function revoke( $tokens )
	{
		$tokens = Utils::single_array( $tokens );
		$tokens = array_map( array( 'ACL', 'token_id' ), $tokens );

		foreach ( $tokens as $token ) {
			ACL::revoke_group_token( $this->id, $token );
		}
	}
Esempio n. 8
0
 /**
  * Add links to the main atom feed
  */
 public function filter_atom_get_collection_content_type($content_type)
 {
     $content_type = Utils::single_array($content_type);
     $content_type[] = Post::type('link');
     return $content_type;
 }
Esempio n. 9
0
 /**
  * Return the property value that is associated with the first present property from an array list
  * This version only searches the list of the class' $properties array, because __get() on this objcet returns named FormControls instances
  * @param array $tag_fields A list of potential fields to try
  * @return bool|string False if no value found, string of the property value found
  */
 public function get_value_out($tag_fields)
 {
     $properties = array_merge($this->properties, get_object_vars($this));
     $value_out = false;
     foreach (Utils::single_array($tag_fields) as $tag_field) {
         if (isset($properties[$tag_field])) {
             $value_out = $properties[$tag_field];
             break;
         }
     }
     return $value_out;
 }
Esempio n. 10
0
 /**
  * Sets fields for the SELECT statement
  * @param array|string $fields A field or list of fields to set as the fields to select, replaces existing selected fields
  * @return Query Returns $this for fluid interface
  */
 public function set_select($fields)
 {
     $this->fields = Utils::single_array($fields);
     return $this;
 }
Esempio n. 11
0
 /**
  * Search directories for templates to use
  * Templates are always taken from the first directory they're found in.
  * To override this behavior, the template must be specifically added via ->add_template()
  * @see add_template
  * @param string|array $dirs A directory to look for templates in
  */
 public function queue_dirs($dirs)
 {
     $dirs = Utils::single_array($dirs);
     $alltemplates = array();
     // If multiple directories are passed, the earlier ones should override the later ones
     $dirs = array_reverse($dirs);
     foreach ($dirs as $dir) {
         $templates = Utils::glob(Utils::end_in_slash($dir) . '*.*');
         $alltemplates = array_merge($alltemplates, $templates);
     }
     // Convert the template files into template names and produce a map from name => file
     $available_templates = array_map('basename', $alltemplates, array_fill(1, count($alltemplates), '.php'));
     $template_map = array_combine($available_templates, $alltemplates);
     $this->template_map = array_merge($this->template_map, $template_map);
     // Workaround for the 404 template key being merged into the 0 integer index
     unset($this->template_map[0]);
     if (isset($template_map[404])) {
         $this->template_map['404'] = $template_map[404];
     }
     // The templates in the list should be uniquely identified
     array_unique($available_templates);
     // Filter the templates that are available
     $available_templates = Plugins::filter('available_templates', $available_templates, __CLASS__);
     $this->available_templates = array_merge($available_templates, $this->available_templates);
 }
Esempio n. 12
0
 /**
  * Display an object using a template designed for the type of object it is
  * The $object is assigned into the theme using the $content template variable
  *
  * @param Theme $theme The theme used to display the object
  * @param object $object An object to display
  * @param string $context The context in which the object will be displayed	 
  * @return
  */
 public function theme_content($theme, $object, $context = null)
 {
     $fallback = array();
     $content_types = array();
     if ($object instanceof IsContent) {
         $content_types = Utils::single_array($object->content_type());
     }
     $content_types[] = 'content';
     $content_types = array_flip($content_types);
     if (isset($context)) {
         foreach ($content_types as $type => $type_id) {
             $content_type = $context . $object->content_type();
             $fallback[] = strtolower($context . '.' . $type);
         }
         $fallback[] = strtolower($context);
     }
     foreach ($content_types as $type => $type_id) {
         $fallback[] = strtolower($type);
     }
     $this->content = $object;
     return $this->display_fallback($fallback, 'fetch');
 }
	/**
	 * Add the 'events' type to the list of templates that we can use.
	 **/
	public function filter_template_user_filters($filters) {
		if(isset($filters['content_type'])) {
			$filters['content_type']= Utils::single_array( $filters['content_type'] );
			$filters['content_type'][]= Post::type('product');
		}
		return $filters;
	}
 public function filter_posts_get_update_preset($preset_parameters, $presetname, $paramarray)
 {
     switch ($presetname) {
         case 'home':
             $content_type = isset($preset_parameters['content_type']) ? Utils::single_array($preset_parameters['content_type']) : array();
             $content_type[] = 'tweet';
             $preset_parameters['content_type'] = $content_type;
             break;
     }
     return $preset_parameters;
 }
Esempio n. 15
0
 /**
  * Remove permissions to one or more tokens from a user
  * @param mixed a token ID, name, or array of the same
  **/
 public function revoke($tokens)
 {
     $tokens = Utils::single_array($tokens);
     // get token IDs
     $tokens = array_map(array('ACL', 'token_id'), $tokens);
     foreach ($tokens as $token) {
         ACL::revoke_user_permission($this->id, $token);
         EventLog::log(_t('User %1$s: Permission to %2$s revoked.', array($this->username, ACL::token_name($token))), 'notice', 'user', 'habari');
     }
 }
Esempio n. 16
0
 /**
  * Accepts a set of term query qualifiers and converts it into a multi-dimensional array
  * of vocabulary (ie: tags), matching method (any, all, not), matching field (id, term, term_display), and list of terms
  * 
  * @return array An array of parsed term-matching conditions
  */
 private static function vocabulary_params($params)
 {
     $return = array();
     foreach ($params as $key => $value) {
         // split vocab off the beginning of the key
         if (strpos($key, ':') !== false) {
             list($newkey, $subkey) = explode(':', $key, 2);
             $params[$newkey][$subkey] = $value;
             unset($params[$key]);
         }
     }
     foreach ($params as $vocab => $values) {
         foreach ($values as $key => $value) {
             $value = Utils::single_array($value);
             // if there's a colon we've got a mode and a field
             if (strpos($key, ':') !== false) {
                 list($mode, $by_field) = explode(':', $key, 2);
                 foreach ($value as $v) {
                     $return[$mode][$vocab][$by_field][] = $v;
                 }
             } else {
                 // if there's no colon we've got a single field name
                 foreach ($value as $v) {
                     if ($v instanceof Term) {
                         // $vocab is not a vocab, but the mode - always match by its ID for the best performance
                         $return[$vocab][$v->vocabulary->name]['id'][] = $v->id;
                     } else {
                         $return['any'][$vocab][$key][] = $v;
                     }
                 }
             }
         }
     }
     return $return;
 }
Esempio n. 17
0
 /**
  * Changes the status of comments
  * @param array|Comments $comments Comments to be moderated
  * @param int|string $status The new status for the provided array of comments, "unapproved" if not provided
  * @return bool True if all the comments were successfully changed
  * @internal param \Comment $mixed IDs to moderate.  May be a single ID, or an array of IDs
  */
 public static function moderate_these($comments, $status = null)
 {
     if (empty($status)) {
         $status = Comment::status('unapproved');
     }
     // Ensure we have an id, not a string
     $status = Comment::status($status);
     $comments = Utils::single_array($comments);
     if (count($comments) == 0) {
         return false;
     }
     if ($comments[0] instanceof Comment) {
         // We were passed an array of comment objects. Use them directly.
         $result = true;
         /** @var Comment $comment */
         foreach ($comments as $comment) {
             $comment->status = $status;
             $result &= $comment->update();
             EventLog::log(_t('Comment %1$s moderated from %2$s', array($comment->id, $comment->post->title)), 'info', 'comment', 'habari');
         }
     } else {
         if (is_numeric($comments[0])) {
             $result = true;
             foreach ($comments as $commentid) {
                 $result &= DB::update(DB::table('comments'), array('status' => $status), array('id' => $commentid));
                 EventLog::log(_t('Comment %1$d moderated', array($commentid)), 'info', 'comment', 'habari');
             }
         } else {
             // We were passed a type we could not understand.
             return false;
         }
     }
     return $result;
 }
Esempio n. 18
0
 /**
  * Add one or more CSS classes to this control's template
  * @param string $target The name of the targeted element in the control template
  * @param array|string $classes An array or a string of classes to add to this control's template
  * @return FormControl $this
  */
 public function add_template_class($target, $classes)
 {
     if (!isset($this->settings['template_attributes'])) {
         $this->settings['template_attributes'] = array();
     }
     if (!isset($this->settings['template_attributes'][$target])) {
         $this->settings['template_attributes'][$target] = array();
     }
     if (!isset($this->settings['template_attributes'][$target]['class'])) {
         $this->settings['template_attributes'][$target]['class'] = array();
     }
     $this->settings['template_attributes'][$target]['class'] = array_merge(Utils::single_array($this->settings['template_attributes'][$target]['class']), explode(' ', $classes));
     return $this;
 }
Esempio n. 19
0
 /**
  * Returns a named Theme descendant.
  * If no parameter is supplied, then
  * load the active theme from the database.
  *
  * If no theme option is set, a fatal error is thrown
  *
  * @param name            ( optional ) override the default theme lookup
  * @param template_engine ( optional ) specify a template engine
  * @param theme_dir       ( optional ) specify a theme directory
  **/
 public static function create($name = null, $template_engine = null, $theme_dir = null)
 {
     static $bound = array();
     $hash = md5(serialize(array($name, $template_engine, $theme_dir)));
     if (isset($bound[$hash])) {
         return $bound[$hash];
     }
     // If the name is not supplied, load the active theme
     if (empty($name)) {
         $themedata = self::get_active();
         if (empty($themedata)) {
             die(_t('Theme not installed.'));
         }
     } else {
         $themedata = self::get_by_name($name);
     }
     // If a theme wasn't found by name, create a blank object
     if (!$themedata) {
         $themedata = array();
         $themedata['name'] = $name;
         $themedata['version'] = 0;
     }
     // If a specific template engine was supplied, use it
     if (!empty($template_engine)) {
         $themedata['template_engine'] = $template_engine;
     }
     // If a theme directory was supplied, use the directory that was supplied
     if (!empty($theme_dir)) {
         $themedata['theme_dir'] = $theme_dir;
     }
     // Set the default theme file
     $themefile = 'theme.php';
     if (isset($themedata['info']->class['file']) && (string) $themedata['info']->class['file'] != '') {
         $themefile = (string) $themedata->xml->class['file'];
     }
     // Convert themedata to QueryRecord for legacy purposes
     // @todo: Potentially break themes by sending an array to the constructor instead of this QueryRecord
     $themedata = new QueryRecord($themedata);
     // Deal with parent themes
     if (isset($themedata->parent)) {
         // @todo If the parent theme doesn't exist, provide a useful error
         $parent_data = self::get_by_name($themedata->parent);
         $parent_themefile = 'theme.php';
         if (isset($parent_data['info']->class['file']) && (string) $parent_data['info']->class['file'] != '') {
             $parent_themefile = (string) $parent_data['info']->class['file'];
         }
         include_once $parent_data['theme_dir'] . $parent_themefile;
         $themedata->parent_theme_dir = Utils::single_array($parent_data['theme_dir']);
         $themedata->theme_dir = array_merge(Utils::single_array($themedata->theme_dir), $themedata->parent_theme_dir);
     }
     $primary_theme_dir = $themedata->theme_dir;
     $primary_theme_dir = is_array($primary_theme_dir) ? reset($primary_theme_dir) : $primary_theme_dir;
     // Include the theme class file
     if (file_exists($primary_theme_dir . $themefile)) {
         include_once $primary_theme_dir . $themefile;
     }
     if (isset($themedata->class)) {
         $classname = $themedata->class;
     } else {
         $classname = self::class_from_filename($primary_theme_dir . $themefile);
     }
     // the final fallback, for the admin "theme"
     if ($classname == '') {
         $classname = 'Theme';
     }
     $created_theme = new $classname($themedata);
     $created_theme->upgrade();
     Plugins::act_id('init_theme', $created_theme->plugin_id(), $created_theme);
     Plugins::act('init_theme_any', $created_theme);
     $bound[$hash] = $created_theme;
     return $created_theme;
 }
Esempio n. 20
0
	/**
	 * Applies a new set of specific tokens to a post
	 * @param mixed $tokens A string token, or an array of tokens to apply to this post
	 */
	public function set_tokens( $tokens )
	{
		$tokens = Utils::single_array( $tokens );
		$new_tokens = array_map( array( 'ACL', 'token_id' ), $tokens );
		$new_tokens = array_unique( $new_tokens );
		DB::delete( '{post_tokens}', array( 'post_id' => $this->id ) );
		foreach ( $new_tokens as $token_id ) {
			DB::insert( '{post_tokens}', array( 'post_id' => $this->id, 'token_id' => $token_id ) );
		}
		$this->tokens = $new_tokens;
	}
Esempio n. 21
0
 /**
  * Handles AJAX from /admin/tags
  * Used to search for, delete and rename tags
  */
 public function ajax_tags()
 {
     Utils::check_request_method(array('POST', 'HEAD'));
     $this->create_theme();
     $params = $_POST['query'];
     // Get a usable array with filter parameters from the odd syntax we received from the faceted search
     $fetch_params = array();
     if (isset($params)) {
         foreach ($params as $param) {
             $key = key($param);
             // Revert translation
             if ($key != 'text') {
                 $key = self::$facets[$key];
             }
             $value = current($param);
             if (array_key_exists($key, $fetch_params)) {
                 $fetch_params[$key] = Utils::single_array($fetch_params[$key]);
                 $fetch_params[$key][] = $value;
             } else {
                 $fetch_params[$key] = $value;
             }
         }
     }
     // Grab facets / params
     $search = array_key_exists('text', $fetch_params) ? $fetch_params['text'] : null;
     $min = array_key_exists('morethan', $fetch_params) ? $fetch_params['morethan'] + 1 : 0;
     $max = array_key_exists('lessthan', $fetch_params) ? $fetch_params['lessthan'] - 1 : null;
     $orderby_code = array_key_exists('orderby', $fetch_params) ? $fetch_params['orderby'] : null;
     $orderby = isset($orderby_code) ? explode('_', self::$facet_values['orderby'][$orderby_code]) : ['alphabetical', 'asc'];
     $this->theme->tags = Tags::get_by_frequency(null, null, $min, $max, $search, self::$orderby_translate[$orderby[0]], $orderby[1] == 'asc');
     // Create FormUI elements (list items) from the filtered tag list
     $this->theme->max = Tags::vocabulary()->max_count();
     $this->theme->min = Tags::vocabulary()->min_count();
     $output = '';
     if (count($this->theme->tags) > 0) {
         $listitems = $this->get_tag_listitems();
         // Get HTML from FormUI
         foreach ($listitems as $listitem) {
             $output .= $listitem->get($this->theme);
         }
     }
     $ar = new AjaxResponse();
     $ar->html('#tag_collection', $output);
     $ar->out();
 }
Esempio n. 22
0
    /**
     * Returns a post or posts based on supplied parameters.
     * <b>THIS CLASS SHOULD CACHE QUERY RESULTS!</b>
     *
     * @param array $paramarry An associated array of parameters, or a querystring
     * @return array An array of Post objects, or a single post object, depending on request
     */
    public static function get($paramarray = array())
    {
        $join_params = array();
        $params = array();
        $fns = array('get_results', 'get_row', 'get_value');
        $select_ary = array();
        // Default fields to select, everything by default
        foreach (Post::default_fields() as $field => $value) {
            $select_ary[$field] = "{posts}.{$field} AS {$field}";
        }
        // Default parameters
        $orderby = 'pubdate DESC';
        // If $paramarray is a querystring, convert it to an array
        $paramarray = Utils::get_params($paramarray);
        // Define the WHERE sets to process and OR in the final SQL statement
        if (isset($paramarray['where']) && is_array($paramarray['where'])) {
            $wheresets = $paramarray['where'];
        } else {
            $wheresets = array(array());
        }
        /* Start building the WHERE clauses */
        $wheres = array();
        $joins = array();
        // If the request as a textual WHERE clause, skip the processing of the $wheresets since it's empty
        if (isset($paramarray['where']) && is_string($paramarray['where'])) {
            $wheres[] = $paramarray['where'];
        } else {
            foreach ($wheresets as $paramset) {
                // Safety mechanism to prevent empty queries
                $where = array();
                $paramset = array_merge((array) $paramarray, (array) $paramset);
                // $nots= preg_grep( '%^not:(\w+)$%iu', (array) $paramset );
                if (isset($paramset['id'])) {
                    if (is_array($paramset['id'])) {
                        array_walk($paramset['id'], create_function('&$a,$b', '$a = intval($a);'));
                        $where[] = "{posts}.id IN (" . implode(',', array_fill(0, count($paramset['id']), '?')) . ")";
                        $params = array_merge($params, $paramset['id']);
                    } else {
                        $where[] = "{posts}.id = ?";
                        $params[] = (int) $paramset['id'];
                    }
                }
                if (isset($paramset['not:id'])) {
                    if (is_array($paramset['not:id'])) {
                        array_walk($paramset['not:id'], create_function('&$a,$b', '$a = intval($a);'));
                        $where[] = "{posts}.id NOT IN (" . implode(',', array_fill(0, count($paramset['not:id']), '?')) . ")";
                        $params = array_merge($params, $paramset['not:id']);
                    } else {
                        $where[] = "{posts}.id != ?";
                        $params[] = (int) $paramset['not:id'];
                    }
                }
                if (isset($paramset['status']) && $paramset['status'] != 'any' && 0 !== $paramset['status']) {
                    if (is_array($paramset['status'])) {
                        // remove 'any' from the list if we have an array
                        $paramset['status'] = array_diff($paramset['status'], array('any'));
                        array_walk($paramset['status'], create_function('&$a,$b', '$a = Post::status($a);'));
                        $where[] = "{posts}.status IN (" . implode(',', array_fill(0, count($paramset['status']), '?')) . ")";
                        $params = array_merge($params, $paramset['status']);
                    } else {
                        $where[] = "{posts}.status = ?";
                        $params[] = (int) Post::status($paramset['status']);
                    }
                }
                if (isset($paramset['content_type']) && $paramset['content_type'] != 'any' && 0 !== $paramset['content_type']) {
                    if (is_array($paramset['content_type'])) {
                        // remove 'any' from the list if we have an array
                        $paramset['content_type'] = array_diff($paramset['content_type'], array('any'));
                        array_walk($paramset['content_type'], create_function('&$a,$b', '$a = Post::type($a);'));
                        $where[] = "{posts}.content_type IN (" . implode(',', array_fill(0, count($paramset['content_type']), '?')) . ")";
                        $params = array_merge($params, $paramset['content_type']);
                    } else {
                        $where[] = "{posts}.content_type = ?";
                        $params[] = (int) Post::type($paramset['content_type']);
                    }
                }
                if (isset($paramset['not:content_type'])) {
                    if (is_array($paramset['not:content_type'])) {
                        array_walk($paramset['not:content_type'], create_function('&$a,$b', '$a = Post::type($a);'));
                        $where[] = "{posts}.content_type NOT IN (" . implode(',', array_fill(0, count($paramset['not:content_type']), '?')) . ")";
                        $params = array_merge($params, $paramset['not:content_type']);
                    } else {
                        $where[] = "{posts}.content_type != ?";
                        $params[] = (int) Post::type($paramset['not:content_type']);
                    }
                }
                if (isset($paramset['slug'])) {
                    if (is_array($paramset['slug'])) {
                        $where[] = "{posts}.slug IN (" . implode(',', array_fill(0, count($paramset['slug']), '?')) . ")";
                        $params = array_merge($params, $paramset['slug']);
                    } else {
                        $where[] = "{posts}.slug = ?";
                        $params[] = (string) $paramset['slug'];
                    }
                }
                if (isset($paramset['user_id']) && 0 !== $paramset['user_id']) {
                    if (is_array($paramset['user_id'])) {
                        array_walk($paramset['user_id'], create_function('&$a,$b', '$a = intval($a);'));
                        $where[] = "{posts}.user_id IN (" . implode(',', array_fill(0, count($paramset['user_id']), '?')) . ")";
                        $params = array_merge($params, $paramset['user_id']);
                    } else {
                        $where[] = "{posts}.user_id = ?";
                        $params[] = (int) $paramset['user_id'];
                    }
                }
                if (isset($paramset['tag']) || isset($paramset['tag_slug'])) {
                    $joins['tag2post_posts'] = ' JOIN {object_terms} ON {posts}.id = {object_terms}.object_id';
                    $joins['tags_tag2post'] = ' JOIN {terms} ON {object_terms}.term_id = {terms}.id';
                    if (isset($paramset['tag'])) {
                        if (is_array($paramset['tag'])) {
                            $where[] = "{terms}.term_display IN (" . implode(',', array_fill(0, count($paramset['tag']), '?')) . ")" . '  AND {object_terms}.object_type_id = ?';
                            $params = array_merge($params, $paramset['tag']);
                        } else {
                            $where[] = '{terms}.term_display = ? AND {object_terms}.object_type_id = ?';
                            $params[] = (string) $paramset['tag'];
                        }
                    }
                    if (isset($paramset['tag_slug'])) {
                        if (is_array($paramset['tag_slug'])) {
                            $where[] = "{terms}.term IN (" . implode(',', array_fill(0, count($paramset['tag_slug']), '?')) . ")" . ' AND {object_terms}.object_type_id = ?';
                            $params = array_merge($params, $paramset['tag_slug']);
                        } else {
                            $where[] = '{terms}.term= ? AND {object_terms}.object_type_id = ?';
                            $params[] = (string) $paramset['tag_slug'];
                        }
                    }
                    $params[] = Vocabulary::object_type_id(Tags::object_type());
                }
                if (isset($paramset['all:tag'])) {
                    $joins['tag2post_posts'] = ' JOIN {object_terms} ON {posts}.id = {object_terms}.object_id';
                    $joins['tags_tag2post'] = ' JOIN {terms} ON {object_terms}.term_id = {terms}.id';
                    if (is_array($paramset['all:tag'])) {
                        $where[] = '{terms}.term_display IN (' . Utils::placeholder_string($paramset['all:tag']) . ')' . ' AND {object_terms}.object_type_id = ?';
                        $params = array_merge($params, $paramset['all:tag']);
                        $groupby = '{posts}.id';
                        $having = 'count(*) = ' . count($paramset['all:tag']);
                    } else {
                        // this is actually the same as plain 'tag' for a single tag search - go with it
                        $where[] = '{terms}.term_display = ? AND {object_terms}.object_type_id = ?';
                        $params[] = $paramset['all:tag'];
                    }
                    $params[] = Vocabulary::object_type_id(Tags::object_type());
                }
                if (isset($paramset['all:tag_slug'])) {
                    $joins['tag2post_posts'] = ' JOIN {object_terms} ON {posts}.id = {object_terms}.object_id';
                    $joins['tags_tag2post'] = ' JOIN {terms} ON {object_terms}.term_id = {terms}.id';
                    if (is_array($paramset['all:tag_slug'])) {
                        $where[] = '{terms}.term IN (' . Utils::placeholder_string($paramset['all:tag_slug']) . ')' . ' AND {object_terms}.object_type_id = ?';
                        $params = array_merge($params, $paramset['all:tag_slug']);
                        $groupby = '{posts}.id';
                        $having = 'count(*) = ' . count($paramset['all:tag_slug']);
                    } else {
                        // this is actually the same as plain 'tag' for a single tag search - go with it
                        $where[] = '{terms}.term = ? AND {object_terms}.object_type_id = ?';
                        $params[] = $paramset['all:tag_slug'];
                    }
                    $params[] = Vocabulary::object_type_id(Tags::object_type());
                }
                if (isset($paramset['not:tag'])) {
                    $nottag = Utils::single_array($paramset['not:tag']);
                    $where[] = 'NOT EXISTS (SELECT 1
						FROM {object_terms}
						INNER JOIN {terms} ON {terms}.id = {object_terms}.term_id
						WHERE {terms}.term_display IN (' . Utils::placeholder_string($nottag) . ')
						AND {object_terms}.object_id = {posts}.id
						AND {object_terms}.object_type_id = ?)
					';
                    $params = array_merge($params, $nottag);
                    $params[] = Vocabulary::object_type_id(Tags::object_type());
                }
                if (isset($paramset['not:tag_slug'])) {
                    $nottag = Utils::single_array($paramset['not:tag_slug']);
                    $where[] = 'NOT EXISTS (SELECT 1
						FROM {object_terms}
						INNER JOIN {terms} ON {terms}.id = {object_terms}.term_id
						WHERE {terms}.term_display IN (' . Utils::placeholder_string($nottag) . ')
						AND {object_terms}.object_id = {posts}.id
						AND {object_terms}.object_type_id = ?)
					';
                    $params = array_merge($params, $nottag);
                    $params[] = Vocabulary::object_type_id(Tags::object_type());
                }
                if (isset($paramset['criteria'])) {
                    preg_match_all('/(?<=")([\\p{L}\\p{N}]+[^"]*)(?=")|([\\p{L}\\p{N}]+)/u', $paramset['criteria'], $matches);
                    foreach ($matches[0] as $word) {
                        $where[] .= "({posts}.title LIKE CONCAT('%',?,'%') OR {posts}.content LIKE CONCAT('%',?,'%'))";
                        $params[] = $word;
                        $params[] = $word;
                        // Not a typo (there are two ? in the above statement)
                    }
                }
                if (isset($paramset['all:info']) || isset($paramset['info'])) {
                    // merge the two possibile calls together
                    $infos = array_merge(isset($paramset['all:info']) ? $paramset['all:info'] : array(), isset($paramset['info']) ? $paramset['info'] : array());
                    if (Utils::is_traversable($infos)) {
                        $pi_count = 0;
                        foreach ($infos as $info_key => $info_value) {
                            $pi_count++;
                            $joins['info_' . $info_key] = " LEFT JOIN {postinfo} ipi{$pi_count} ON {posts}.id = ipi{$pi_count}.post_id AND ipi{$pi_count}.name = ? AND ipi{$pi_count}.value = ?";
                            $join_params[] = $info_key;
                            $join_params[] = $info_value;
                            $where[] = "ipi{$pi_count}.name <> ''";
                            $select_ary["info_{$info_key}_value"] = "ipi{$pi_count}.value AS info_{$info_key}_value";
                        }
                    }
                }
                if (isset($paramset['any:info'])) {
                    if (Utils::is_traversable($paramset['any:info'])) {
                        $pi_count = 0;
                        $pi_where = array();
                        foreach ($paramset['any:info'] as $info_key => $info_value) {
                            $pi_count++;
                            $join_params[] = $info_key;
                            if (is_array($info_value)) {
                                $joins['any_info_' . $info_key] = " LEFT JOIN {postinfo} aipi{$pi_count} ON {posts}.id = aipi{$pi_count}.post_id AND aipi{$pi_count}.name = ? AND aipi{$pi_count}.value IN (" . Utils::placeholder_string(count($info_value)) . ")";
                                $join_params = array_merge($join_params, $info_value);
                            } else {
                                $joins['any_info_' . $info_key] = " LEFT JOIN {postinfo} aipi{$pi_count} ON {posts}.id = aipi{$pi_count}.post_id AND aipi{$pi_count}.name = ? AND aipi{$pi_count}.value = ?";
                                $join_params[] = $info_value;
                            }
                            $pi_where[] = "aipi{$pi_count}.name <> ''";
                            $select_ary["info_{$info_key}_value"] = "aipi{$pi_count}.value AS info_{$info_key}_value";
                        }
                        $where[] = '(' . implode(' OR ', $pi_where) . ')';
                    }
                }
                if (isset($paramset['has:info'])) {
                    $the_ins = array();
                    $has_info = Utils::single_array($paramset['has:info']);
                    $pi_count = 0;
                    $pi_where = array();
                    foreach ($has_info as $info_name) {
                        $pi_count++;
                        $joins['has_info_' . $info_name] = " LEFT JOIN {postinfo} hipi{$pi_count} ON {posts}.id = hipi{$pi_count}.post_id AND hipi{$pi_count}.name = ?";
                        $join_params[] = $info_name;
                        $pi_where[] = "hipi{$pi_count}.name <> ''";
                        $select_ary["info_{$info_name}_value"] = "hipi{$pi_count}.value AS info_{$info_name}_value";
                    }
                    $where[] = '(' . implode(' OR ', $pi_where) . ')';
                }
                if (isset($paramset['not:all:info']) || isset($paramset['not:info'])) {
                    // merge the two possible calls together
                    $infos = array_merge(isset($paramset['not:all:info']) ? $paramset['not:all:info'] : array(), isset($paramset['not:info']) ? $paramset['not:info'] : array());
                    if (Utils::is_traversable($infos)) {
                        $the_ins = array();
                        foreach ($infos as $info_key => $info_value) {
                            $the_ins[] = ' ({postinfo}.name = ? AND {postinfo}.value = ? ) ';
                            $params[] = $info_key;
                            $params[] = $info_value;
                        }
                        $where[] = '
							{posts}.id NOT IN (
							SELECT post_id FROM {postinfo}
							WHERE ( ' . implode(' OR ', $the_ins) . ' )
							GROUP BY post_id
							HAVING COUNT(*) = ' . count($infos) . ' )
						';
                        // see that hard-coded number? sqlite wets itself if we use a bound parameter... don't change that
                    }
                }
                if (isset($paramset['not:any:info'])) {
                    if (Utils::is_traversable($paramset['not:any:info'])) {
                        foreach ($paramset['not:any:info'] as $info_key => $info_value) {
                            $the_ins[] = ' ({postinfo}.name = ? AND {postinfo}.value = ? ) ';
                            $params[] = $info_key;
                            $params[] = $info_value;
                        }
                        $where[] = '
							{posts}.id NOT IN (
								SELECT post_id FROM {postinfo}
								WHERE ( ' . implode(' OR ', $the_ins) . ' )
							)
						';
                    }
                }
                /**
                 * Build the statement needed to filter by pubdate:
                 * If we've got the day, then get the date;
                 * If we've got the month, but no date, get the month;
                 * If we've only got the year, get the whole year.
                 */
                if (isset($paramset['day']) && isset($paramset['month']) && isset($paramset['year'])) {
                    $where[] = 'pubdate BETWEEN ? AND ?';
                    $startDate = sprintf('%d-%02d-%02d', $paramset['year'], $paramset['month'], $paramset['day']);
                    $startDate = HabariDateTime::date_create($startDate);
                    $params[] = $startDate->sql;
                    $params[] = $startDate->modify('+1 day')->sql;
                    //$params[] = date( 'Y-m-d H:i:s', mktime( 0, 0, 0, $paramset['month'], $paramset['day'], $paramset['year'] ) );
                    //$params[] = date( 'Y-m-d H:i:s', mktime( 23, 59, 59, $paramset['month'], $paramset['day'], $paramset['year'] ) );
                } elseif (isset($paramset['month']) && isset($paramset['year'])) {
                    $where[] = 'pubdate BETWEEN ? AND ?';
                    $startDate = sprintf('%d-%02d-%02d', $paramset['year'], $paramset['month'], 1);
                    $startDate = HabariDateTime::date_create($startDate);
                    $params[] = $startDate->sql;
                    $params[] = $startDate->modify('+1 month')->sql;
                    //$params[] = date( 'Y-m-d H:i:s', mktime( 0, 0, 0, $paramset['month'], 1, $paramset['year'] ) );
                    //$params[] = date( 'Y-m-d H:i:s', mktime( 23, 59, 59, $paramset['month'] + 1, 0, $paramset['year'] ) );
                } elseif (isset($paramset['year'])) {
                    $where[] = 'pubdate BETWEEN ? AND ?';
                    $startDate = sprintf('%d-%02d-%02d', $paramset['year'], 1, 1);
                    $startDate = HabariDateTime::date_create($startDate);
                    $params[] = $startDate->sql;
                    $params[] = $startDate->modify('+1 year')->sql;
                    //$params[] = date( 'Y-m-d H:i:s', mktime( 0, 0, 0, 1, 1, $paramset['year'] ) );
                    //$params[] = date( 'Y-m-d H:i:s', mktime( 0, 0, -1, 1, 1, $paramset['year'] + 1 ) );
                }
                if (isset($paramset['after'])) {
                    $where[] = 'pubdate > ?';
                    $params[] = HabariDateTime::date_create($paramset['after'])->sql;
                }
                if (isset($paramset['before'])) {
                    $where[] = 'pubdate < ?';
                    $params[] = HabariDateTime::date_create($paramset['before'])->sql;
                }
                // Concatenate the WHERE clauses
                if (count($where) > 0) {
                    $wheres[] = ' (' . implode(' AND ', $where) . ') ';
                }
            }
        }
        // Only show posts to which the current user has permission
        if (isset($paramset['ignore_permissions'])) {
            $master_perm_where = '';
        } else {
            // This set of wheres will be used to generate a list of post_ids that this user can read
            $perm_where = array();
            $perm_where_denied = array();
            $params_where = array();
            $where = array();
            // Get the tokens that this user is granted or denied access to read
            $read_tokens = isset($paramset['read_tokens']) ? $paramset['read_tokens'] : ACL::user_tokens(User::identify(), 'read', true);
            $deny_tokens = isset($paramset['deny_tokens']) ? $paramset['deny_tokens'] : ACL::user_tokens(User::identify(), 'deny', true);
            // If a user can read his own posts, let him
            if (User::identify()->can('own_posts', 'read')) {
                $perm_where['own_posts_id'] = '{posts}.user_id = ?';
                $params_where[] = User::identify()->id;
            }
            // If a user can read any post type, let him
            if (User::identify()->can('post_any', 'read')) {
                $perm_where = array('post_any' => '(1=1)');
                $params_where = array();
            } else {
                // If a user can read specific post types, let him
                $permitted_post_types = array();
                foreach (Post::list_active_post_types() as $name => $posttype) {
                    if (User::identify()->can('post_' . Utils::slugify($name), 'read')) {
                        $permitted_post_types[] = $posttype;
                    }
                }
                if (count($permitted_post_types) > 0) {
                    $perm_where[] = '{posts}.content_type IN (' . implode(',', $permitted_post_types) . ')';
                }
                // If a user can read posts with specific tokens, let him
                if (count($read_tokens) > 0) {
                    $joins['post_tokens__allowed'] = ' LEFT JOIN {post_tokens} pt_allowed ON {posts}.id= pt_allowed.post_id AND pt_allowed.token_id IN (' . implode(',', $read_tokens) . ')';
                    $perm_where['perms_join_null'] = 'pt_allowed.post_id IS NOT NULL';
                }
            }
            // If a user is denied access to all posts, do so
            if (User::identify()->cannot('post_any')) {
                $perm_where_denied = array('(1=0)');
            } else {
                // If a user is denied read access to specific post types, deny him
                $denied_post_types = array();
                foreach (Post::list_active_post_types() as $name => $posttype) {
                    if (User::identify()->cannot('post_' . Utils::slugify($name))) {
                        $denied_post_types[] = $posttype;
                    }
                }
                if (count($denied_post_types) > 0) {
                    $perm_where_denied[] = '{posts}.content_type NOT IN (' . implode(',', $denied_post_types) . ')';
                }
            }
            // If there are granted permissions to check, add them to the where clause
            if (count($perm_where) == 0 && !isset($joins['post_tokens__allowed'])) {
                // You have no grants.  You get no posts.
                $where['perms_granted'] = '(1=0)';
            } elseif (count($perm_where) > 0) {
                $where['perms_granted'] = '
					(' . implode(' OR ', $perm_where) . ')
				';
                $params = array_merge($join_params, $params, $params_where);
            }
            if (count($deny_tokens) > 0) {
                $joins['post_tokens__denied'] = ' LEFT JOIN {post_tokens} pt_denied ON {posts}.id= pt_denied.post_id AND pt_denied.token_id IN (' . implode(',', $deny_tokens) . ')';
                $perm_where_denied['perms_join_null'] = 'pt_denied.post_id IS NULL';
            }
            // If there are denied permissions to check, add them to the where clause
            if (count($perm_where_denied) > 0) {
                $where['perms_denied'] = '
					(' . implode(' AND ', $perm_where_denied) . ')
				';
            }
            $master_perm_where = implode(' AND ', $where);
        }
        // Extract the remaining parameters which will be used onwards
        // For example: page number, fetch function, limit
        $paramarray = new SuperGlobal($paramarray);
        $extract = $paramarray->filter_keys('page', 'fetch_fn', 'count', 'orderby', 'groupby', 'limit', 'offset', 'nolimit', 'having');
        foreach ($extract as $key => $value) {
            ${$key} = $value;
        }
        // Define the LIMIT if it does not exist, unless specific posts are requested
        if (!isset($limit) && !isset($paramset['id']) && !isset($paramset['slug'])) {
            $limit = Options::get('pagination') ? (int) Options::get('pagination') : 5;
        } elseif (!isset($limit)) {
            $selected_posts = 0;
            if (isset($paramset['id'])) {
                $selected_posts += count(Utils::single_array($paramset['id']));
            }
            if (isset($paramset['slug'])) {
                $selected_posts += count(Utils::single_array($paramset['slug']));
            }
            $limit = $selected_posts > 0 ? $selected_posts : '';
        }
        // Calculate the OFFSET based on the page number
        if (isset($page) && is_numeric($page) && !isset($paramset['offset'])) {
            $offset = (intval($page) - 1) * intval($limit);
        }
        /**
         * Determine which fetch function to use:
         * If it is specified, make sure it is valid (based on the $fns array defined at the beginning of this function);
         * Else, use 'get_results' which will return a Posts array of Post objects.
         */
        if (isset($fetch_fn)) {
            if (!in_array($fetch_fn, $fns)) {
                $fetch_fn = $fns[0];
            }
        } else {
            $fetch_fn = $fns[0];
        }
        /**
         * Turn the requested fields into a comma-separated SELECT field clause
         */
        $select = implode(', ', $select_ary);
        /**
         * If a count is requested:
         * Replace the current fields to select with a COUNT();
         * Change the fetch function to 'get_value';
         * Remove the ORDER BY since it's useless.
         * Remove the GROUP BY (tag search added it)
         */
        if (isset($count)) {
            $select = "COUNT({$count})";
            $fetch_fn = 'get_value';
            $orderby = '';
            $groupby = '';
            $having = '';
        }
        // If the month counts are requested, replaced the select clause
        if (isset($paramset['month_cts'])) {
            if (isset($paramset['tag']) || isset($paramset['tag_slug'])) {
                $select = 'MONTH(FROM_UNIXTIME(pubdate)) AS month, YEAR(FROM_UNIXTIME(pubdate)) AS year, COUNT(DISTINCT {posts}.id) AS ct';
            } else {
                $select = 'MONTH(FROM_UNIXTIME(pubdate)) AS month, YEAR(FROM_UNIXTIME(pubdate)) AS year, COUNT(*) AS ct';
            }
            $groupby = 'year, month';
            $orderby = 'year, month';
        }
        // Remove the LIMIT if 'nolimit' or 'month_cts' is set
        // Doing this first should allow OFFSET to work
        if (isset($nolimit) || isset($paramset['month_cts'])) {
            $limit = '';
        }
        // Define the LIMIT and add the OFFSET if it exists
        if (!empty($limit)) {
            $limit = " LIMIT {$limit}";
            if (isset($offset)) {
                $limit .= " OFFSET {$offset}";
            }
        } else {
            $limit = '';
        }
        /* All SQL parts are constructed, on to real business! */
        /**
         * Build the final SQL statement
         */
        $query = '
			SELECT DISTINCT ' . $select . '
			FROM {posts} ' . implode(' ', $joins);
        if (count($wheres) > 0) {
            $query .= ' WHERE (' . implode(" \nOR\n ", $wheres) . ')';
            $query .= $master_perm_where == '' ? '' : ' AND (' . $master_perm_where . ')';
        } elseif ($master_perm_where != '') {
            $query .= ' WHERE (' . $master_perm_where . ')';
        }
        $query .= !isset($groupby) || $groupby == '' ? '' : ' GROUP BY ' . $groupby;
        $query .= !isset($having) || $having == '' ? '' : ' HAVING ' . $having;
        $query .= ($orderby == '' ? '' : ' ORDER BY ' . $orderby) . $limit;
        /**
         * DEBUG: Uncomment the following line to display everything that happens in this function
         */
        //print_R('<pre>'.$query.'</pre>');
        //Utils::debug( $paramarray, $fetch_fn, $query, $params );
        //Session::notice($query);
        /**
         * Execute the SQL statement using the PDO extension
         */
        DB::set_fetch_mode(PDO::FETCH_CLASS);
        DB::set_fetch_class('Post');
        $results = DB::$fetch_fn($query, $params, 'Post');
        //		Utils::debug( $paramarray, $fetch_fn, $query, $params, $results );
        //		var_dump( $query );
        /**
         * Return the results
         */
        if ('get_results' != $fetch_fn) {
            // Since a single result was requested, return a single Post object.
            return $results;
        } elseif (is_array($results)) {
            // With multiple results, return a Posts array of Post objects.
            $c = __CLASS__;
            $return_value = new $c($results);
            $return_value->get_param_cache = $paramarray;
            return $return_value;
        }
    }
Esempio n. 23
0
 /**
  * Handles AJAX requests from the manage posts page.
  */
 public function ajax_posts()
 {
     Utils::check_request_method(array('POST', 'HEAD'));
     $this->create_theme();
     $params = $_POST['query'];
     $fetch_params = array();
     if (isset($params) && !empty($params)) {
         foreach ($params as $param) {
             $key = key($param);
             $value = current($param);
             if (isset($fetch_params[$key])) {
                 $fetch_params[$key] = Utils::single_array($fetch_params[$key]);
                 $fetch_params[$key][] = $value;
             } else {
                 $fetch_params[$key] = $value;
             }
         }
     }
     $this->fetch_posts($fetch_params);
     $items = $this->theme->fetch('posts_items');
     $timeline = $this->theme->fetch('timeline_items');
     $item_ids = array();
     foreach ($this->theme->posts as $post) {
         if (ACL::access_check($post->get_access(), 'delete')) {
             $item_ids['p' . $post->id] = 1;
         }
     }
     $ar = new AjaxResponse();
     $ar->html('.posts', $items);
     $ar->data = array('items' => $items, 'item_ids' => $item_ids, 'timeline' => $timeline);
     $ar->out();
 }