I'm working on a function to recursively remove arrays and objects recursively. The problem is that certain recursions may be inside private properties of objects.
below is what I tried as well as the entries I tried to use.
this is my entrie
class TestOBJ{
private $fooClosure = null;
public $bar = 5;
private $myPrivateRecursion = null;
private $aimArrayAndContainsRecursion = [];
public function __construct()
{
$this->fooClosure = function(){
echo 'pretty closure';
};
}
public function setMyPrivateRecursion(&$obj){
$this->myPrivateRecursion = &$obj;
}
public function setObjInsideArray(&$obj){
$this->aimArrayAndContainsRecursion[] = &$obj;
}
}
$std = new stdClass();
$std->std = 'any str';
$std->obj = new stdClass();
$std->obj->other = &$std;
$obj = new TestOBJ();
$obj->bar = new TestOBJ();
$obj->bar->bar = 'hey brow, please works';
$obj->bar->setMyPrivateRecursion($std);
my entrie is var $obj
and this is my function / solution
function makeRecursionStack($vector, &$stack = [], $from = null)
{
if ($vector) {
if (is_object($vector) && !in_array($vector, $stack, true) && !is_callable($vector)) {
$stack[] = &$vector;
if (get_class($vector) === 'stdClass') {
foreach ($vector as $key => $value) {
if (in_array($vector->{$key}, $stack, true)) {
$vector->{$key} = null;
} else {
$vector->{$key} = $this->makeRecursionStack($vector->{$key}, $stack, $key);
}
}
return $vector;
} else {
$object = new \ReflectionObject($vector);
$reflection = new \ReflectionClass($vector);
$properties = $reflection->getProperties();
if ($properties) {
foreach ($properties as $property) {
$property = $object->getProperty($property->getName());
$property->setAccessible(true);
if (!is_callable($property->getValue($vector))) {
$private = false;
if ($property->isPrivate()) {
$property->setAccessible(true);
$private = true;
}
if (in_array($property->getValue($vector), $stack, true)) {
$property->setValue($vector, null);
} else {
//if($property->getName() === 'myPrivateRecursion' && $from === 'bar'){
//$get = $property->getValue($vector);
//$set = $this->makeRecursionStack($get, $stack, $property->getName());
//$property->setValue($vector, $set);
//pre_clear_buffer_die($property->getValue($vector));
//}
$property->setValue($vector, $this->makeRecursionStack($property->getValue($vector), $stack, $property->getName()));
}
if ($private) {
$property->setAccessible(false);
}
}
}
}
return $vector;
}
} else if (is_array($vector)) {
$nvector = [];
foreach ($vector as $key => $value) {
$nvector[$key] = $this->makeRecursionStack($value, $stack, $key);
}
return $nvector;
} else {
if (is_object($vector) && !is_callable($vector)) {
return null;
}
}
}
return $vector;
}
The place where I have comments is where I noticed the problem. if the If is not commented there $get would receive a stdClass that has recursion and this works perfectly and $set would receive the stdClass without recursion. In that order.
$get =
$set =
After this lines
$property->setValue($vector, $set);
pre_clear_buffer_die($property->getValue($vector));
i obtain this
I try to put other value like an bool or null inside property and after set the $set but it's not works.
P.S: pre_clear_buffer_die kill php buffer, init other buffer and show var inside a <pre> after exit from script. Is an debugger function.
Related
So i try to make a hooking API like wordpress add_filter and apply_filters,
So this is my implementation
My problem is that apply_filters does not filter the hook
$hook = new Hook();
$hook->add_filter('filter',function($test) {
return ' stackoverflow';
});
$hook->add_filter('filter',function($test) {
return $test .' world';
},1);
echo $hook->apply_filters('filter','hello');
// Result is hello world
What's wrong with my code, I want to result like this
hello world stackoverflow
For adding filters
public function add_filter(string $tag,mixed $object,int $priority = 10,int $args_limit = 1): void
{
$hooks = static::$hooks;
if(isset($hooks[$tag])) {
static::$hooks[$tag]['sorted'] = false;
static::$hooks[$tag]['priority'][] = $priority;
static::$hooks[$tag]['object'][] = $object;
static::$hooks[$tag]['args_limit'][] = $args_limit;
} else {
static::$hooks[$tag] = [
'sorted' => true,
'priority' => [$priority],
'object' => [$object],
'args_limit' => [$args_limit]
];
}
}
and for applying the filters
public function apply_filters(string $tag,mixed $value,mixed ...$args): mixed
{
$hooks = static::$hooks;
// Shift value to args
array_unshift($args,$value);
$num_args = count($args);
if(isset($hooks[$tag])) {
$hooks = $hooks[$tag];
if(!$hooks['sorted']) {
// Sort filter by priority
array_multisort(
$hooks['priority'],
SORT_NUMERIC,
$hooks['object'],
$hooks['args_limit']
);
$hooks['sorted'] = true;
}
foreach($hooks['object'] as $key => $object) {
$args_limit = $hooks['args_limit'][$key];
if(0 === $args_limit) {
$value = call_user_func($object);
} elseif($args_limit >= $num_args) {
$value = call_user_func_array($object,$args);
} else {
// Slice arguments if not meet from the second statement
$value = call_user_func_array($object,array_slice($args,0,$args_limit));
}
}
}
return $value;
}
So I try to look wordpress core code but the too complicated.
Thanks
Finally solved it! , I just forgot that $value doesn't pass to the callbacks
Here's the fix, for future references
public function apply_filters(string $tag,mixed $value,mixed ...$args): mixed
{
$hooks = static::$hooks;
// +1 for $value parameter
$num_args = count($args) + 1;
if(isset($hooks[$tag])) {
$hooks = $hooks[$tag];
if(!$hooks['sorted']) {
// Sort filter by priority
array_multisort(
$hooks['priority'],
SORT_NUMERIC,
$hooks['object'],
$hooks['args_limit']
);
$hooks['sorted'] = true;
}
foreach($hooks['object'] as $key => $object) {
$args_limit = $hooks['args_limit'][$key];
if(0 === $args_limit) {
$value = call_user_func($object);
} elseif($args_limit >= $num_args) {
$value = call_user_func($object,$value,...$args);
} else {
// Slice arguments if not meet from the second statement
$slice = array_slice($args,0,$args_limit);
$value = call_user_func($object,$value,...$slice);
}
}
}
return $value;
}
When I showed it in a browser when upgrading to symfony3, I had a title error (line 25).
I had questions on similar mistakes in StackOverflow, but I think it's a different trend.
I want to know how it can be improved.
Stack Trace
[1] Symfony\Component\Debug\Exception\FatalErrorException: Error:
Cannot use object of type Symfony\Component\HttpFoundation\Request as array
at n/a
in /Symfony/.../Bundle/Listener/PortalListener.php line 25
Code
PortalListener.php
<?php
namespace Ahi\Sp\PublicBundle\Listener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Ahi\Sp\PublicBundle\Controller\BaseController;
use Ahi\Sp\PublicBundle\Model\Service\AhiCookieService;
use Symfony\Component\HttpFoundation\Request;
/**
*/
class PortalListener
{
/*
*
* #param FilterControllerEvent $event
*/
public function preControllerExecute(FilterControllerEvent $event, Request $request)
{
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
$_controller = $event->getRequest();
if (isset($_controller[0])) { //line25
$controller = $_controller[0];
if (method_exists($controller, 'preExecute')) {
$controller->preExecute($request);
}
}
}
}
BaseController.php
<?php
namespace Ahi\Sp\PublicBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/ **
* Front controller.
* /
abstract class BaseController extends Controller
{
const MAX_ITEM_COUNT = 4; // Maximum number to get the item part number from the coordination. (You can get up to 4)
protected $parameters = array();
protected $response = null;
protected $cookie = null;
public function preExecute (Request $request) {
$this->cookie = $this->get('public.ahiCookieService');
// ---------------------------------------
// Gender (The order is the member's gender → portal top gender button → brand → shop → MEN'S $LADIE'S button)
$this->gender = $this->cookie->get('gender');
// Get the brand and overwrite the gender of the brand
$this->brand = null;
$brandDir = null;
$brandDirUrlParam = $request->attributes->get('brandDir');
$brandDirGetParam = $request->query->get('brandDir');
if ($brandDirUrlParam) {
$brandDir = $brandDirUrlParam;
} elseif ($brandDirGetParam) {
$brandDir = $brandDirGetParam;
}
$brandService = $this->get('public.brandService');
if ($brandDir) {
$brand = $brandService->getBrand($brandDir);
if (!$brand) {
throw $this->createBrandNotFoundException();
}
if(!$this->isPreview() && !$brand->getDispFlg()) {
throw $this->createBrandNotFoundException();
}
$brandSex = $brand->getBrandSex();
if ($brandSex != 2) {
$this->gender = $brandSex;
}
$this->brand = $brand;
}
// shop --------------------------------->
$this->shop = null;
$shopDir = null;
$shopDirUrlParam = $request->attributes->get('shopDir');
$shopDirGetParam = $request->query->get('shopDir');
if ($shopDirUrlParam) {
$shopDir = $shopDirUrlParam;
} elseif ($shopDirGetParam) {
$shopDir = $shopDirGetParam;
}
$this->shopDir = $shopDir;
$shopService = $this->get('public.shopService');
if ($shopDir) {
$shop = $shopService->getShop($shopDir);
if (!$shop) {
throw $this->createShopNotFoundException();
}
if (!$this->isPreview() && !$shop->getDispFlg()) {
if ($shop->getRedirectFlg() == true) {
$redirectUrl = $shop->getRedirectUrl();
if (empty($redirectUrl)) {
$redirectUrl = $this->generateUrl('ahi_sp_public_brand_top', array('brandDir' => $shop->getBrand()->getDirName()));
}
throw new ShopRedirectException($redirectUrl);
} else {
throw $this->createShopNotFoundException();
}
}
$shopSex = $shop->getShopSex();
if ($shopSex != 2) {
$this->gender = $shopSex;
}
$this->shop = $shop;
}
// shop <---------------------------------
$gender = $request->query->get('gender');
if ($gender !== null) {
$this->gender = $gender;
}
if ($this->getRequest()->get('_route') !== 'ahi_sp_public_portal_top') {
$gender = $request->query->get('gender');
if ($gender !== null) {
$this->gender = $gender;
}
}
if ($this->gender !== null) {
$this->gender = intval($this->gender);
$this->cookie->set('gender', $this->gender, 30);
$this->cookie->set('ec_gender', $this->gender, 30);
}
if ($this->gender === 0 or $this->gender === 1) {
$this->paramsSex = array('sex'=> array($this->gender, 2));
} else {
$this->paramsSex = array('sex'=> array(0, 1, 2));
}
$mid = $this->cookie->get('member_id');
$session = $request->getSession();
if ($mid && !$session->has('favoriteShops')) {
$route = $this->container->getParameter('ats_http');
$list = $this->container->getParameter('favorite_shop_list');
$url = $route . $list . $mid;
$ahiStoreIdList = file_get_contents($url);
$favoriteShops = array();
if ($ahiStoreIdList !=='') {
$ahiStoreIdArray = explode(",", $ahiStoreIdList);
$shopService = $this->get("public.shopService");
$sortKey = array();
foreach ($ahiStoreIdArray as $key => $storeId) {
$id = explode(':', $storeId);
$shop = $shopService->getShopById($id[1]);
if ($shop) {
$favoriteShops[$key]['shopName'] = $shop->getShopName();
$favoriteShops[$key]['shopDir'] = $shop->getDirName();
$sortKey[$key] = $shop->getShopName();
}
}
array_multisort($sortKey, SORT_ASC, $favoriteShops);
}
$session->set('favoriteShops', $favoriteShops);
}
$trend_tag_list_limit = $this->container->getParameter("trend_tag_list_limit");
if(!$brandDirUrlParam and !$shopDirUrlParam){
$this->parameters['brandPrefectures'] = $this->service('coordinate')->getPrefExistBrand();
$this->parameters['prefBrands'] = $this->service('coordinate')->getBrandPerPref();
$this->parameters['shopBrandPrefectures'] = $this->service('brand')->getPrefExistBrand();
$this->parameters['shopPrefBrands'] = $this->service('brand')->getBrandPerPref();
$this->parameters['trendTags'] = $this->service('ecTrendTag','common')->getTrendTag($this->paramsSex,false,$trend_tag_list_limit);
}elseif($brandDirUrlParam){
$this->parameters['brandPrefectures'] = $this->service('coordinate')->getPrefExistBrand($brandDirUrlParam);
$this->parameters['trendTags'] = $this->service('ecTrendTag','common')->getTrendTag($this->brand,false,$trend_tag_list_limit);
}else{
$this->parameters['coordinateCount'] = $this->service('coordinate')->getCountArticle(
$this->brand,
$this->shop
);
$this->parameters['trendTags'] = $this->service('ecTrendTag','common')->getTrendTag($this->shop->getBrand(),false,$trend_tag_list_limit);
}
}
Version
Cent OS 6.7
PHP 5.6
Symfony3.0.9
The error was resolved when I fixed it as follows.
public function preControllerExecute(FilterControllerEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
$request = $event->getRequest();
$_controller = $event->getController();
if (isset($_controller[0])) {
$controller = $_controller[0];
if (method_exists($controller, 'preExecute')) {
$controller->preExecute($request);
}
}
}
}
<?php
class User {
public $id;
public $counter;
public $removed;
}
$dB = json_decode(file_get_contents('dataBase.json'), true);
$dataBase = &$dB['noob'];
$userInDB = null;
$user = array('id' => (int)$_GET['id'], 'counter' => (int)$_GET['counter'], 'removed' => (bool)$_GET['removed']);
foreach ($dataBase as $usr) {
if ($usr['id'] == $user['id']) {
$userInDB = &$usr;
break;
}
}
if ($userInDB) {
$userInDB['counter'] = $userInDB['counter'] + $user['counter'];
$userInDB['removed'] = $user['removed'];
print_r($userInDB);
} else {
$dataBase[] = $user;
print_r($dataBase);
}
if(isset($_GET['id'])) {
$json = json_encode($user);
$updateddB = json_encode($dB);
file_put_contents('dataBase.json', $updateddB);
}
?>
Everything works except the part where I attempt to edit a value within an array. $userInDB is changed, but the section that it refers to within $dB isn't, even though I'm pretty sure I referred to it. Someone please help, I've had my head in knots.
You have the following loop:
foreach ($dataBase as $usr) {
if ($usr['id'] == $user['id']) {
$userInDB = &$usr;
break;
}
}
The $userInDB is a reference to $usr, however $usr was just created by the foreach loop, and is is not referenced to the original array it is looping over. So say, for example, you have this very simple case:
foreach ($foo as $var) {
$var++;
}
This does NOT affect $foo at all.
What you need to do is reference the $dataBase variable directly:
foreach ($dataBase as $key => $usr) {
if ($usr['id'] == $user['id']) {
$userInDB = &$dataBase[$key];
break;
}
}
I am trying to port my web app from laravel 4 to 5 but I am having issues in that one of my model classes is not found.
I have tried to utilize namespacing and have the following my Models which are located locally C:\xampp\htdocs\awsconfig\app\Models
the file which the error appears in looks like
<?php
use App\Models\SecurityGroup;
function from_camel_case($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match)
{
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}
return implode('_', $ret);
}
$resource_types = array();
$resource_types['AWS::EC2::Instance'] = 'EC2Instance';
$resource_types['AWS::EC2::NetworkInterface'] = 'EC2NetworkInterface';
$resource_types['AWS::EC2::VPC'] = 'VPC';
$resource_types['AWS::EC2::Volume'] = 'Volume';
$resource_types['AWS::EC2::SecurityGroup'] = 'SecurityGroup';
$resource_types['AWS::EC2::Subnet'] = 'Subnet';
$resource_types['AWS::EC2::RouteTable'] = 'RouteTable';
$resource_types['AWS::EC2::EIP'] = 'EIP';
$resource_types['AWS::EC2::NetworkAcl'] = 'NetworkAcl';
$resource_types['AWS::EC2::InternetGateway'] = 'InternetGateway';
$accounts = DB::table('aws_account')->get();
$account_list = array();
foreach(glob('../resources/sns messages/*.json') as $filename)
{
//echo $filename;
$data = file_get_contents($filename);
if($data!=null)
{
$decoded=json_decode($data,true);
if(isset($decoded["Message"]))
{
//echo "found message<br>";
$message= json_decode($decoded["Message"]);
if(isset($message->configurationItem))
{
// echo"found cfi<br>";
$insert_array = array();
$cfi = $message->configurationItem;
switch ($cfi->configurationItemStatus)
{
case "ResourceDiscovered":
//echo"found Resource Discovered<br>";
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$insert_array[from_camel_case($key)] = $value;
}
}
$resource->populate($insert_array);
if (!$resource->checkExists())
{
$resource->save();
if(isset($cfi->configuration->tags))
{
foreach ($cfi->configuration->tags as $t )
{
$tag= new Tag;
$tag->resource_type = "instance";
$tag->resource_id = $resource->id;
$tag->key = $t->key;
$tag->value = $t->value;
$tag->save();
/*if(isset($cfi->awsAccountId))
{
foreach ($accounts as $a)
{
$account_list = $a->account_id;
}
if (!in_array($account_id,$account_list))
{
$account_id = new Account;
$account_id->aws_account_id = $cfi->awsAccountId;
$account_list[] = $account_id;
$account_id->save();
}
} */
}
}
}
}
else
{
echo "Creating ".$cfi["resourceType"]." not yet supported<br>";
}
break;
case 'ResourceDeleted':
// echo"found Resource Deleted<br>";
//ITEM DELETED
if (array_key_exists($cfi->resourceType,$resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
if ($resource->checkExists($cfi->resourceId))
{
$resource->delete();
if( isset($cfi->configuration->tags))
{
foreach ($cfi->configuration->tags as $t )
{
$tag= new Tag;
$tag->resource_type = "instance";
$tag->resource_id = $resource->id;
$tag->key = $t->key;
$tag->value = $t->value;
if ($tag->checkExists($cfi->configuration->tags))
{
$tag->delete();
}
}
}
}
}
else
{
echo "Deleting ".$cfi["resourceType"]." not yet supported<br>";
}
break;
case 'OK':
//echo"found Resource OK<br>";
//ITEM UPDATED
if (array_key_exists($cfi->resourceType, $resource_types))
{
//var_dump($cfi->resourceType);
$resource = new $resource_types[$cfi->resourceType];
if ($resource->checkExists($cfi->resourceId))
{
foreach ($cfi->configuration as $key => $value)
{
if (in_array($key,$resource->fields))
{
$update_array[from_camel_case($key)] = $value;
}
}
$resource->populate($update_array);
$resource->save();
}
}
else
{
echo "Updating ".$cfi["resourceType"]." not yet supported<br>";
}
break;
default:
echo "Status ".$cfi['configurationItemStatus']." not yet supported<br>";
break;
}
}
}
}
}
and the corresponding model whose class cannot be found looks like :
<?php namespace App\Models;
use Eloquent;
class SecurityGroup extends Eloquent
{
protected $table = 'security_group';
public $timestamps = false;
protected $guarded = array('id');
public $fields = array('groupId',
'groupName',
'description',
'ownerId'
);
public function checkExists()
{
return self::where('group_id', $this->group_id)->first();
}
public function populate($array)
{
foreach ($array as $k => $v)
{
$this->$k = $v;
}
}
}
I am lost as to what is causing the problem I don't see any typos but then again who knows as always thanks for any help given.
to solve the resource type needs the full namespace declaration
I have the simple app below. I'm turning off query logging in Laravel, I'm unsetting where possible, yet this function will only process about 800 records before I'm out of RAM on my 2GB Linode. I know I'm asking a lot of you guys but I can't seem to see where I'm leaking memory.
There are really only two major steps.
Step 1 - Move records from a temp table to production
class ListingMigrator
{
public function __construct($tempListing, $feed)
{
$this->tempListing = $tempListing;
$this->listing = $this->listingInstance();
$this->feed = $feed;
}
public static function migrateListing($listing, $feed)
{
$instance = new static($listing, $feed);
return $instance->migrate();
}
public function migrate()
{
$this->addExternalData();
$this->populateListing();
$this->processPhotos();
$this->deleteTempListing();
}
private function listingInstance()
{
DB::connection()->disableQueryLog();
$listing = Listing::findByMud($this->tempListing->matrix_unique_id);
return $listing ?: new Listing;
}
private function processPhotos()
{
$retsApi = new RetsFeedApi($this->feed);
/* Initialize Object */
$rets = $retsApi->findMostRecent();
$photos = $rets->getPhotosForListing($this->listing->matrix_unique_id);
foreach ($photos as $photo)
{
$uploader = new PhotoProcessor($this->listing, $photo);
$uploader->process();
}
}
private function populateListing()
{
DB::connection()->disableQueryLog();
$this->listing->fill($this->tempListing->toArray());
$this->listing->imported_at = $this->tempListing->created_at;
$this->listing->board = $this->tempListing->board;
return $this->listing->save();
}
private function addExternalData()
{
// Get Google lattitude and longitude
$googlecoords = getGoogleMapInfo($this->tempListing->FullAddress, $this->tempListing->City);
$this->listing->GoogleLat = $googlecoords['GoogleLat'];
$this->listing->GoogleLong = $googlecoords['GoogleLong'];
// Add or update the Subdivision Table (helper function)
$subdivisiondata = SubdivisionUpdate($this->tempListing->board, $this->tempListing->SubCondoName, $this->tempListing->Development);
$this->listing->SubdivisionID = $subdivisiondata['id'];
}
private function deleteTempListing()
{
return $this->tempListing->delete();
}
}
Step 2 - Download photos and reupload to Amazon S3
class PhotoProcessor
{
public function __construct(Listing $listing, $photoData)
{
$this->bucket = 'real-estate-listings';
$this->s3 = App::make('aws')->get('s3');
$this->tempFileName = 'app/storage/processing/images/retsphotoupload';
$this->photoData = $photoData;
$this->listing = $listing;
$this->photo = new RetsPhoto;
}
public function process()
{
$this->storeTempFile();
$this->storeFileInfo();
$this->buildPhoto();
$success = $this->pushToS3();
// if Result has the full URL or you want to build it, add it to $this->photo
DB::connection()->disableQueryLog();
$this->listing->photos()->save($this->photo);
$this->removeTempFile();
unset ($this->photoData);
return $success;
}
private function storeTempFile()
{
return File::put($this->tempFileName, $this->photoData['Data']) > 0;
}
private function storeFileInfo()
{
$fileInfo = getimagesize($this->tempFileName);
// Could even be its own object
$this->fileInfo = [
'width' => $fileInfo[0],
'height' => $fileInfo[1],
'mimetype' => $fileInfo['mime'],
'extension' => $this->getFileExtension($fileInfo['mime'])
];
}
private function buildPhoto()
{
$this->photo->number = $this->photoData['Object-ID']; // Storing this because it is relevant order wise
$this->photo->width = $this->fileInfo['width'];
$this->photo->height = $this->fileInfo['height'];
$this->photo->path = $this->getFilePath();
}
private function getFilePath()
{
$path = [];
if ($this->listing->City == NULL)
{
$path[] = Str::slug('No City');
}
else
{
$path[] = Str::slug($this->listing->City, $separator = '-');
}
if ($this->listing->Development == NULL)
{
$path[] = Str::slug('No Development');
}
else
{
$path[] = Str::slug($this->listing->Development, $separator = '-');
}
if ($this->listing->Subdivision == NULL)
{
$pathp[] = Str::slug('No Subdivision');
}
else
{
$path[] = Str::slug($this->listing->Subdivision, $separator = '-');
}
if ($this->listing->MLSNumber == NULL)
{
$pathp[] = Str::slug('No MLSNumber');
}
else
{
$path[] = Str::slug($this->listing->MLSNumber, $separator = '-');
}
$path[] = $this->photoData['Object-ID'].'.'.$this->fileInfo['extension'];
return strtolower(join('/', $path));
}
private function pushToS3()
{
return $this->s3->putObject([
'Bucket' => $this->bucket,
'Key' => $this->photo->path,
'ContentType'=> $this->fileInfo['mimetype'],
'SourceFile' => $this->tempFileName
]);
}
private function getFileExtension($mime)
{
// Use better algorithm than this
$ext = str_replace('image/', '', $mime);
return $ext == 'jpeg' ? 'jpg' : $ext;
}
private function removeTempFile()
{
return File::delete($this->tempFileName);
}
}
Edit to show RetsPhoto
class RetsPhoto extends Eloquent {
protected $table = 'rets_property_photos';
public function listing() {
return $this->belongsTo('Listing', 'matrix_unique_id', 'matrix_unique_id');
}
}
Edit #2: Chunk Call
This is in the app/command and the only thing in there is the fire() function below:
public function fire()
{
// Turn off query logging
DB::connection()->disableQueryLog();
$feeds = RetsFeed::where('active','=',1)->get();
foreach ($feeds as $feed)
{
$class = "TempListing{$feed->board}";
$listings = $class::orderBy('MatrixModifiedDT','desc');
$listings->chunk(50, function($listings) use($feed) {
$listings->each(function($listing) use ($feed) {
ListingMigrator::migrateListing($listing,$feed);
echo "Feed: $feed->board\r\n";
echo "SubcondoName: $listing->SubCondoName\r\n";
echo "Development: $listing->Development\r\n";
echo "\r\n";
});
});
}
}
I think I have figured it out.
Your system holds in memory all of the photo data. As witnessed by the unset ($this->photoData);
The problem is that you need to first complete the process function. Your application is not likely processing ANY photos so when you keep grabbing them from the file system you run out of memory BEFORE you even process a single one.
To Confirm this, simply grab 1 file not using the chunk method.
I am not very familar with Laravel, it could be grabbing all of the files all at once as well and eating the ram.
You can do some tracing with memory_get_usage(true) to find out exactly where the ram is getting eaten from. I would suggest analysing the fire method first.