Im using the get_users function to show a custom list of users on the site. The only issue Im having a problem figuring out now is how to paginate the result.
This is a sample of the function that Im using:
<ul>
<?php
$args = array(
'meta_key' => 'jabber',
'meta_value' => 'User Name',
'meta_compare' => 'LIKE',
'order' => 'ASC',
'count_total' => true,
'fields' => 'all',
);
$blogusers = get_users($args_1);
foreach ($blogusers as $user) {
$user_id = $user->ID;
$user = get_userdata($user_id);
echo '<li class="provider-list prov-list-gradient">' . $user->display_name . '</li>';
}
?>
</ul>
There doesn't seem to be an obvious way of creating a pagination for the this function. I would appreciate some help with this.
UPDATE:
This is the get_users function source code:
function get_users( $args = array() ) {
$args = wp_parse_args( $args );
$args['count_total'] = false;
$user_search = new WP_User_Query($args);
return (array) $user_search->get_results();
}
Provided you're running get_users() before you load each page of N results, you could revise your get_users() query to use the OFFSET keyword in mysql.
Pseudoquery example (where P is your page number):
SELECT * FROM USERS LIMIT N OFFSET N*P
Related
I have a Customer fiels that is dependent on a Project field.
In my form, I have a dropdown for project, and I need my second dropdown of customers to change dynamically according to the project.
I find the solution in a few places on the web, but the array doesn't change.
Can anyone help with this?
My form:
$dataProject=ArrayHelper::map(Project::find()->asArray()->all(), 'id', 'name');
echo $form->field($model, 'project_id')->dropDownList($dataProject,
['prompt'=>'-Choose a Project-',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('customer/lists?id=').'"+$(this).val(), function( data ) {
$( "select#title" ).html( data );
});
']);
$dataPost=ArrayHelper::map(Customer::find()->asArray()->all(), 'id', 'first_name');
echo $form->field($model, 'customer_id')
->dropDownList(
$dataPost,
['id'=>'title']
);
Code in the Customer controller:
public function actionLists($id) {
$countPosts = Customer::find()
->where(['project_id' => $id])
->count();
$posts = Customer::find()
->where(['project_id' => $id])
->orderBy('id DESC')
->all();
if($countPosts>0) {
foreach($posts as $post){
echo "<option value='".$post->id."'>".$post->first_name."</option>";
}
}
else{
echo "<option>-</option>";
}
}
So far the best way to add the dropdown options to the select when you have the access to jquery is to use .each() but you need to provide the options from the controller/action as json rather than creating the html and then adding the html to the dropdown.
Then you are using $.post and adding query string with the url for the id whereas you can use the data option to send the id.
Change your onchange function to the following
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('/customer/lists').'", {id:$(this).val()},function( data ) {
//this will clear the dropdown of the previous options
$("#title").children("option").remove();
//optionally you can use the following if you have a placeholder in the dropdown so that the first option is not removed
//$("#title").children("option:not(:first)").remove();
$.each(data, function(key, value) {
$("#title")
.append($("<option></option>")
.attr("value",key)
.text(value));
});
});
Then you are querying 2 times to the Customer table once for count all records and one for all the lists of customers
$countPosts = Customer::find()
->where(['project_id' => $id])
->count();
$posts = Customer::find()
->where(['project_id' => $id])
->orderBy('id DESC')
->all();
you can simply query for the customers and use php:count() function on the result set $posts to count the total number of records.
$posts = Customer::find()
->where(['project_id' => $id])
->orderBy('id DESC')
->all();
$countPosts = count($post);
But we are not going to need the count anyway this was just for information, change your action actionLists() to below and remove the parameter $id now as we are sending the id with post.
public function actionLists() {
//set the response format to JSON
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
//get the id
$id = Yii::$app->request->post ( 'id' );
$posts = Customer::find ()
->where ( [ 'project_id' => $id ] )
->orderBy ( 'id DESC' )
->all ();
return ArrayHelper::map ( $posts , 'id' , 'first_name' );
}
Apart from doing all the above you should get used to of using available resources in form of extensions or plugins that are widely available one of them is Kartik/DepDropdown which does the same thing with a lot of less pain of writing the javascript and just providing data from server-side.
I'm following the official guide in ACF documentation but hasn't been able to get it right. I'm using Advanced custom fields and Custom post type UI plugins.
I have a custom post type named materials, each material has a files repeater field, one of the subfield is title. I want to query the posts based on the title and put the results onto the page using ajax.
Here's my functions.php:
function materialsSearchAjax() {
$html = "";
$keyword = $_POST['keyword'];
// args
$args = array(
'numberposts' => -1,
'posts_per_page' => -1,
'post_type' => 'materials',
'meta_key' => 'type',
'meta_value' => 'students',
'meta_query' =>
array(
'key' => 'files_%_title',
'compare' => 'LIKE',
'value' => $keyword,
)
);
$query = new WP_Query( $args );
$posts = array();
$html .= '<div class="Materials-students">';
while( $query->have_posts() ) : $query->the_post();
$html .= '<div class="Files-list u-padding-left--12">';
if( have_rows('files') ){
while ( have_rows('files') ) : the_row();
$html .= '<div class="Files-item u-margin-right--30 u-margin-bottom--18">';
$html .= '<div class="Files-itemImage"></div>';
$html .= '<a href="' . the_sub_field("document") . '" target="_blank" class="Files-itemLink">';
$html .= the_sub_field('title');
$html .= '</a>';
$html .= '</div>';
endwhile;
}
$html .= '</div>';
endwhile;
$html .= '</div>';
wp_reset_query();
return $html;
}
// filter
function materials_where( $where ) {
$where = str_replace("meta_key = 'files_%", "meta_key LIKE 'files_%", $where);
return $where;
}
function igs_scripts_styles() {
wp_enqueue_script( 'ajaxMaterialsSearch', get_template_directory_uri() . '/assets/scripts/ajaxMaterialsSearch.js', array(), false, true );
wp_localize_script( 'ajaxMaterialsSearch', 'ajax_data_object', array( 'url' => admin_url( 'admin-ajax.php' )) );
}
add_action('wp_ajax_nopriv_materialsSearchAjax', 'materialsSearchAjax');
add_action('wp_ajax_materialsSearchAjax', 'materialsSearchAjax');
add_filter('posts_where', 'materials_where');
add_action('wp_enqueue_scripts', 'igs_scripts_styles');
Here's my ajax:
(function($) {
// Trigger submit
$('.Search-magnifier').on('click', function(){
var $form = $(this).parent();
$($form).submit();
});
$('.Search-form').on('submit', function(event){
event.preventDefault();
var $form = $(this);
var searchKeyword = $($form).find('input[type="search"]').val();
console.log('keyword: ' + searchKeyword);
$.ajax({
type: 'POST',
url: ajax_data_object.url,
data: {action: 'materialsSearchAjax', keyword: searchKeyword},
success: function(textStatus) {
// update the content
console.log(textStatus);
$('.Materials-students').replaceWith(textStatus);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
})(jQuery);
The ajax and query work fine if I query all the materials post without filtering the title so the only think that's wrong is the query itself. I followed the guide but been stuck for hours.
I guess your only mistake is within the meta_query itself. Besides the (optional) first-level relation, a meta_query has to be an array of array(s). Try:
$args = array(
'posts_per_page' => -1,
'post_type' => 'materials',
'meta_key' => 'type',
'meta_value' => 'students',
'meta_query' => array(
array(
'key' => 'files_%_title',
'compare' => 'LIKE',
'value' => $keyword,
)
)
);
From WP Codex:
meta_query (array) - Contains one or more arrays with the following keys: […]
I replicated your case (except for the Ajax) and the query worked fine, so I guess this should also work over Ajax calls.
Tearing my hair out at this point, hopefully someone can help me out!
I am using the Kartik-V Typeahead Advanced widget with Yii2.
The plugin works, in that the functionality is working perfectly on the page, I search and the results appear in the auto complete list.
Unfortunately, I am unable to store the result in my database. I am seeing an issue on the following line:
->where([ 'name' => $model->name ])//This variable is returning null
Am I trying to store the data incorrectly? I have tried everything I can think of, but I am sure someone here will come up with something better!
See below for the full code.
My controller:
public function actionIndex()
{
$model = new Member();
if ($model->load(Yii::$app->request->post())) {
$test = Test::find()
->where([ 'name' => $model->name ])//This variable is returning null
->one();
$test->updateCounters(['times_used' => 1]);
}
return $this->render('index', [
'model' => $model,
]);
}
/*************
* Initial prefetch of results
*************/
public function actionPrefetchlist() {
$query = new Query;
$query->select('name')
->from('test_table')
->limit(10)
->orderBy('times_used');
$command = $query->createCommand();
$data = $command->queryAll();
$out = [];
foreach ($data as $d) {
$out[] = ['value' => $d['name']];
}
echo Json::encode($out);
}
/*************
* Remote results
*************/
public function actionRemotelist() {
$query = new Query;
$query->select('name')
->from('test_table')
->where('name LIKE "%' . $q .'%"')
->limit(10)
->orderBy('times_used');
$command = $query->createCommand();
$data = $command->queryAll();
$out = [];
foreach ($data as $d) {
$out[] = ['value' => $d['name']];
}
echo Json::encode($out);
}
The view file:
echo $form->field($model, 'name')->label(false)->widget(Typeahead::classname(), [
'name' => 'name',
'options' => ['placeholder' => 'Filter as you type ...'],
'pluginOptions' => ['highlight'=>true],
'dataset' => [
[
'datumTokenizer' => "Bloodhound.tokenizers.obj.whitespace('value')",
'display' => 'value',
'prefetch' => Url::to(['prefetchlist']),
'remote' => [
'url' => Url::to(['remotelist']) . '?q=%QUERY',
'wildcard' => '%QUERY'
]
]
]
]);
you ask here for a new model:
$model = new Member();
so you get a empty model
so the $model->name is empty
if you set the model $model->name='test';
than it will be filled so, fill the model first
So it turns out it was a massive rookie error.
If anyone else stumbles upon something similar, I removed the attribute name from the model's "rules()"
I need an integer in the database but I wanted users to enter in a string (I would then convert it in the controller). Removing it from the rule broke everything.
Hopefully this helps someone else :)
I'm new to cakephp2 and mysql and need some help.
I want to get the data from yesterday and daybefore yesterday date from the same Model in cakephp2,
However the conditions will be different so I am trying to get the data by making two different methods that contains the find() with different conditions. ,however,I'ts not working. Here is the sample below ↓
This method getYesterday() will return the data as a array but I want to add a condition
that will check if the pageview count is not 0, how will I do that ?
public function getYesterday() {
$yes = array();
$dt = date('Y-m-d', strtotime('-1 day'));
// $dy = date('Y-m-d', strtotime('-2 day'));
$yesterday = $this->PvLog->find('all', array(
'fields' => array('dt', 'params', 'count(params) as yesterday_pv'),
'conditions' => array('dt' => "2014/09/26", 'is_crawler' => 0,'count(page_view)>'=>0),
'group' => array('params'),
'order' => array('count(params)' => 'DESC'),
));
foreach ($yesterday as $y) {
$yes[] = $y;
//$i++;
}
return $yes;
}
The function below will get the data from daybefore yesterday
public function getDBY() {
$dayyes = array();
$dt = date('Y-m-d', strtotime('-2 day'));
$daybefore = $this->PvLog->find('all', array(
'fields' => array('dt', 'params', 'count(params) as daybefore_pv'),
'conditions' => array('dt' => "{$dt}", 'is_crawler' => 0),
'group' => array('params'),
'order' => array('count(params)' => 'DESC'),
));
foreach ($daybefore as $dby) {
$dayyes[] = $dby;
//$i++;
}
return $dayyes;
}
The probelem is I'm not sure about this way, Is there a better solution that you can get the different result with different conditions in mysql cakephp2 ? The main thing I want to do Is to get the yesterdays data and daybefore yesterdays data from the same model but I'm not sure how I can do this, I've checked cakes documents but cant find the solution. Sorry for my broken English.
I have a stupid little question.
As I already know a select query in Laravel will always return an array of results,
I have this query:
$id = DB::select(
'select id from users where username = ?', array(Session::get('theuser')));
by inserting this id into my table
DB::table('characters')->insert(array(
'id' => $id,
'char_name' => $charname,
'char_dynasty' => $dynastyname,
'picture' => 'Male1.png'
));
I will get the error: ksort() expects parameter 1 to be array, string given.
How can I get rid of this? Thanks in advance!
At least one of $id, $charname or $dynastyname is an array and should not be.
You are using it wrong.
Below is a POC proving this.
The output is "Warning: ksort() expects parameter 1 to be array, integer given on line 13"
It runs as expected when providing 'id' => 'a'.
function insert(array $values)
{
if ( ! is_array(reset($values)))
{
$values = array($values);
}
else
{
foreach ($values as $key => $value)
{
ksort($value); $values[$key] = $value;
}
}
var_dump($values);
}
insert(array(
'id' => array('a'),
'char_name' => 2,
'char_dynasty' => 3,
'picture' => 'Male1.png'
));