Yii2 - save() doesn't save - php

I have Order model, and I want to change "status" in one of orders. I execute such a code:
$order = new Order();
$new = $order->find()->where(['status' => 'new'])->orderBy(['id' => SORT_ASC])->one();
if($new){
$new->status = "queued";
$ok = $new->save();
return true;
}
And, $new is the record that I want, so that's ok. So, when I try to save changes, it doen't do it, and $ok gives me "false". I have no idea why, I have used save() before and never have problems with it.
Update:
Found mistake, it was not connected to save() function.

Your value is not saving because of model validation, You can skip model validation by putting false.
$order = new Order();
$new = $order->find()->where(['status' => 'new'])->orderBy(['id' => SORT_ASC])->one();
if($new){
$new->status = "queued";
$ok = $new->save(false); // skip model validation
return true;
}

Related

How to check duplicate title and not save to database in laravel

i have a problem that when i get data from other api and want if same title wont save to api. Each time getting data from the api is 20 and want to save it to the database without duplicate. Please help me. Thank you very much!!!
public function getTitle($title){
$title = $this->posts->where('title', $title)->get();
return $title;
}
public function getApi(Request $request){
$url = "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=87384f1c2fe94e11a76b2f6ff11b337f";
$data = Http::get($url);
$item = json_decode($data->body());
$i = collect($item->articles);
$limit = $i->take(20); // take limited 5 items
$decode = json_decode($limit);
foreach($decode as $post){
$ite = (array)$post;
$hi = $this->getTitle($ite['title']);
dd($ite['title'], $hi);
if($ite['title']==$hi){
dd('not save');
}
else{
dd('save');
}
//dd($hi, $ite['title']);
// create post
$dataPost = [
'title'=>$ite['title'],
'description'=>$ite['description'],
'content'=>$ite['content'],
'topic_id'=>'1',
'post_type'=>$request->type,
'user_id'=>'1',
'enable'=>'1',
'feature_image_path'=>$ite['urlToImage']
];
//dd($dataPost);
//$this->posts->create($dataPost);
}
return redirect()->route('posts.index');
}
You can use first or create for saving data in database if title name is new. using firstOrNew you dont have to use any other conditions
for example:-
$this->posts->firstOrCreate(
['title' => $ite['title']],
['description'=>$ite['description'],
'content'=>$ite['content'],
'topic_id'=>'1',
'post_type'=>$request->type,
'user_id'=>'1',
'enable'=>'1',
'feature_image_path'=>$ite['urlToImage']]);
firstOrNew:-
It tries to find a model matching the attributes you pass in the first parameter. If a model is not found, it automatically creates and saves a new Model after applying any attributes passed in the second parameter
From docs
If any records exist that match your query's constraints, you may use
the exists and doesntExist methods
if($this->posts->where('title', $title)->doesntExist())
{
// save
} else {
// not save
}

Laravel 5.5 - Unable to update object

