Laravel and redis scan - laravel

I am trying to use redis scan with laravel. I can make a single request which returns 10 keys but I wish to loop until all the keys have been returned. I am unsure how to do this with laravel. Currently I have
$test = Redis::scan(0, 'match', '*keypattern*');
I don't know if there is a 'laravel' way of doing this.
EDIT:
I used composer to import predis/predis and got it working with
use Predis\Collection\Iterator;
use Predis;
...
$client = new Predis\Client([
'scheme' => 'tcp',
'host' => 'localhost',
'port' => 6379,
]);
foreach (new Iterator\Keyspace($client, '*keypattern*') as $key) {
$arr[] = $key;
}
but I would like to know the laravel way
EDIT:
var_dump of the single Redis::scan
array(2) {
[0]=>
string(4) "23"
[1]=>
array(10) {
[0]=>
string(19) "key17"
[1]=>
string(19) "key72"
[2]=>
string(76) "key11"
[3]=>
string(19) "key73"
[4]=>
string(19) "key63"
[5]=>
string(19) "key87"
[6]=>
string(19) "key70"
[7]=>
string(19) "key65"
[8]=>
string(19) "key82"
[9]=>
string(19) "key43"
}
}

Thanks #martinczerwi
Here is a non-recursional version:
function scanAllForMatch($pattern)
{
$cursor = 0;
do {
list($cursor, $keys) = Redis::scan($cursor, 'match', $pattern);
foreach ($keys as $key) {
yield $key;
}
} while ($cursor);
}

