Having trouble making a query builder work properly for finding all posts from last 7 days - doctrine

I'm using Doctrine query builder to try to find all occurrences from the last 7 days. Here's my code:
return $this->createPublishedQueryBuilder('content')
->andWhere('content.date BETWEEN :today AND :sevenDaysAgo')
->setParameter('today', new \DateTime())
->setParameter('sevenDaysAgo', new \DateTime('-7 day'))
->orderBy('content.pageviews.weekly', 'desc')
->setMaxResults($count)
->getQuery()
->getResult();
But it's not returning any results. The recently added lines were the andwhere and two setparameter lines below that in order to add the additional search functionality. Any thoughts on what's going on would be greatly appreciated.
EDIT 1:
No luck switching :today AND :sevenDaysAgo
I also forgot to mention here is the date variable:
/**
* #ORM\Column(type="datetime")
*
* #Serial\SerializedName("publication_date")
* #Serial\Type("DateTime<'Y-m-d'>")
* #Serial\Groups({"list", "fixture", "detail", "email"})
*
* #Assert\Date()
*
* #var DateTime
*/
protected $date;

instead of using a between query I would suggest using a higher-than method.
return $this->createPublishedQueryBuilder('content')
->andWhere('content.date > :sevenDaysAgo')
->setParameter('sevenDaysAgo', new \DateTime('-7 day'))
->orderBy('content.pageviews.weekly', 'desc')
->setMaxResults($count)
->getQuery()
->getResult();
otherwise I see no errors in your query. I guess "createPublishedQueryBuilder" is intentional and an abstract form of "createQueryBuilder" ?

Related

Laravel how many rows inserted in an insert query?

