How to search in an array by value part - php

I want to get data from api request. I make a query on the value of oc52. Get $date array. The issuing server adds the MH prefix. Which generates itself relative to the name. I am trying to extract part of the array using the class.
This is the array I get when querying:
$data = [
[
'product' => 'CH C104.12',
'brand' => 'CH C104.12',
'price' => 12.34,
],
[
'product' => 'MH OC52',
'brand' => 'MH OC52',
'price' => 56.78,
],
[
'product' => 'WX WL7074-12',
'brand' => 'WX WL7074-12',
'price' => 90.12,
],
];
Here's the class I'm doing a search for
class ProductFilterIterator extends \FilterIterator
{
protected $filter;
public function __construct(\Iterator $iterator, $filter)
{
$this->filter = $filter;
parent::__construct($iterator);
}
public function accept() : bool
{
$current = $this->getInnerIterator()->current();
return $current['product'] == $this->filter;
}
}
$iterator = (new \ArrayObject($data))->getIterator();
$filter1 = new ProductFilterIterator($iterator, 'OC52');
foreach ($filter1 as $data) {
echo "<pre>";
var_dump($data);
echo "</pre>";
}
Does nothing reflect? If I write in line MH OC52:
$filter1 = new ProductFilterIterator($iterator, 'MH OC52');
Then everything works.
How do I implement it if I don't know the front - MH ???

If you just want to check the end of the string, this stores the length to check after storing the filter. Then in the main accept() method, it just looks at the last part of the string (using substr()) in the array to compare...
class ProductFilterIterator extends \FilterIterator
{
protected $filter;
protected $length;
public function __construct(\Iterator $iterator, $filter)
{
$this->filter = $filter;
$this->length = -strlen($filter);
parent::__construct($iterator);
}
public function accept() : bool
{
$current = $this->getInnerIterator()->current();
return substr($current['product'], $this->length) == $this->filter;
}
}

Related

Laravel Excel export row number starts from total row count instead of 1

I know there is a very simple solution requiring minor adjustment to my code but I'm stuck and I have wasted a lot of time trying to find the solution.
Using Laravel Excel I am able to export successfully except that the row numbers are off.
I was able to deduce that the numbering begins with the total number rows within the collection, but they are supposed to begin at 1.
Any help is greatly appreciated.
protected $table_data;
private $row = 0;
public function __construct(array $table_data)
{
$this->table_data = $table_data;
}
public function model(array $row)
{
++$this->row;
}
public function columnFormats(): array
{
return [
'E' => '0',
];
}
public function map($table_data): array
{
$department = (empty($table_data['department'])) ? 'Cast' : $table_data['department']['name'];
return [
++$this->row,
$department,
$table_data['name'],
$table_data['name_eng'],
$table_data['phone_number'],
$table_data['email'],
];
}
public function startCell(): string
{
return 'A6';
}
public function drawings()
{
$drawing = new Drawing();
$drawing->setName('Logo');
$drawing->setPath(public_path('/images/form_logo.png'));
$drawing->setHeight(90);
$drawing->setCoordinates('A1');
return $drawing;
}
public function headings(): array
{
return [
[
'#',
'Department',
'Position/Role',
'Name',
'Phone',
'Email',
]
];
}
public function styles(Worksheet $sheet)
{
$sheet->getStyle('A6:F6')->getFill()->applyFromArray(['fillType' => 'solid','rotation' => 0, 'color' => ['rgb' => '7BC1FA'],]);
$styleArray = array(
'font' => array(
'bold' => true,
'color' => array('rgb' => 'FFFFFF'),
'size' => 12,
'name' => 'Arial'
));
$sheet->getStyle('A6:F6')->applyFromArray($styleArray)->getAlignment()->setWrapText(true)->setHorizontal('left');
}
public function array(): array
{
return $this->table_data;
}
The problem is probably ++$this->row being executed at least twice as often as you expect. I'm not sure if that's because you have it both in model and map method but it might as well go wrong if it's only in map or you are not using import features and it's in model.
So I'd suggest a different solution:
If you are only exporting Data and specifically using the array approach for your data you could add the row index on the data set and use it in map and so on:
public function __construct(array $table_data)
{
$newTableData = [];
foreach($table_data as $index => $data) {
// add row index
$newTableData[] = array_merge(['row' => $index], $data);
}
$this->table_data = $newTableData;
}
//...
public function map($table_data): array
{
$department = (empty($table_data['department'])) ? 'Cast' : $table_data['department']['name'];
return [
// use row index
$table_data['row'],
$department,
$table_data['name'],
$table_data['name_eng'],
$table_data['phone_number'],
$table_data['email'],
];
}

php laravel foreach loop giving only 1 result from the array