It's been a while since I've used Laravel and I'm pulling my hair out over the below issue, seems to be relatively straight forward and probably 100% obvious.
I'm adding some new fields to an existing view, I've created a new model, added the relations and added the fields. I can confirm that I'm able to view the data on the View successfully, I can take the data from the view successfully and insert a new record on the target table.
The problem I'm having is I'm unable to update an existing record, I can retrieve the record by ID, but I can't use the object selector ($object->data) on it, I've added the function and the comments below:
//Create the license
$license = License::where('id', $venue->license_id)->get();
if(empty($license->id))
{
Log::notice("Nothing to show");
} else {
//I have added this in as a sanity check, I've been able to
//perform Log::notice($license); successfully but the below doesn't work?
Log::notice($license->id);
Log::notice($license->license_name);
}
//This works, I am able to create a new License if there is no ID set.
$license_class_id = $request->get('license_class_id');
$license_type_id = $request->get('license_type_id');
$liquor_license_no = $request->get('liquor_license_no');
$site_reference_no = $request->get('site_reference_no');
$holder_name = $request->get('holder_name');
$license_name = $request->get('license_name');
$trading_name = $request->get('trading_name');
//This works
if( !$license || !$license->exists ) {
$license = new License;
}
//This is to update the object but it doesn't seem to happen.
$license->license_class_id = $license_class_id;
$license->license_type_id = $license_type_id;
$license->liquor_license_no = $liquor_license_no;
$license->site_reference_no = $site_reference_no;
$license->holder_name = $holder_name;
$license->license_name = $license_name;
$license->trading_name = $trading_name;
if ( ! $license->save() ) {
return $license->errors();
}
if(!empty($license->id))
{
$venue->license_id = $license->id;
}
if ( ! $venue->save() ) {
return $venue->errors();
}
use update() method for update not save(). save() is used at the insert time
$license->update();
And fetch record as single collection. If id is not primary key then by below way
//Create the license
$license = License::where('id', $venue->license_id)->first();
And if id is primary key then you directly get by
$license = License::find($venue->license_id);
You can use updateOrCreate method here too.
By this code,
//Create the license
$license = License::where('id', $venue->license_id)->first();
if(empty($license))
{
Log::notice("Nothing to show");
} else {
//I have added this in as a sanity check, I've been able to
//perform Log::notice($license); successfully but the below doesn't work?
Log::notice($license->id);
Log::notice($license->license_name);
}
//This works, I am able to create a new License if there is no ID set.
$license_class_id = $request->get('license_class_id');
$license_type_id = $request->get('license_type_id');
$liquor_license_no = $request->get('liquor_license_no');
$site_reference_no = $request->get('site_reference_no');
$holder_name = $request->get('holder_name');
$license_name = $request->get('license_name');
$trading_name = $request->get('trading_name');
License::updateOrCreate([
'license_class_id' => $license_class_id ,
'license_type_id' => $license_type_id,
'license_type_id' => $license_type_id,
'license_type_id' => $license_type_id,
'holder_name' => $holder_name,
'license_name' => $license_name,
'trading_name' => $trading_name
]);
For more information check this link.
If you will use this method, You do not need to check if a record exists or not. That is the advantage.

Additing two array variable in codeigniter

I am building a system where i need to update the value in the database field but before doing that i need to take the current value in the database then adding it to the current value the following is a code from the controller.
public function transfer_amount(){
$email = $this->input->post('view');
$this->load->model('user_model');
$data['user_balance'] = $this->user_model->fetch_balance($email);
$data['balance'] = $this->input->post('amount');
$data['total'] = $this->math->add($data['balance'],$data['user_balance']);
$data = array(
'balance' => $data['total'],
);
if($this->user_model->transfer_amount($data,$email)== true){
$this->load->view('layer_service/success',$data);
}
else
{
$this->load->view('layer_service/unsuccessfull',$data);
}
}
}
then the code in the module that fetch the current balance from the database is as following.
function fetch_balance($email){
$this->db->select('balance');
$this->db->from('tbl_users');
$this->db->where('email', $email);
$query = $this->db->get();
$result = $query->result();
return $result;
}
not sure but look at this part - don't call it $data because i think thats messing you up later
for example call it $balance
$balance = array(
'balance' => $data['total'],
);
// pass the $balance to your model method
if($this->user_model->transfer_amount($balance,$email) == true){
// keeping $data here to pass to the view
$this->load->view('layer_service/success',$data);
}
getting the balance should be wrapped in an if in case it fails
if( ! $data['user_balance'] = $this->user_model->fetch_balance($email) )
{
$this->_showNoUserFor($email) ;
}
another suggestion:
$email = $this->input->post('view');
validate the email first before sending it to your database table. codeigniter form validation library works really well.
======
EDIT ok this part
$data['total'] = $this->math->add($data['balance'],$data['user_balance']);
means that you have a model called math with a method called add()
so if you don't have that you would just use php math which is very simple
$data['total'] = $data['balance'] + $data['user_balance'] ;
of course this assumes everything has been validated first so you are actually adding together two numbers.

