Codeingiter 4 : "there is no data to update" exception - php

i'm trying to understand up Codeingiter works with entity.
Here's my code from InterventionController.php :
$intervention = $this->interventionsModel->find($id);
$intervention->title = $this->request->getVar("title");
$this->interventionsModel->save($intervention);
-> if i change the title into the form and if i click the "update" button : it works well (database get updates)
-> When i don't change the title and i just click the "update" button : it throws an exception : "There is no data to update."
How can i use codeingiter 4 without getting that exception if no data have been changed by the user ?
Thanks

Save is a wrapper for update/insert. When you know you're updating a record, you can use the update function, pass the variables in and the update will save, regardless of whether the properties of the record have changed.
$intervention = $this->interventionsModel->find($id);
$intervention->title = $this->request->getVar("title");
$this->interventionsModel->update($id, [
"title" => $intervention->title
]);
I think there should be a property of the model that turns this functionality off for the save() wrapper, but it doesn't appear there is.
Documentation: https://codeigniter.com/user_guide/models/model.html?highlight=data%20update#saving-data

try this
$this->obj->update($id, $p);
instead of
$this->obj->where('id',$id)->update( $p);

You can check if the value from form is empty or not and use the IF Condtion
$intervention = $this->interventionsModel->find($id);
if($this->request->getVar("title"))
{
$intervention->title = $this->request->getVar("title");
$this->interventionsModel->save($intervention);
} else {
// title is empty or null;
}

Related

PHP / Laravel Firebase Realtime Database updating a specific field

I'm trying to update firebase realtime database using kreait/firebase-php package.
Here's my tree:
I need to update the child of /detail/pesan/1/<unique ID> which have is_read value of false and update it to true.
Here's part of my code:
$database = $firebase->getDatabase();
$id_pesan=1;
/*
Update Firebase is_read
*/
$update = ['/is_read' => "true"];
$updatePesan_1 = $database
->getReference('chat/detail/'. $id_pesan)
->orderByChild('is_read')
->equalTo('false')
->update($update);
But i get this error :
Call to undefined method Kreait\Firebase\Database\Query::update()
when I change it to get the value first then update / set it :
$updatePesan_1 = $database
->getReference('chat/detail/'. $id_pesan)
->orderByChild('is_read')
->equalTo('false')
->getValue()
->set($update);
I get this error :
{"status":"error","error":400,"message":"Index not defined, add \".indexOn\": \"is_read\", for path \"/chat/detail/1\", to the rules"}
What I'm trying to do is filter / query database first to find child of specific tree which have is_read = false and update the value from "false" to "true".
Is it possible to do query of firebase database then updating it?
If yes how do I fix my code to achieve that?
Here's my solution
Okay so after many research and trial and error.
I did a couple of things :
Change the new rule to enable editing specific field on firebase database
Change the PHP code since I am unable to do filter / query then update. so I had to do it without filter / query and then updating data
1. Changes to Firebase database Rule
I change the rule to this :
{
"rules": {
".read": true,
".write": true,
"chat": {
"detail": {
"$id_pesan" :{
".indexOn": ["is_read"]
}
}
}
}
}
Some short explaination :
The data is stored in chat/detail///
since I need to be able to change what's inside I added ".indexOn" : ["is_read"] I change the rule and put indexing inside chat/detail/.
2. Change PHP code
At first what I want to do is this :
Initialize Firebase
Set references
Do Update call while query-ing field (in 1 call)
But it seems the package doesn't support what I wanted to do. so instead what I had to do is I have to query the field and get the unique ID value first. Then I made it into an Associative Array, then use it to update Database
here's the new code
//initialize
$database = $firebase->getDatabase();
//get value of all the unique ID
$getValue = $database
->getReference('chat/detail/'. $id_pesan)
->orderByChild('is_read')
->equalTo('false')
->getValue();
//initialize Array
$update = [];
//make the array necessary to update the firebase database
/*
What the Array should looks like
<Unique ID>/<variable I wanted to change> => "<new Value>"
Example :
"-IUAYS678/is_read" => "true"
"-JVHBY817/is_read" => "true"
*/
foreach($updatePesan_1 as $k => $v)
{
$update[$k. "/is_read"]="true";
}
//Update the Firebase Database
$updatePesan_1_process=$database->getReference('chat/detail/'. $id_pesan)
->update($update);
I hope this helps