what I want to do is to print the data with foreach, but whatever I have done, it prints the last element and not the other one,
where am i going wrong?
I want "PartyIdentification" to return up to each element.
I don't understand if I'm making a mistake in get and sets. Is there a short solution? I want to print more than one property.
the result of my output
i want to do
$aa = array(
0 => ['ID' => ['val' => '4000068418', 'attrs' => ['schemeID="VKN"']]],
1 => ['ID' => ['val' => '12345678901', 'attrs' => ['schemeID="TICARETSICILNO"']]],
2 => ['ID' => ['val' => '132546555', 'attrs' => ['schemeID="MERSISNO"']]]
);
$invoice_AccountSupplierParty_Party = new \Pvs\eFaturaUBL\Party();
$invoice_AccountSupplierParty_Party->PartyIdentification = InvoiceBuilder::getasd($aa);
public static function getasd(array $data)
{
$asd = new Olusturma();
$date = array();
foreach ($data as $datum) {
$asd->getID($data);
}
return $asd->getResult();
}
namespace App\Support\Invoice;
class Olusturma
{
public $contactDetails = array();
public function __construct()
{
$this->contactDetails = new \Erkan\eFaturaUBL\PartyIdentification();
}
public function setOlusturma(): Olusturma
{
return $this;
}
public function getID($data)
{
foreach ($data as $row => $innerArray) {
foreach ($innerArray as $innerRow => $value) {
$this->setID($value);
}
}
return $this;
}
public function setID($data): Olusturma
{
$this->contactDetails->ID = $data;
return $this;
}
public function getResult(): \Erkan\eFaturaUBL\PartyIdentification
{
return $this->contactDetails;
}

Recursive function return issue

I'm writing a recursive function like below:
private function getManager($employee)
{
$manager = $employee->manager;
if ($manager) {
array_push($this->managers, $manager->id);
$this->getManager($manager);
}
return;
}
This function receive an employee and find his manage. If find a manage, then push manager id into an array ($this->managers on line 5). Then call this function recursively and pass manager as an employee. If no manager found on line 3, then this function just return (line 8).
So my question is, is their any problem if i'm not return the recursive call at line 6 ($this->getManager($manager);)
Not sure if this is what you think, but it works.
function getManagers($employee)
{
$managers = [];
if (isset($employee->manager)) {
array_push($managers, $employee->manager->id);
array_push($managers, ...getManagers($employee->manager));
}
return $managers;
}
No, there is absolutely no benefit in writing the empty return. The method will halt regardless of the existence of the return.
Please observe the two methods below which show identical, error-less outcomes regardless of the return.
Code: (Demo)
class Management
{
private $managers = [];
function __construct($managerTree)
{
$this->getManager($managerTree);
var_export($this->managers);
echo "\n---\n";
$this->managers = [];
var_export($this->managers);
echo "\n---\n";
$this->getManager2($managerTree);
var_export($this->managers);
}
private function getManager(?object $employee): void
{
$manager = $employee->manager;
if ($manager) {
array_push($this->managers, $manager->id);
$this->getManager($manager);
}
return;
}
private function getManager2(?object $employee): void
{
$manager = $employee->manager;
if ($manager) {
array_push($this->managers, $manager->id);
$this->getManager($manager);
}
}
}
new Management(
(object) [
'id' => 3,
'manager' => (object) [
'id' => 2,
'manager' => (object) [
'id' => 1,
'manager' => null
]
]
]
);
Output:
array (
0 => 2,
1 => 1,
)
---
array (
)
---
array (
0 => 2,
1 => 1,
)

Laravel Argument 1 passed to

I'm trying to do my coding, but I ran into this issue. Thing is, I did it exactly the same like my first code, but it's working there.
ErrorException in CoinflipController.php line 115: Argument 1 passed
to App\Http\Controllers\CoinflipController::CoinflipToJson() must be
an instance of App\Models\Game\Coinflip\Coinflip, instance of
Illuminate\Database\Eloquent\Collection given, called in
C:\xampp\htdocs\site\app\Http\Controllers\CoinflipController.php on
line 104 and defined
Coinflip File
<?php
namespace App\Models\Game\Coinflip;
use Illuminate\Database\Eloquent\Model;
class Coinflip extends Model {
const STATUS_ACTIVE = 0;
const STATUS_ROLLING = 1;
const STATUS_ENDED = 2;
protected $table = 'coinflip';
protected $fillable = [
'status',
'winner_steam_id',
'winner_probability',
'winner_value',
'hash',
'ticket',
'seed',
'player1',
'player1_side',
];
protected $dates = [ 'draw_at' ];
protected $casts = [
'winner_steam_id' => 'string',
'winner_probability' => 'float',
'winner_value' => 'float',
'ticket' => 'double'
];
public function entry(){
return $this->hasMany( 'App\Models\Game\Coinflip\CoinflipEntry', 'coinflip_id' );
}
public function winner(){
return $this->hasOne( 'App\User', 'steam_id', 'winner_steam_id' );
}
public function getCommissionValue(){
$val = 0;
foreach( $this->entry as $entry ){
foreach( $entry->item as $item ){
if ( $item->status == CoinflipEntryItem::STATUS_COMMISIONED )
$val += (float)$item->price;
}
}
return $val;
}
}
CoinflipToJson Function (From 1st line is the Error)
public function CoinflipToJson( Coinflip $coinflip, $showExtra = false ){
$canDeposit1 = $coinflip->value * 0.10 + $coinflip->value;
$canDeposit2 = $coinflip->value - $coinflip->value * 0.10;
$data = [
'id' => $coinflip->id,
'hash' => $coinflip->hash,
'gameValue' => $coinflip->value,
'canDeposit1' => $canDeposit1,
'canDeposit2' => $canDeposit2,
'skinValue' => 0,
'skinCount' => 0,
'timeStart' => $coinflip->created_at->getTimestamp(),
'timeEnd' => $coinflip->draw_at ? $jackpot->draw_at->getTimestamp() : 0,
'timeEndIn' => $coinflip->draw_at ? $jackpot->draw_at->getTimestamp() - time() : -1,
'timeMax' => Setting::of('JackpotExtendTime', 15)->getValue(),
'entry' => []
];
if ( $showExtra ){
$data['winningPercentage'] = $coinflip->ticket;
$data['winnerId'] = $coinflip->winner_steam_id;
$data['secret'] = $coinflip->seed;
}
foreach( $coinflip->entry as $entry ){
$entryData = $this->entryToJson( $entry );
$data['entry'][] = $entryData;
$data['skinValue'] += $entryData['skinValue'];
$data['skinCount'] += $entryData['skinCount'];
}
return $data;
}
Code where I am calling it (Line 5)
public function current( Request $request ){
$coinflip = $this->getCurrentGame();
if($coinflip){
$data = [
'current' => $this->CoinflipToJson($coinflip)
];
return response()->json($data);
} else return response()->json(['error' => 'No Games']);
}
getCurrent Game Function
public function getCurrentGame(){
$coinflip = Coinflip::where('status', Coinflip::STATUS_ACTIVE)->get();
return $coinflip;
}
In your getCurrentGame() method, the get() method always returns a Collection, even if there was only one record. If you query will only ever return one record, you can just change get() to first(), and it will return the record instance, instead of a Collection.

Retrieving Data from an object of an array of arrays

I know this question is more data structures but since I am doing it in Symfony there might be a simpler way. I have a recursive function treeBuilder() I want to call on some data to create a hierarchy. Say a database of people and I want to create a tree structure if they live with their parents. I know I am passing an array of object to the function but it needs to be an array. I am pretty sure I need to rewrite this function so that it handles the the array of object but am stumped. I am not sure how to access the elements of the array to check the parentid. I know the code below is not correct but that is where I am at now.
Controller:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('CompanyMyBundle:Org')->findAll();
var_dump($entities);
$tree=$this->treeBuilder($entities);
return array(
'entities' => $tree,
);
}
private function treeBuilder($ar, $pid=null)
{
$op=array();
foreach( $ar as $item ) {
// I know I have an array of objects
if( $item['ParentId'] == $pid ) {
$op[$item['Id']] = array(
'Street' => $item['Street'],
'ParentId' => $item['ParentId']
);
$children = self::treeBuilder( $ar, $item['Id'] );
if( $children ) {
$op[$item['Id']]['children'] = $children;
}
}
}
return $op;
}
var_dump($entities) from indexAction():
/export/www/working/symfony/src/Company/MyBundle/Controller/DepController.php:34:
array (size=60)
0 =>
object(Company\MyBundle\Entity\Org)[1556]
private 'Name' => string 'Me' (length=46)
private 'Street' => string '123 Sesame' (length=255)
private 'City' => string 'Myhometown' (length=255)
private 'ParentId' => int 0
private 'Id' => int 1
1 =>
object(Company\MyBundle\Entity\Org)[1557]
private 'Name' => string 'Me2' (length=46)
private 'Street' => string '123 Sesame' (length=255)
private 'City' => string 'Myhometown' (length=255)
private 'ParentId' => int 1
private 'Id' => int 2
If you need to get entities as arrays instead of objects, you would need to use Doctrine's hydrator:
$em = $this->getDoctrine()->getManager();
$orgRepo = $em->getRepository('CompanyMyBundle:Org');
$entities = $orgRepo->createQueryBuilder('org')
->getQuery()
->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
Note:
I would suggest to leave entities as objects and use getters:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('CompanyMyBundle:Org')->findAll();
$tree = $this->treeBuilder($entities);
return array(
'entities' => $tree,
);
}
private function treeBuilder($entities, $pid = null)
{
$op = array();
/** Org $entity */ //Type hinting, if you use autocompletion
foreach ($entities as $entity) {
if ($entity->getParentId() == $pid) {
$op[$entity->getId()] = [
'Street' => $entity->getStreet(),
'ParentId' => $entity->getParentId()
];
$children = self::treeBuilder($entities, $entity->getId());
if (!empty($children)) {
$op[$entity->geId()]['children'] = $children;
}
}
}
return $op;
}

Categories