Using docrtrine in Symfony2

I'm working on a php project but I have a problem with the database , I use this code to get data from the database :
public function getSeenAction(Request $request , $notificationId)
{
$sessionId = $request->headers->get('SessionID');
if( $sessionId == null )
{
//return new Response("Unauthorized",401);
}
$notificationRepo = $this->getDoctrine()->getRepository('MegasoftEntangleBundle:Notification');
$notification = $notificationRepo->findOneById($notificationId);
if($notification == null)
{
return new Response("Notification not found" ,404);
}
$seen = $notification->getSeen();
$response = new JsonResponse();
$response->setdata(array('seen'=>$seen));
$response->setStatusCode(200);
return $response;
}
I tried the same code with other tables and it worked , but whenever I retrive data from the Notification table it always give null , although the table contains the data.
$notificationRepo = $this->getDoctrine()->getRepository('MegasoftEntangleBundle:Notification');
$notification = $notificationRepo->findAll();
var_dump(notification);
Is this code returns you something ? Probably the code of your NotificationRepository.php is not good, can you put it on ?
Try using find instead of findOneById if you just want to find record by Id.
On the other hand if you want to use findOneBy the passed argument for criteria should be an array.
$result = $notificationRepo->find($notificationId);
Or
$result = $notificationRepo->findOneBy(array('id' => $notificationId));
Or
make sure you have a proper code for findOneById in your NotificationRepository.php file
Then you can check
if (!empty($result)) { ... }

php passing object of an object: reference or value?

