Yii2 isnewrecord generates exception - yii2

In yii2 set-up I have multiple models - one being one to many with repeat fields in form where I can edit fieldset or add new records.
but I am facing issue of duplicate key error.
To overcome the same I am trying this code:
try{
$userchild->save();
}
catch(\Exception $e){
$userchild->isNewRecord = false;
$usrchild->save();
}
but I am getting the exception:
Unknown Method – yii\base\UnknownMethodException
Calling unknown method: app\controllers\UserController::setIsNewRecord()
What I am missing here?
update with more code:
if ($model->load(Yii::$app->request->post()) && $profile->load(Yii::$app->request->post()) && $billinginfo->load(Yii::$app->request->post()) ) {
$model->username = $model->email;
$model->save();
$profile->save();
$billinginfo->save();
if (!empty($_POST['UserChildren']) && !is_null($_POST['UserChildren'])) {
foreach($_POST['UserChildren'] as $rows){
$userchild = New UserChildren;
$userchild->user_id = $model->id;
$userchild->id =$rows['id'];
$userchild->attributes=$rows;
try{
$userchild->save();
} catch(\Exception $e){
$userchild->setIsNewRecord(false);
$usrchild->save();
}
}
}
Now I am getting the error:
Unknown Property – yii\base\UnknownPropertyException
Getting unknown property: app\models\UserChildren::_attributes

if you want assigng the attributes you should use
$userchild->setAttributes($rows, TRUE);
https://www.yiiframework.com/doc/api/2.0/yii-base-model#$attributes-detail

Related

Got an error in `php artisan migrate` in Laravel

I always use Laravel project since Laravel 4 up to 7. But this is my first time encountering and error when I migrate my database in freshly download Laravel. This is the error when I migrate:
$e = $event->getThrowable();
if (!$event->hasResponse()) {
$this->finishRequest($request, $type);
throw $e;
}
$response = $event->getResponse();
// the developer asked for a specific status code
if (!$event->isAllowingCustomResponseCode() && !$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
// ensure that we actually have an error response
if ($e instanceof HttpExceptionInterface) {
// keep the HTTP status code and headers
$response->setStatusCode($e->getStatusCode());
$response->headers->add($e->getHeaders());
} else {
$response->setStatusCode(500);
}
}
try {
return $this->filterResponse($response, $request, $type);
} catch (\Exception $e) {
return $response;
}
}
/**
* Returns a human-readable string for the specified variable.
*/
private function varToString($var): string
{
if (\is_object($var)) {
return sprintf('an object of type %s', \get_class($var));
}
if (\is_array($var)) {
$a = [];
foreach ($var as $k => $v) {
$a[] = sprintf('%s => ...', $k);
}
return sprintf('an array ([%s])', mb_substr(implode(', ', $a), 0, 255));
}
if (\is_resource($var)) {
return sprintf('a resource (%s)', get_resource_type($var));
}
if (null === $var) {
return 'null';
}
if (false === $var) {
return 'a boolean value (false)';
}
if (true === $var) {
return 'a boolean value (true)';
}
if (\is_string($var)) {
return sprintf('a string ("%s%s")', mb_substr($var, 0, 255), mb_strlen($var) > 255 ? '...' : '');
}
if (is_numeric($var)) {
return sprintf('a number (%s)', (string) $var);
}
return (string) $var;
}
}
Error
Stack trace:
#0 D:\Supporting Enterprises\Projects\Laravel Projects\SuperpagesAPI\artisan(18): require()
#1 {main}
thrown in D:\Supporting Enterprises\Projects\Laravel Projects\SuperpagesAPI\vendor\autoload.php on line 7
Fatal error: Uncaught Error: Class 'ComposerAutoloaderInitbe984857c53a573c5f216d0eb36fe0e7' not found in D:\Supporting Enterprises\Projects\Laravel Projects\SuperpagesAPI\vendor\autoload.php:7
Stack trace:
#0 D:\Supporting Enterprises\Projects\Laravel Projects\SuperpagesAPI\artisan(18): require()
#1 {main}
thrown in D:\Supporting Enterprises\Projects\Laravel Projects\SuperpagesAPI\vendor\autoload.php on line 7
Before this happen I start IIS from the IIS Manager. I don't know if this will effect. I turn it on because I run a C# web application on my end.
It looks like this is composer problem. Just try to run this bash script:
composer dump-autoload

