Laravel - Error with objects and arrays - php

I'm working on a Laravel application that needs to export .xls reports, and for this I'm using the Laravel-Excel library. When I'm in the development environment, the flow happens normally. The problem happens in the production environment, when we try export the report, the system says I'm working with an object, not an array. But when I change the declaration to object, it accuses it is actually an array. I'm not understanding anything else. Has anyone ever had this? What is the solution?
This code is where the error occurs:
$excel->sheet("Sheet1", function ($sheet) use ($followupData) {
//some code above
$city = $paciente['demographic']['city'];
$sheet->cell('AK8', ExportCenter::TranslateOption($city->joinville));
//some code below
)->export('xls');
The function TranslateOption() :
private static function TranslateOption($value)
{
$options = new \App\Option();
$op = $options->where('value', $value)->first();
return ExportCenter::TratamentoBranco($op['label']);
}

Related

Yii2 $model->_attributes assignment does not work in new version

I inherited a project that was created with Yii2, ver. 2.0.4, with the task to update said project to a more current version of Yii2 (2.0.15) because of the incompatibility of the older one with PHP 7.2+.
I noticed that there is a lot of use of assigning arrays to a model:
$model->_attributes = $array;
With the new version this results in an exception
'yii\base\UnknownPropertyException' with message 'Setting unknown property: app\models\model::_attributes'
For the time being I created a workaround with the following function:
function customSetAttributes(&$model, $array) {
foreach($model->attributeLabels() as $model_key => $model_label) {
if(!isset($array[$model_key])) continue;
$model->$model_key = $array[$model_key];
}
}
Also, the getter function now has a similar issue.
What I would like to know:
Was this type of assignment never intended in the first place (and I just haven't found the previous developer's code that enables it)? I skimmed over the Yii2 changelog but didn't notice anything related.
Is there a way to "salvage" the previous behaviour so I don't have to replace each occurence with my workaround function?
ActiveRecord::$_attributes was always private and never should be used in this way. I guess that previous developer edited framework core files in vendor directory and make this property protected/public.
You may try to emulate this behavior by creating virtual attribute using getter and setter:
public function get_attributes() {
return $this->getAttributes();
}
public function set_attributes($values) {
$this->setAttributes($values, false);
}
But this will not always work and it is more like an ugly hack to make crappy code work. I strongly suggest to fix code to use setAttributes() instead of _attributes.
Also you should compare yii2 package from vendor directory with source from https://github.com/yiisoft/yii2-framework/releases/tag/2.0.4 - you may find more places where core was edited.

Generating an XML Sitemap in Laravel 5

I have a laravel application that is still in the development stages. I am currently trying to generate a sitemap for the application using Spatie\Sitemap\SitemapGenerator but my code isn't working. This is my sitemap code in a file called GenerateSiteMap.php:
<?php
use Spatie\Sitemap\SitemapGenerator;
class GenerateSiteMap
{
public function generateSite()
{
$generator = SitemapGenerator::create('http://127.0.0.1:8000/')->writeToFile('sitemap.xml');
return $generator;
}
}
It doesn't give me any errors when I run it, it just doesn't do anything. Any idea how I can fix it?
If your file is at public folder you need to add public_path
$generator = SitemapGenerator::create('http://127.0.0.1:8000/')->writeToFile(
public_path('sitemap.xml'));
otherwise it might be a permission issue

Testing method with no output

I have the following method I want to test:
class SomeObject {
public function actionFromSomeController() {
$obj = new OtherObject();
$obj -> setAttributes();
$obj -> doAction();
}
}
class OtherObject {
private $_attr;
public function setAttributes() {
$this -> _attr = 'something';
Database :: execute('INSERT INTO table VALUES (' . $this -> _attr . ')');
$fileObj = new FileObj();
$content = $fileObj -> getSomeFileContent();
// do something else
}
public function doAction() {
echo $this -> _attr;
}
}
Now I want to test this method, its output depends on database content and one file on the server. It does a lot of things on the way, and the output is just one ID and success => 1.
How should I test it properly?
Some ideas on how to test small code pieces like this:
Generate test-data and pass it to your methods (also, fake database return data or file contents)
Use echo / var_dump() / die() to check property and variable content at different positions in your methods
Also use these commands to check whether execution reaches a certain point (for example to see whether a function got called or not)
If something doesn't work as expected without an error message: Check line by line with the above methods until you find the problem
Consider using interfaces and dependency injection if your code gets bigger - this is a bit over-the-top for this amount of code, but can be a tremendous time-saver when your application becomes big
Testing is never an automatic process and you will always have to think about what makes sense to do and what not. These things to do are never magic but basic PHP.
You should consider letting your scripts throw errors/exceptions if something goes wrong. Writing "silent" applications is almost never good since you can, if you really need a silent execution for production environments, just turn off error reporting and have the same effect. Many PHP functions return something special on failure and/or success and you can check for this. Database handlers do so, too. Do yourself a favor and use these return values!

PHP variable loses its value

I have a really serious problem that I have not seen before.
On a website we are using opensource SQC eshop, PHP Version 5.3.3-7+squeeze15 and there is some kind of problem with variable memory I think.
SQC uses notORM and here the problem starts with fatal error "Call to function on non object notORMResult" .
So I dug deeper and found the constructor of NotORM that looks like this:
function __construct(PDO $connection, NotORM_Structure $structure = null,NotORM_Cache $cache = null) {
$this->connection = $connection;
if($_GET['test']){
var_dump($structure);
}
if (!isset($structure)) {
$structure = new NotORM_Structure_Convention;
}
if($_GET['test']){
var_dump($structure);
}
$this->structure = $structure;
if($_GET['test']){
var_dump($this->structure);
exit("1");
}
$this->cache = $cache;
}
And so the output is NULL because the constructor gets no structure param so we create an object. Second output is the object. Then we set the object to attribute and then the THIRD OUTPUT IS NULL
How is this even possible? The site was running for about year and half and no problems till yesterday. I didn't made yet any updates to php and this thing really freaks me out 'cause it's not a constant problem. It just happens sometimes after 2 hours, sometimes after 2 mins and I have really no idea why is this happening.
And btw ... this is just the start it happens across the whole script. Object attributes are set but when you want to read them they give you NULL. There is also second website running on the same server, same php same configuration without problem.
Thanks for any ideas :)