Gii model generation not getting past first step - strange bevavior, what's causing this?

I've installed the latest version of yii2 using the advanced template. The website is working fine. For some reason the Gii generation tool is stuck and does not react as expected after clicking the preview button. Instead of showing a new form with the "Generate" button, it shows the same form unchanged without any messages as to what is happening.
Using xdebug I can see in the "actionView" method of the DefaultController that the array value $_POST['preview'] is not set, i.e. it doesn't exist in the $_POST array. I have not changed anything in the Form of the view and everything looks OK. The submit button has the name "preview" and the form is submitted but the $_POST array is not being filled with the value of the submit button. Therefore the controller does not proceed with the next steps of the generation process.
public function actionView($id)
{
$generator = $this->loadGenerator($id);
$params = ['generator' => $generator, 'id' => $id];
// ###############################################################################
// ### THIS IF STATEMENT IS NOT TRUE BECAUSE $_POST['preview'] IS NOT SET !!! ###
// ###############################################################################
if (isset($_POST['preview']) || isset($_POST['generate'])) {
// ###############################################################################
if ($generator->validate()) {
$generator->saveStickyAttributes();
$files = $generator->generate();
if (isset($_POST['generate']) && !empty($_POST['answers'])) {
$params['hasError'] = !$generator->save($files, (array) $_POST['answers'], $results);
$params['results'] = $results;
} else {
$params['files'] = $files;
$params['answers'] = isset($_POST['answers']) ? $_POST['answers'] : null;
}
}
}
return $this->render('view', $params);
}
Does anyone have an idea what could be causing this? I have a hunch that it is something quite simple that I'm overlooking, but I've never had a situation where POST variable from a Form are not being sent to the server.
False Alarm. I've found the problem. The Gii view was creating the HTML Form incorrectly.

Create a form for dynamic models - Yii

I have to create a form for a set of models, but unfortunately, I don't know how to do.
My first idea is to create a single form and a controller action which renders the view containing the form. But, this idea let me face an error. I create an action like this :
public function actionAddInfo($id){
$participant = Participant::model()->find('id_participant = ' . $id);
$info = InfoComp::model()->findAll('id_event = ' . $participant->id_event);
// here I must save the model if submitted
$this->render('addInfo', array('model' => $info));
}
In fact, the relationship in my models Participant, Evenement is below :
'idEvent' => array(self::BELONGS_TO, 'Evenement', 'id_event');
When accessing the variable $info in the view,
echo count($info);
I got the exception :
Undefined variable $info
This exception let me ask whether it is possible to proceed like that. I need your help. Else, can somebody suggest me another way to proceed ?
You are sending the variable with name model and you are trying to access it with name $info..
All you need to change is this:
$this->render('addInfo', array('info' => $info));

setting persistent plugin parameters in Joomla 3