make laravel report malformed JSON

Is there a way to make laravel report a malformed JSON on input? Now the controller just doesnt receive any data and I would want it to raise an exception if content type is json on request
Do it in a before filter:
App::before(function ($request)
{
if ( ! str_contains($request->getContentType(), 'json')) return;
json_decode($request->getContent());
if (json_last_error() != JSON_ERROR_NONE)
{
throw new Exception('Malformed JSON.');
}
});
If you don't want it to fail when there's no content, use this:
App::before(function ($request)
{
if ( ! ($content = $request->getContent())) return;
if ( ! str_contains($request->getContentType(), 'json')) return;
json_decode($content);
if (json_last_error() != JSON_ERROR_NONE)
{
throw new Exception('Malformed JSON.');
}
});

Codeigniter Displaying Information In A View?

I'm extracting two different sets of data from a function in my model (syntax below). I'm trying to display the data my view. I put the variable in var_dump and var_dump is displaying the requested information but I'm having a hard time accessing that information. I'm getting two different sets of error messages as well. They are below. How would I display the information in my view? Thanks everyone.
Site Controller
public function getAllInformation($year,$make,$model)
{
if(is_null($year)) return false;
if(is_null($make)) return false;
if(is_null($model)) return false;
$this->load->model('model_data');
$data['allvehicledata'] = $this->model_data->getJoinInformation($year,$make,$model);
$this->load->view('view_show_all_averages',$data);
}
Model_data
function getJoinInformation($year,$make,$model)
{
$data['getPrice'] = $this->getPrice($year,$make,$model);
$data['getOtherPrice'] = $this->getOtherPrice($year,$make,$model);
return $data;
}
function getPrice($year,$make,$model)
{
$this->db->select('*');
$this->db->from('tbl_car_description d');
$this->db->join('tbl_car_prices p', 'd.id = p.cardescription_id');
$this->db->where('d.year', $year);
$this->db->where('d.make', $make);
$this->db->where('d.model', $model);
$query = $this->db->get();
return $query->result();
}
function getOtherPrice($year,$make,$model)
{
$this->db->select('*');
$this->db->from('tbl_car_description d');
$this->db->where('d.year', $year);
$this->db->where('d.make', $make);
$this->db->where('d.model', $model);
$query = $this->db->get();
return $query->result();
}
View
<?php
var_dump($allvehicledata).'<br>';
//print_r($allvehicledata);
if(isset($allvehicledata) && !is_null($allvehicledata))
{
echo "Cities of " . $allvehicledata->cardescription_id . "<br />";
$id = $allvehicledata['getPrice']->id;
$model = $allvehicledata[0]->model;
$make = $allvehicledata->make;
echo "$id".'<br>';
echo "$make".'<br>';
echo "$model".'<br>';
echo $allvehicledata->year;
}
?>
Error Messages
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: views/view_show_all_averages.php
Line Number: 7
A PHP Error was encountered
Severity: Notice
Message: Undefined offset: 0
Filename: views/view_show_all_averages.php
Line Number: 9
In your controller you are assigning the result of function getJoinInformation to the variable allvehicledata. This variable is then assigned to the view.
The function getJoinInformation is returning an array with the following
$data = array(
'getPrice' => $this->getPrice($year,$make,$model),
'getOtherPrice' => $this->getOtherPrice($year,$make,$model)
);
So in your view you can access the attributes getPrice and getOtherPrice in the object $allvehicledata like
$allvehicledata->getPrice;
$allvehicledata->getOtherPrice;
In line 7 you try to access the attribute cardescription_id, which is not an attribute of the object $allvehicledata.
I think this is an attribute which is get from the db query, so you should try to access it allvehicledata->getPrice->cardescription_id or allvehicledata->getOtherPrice->cardescription_id.
In line 9 you try to access some data stored in an array $model = $allvehicledata[0]->model;, but $allvehicledata is not an array.