Using $this when not in object context - in Laravel controller

I am using Laravel and I have just moved my code that is working locally into Live and am getting the exception below within my 'User' controller:
Unhandled Exception
Message:
Using $this when not in object context
The strange thing is, that this IS a class and works locally fine so I don't expect the solution to be using the static notation. It's only when I promote this to Live that I get this error. Could it be that something in the Laravel core that is missing from Live that is not loading the controller class properly?
Has anyone experienced this after promoting their code to Live? any ideas?
UPDATED: snippet of code where error is occuring. remember this code works locally so i believe something is missing rather than this code needs to be changed to fix this issue.
class User_Controller extends Base_Controller {
...
public function action_register() {
...
if ($user) {
//Create the Contact
DB::transaction(function() use ($user_id) {
$org = $this->create_org($user_id); //failing on this line with exception. btw $user is created fine
$this->create_contact($org->id);
$this->create_address($org->id);
});
private function create_org($user_id) {
$result = Org_type::where('name','=',$_POST['org_type'])->first();
$org = Org::Create(
array(
'name' => $_POST['org_name'],
'user_id' => $user_id,
'org_type_id' => $result->id,
)
);
return $org;
}
...
It seems the problem is that you're using $this inside a Closure you're providing to the DB::transaction function, i'm not sure why it would be working on live local, but you must import the instance of the controller into the function to use it.
The best way to do that, to avoid confusion, would be to alias it too, and possibly pass it by reference so you're not copying it, like:
$this_var = $this;
DB::transaction(function() use ($user_id, &$this_var as $controller) {
$org = $this->create_org($user_id); //failing on this line with exception. btw $user is created fine
$controller->create_contact($org->id);
$controller->create_address($org->id);
});
I'm not entirely sure if the syntax is perfect, but the logic is sound.

Categories