I have this query eloquent in Laravel, I was curious to know. If there is a way to know how many records inserted or how many records ignored to the table?
DB::table('mytable')->insertOrIgnore($data)
Note: One of the manual ways can be, counting records of table before and after process. but this has performance effect, if there be any better way achieving this.
The function insertOrIgnore() returns the affected rows.
/**
* Insert a new record into the database while ignoring errors.
*
* #param array $values
* #return int
*/
public function insertOrIgnore(array $values) {
So you can simply use the returned value and compare it to what was expected to be inserted:
$affected = DB::table('mytable')->insertOrIgnore($data);
$ignored = count($data) - $affected;

How do I create a new Eloquent model with an incrementing field if the name exists?

Hello i have a schedule table in my database, users are allowed to save their schedules into the database, my problem is a situation where for some reason the user has Two schedules with the same name on the same date. I use the fullCalendar plugin to capture my info from the user. Also records are deleted by title, start, and end dates.
I wanted to know if it was possible in eloquent to let the system check for the existence of a particular record and add a number to the title whensaving the record if not found then it would just save the title without the number.
Is this possible? Is there already a feature like this in eloquent? If yes how can it be done.
Note: I know i can do this in my controller by checking for existence and adding a number to the retrieved title my question is if there is already a way to do this directly from the model without having to write code in the controller like how slugs are generated.
Well since i was unable to find a solution i just wrote this function instead:
/**
* #param $str
* #param Model $model
* #param $column
* #return string
*/
protected function increment_if_exists($str, \Illuminate\Database\Eloquent\Model $model, $column)
{
// Finding max ID of any occurrence of specified string
$max = $model::select($column)->whereRaw($column ." REGEXP '" . addSlashes($str) . "'")
->orWhereRaw($column ." REGEXP '" . addSlashes($str) . " \\\\([0-9]+\\\\)'")
->max('id');
// If 0 matches found supplied string is used.
// If 1 or more matches found 1 is added to the returned value and appended to supplied string in parenthesis.
$new = empty($max) ? $str : $str . ' (' . ($max + 1) . ')';
return $new;
}
I use it in my controller so it's not really exactly what i wanted but perhaps somebody will see this and come up with a way of integrating this into a model so that it does it for you automatically on save.

Laravel Eloquent sql statement after exist check is limited to 1

I've found a really weird behaviour in the current laravel 4.2 patch. Until now whenever I want to get some datas from my eloquent model I check if results are available before i get them via the following code example:
$foo = $model->hasManyRelationFunction();
if($foo->exists())
foreach($foo->get() as $elem)
....
this results in the following sql statement:
select count(*) as aggregate from "vendor_tabs" where "vendor_tabs"."vendor_id" = '80' limit 1 <-- exist() ?
following by the real select sql statement without Limit 1, for example:
select * from "vendor_tabs" where "vendor_tabs"."vendor_id" = '80' order by "id" asc
Since i've updated laravel 4.2 to the current patch, it also limits the real sql statement to 1
`select * from "vendor_tabs" where "vendor_tabs"."vendor_id" = '80' order by "id" asc` limit 1
but ONLY when I make the if($foo->exists()) check. As soon i comment out the exist condition everything works fine. Are their any informations about this behaviour or am I just stupid? :D
Edit: It seems like they made the eloquent builder "more fluent" in patch 4.2.13. I still dont know if this is a bug or a feature, imo this shouldnt be the normal behaviour.
/**
* Determine if any rows exist for the current query.
*
* #return bool
*/
public function exists()
{
$limit = $this->limit;
$result = $this->limit(1)->count() > 0;
$this->limit($limit);
return $result;
}
In fact you don't need to check existence. You should only do:
foreach ($model->hasManyRelationFunction as $elem) {
// do whathever you want
}
and it's just enough to get the data. You don't need to check existence here or if you think you do, you should show a real example of a code what you are trying to achieve.

Pluck together with first using Query builder

If I want to get get name of first user in database using eloquent I can do something like that:
$user = User::select('name')->first()->pluck('name');
// or $user = User::first()->pluck('name');
echo $user;
to get only name of this user as string.
However If I try the same using only query builder:
$user = DB::table('users')->select('name')->first()->pluck('name');
echo $user;
I get exception:
Call to undefined method stdClass::pluck()
But without using first it will work:
$user = DB::table('users')->select('name')->where('id',1)->pluck('name');
echo $user;
Is it not possible to use pluck with first using query builder or am I doing something wrong?
PS. Of course I know that I can display any property using $user->name without using pluck but I'm just curious why using Eloquent it works and using Query Builder it works only when not having both first and pluck
You don't want to use pluck with first, because it's redundant:
$query->first() // fetch first row
->pluck('name'); // fetch first row again and return only name
So use only pluck:
$query->pluck('name');
It does all you need.
But there's more.
Under the hood first and pluck run 2 separate queries, so:
$query->where(..)->orderBy(..)->first() // apply where and orderBy
->pluck('name'); // no where and orderBy applied here!
So it's not only redundant to use first before pluck, but also it causes unexpected results.
You can chain those methods on Eloquent query, since it returns a collection (get) or model (first), but Query\Builder returns just an array (get) or stdObject (first). That's why you couldn't do the same oon the query builder.
In Laravel 5.1+, you can use the value method.
From the docs:
If you don't even need an entire row, you may extract a single value
from a record using the value method. This method will return the
value of the column directly:
$email = DB::table('users')->where('name', 'John')->value('email');
This is how it works behind the scenes in the Builder class:
/**
* Get a single column's value from the first result of a query.
*
* #param string $column
* #return mixed
*/
public function value($column)
{
$result = (array) $this->first([$column]);
return count($result) > 0 ? reset($result) : null;
}
Try this one:
$user = User::pluck('name')->first();
echo $user;
Current alternative for pluck() is value().
To get first occurence, You can either use
DB::table('users')->value('name');
or use,
DB::table('users')->pluck('name')->first();

Laravel 4: how can I understand how it all works?

I am using Laravel 3 in one project and it's been a joy. I have also looked at the source code several times to see how some things work behind the scenes.
But now in Laravel 4, I don't know where to begin or how to understand it all. Where can I learn all the behind the scenes of Laravel 4?
Case in point: I wanted to find out if the DB::insert() returns the id of inserted row. So I started searching.
1. I found the Illuminate\Support\Facades\Facade class that "encapsulates" DB.
2. The resolveFacadeInstance function is called and then I tried to print these arrays, but my computer hangs :-/. And I'm sure this would lead to many more classes that I wouldn't understand.
Is there a way I could try to learn the inner workings of Laravel 4? Maybe stack traces?
The facade class is just a filter class to allow you to call methods as if they were static.
For the facade mappings go here: http://laravel.com/docs/facades#facade-class-reference
The starting point to fully understand laravel's inner-workings should begin at:
/public/index.php
You can follow the logic of the program, noticing that requires start.php, which loads an instance of the "Application" which is found here:
/vendor/laravel/framework/src/Illuminate/Foundation/Application.php
This Tuts+ video shows a couple of ways of finding out what class is actually doing the work.
E.g.:
$root = get_class(DB::getFacadeRoot());
var_dump($root);
You can check out the early docs for Laravel 4 here : http://four.laravel.com/ – that should give you a good starting point
The actual Laravel 4 code is well documented in the files. If you want to understand the inner workings then open up the source code files and read the notes. For example I looked up the DB::insert() code in /vendor/laravel/framework/src/Illuminate/Foundation/Application.php.
/**
* Run an insert statement against the database.
*
* #param string $query
* #param array $bindings
* #return bool
*/
public function insert($query, $bindings = array())
{
return $this->statement($query, $bindings);
}
Ok, so this is calling the statement function so I search for function statement in the same code / class:
/**
* Execute an SQL statement and return the boolean result.
*
* #param string $query
* #param array $bindings
* #return bool
*/
public function statement($query, $bindings = array())
{
return $this->run($query, $bindings, function($me, $query, $bindings)
{
if ($me->pretending()) return true;
$bindings = $me->prepareBindings($bindings);
return $me->getPdo()->prepare($query)->execute($bindings);
});
}
We can now see that this returns the boolean result based on the comments above the code.
If you come from Laravel 3 this article is for you. After that you should read the other tutorials of that series.
Author's note:
This article should outline some of the more important changes to Laravel between versions 3 and the upcoming version 4. Bear in mind
this isn’t all of the changes. As the release of Laravel 4 gets closer
I’ll keep this article up to date. If you’re having any problems with
Laravel 4 please jump on to #laravel on Freenode. At this time we’d
like to ask people not to post help topics on the forums.

Resources