As the Redis facade passes commands directly to Predis (or Redis itself you might say), this goes hand in hand with the Redis docs (http://redis.io/commands/scan). You can use the cursor (first array entry) for subsequent calls to iterate until the cursor is zero.
I've put together a recursive approach, to scan all entries:
function scanAllForMatch ($pattern, $cursor=null, $allResults=array()) {
// Zero means full iteration
if ($cursor==="0") {
return $allResults;
}
// No $cursor means init
if ($cursor===null) {
$cursor = "0";
}
// The call
$result = Redis::scan($cursor, 'match', $pattern);
// Append results to array
$allResults = array_merge($allResults, $result[1]);
// Recursive call until cursor is 0
return scanAllForMatch($pattern, $result[0], $allResults);
}
Note that you might need to add $this before the recursion, if you use this in a class (would be return $this->scanAllForMatch(...))
You would call it like that:
// Don't pass a cursor yourself!
$allResults = scanAllForMatch('*keypattern*');

Related

Laravel error: View::__toString() must not throw an exception

I have a problem to loop GET data from URL.
My array looks like after var dump :
array(5) {
[0]=>
array(5) {
["sku"]=>
string(9) "AH1172164"
["name"]=>
string(21) "dasdas"
["url"]=>
string(42) "21321312"
["price"]=>
string(6) "866.00"
["stocks"]=>
array(1) {
[0]=>
array(3) {
["partner"]=>
string(6) "321312"
["qty"]=>
string(1) "1"
["spotted"]=>
string(14) "1 month "
}
}
}
My code for looping the data in blade file:
#php
$d=$_GET['Api'];
var_dump($d);
foreach($d as $value)
{
echo $value;
}
#endphp
When I use var_dump the data are listed correctly but when I want to loop the variable $d I got this error:
Method Illuminate\View\View::__toString() must not throw an exception, caught Facade\Ignition\Exceptions\ViewException: Array to string conversion (View: F:\xampp\htdocs\semafor-master\resources\views\platform\tools\
I have API.. and my controller for this :
public function gen(Request $request)
{
// Some queries, and loops to fill $data variable..
return \Redirect::route('platform.tools.gen', ['Api'=>$data]);
}
I can't use return view, I must use return redirect because after API REQUEST I want to redirect to this route.
The gen view is Orchid admin panel screen.
What can be the problem?
Thanks in advance.
Part of the answer is that somewhere in the stack, there's a call to a magic __toString() method. Exceptions being called therein is only allowable in Php 7.4 and up. Try wrapping your behavior in a generic try/catch and make it dump the message from the Exception that it's trying to throw. The message you're seeing now is just a symptom of a different problem.
Looks like you have an array of array variable, so you should encode your value to a string before printing it:
#php
$d=$_GET['Api'];
foreach($d as $value)
{
echo json_encode($value);
}
#endphp

Laravel Collection - Remove Object containing empty array

I have an Collection of objects - some of which contain empty arrays.
object(Illuminate\Support\Collection)#34225 (1) {
["items":protected]=>
array(0) {
}
}
object(Illuminate\Support\Collection)#34226 (1) {
["items":protected]=>
array(0) {
}
}
object(Illuminate\Support\Collection)#34227 (1) {
["items":protected]=>
array(0) {
}
}
object(Illuminate\Support\Collection)#34228 (1) {
["items":protected]=>
array(0) {
}
}
object(Illuminate\Database\Eloquent\Collection)#23760 (1) {
["items":protected]=>
array(2) {
[0]=>
object(App\Models\File)#23766 (27) {
["primaryKey":protected]=>
string(6) "FileID"
["table":protected]=>
I could use someones help in filtering the Collection of objects so that the objects containing empty arrays are gone/removed.
So that all that remains are the objects with non empty arrays
object(Illuminate\Database\Eloquent\Collection)#23760 (1) {
["items":protected]=>
array(2) {
[0]=>
object(App\Models\File)#23766 (27) {
["primaryKey":protected]=>
string(6) "FileID"
I have populated the collection using
$things = $foos->get($thing->ID, collect());
Any help would be greatly appreciated
You may convert it to an array using toArray() method
$things = $foos->get($thing->ID, collect())->toArray();
foreach($things as $thing) {
if(empty($thing['items'])) {
unset($thing);
}
}
$things = array_values($things);
Or
Using filter()
The filter method filters the collection using the given callback, keeping only those items that pass a given truth test:
$things = $foos->get($thing->ID, collect());
$filtered = $things->filter(function ($value, $key) {
return !empty($value->items) ;
});
$result = $filtered->all();
Collection Unexpectedly :) has method filter.
$collection = collect([
[],
['1'],
[],
]);
$collection->filter(); // will return collection with only [ [1] ]

How to add conditional where conditional in query laravel framework?

Actually the scenario is my queries are running on the basis of if
condition. In first scenario
if ($a != "") {
$getData = DB::table('students')->where([
['code', '=', '1'],
['class', '!=', 'General'],
['gender', '=', 'm']
]);
}
> //second scenario
if ($b != '') {
$queryData = $getData->where(ST_Distancesphere(geom, ST_SetSRID(ST_MakePoint($longt, $latt), 4326)), '<', $b)->get();
} else {
$queryData = $getData->get();
}
return $queryData;
in first scenario query is working fine but when $b is not equal to
blank then where condition is not working
It seems you want to use ST_Distancesphere method, you need to use the raw sql.
So if you use whereRaw() like this, and set binding for preventing SQL Injection:
$queryData=$getData->whereRaw("ST_Distancesphere(geom, ST_SetSRID(ST_MakePoint(:lng,:lat), 4326)) < :b", ["lng" => $longt, "lat" => $latt, "b" => $b])
->get();
However, you have different bindings' way before this query,
DB::table('students')->where([['code', '=', '1'],['class', '!=', 'General'],['gender','=', 'm']])
Laravel will get Invalid parameter number error.
So I think you need to change the previous bindings, make them all use same bindings' way:
if($a != "") {
$getData = DB::table('students')
->whereRaw("code = :code AND class != :class AND gender = :gender", ["code" => 1, "class" => "General", "gender" => "m"]);
}
if($b != '') {
$queryData=$getData->whereRaw(" ST_Distancesphere(geom,ST_SetSRID(ST_MakePoint(:longt, :latt), 4326)) < :b", ["longt" => $longt, "latt" => $latt, "b" => $b])->get();
} else {
$queryData=$getData->get();
}
return $queryData;
follow official documentation
https://laravel.com/docs/5.8/queries#conditional-clauses

Undefined index codeigniter

i have a problem with result array in codeigniter
Model Is
function ReadMessages($UID)
{
$query = $this->db->get('ls_messages3');
return $query->result_array();
}
Controller:
function messages()
{
$data['user_info']['UnreadMessagesCount']=$this->pages_model->MessagesCount($this->session->userdata('user_id'));
$this->load->model("articles_model");
$this->load->model("login_model");
$this->load->model("cabinet_model");
$this->load->model("user_model");
$this->load->library("form_validation");
$data['pages'] = $this->pages_model->get_pages();
$data['pages_info'] = $this->login_model->get_info("pm");
$data['categories'] = $this->pages_model->get_cat();
$data['user'] = $this->session->userdata('user');
$data['user_info']['user_id']=$this->session->userdata('user_id');
$data['user_info']['user_category']=$this->session->userdata('user_cat');
$data['user_info']['avatar'] = $this->session->userdata('avatar');
$data['error']='';
$name="pm";
$data['single_user'] = $this->login_model->user_info($data['user']);
$data['mess'] = $this->user_model->ReadMessages($data['user_info']['user_id']);
$this->template->page($data,$name);
}
And view:
<div id="body-in">
<div id="profile_content">
<?=var_dump($mess);?>
<?=$mess['id'];?>
</div>
</div>
Result array locate in $data['mess'] variable. When in view i use var_dump function to this variable, i get normal answer, like this:
array(1) { [0]=> array(7) { ["id"]=> string(1) "1" ["user_id"]=> string(1) "1" ["lstext"]=> string(95) " Hello! This is the Message! " ["isread"]=> string(5) "FALSE" ["date"]=> string(10) "2014-05-18" ["touser_id"]=> string(1) "2" ["time"]=> string(5) "16:06" } }
but when i'am trying to get a single value from this array i have error "Message: Undefined index" on this page
Change Model code to
function ReadMessages()
{
$query = $this->db->get('ls_messages3');
return $query->row_array();
}
and in controller
$this->user_model->ReadMessages($data['user_info']['user_id']);
to
$this->user_model->ReadMessages();
or
use <?php echo $mess[0]['id']; ?> in view

Joomla 2.5 custom component: filter entries

In a custom component, in the site view, I display a list of countries, each as a link to another page, displaying persons living in that country.
This is a link:
index.php?option=com_example&view=persons&country=1&Itemid=131
What's missing:
When the persons-page is opened, all persons are listed.
What I'm looking for:
I'd like to show only persons with country as in the link, 1 in the example above.
I tried to add this condition in the model-files of persons, but failed miserably.
+++ EDIT ++++
Thanks to the accepted answer, I was able to accomplish what I needed. Unfortunately, this seems to produce side-effects:
Fatal error: Call to a member function getPagesCounter() on a non-object
in .../view/persons/tmpl/default.php` (...)
The code throwing that error is
<?php echo $this->pagination->getPagesCounter(); ?>
When commenting out that line, the same erroer will occur with this code:
<?php echo $this->pagination->getPagesLinks(); ?>
How did that happen, and what can I do? Tried to track down that problem, but didn't know where to start.
+++ EDIT +++
Wasnm't able to solve that issue yet. Did a var_dump($this->pagination);, this is the output:
array(1) {
[0]=>
object(stdClass)#150 (20) {
["id"]=>
string(1) "6"
["name"]=>
string(11) "Fleur Leroc"
["country"]=>
string(1) "2"
(...)
["ordering"]=>
string(1) "6"
["state"]=>
string(1) "1"
["checked_out"]=>
string(3) "615"
["checked_out_time"]=>
string(19) "2013-10-10 10:53:14"
["created_by"]=>
string(10) "Super User"
["editor"]=>
string(10) "Super User"
["countriestrainers_country_828045"]=>
string(6) "France"
["countriestrainers_flag_828045"]=>
string(28) "images/trainers/flags/fr.gif"
}
}
So the object does exist, doesn't it?
You were close editing the model files.
In your Persons model (ExampleModelPersons) you need to make sure you have the following elements:
Whitelist the filter name:
<?php
public function __construct($config = array())
{
if (empty($config['filter_fields'])) {
$config['filter_fields'] = array(
'country',
// other not standard filters
);
}
parent::__construct($config);
}
?>
Autopopulate the state filter:
<?php
protected function populateState($ordering = null, $direction = null)
{
$country = $this->getUserStateFromRequest($this->context.'.filter.country', 'country', '', null, false);
$this->setState('filter.country', (int) $country);
// ....Other states
{
?>
Store id for the context:
<?php
protected function getStoreId($id = '')
{
$id .= ':'.$this->getState('filter.country');
// Other states
}
?>
And the most important one, the database query
<?php
protected function getListQuery()
{
// ... Other parts of the querty
if ($country = $this->getState('filter.country'))
$query->where("country = ". (int) $country);
}
?>
If you don't need saving the state in user's session this can be easily stripped into two liner in the database query.
<?php
// ... Other parts of the querty
if ($country = $app->input->getInt('country'))
$query->where("country = ". (int) $country);
?>

Resources