Hi all I'm using zend framework (but I think this is irrelevant) and php5 and I just want to modify an object of an object
public function saveSite($post) {
$form = new Diff_Form_Download();
$subform = new Diff_Form_DownloadSubform();
$form = $this->view->form;
$newSite = 0;
$sitesRecord = new Diff_Model_Sites();
$debugString = null;
if (is_array($post)) {
$subform = $this->getSubformByPost($post);
$debugString = $subform->getContent();
echo $debugString;
//new site instertion
if (is_null($subform)) {
$subform = $form->getSubForm('NewSite');
$newSite = 1;
}
$values = reset($subform->getValues());
$sitesRecord = Doctrine_Core::getTable('Diff_Model_Sites')->findOneBy('idSite', $values['idSite']);
if ($sitesRecord) {
$sitesRecord->idSite = $values['idSite']; //useless but necessary to make Doctrine understand to use update?
} else { //if the record is not present instantiate a new object (otherwise save() will not work
$sitesRecord = new Diff_Model_Sites();
}
$sitesRecord->content = $subform->getContent(); //$values['content'];
$sitesRecord->newHtml = $subform->getContent();
$sitesRecord->url = $values['url'];
$sitesRecord->shortName = $values['shortName'];
$sitesRecord->lastChanged = date("Y-m-d H:i:s");
$sitesRecord->pollingHours = $values['pollingHours'];
$sitesRecord->minLengthChange = $values['minLenghtChange'];
if (Zend_Auth::getInstance()->hasIdentity()) { //save the owner
$sitesRecord->idOwner = Zend_Auth::getInstance()->getIdentity()->idOwner; //retrieve the owner
$sitesRecord->save();
} else {
throw new Exception("your session have expired: \n please login again");
}
}
}
/**
* return the calling subform
* #param type $post
* #return type
*/
public function getSubformByPost($post) {
$form = new Diff_Form_Download();
$form = $this->view->form;
$subform = new Diff_Form_DownloadSubform();
$subformName = "site" . $post['idSite'];
$subform = $form->getSubForm($subformName);
return $subform;
}
public function refreshOneDiff($post) {
$debugString;
if (is_array($post)) {
$form = new Diff_Form_Download();
$form = $this->view->form;
$subform = new Diff_Form_DownloadSubform();
$subform = $this->getSubformByPost($post);
if (!$subform)
$subform = $this->view->form->getSubformByPost('NewSite');
$url = $subform->getUrl();
$idSite = $subform->getIdSite();
$crawler = new Crawler();
$newpageContent = $crawler->get_web_page($url);
$siteRecord = new Diff_Model_Sites();
$siteRecord = $subform->getSiteRecord();
if ($siteRecord) //check if the record is not null
$oldpageContent = $siteRecord->get('content');
else
$oldpageContent = null;
$differences = $this->getDiff($oldpageContent, $newpageContent);
if (!is_null($differences)) {
$siteRecord->content = $newpageContent;
$subform->setContent($newpageContent);
$subform->setContentDiff($differences);
$subform->setSiteRecord($siteRecord);
$subform = $this->getSubformByPost($post);
$debugString = $subform->getContent();
}
//echo $debugString;
$sitePresence = Doctrine_Core::getTable('Diff_Model_Sites')->findOneBy('idSite', $idSite);
if ($sitePresence) {
//$this->saveSite($post);
$this->debugtry($post);
}
} else {
}
}
Basically what I'm doing here is:
1) grab a the form from the view
2) grab a subform from the form (let's call it SubformX)
3) grab an object "siteRecordX" from SubformX
4) change a value of "siteRecordX"
5) call a function saveRecord()
6) In this function regrab the same SubformX and echoing the value of the object siteRecordX
Surprisingly if i change a variable of SubformX it will stay that way, if I change a variable of an object of SubformX it will remain unchanged (if I retrieve SubformX).
It looks like, even if SubformX is passed by reference it is not the same for it's subobjects, wich are passed by value and so they disappear changing the context of the function.
Can you please help me?
Thanks
EDIT
I still cannot solve this issue nor understand it:
This is the constructor of the subform:
public function __construct($site = null, $options = null) {
if ($site instanceof Diff_Model_Sites) {
$this->_shortName = $site->get('shortName');
$this->_url = $site->get('url');
$this->_content = $site->get('content');
$this->_idSite = $site->get('idSite');
$this->_siteRecord = $site;
$this->_lastChanged = $site->get('lastChanged');
}parent::__construct($options);}
while this is the function of SubformX i use to set the value.
public function setContent($contentText) {
$this->_siteRecord->content = $contentText;
$this->_content = $contentText;
}
and this is the function of the subform that I call to get the value
public function getContent() {
if (isset($this->_siteRecord)) {
//return $this->_content;
return $this->_siteRecord->content;
}
}
with the commented line I'm able to retrieve the updated value, not with the second.
This is a real mystery to me because i set and get them exactly the same way at exactly the same point and i cannot understand the difference.
Your _siteRecord property is an ORM object (Doctrine, it appears). So its data may have some behaviors that are not standard for a reference-type object. It surely has some override of __get and __set. It also employs caching. These things are necessary to keep the database-model interaction working properly, but they can confuse what should be a reference and value types. (See: http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html)
P.S.: in your constructor you use:
$this->_content = $site->get('content');
$this->_siteRecord = $site;
but in your getContent() you use:
$this->_siteRecord->content;
That difference might be part of the problem.
Thank you all guys. It was Doctrine caching.
I have not investigated further the problem, but after getting rid of Doctrine everything works fine.
I have lost one entire day after this issue.
Moreover today I have lost another day for another curious problem related to Doctrine.
It seems that each time you gather data from your db Doctrine decode them for you (just like the php function utf8_decode($data).
Of course if you get the data and then put it back in the db again it will result in a total mayhem of coding and decoding.
This is enough. I still think that ORM are great programming tools but simply Doctrine is not.
I will not rest in peace since I'll have it eliminated from my program.
I will use Zend_Db library instead. Which I have mostly already done without regret and without facing the above-mentioned Doctrine's problems.
Again thanks to Seth Battin and Dave Random for the help and patience to understand my noob-coding.

Categories