I'm developing a Joomla 3.x plugin, and want to be able to change the plugin parameter set in the plugin's manifest file programmatically. I believe I need to use a JRegistry object, but I'm not sure about the syntax.
Here's the issue:
// token A is set in plugin params as defined in plugin's XML manifest
var_dump($this->params->get('token')); // prints token "A" as expected
// do some stuff to get a fresh access token, called token "B"
$tokenB = $function_to_get_fresh_token();
// set the new token
if ($tokenB) $this->params->set('token', $tokenB);
var_dump($this->params->get('apptoken')); // prints token "B" as expected
the problem is that on subsequent page reloads, the token reverts to tokenA rather than what I assumed would be the stored value of tokenB.
How do I store the tokenB value in the plugin's parameters in the database?
This is a working example of how to change plugin params from within the plugin (J! 3.4):
// Load plugin called 'plugin_name'
$table = new JTableExtension(JFactory::getDbo());
$table->load(array('element' => 'plugin_name'));
// Params can be changed like this
$this->params->set('new_param', 'new value'); // if you are doing change from a plugin
$table->set('params', $this->params->toString());
// Save the change
$table->store();
Note: If new params are added by plugin dynamically and the plugin is saved afterwards, these new params gets deleted. So one way to deal with it is to add those params as hidden fields to plugin's config XML.
This is just an outline, but something along these lines
$extensionTable = new JtableExtension();
$pluginId = $extensionTable->find('element', 'my_plugin');
$pluginRow = $extensionTable->load($pluginId);
// Do the jregistry work that is needed
// do some stuff to get a fresh access token, called token "B"
$tokenB = $function_to_get_fresh_token();
// set the new token
if ($tokenB) $this->params->set('token', $tokenB);
// more stuff
$extensionTable->save($pluginRow);
I spent a lot of time googling and reading and found no real answer to this. Oddly enough this doesn't seem to have been provided for in Joomla. So here's what I ended up doing:
1) build a function to get your plugin ID, since it will change from one installation to another
private function getPlgId(){
// stupid hack since there doesn't seem to be another way to get plugin id
$db = JFactory::getDBO();
$sql = 'SELECT `extension_id` FROM `#__extensions` WHERE `element` = "my_plugin" AND `folder` = "my_plugin_folder"'; // check the #__extensions table if you don't know your element / folder
$db->setQuery($sql);
if( !($plg = $db->loadObject()) ){
return false;
} else {
return (int) $plg->extension_id;
}
}
2) use the plugin id to load the table object:
$extension = new JTableExtension($db);
$ext_id = $this->getPlgId();
// get the existing extension data
$extension->load($ext_id);
3) when you're ready to store the value, add it to the params, then store it:
$this->params->set('myvalue', $newvalue);
$extension->bind( array('params' => $this->params->toString()) );
// check and store
if (!$extension->check()) {
$this->setError($extension->getError());
return false;
}
if (!$extension->store()) {
$this->setError($extension->getError());
return false;
}
If anyone knows a better way to do this please let me know!

Error Displayed with JToolbar DeleteList Static Function

I am building a Joomla 2.5 component and have a bit of trouble getting the Delete button to function properly. Here is a sample code from the view.html.php file:
if ($canDo->get('core.delete'))
{
JToolBarHelper::deleteList('You Really Wanna Delete that', mycomponentname.delete, 'JTOOLBAR_DELETE');
When I select an item from a dropdown list and click to delete I get the following pop-up:
You Really Wanna Delete that
The problem with this is when I click the option to verify the deletion from the pop-up I am redirected to a 500 error message and the item is not deleted.
Now when I review the Joomla documentation here:
http://docs.joomla.org/JToolBarHelper
I see that JToolBarHelper is defined in administrator/includes/toolbar.php. So I went for a visit over to review the deleteList info there. I see the following code:
public static function deleteList($msg = '', $task = 'remove', $alt = 'JTOOLBAR_DELETE')
{
$bar = JToolBar::getInstance('toolbar');
// Add a delete button.
if ($msg) {
$bar->appendButton('Confirm', $msg, 'delete', $alt, $task, true);
} else {
$bar->appendButton('Standard', 'delete', $alt, $task, true);
}
}
So I have attempted to adjust my script by changing the second parameter $task = 'remove' to read as remove rather than mycomponentname.delete as follows:
JToolBarHelper::deleteList('You Really Wanna Delete that', 'remove', 'JTOOLBAR_DELETE');
This will eliminate the 500 error, but the item is not removed. What am I missing here? My guess is that it has something to do with improperly configuring the mycomponentname.delete function.
PS- I should add that the 500 error states:
Layout default not found
There is only one problem you have. You don't need to put the component name on to the button task. You need to put controller name instead of component name.
if ($canDo->get('core.delete'))
{
JToolBarHelper::deleteList('You Really Wanna Delete that', 'controllerName.delete', 'JTOOLBAR_DELETE');
}
For example :
JToolBarHelper::deleteList('delete', 'hellos.delete','JTOOLBAR_DELETE');
Hope this helps you.

Categories