I'm using Laravel 4.2 PHP framework. This is so odd that the code is correct, but it's always return unexpected boolean value.
$enjoying = (DB::table('enjoy')->where('user_id','=',$authUserId)->where('video_id','=',$video_id)->get()) ? true : false;
I'm so sure that I have a table called "enjoy" where user_id and video_id is matches exactly the above statement. But it returns false always unexpectedly.
On the other hand, I also created a Enjoy Model, so I replace and modify the above statement.
$enjoying = (Enjoy::where('user_id','=',$authUserId)->where('video_id','=',$video_id)->get()) ? true : false;
This time again, assume my table 'enjoy' don't have any data. But it will unexpectedly returns TRUE always. I have no idea what's going on.
Enjoy Model
<?php
class Enjoy extends Eloquent
{
protected $fillable = array('user_id', 'video_id');
protected $table = 'enjoy';
public $timestamps = false;
public function users() {
return $this->has_many_and_belongs_to('User');
}
}
Try this...
$data = Enjoy::where('user_id','=',$authUserId)->where('video_id','=',$video_id)->get();
echo $enjoying = (count($data)) ? 1 : 0;
or
echo $enjoying = (count($data)) ? true : false;
Maybe you need the "exists" method?
$enjoying = Enjoy::where('user_id','=',$authUserId)
->where('video_id','=',$video_id)
->exists();
Related
I am trying to run some dynamic method calls based on the value of a database field. Some context: I have a model Anniversary and I want to display all upcoming anniversaries within the next x days. An anniversary has a date and a frequency. For example, monthly, quarterly, etc. Based on the frequency, I want to check for each anniversary if it is upcoming.
Here is my code so far:
$anniversaries = auth()->user()->anniversaries()->get();
$test = $anniversaries->filter(function ($anniversary) {
$method = Str::of($anniversary->frequency)->camel();
return ${$anniversary->$method}() == true;
});
dd($test);
The above works, when in the actual method I dd() something. But when returning true or false, I get the error:
App\Models\Anniversary::monthly must return a relationship instance
And in my model I just have a few methods like below, for testing:
public function monthly()
{
return true;
}
public function quarterly()
{
return false;
}
My only question is, I want to understand why I am getting this error and ofcourse any pointers in the right direction to get what I want to work. Thanks!
The following line creates an Illuminate\Support\Str object instead of a string. This causes the Method name must be a string error.
$method = Str::of($anniversary->frequency)->camel();
You can fix this by manually casting it to a string and invoking it directly:
$test = $anniversaries->filter(function ($anniversary) {
$method = (string) (Str::of($anniversary->frequency)->camel());
return $anniversary->$method() == true;
});
Throwing in my 2 cents for this as well. The Str::of(), which are "Fluent Strings" added in Laravel 7.x return an instance of Stringable:
https://laravel.com/api/8.x/Illuminate/Support/Stringable.html
For example:
dd(Str::of('monthly')->camel());
Illuminate\Support\Stringable {#3444
value: "monthly"
}
To get the value of this, as a string and not an object, you can cast it (as shown in MaartenDev's answer), or call the __toString() method:
dd(Str::of('monthly')->camel()->__toString());
"monthly"
In your code example, that would simply be:
$method = Str::of($anniversary->frequency)->camel()->__toString();
return $anniversary->{$method}() == true;
Alternatively, you can just use the Str::camel() function to bypass this Stringable class:
$method = Str::camel($anniversary->frequency);
return $anniversary->{$method}() == true;
https://laravel.com/docs/8.x/helpers#method-camel-case
Hope that helps clear up some confusion 😄
you have issue in this part ${$anniversary->$method}(). if you access a function like property laravel models thinks its relation function.
so replace with $anniversary->{$method}()
try this one
$anniversaries = auth()->user()->anniversaries()->get();
$test = $anniversaries->filter(function ($anniversary) {
$method = Str::of($anniversary->frequency)->camel();
return $anniversary->{$method}() == true;
});
dd($test);
For my API we are accepting loads of JSON data. Sometimes there is missing data when we refer to it. So given the following JSON that is posted to the API:
{
"reference_id": "6599",
"balance_0_30": "0",
"balance_31_60": "0",
"balance_over_90": "0",
"account_balance": "0"
}
As I loop over it like this:
foreach ($request->input('data') as $record) {
$record = (object) $record;
$accounting->reference_id = isset($record->reference_id) ? $record->reference_id : NULL;
$accounting->reference_guarantor_id = $record->reference_guarantor_id ?: NULL;
$accounting->balance_0_30 = isset($record->balance_0_30) ? $record->balance_0_30 : NULL;
$accounting->balance_31_60 = isset($record->balance_31_60) ? $record->balance_31_60 : NULL;
$accounting->balance_61_90 = isset($record->balance_61_90 ) ? $record->balance_61_90 : NULL;
$accounting->balance_over_90 = isset($record->balance_over_90) ? $record->balance_over_90 : NULL;
$accounting->account_balance = isset($record->account_balance) ? $record->account_balance : NULL;
This works, but it is rather "messy" to read, and I have about 4000 lines of similar code and growing.
The issue is that if I send up JSON data without the account_balance declared, I get the error:
Undefined property: stdClass
I was thinking I could write a tiny function like this:
function i($value) {
if($value!=null){
if(is_int($value)){
return $value;
}
if(is_float($value)){
return $value;
}
}
return 0;
}
Where if I knew that column would be an integer or float, I could call it like this:
$accounting->account_balance = i($record->account_balance);
Then if the value was null, it would just fill in a 0 and not error out. That would make things much easier to read, troubleshoot and so on. Trouble is that the Exception is thrown before it gets to the i function.
I tried using the set_exception_handler() as described here, including the class example from Glen: https://www.php.net/manual/en/function.set-exception-handler.php but it didn't work.
Am I out of luck, or is there a way to do what I want?
You could just do this:
foreach ($request->input('data') as $record) {
Accounting::create($record);
}
Your database columns should be nullable and do not forget to set $fillable attribute in your Accounting model (For this you can set protected $guarded = ['id', 'created_at', 'updated_at']; in your model to consider all other columns as fillable).
I.m trying to check if a value exists in two columns from a table. The column names are on_number and off_number.
I've tried the following in my controller. The check works however for only the off_number columns and not the on_number.
my controller.
public function check()
{
$on_number = !empty(get('on_number')) ? get('on_number') : false;
$notId = !empty($this->input->get('notId')) ? $this->input->get('notId') : 0;
if($on_number)
$exists = count($this->duty_book_model->getByWhere([
'on_number' => $on__number,
'id !=' => $notId,
])) > 0 ? true : false;
if($on_number)
$exists = count($this->duty_book_model->getByWhere([
'off_number' => $on_number,
'id !=' => $notId,
])) > 0 ? true : false;
echo $exists ? 'false' : 'true';
}
My Model
class Duty_book_model extends MY_Model {
public $table = 'tbl_duty_type';
public function __construct()
{
parent::__construct();
}
}
The extends MY_Model has:
public function getByWhere($whereArg, $args = [])
{
if(isset($args['order']))
$this->db->order_by($args['order'][0], $args['order'][1]);
return $this->db->get_where($this->table, $whereArg)->result();
}
I would like it to check both columns if the value exists.
I believe the reason it doesn't work for "off_number" is in this code
if($on_number)
$exists = count($this->duty_book_model->getByWhere([
//THE NEXT LINE IS THE PROBLEM - LOOK AT THE VALUE!!!
'off_number' => $on_number, //value should be $off_number - right?
'id !=' => $notId,])) > 0 ? true : false;
That said, I think your code is a hot mess.
I say that because to adhere to the MVC pattern a lot of your controller logic should be in the model. IMO, all of it should be.
I would replace the model function getByWhere() with one named check(). It will return true if any record where 'id != $notIdAND'on_number' = $on__number` AND off_number', $off_number. If either of the requred inputs are missing, or if no records are found it returns false.
As you look at the following code it's important to understand that $this->input->get('some_input') will return null if $_GET('some_input') is empty.
class Duty_book_model extends MY_Model
{
public $table = 'tbl_duty_type';
public function check()
{
$on_number = $this->input->get('on_number');
$notId = $this->input->get('notId');
if(empty($on_number) || empty($notId))
{
return false;
}
$query = $this->db
->select('id') //could be any field
->where('id !=', $notId)
->where('on_number', $on__number)
->where('off_number', $off_number)
->get($this->table);
//given $notId = 111 AND $on_number = 222 AND $off_number = 333
//produces the query string
//SELECT `id` FROM `tbl_duty_type` WHERE `id` != 111 AND `on_number` = 222 AND `off_number` = 333
if($query) //might be false if the query string fails to work
{
return $query->num_rows > 0; //returns boolean
}
return false;
}
}
Then all you need in the controller is
$exists = $this->duty_book_model->check();
echo $exists ? 'false' : 'true';
First of all, you have a typo in
'on_number' => $on__number,
You have doubled underscore in $on__number
The second thing - the reason why your check works only for off_number is because you use $exist variable in both cases. Doesn't matter what check result will be for on_number, because it always will be rewritten by off_number checks.
One way you can solve those is by using two different variables:
if($on_number){
$exists_on = count($this->duty_book_model->getByWhere([
'on_number' => $on_number,
'id !=' => $notId,
])) > 0 ? true : false;
$exists_off = count($this->duty_book_model->getByWhere([
'off_number' => $on_number,
'id !=' => $notId,
])) > 0 ? true : false;
}
echo (($exists_on===true)&&(exists_off===true)) ? 'false' : 'true';
It's not the best solution, but it must be most clear.
I was following a tutorial that I got a problem
function old($field) {
return request($field);
}
function request($field = null) {
$request = new \App\Helper\Request();
if(is_null($field))
return $request;
return $request->input($field);
}
I can't figure out why we should set $filed as null and what happens while using two return?the usage of old function is keeping true values after validation in register menu textboxes
the following source code is request class which manages the requests:
class Request
{
public function input($filed, $post = true)
{
if ($this->isPost() && $post)
return isset($_POST[$filed]) ? htmlspecialchars($_POST[$filed]) : "";
return isset($_GET[$filed]) ? htmlspecialchars($_GET[$filed]) : "";
}
public function all($post = true)
{
if ($this->isPost() && $post)
return isset($_POST) ? array_map('htmlspecialchars' , $_POST) : null;
return isset($_GET) ?array_map('htmlspecialchars' , $_GET) : null;
}
public function isPost()
{
return $_SERVER['REQUEST_METHOD'] == 'POST';
}
}
PS:if someone needs more information, please tell me I will send the complete source code.
Thank you
i can't figure out why we should set $field as null and what happens while using two return?
You are not setting $field to null but $field here is an optional argument that means, if no argument is passed to the function, null will be used as default value.
And then this:
$request = new \App\Helper\Request();
if(is_null($field))
return $request;
return $request->input($field);
simply means, if $field is null then return the result of new \App\Helper\Request() otherwise the result of $request->input($field) where $request=new \App\Helper\Request()
Even if I may have just one single line instruction inside if statement, I prefer to use parenthesis for more readability and best understanding.
I have a bunch of optional settings and I'm sick of checking for isset and property_exists.
In Laravel, if I ask for a property that does not exist on a model or request, I get null and no complaints (errors). How can I do the same for my data structure.
If I try array, I can't do simple $settings['setting13'], I have to either pre-fill it all with nulls or do isset($settings['setting13']) ? $settings['setting13'] : '' or $settings['setting13'] ?? null. If I try an object (new \stdClass()), $settings->setting13 still gives me a warning of Undefined property.
How can I make a class such that it responds null or an empty string whenever it is asked for a property that it doesn't have?
Simply do what Laravel does, create a class that deals with your data structure which returns a value if key exists, and something else if it doesn't.
I'll illustrate with an example class (this class supports the "dot notation" of accessing array keys):
class MyConfigClass
{
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function get($path = '', $default = null)
{
if(!is_string($path))
{
return $default;
}
// There's a dot in the path, traverse the array
if(false !== strpos('.', $path))
{
// Find the segments delimited by dot
$segments = explode('.', $path);
$result = $this->data;
foreach($segments as $segment)
{
if(isset($result[$segment]))
{
// We have the segment
$result = $result[$segment];
}
else
{
// The segment isn't there, return default value
return $default;
}
}
return $result;
}
// The above didn't yield a result, check if the key exists in the array and if not - return default
return isset($this->data[$path]) ? $this->data[$path] : $default;
}
}
Use:
$my_structure = [
'url' => 'www.stackoverflow.com',
'questions' => [
'title' => 'this is test title'
]
];
$config = new MyConfigClass($my_structure);
echo $config->get('url'); // echoes www.stackoverflow.com
echo $config->get('questions.title'); // echoes this is test title
echo $config->get('bad key that is not there'); // returns null
There is also a possibility to create wrapper as Jon Stirling mentioned in a comments. This approach will allow to keep code clean and also add functionality via inheritance.
<?php
class myArray implements ArrayAccess {
private $container;
function __construct($myArray){
$this->container = $myArray;
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
}
$settings = array("setting1"=>1,"setting2"=>2,"setting3"=>3);
$arr = new myArray($settings);
echo $arr['setting1'];
echo "<br>";
echo $arr['setting3'];
echo "<br>";
echo $arr['setting2'];
echo "<br>";
echo "------";
echo "<br>";
echo $arr['setting4'] ?:"Value is null";
!empty($settings['setting13']) ? $settings['setting13'] : ''
can be replaced with
$settings['setting13'] ?: ''
as long as whatever you want to print and whatever you want to check exists is the same expression. It's not the cleanest thing ever - which would be to check the existence of anything - but it's reasonably clear and can be chained :
echo ($a ?: $b ?: $c ? $default ?: '');
However, you are not the first who are "sick of checking for isset and property_exists, it's just that we still have to do it, or else we get unexpected results when we expect it the least.
It's not about saving time typing code, it's about saving time not debugging.
EDIT : As pointed in the comments, I wrote the first line with isset() instead of !empty(). Since ?: returns the left operand if it's equal to true, it's of course uncompatible with unchecked variables, you have at least to check for existence beforehand. It's emptiness that can be tested.
The operator that returns its left operand if it exists and is different from NULL is ??, which can be chained the same way ?: does.
Admittedly not the best way to do this, but you can use the error suppressor in php like this:
$value = #$settings['setting13'];
This will quitely set$value to NULL if $settings['setting13'] is not set and not report the undefined variable notice.
As for objects, you should just calling for attributes that are not defined in class.