Silex: error handlers for specific exception types

It it possible in Silex to use an error handler based on what exception is thrown?
I know this is possible with a single exception handler and a switch statement on the classname of the thrown exception but to me it seems the "Silex way" is cleaner, yet doesn't work.
This is how I would expect it to work
<?php
// Handle access denied errors
$app->error(function (\App\Rest\Exception\AccessDenied $e) {
$message = $e->getMessage() ?: 'Access denied!';
return new Response($message, 403);
});
// Handle Resource not found errors
$app->error(function (\App\Rest\Exception\ResourceNotFound $e) {
$message = $e->getMessage() ?: 'Resource not found!';
return new Response($message, 404);
});
// Handle other exception as 500 errors
$app->error(function (\Exception $e, $code) {
return new Response($e->getMessage(), $code);
});
Problem is that when I throw a ResourceNotFound exception in my controller, the errorhandler tied to AccessDenied is executed
Catchable fatal error: Argument 1 passed to {closure}() must be an instance of App\Rest\Exception\AccessDenied, instance of App\Rest\Exception\ResourceNotFound given
Is this achievable in another way or should I just stuff everything in the handler that works with generic Exceptions and switch on the type of exception thrown?
PS: i'm aware of the $app->abort() method but prefer working with exceptions
EDIT: This feature has now made it into Silex core!
This is currently not possible. Right now you'd have to either have a single handler with a switch statement, or many handlers with an if ($e instanceof MyException) each.
I do like the idea though, and it should be possible to implement it by using reflection. It would be awesome if you could create a new ticket on the tracker, or even work on a patch, if you're interested.
Cheers!
Another solution that I use in my projects:
class ProcessCallbackException extends Exception
{
public function __construct(\Closure $callback, $message = "", Exception $previous = null)
{
parent::__construct($message, 0, $previous);
$this->callback = $callback;
}
public $callback;
}
class AccessDeniedException extends ProcessCallbackException
{
public function __construct($message = null)
{
$f = function() {
return app()->redirect('/login');
};
parent::__construct($f, $message);
}
}
# Handle your special errors
$app->error(function (\Exception $e, $code) {
if ($e instanceof ProcessCallbackException)
{
/** #var ProcessCallbackException $callbackException */
$callbackException = $e;
return call_user_func($callbackException->callback);
}
else
return null;
});

Elmah and DbEntityValidationException

I have setup a project with both Elmah and EF4.1 Code First.
The project is throwing a System.Data.Entity.Validation.DbEntityValidationException, but Elmah is not providing enough detail to determine what validation is failing. All that is logged is:
System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Is there a way to make Elmah expand and log the EntityValidationErrors property?
List<IUserFeedback> errors = new List<IUserFeedback>();
try
{
_dbContext.SaveChanges();
Updated(this, HasUnsavedChanges);
}
catch (DbEntityValidationException ex)
{
foreach (var x in ex.EntityValidationErrors)
{
foreach (var y in x.ValidationErrors)
{
if (!String.IsNullOrWhiteSpace(y.PropertyName))
errors.Add(new UserFeedback() {
FeedbackFlags = TypeOfUserFeedbackFlags.Error,
Message = String.Format("Unable to save {0} due to an issue with its \"{1}\" value. The error returned was \"{2}\"",x.Entry.Entity, y.PropertyName, y.ErrorMessage)
});
else
errors.Add(new UserFeedback() {
FeedbackFlags = TypeOfUserFeedbackFlags.Error,
Message = String.Format("Unable to save {0} due to the error \"{1}\"", x.Entry, y.ErrorMessage)
});
}
}
}
return errors;