Self calling array return php - algorithm

i am writing a module that sorts through categories and returns me the lowest possible subcategory.
private function getChild($array){
foreach($array as $item){
if(is_array($item)){
$this->getChild($item);
} else {
array_push($this->catsToReturn, $item);
}
}
}
So my actual issue and question is why can't i return value in else enclosure? I would like to return $item and push that value to array, that would give me a better code readability, since now i have
$this->getChild($this->postCategories);
Hanging randomly in my code.
The strange and new thing for me is that i can echo the value but i can't return it, i know it's an issue with scope, but can't find any info on how to solve it.
Just wanted to know how to improve this.
Cheers

You could change your code by adding $item in an array and doing an array_merge to take results from subsequent calls.
<?php
private function getChild($array){
$result = [];
foreach($array as $item){
if(is_array($item)){
$result = array_merge($result,$this->getChild($item));
} else {
$result[] = $item;
}
}
return $result;
}
From wherever you are calling in your class, you can just do
$this->catsToReturn = $this->getChild($array)

Related

How to check the value on the array cart

I have an array cart on codeigniter and creates a function to separate if there is engrave or not on the array like this,
$cart_count = 0;
$cart_cek = $this->cart->contents();
foreach ($cart_cek as $value2) {
if($cart_count >= 1){
break;
}
else{
if($value2['engrave-text'] != ""){
$order_id = $this->generate_order_id_costume();
$cart_count++;
}
else{
$order_id = $this->generate_order_id();
$cart_count++;
}
}
}
but when I run the function it always goes into else with value
$order_id = $this->generate_order_id();
even though there is engrave in the cart array.
For example, I have 3 items in the cart that each have the engrave field. How do I know that there are at least 1 engrave field filled in all the carts?
If you want to check that if the cart contains at least one engrave-text field is filled, you could use array_column to get the engrave-text arrays, then array_filter to check if it's empty :
$cart_cek = $this->cart->contents();
if (!empty(array_filter(array_column($cart_cek, 'engrave-text')))) { // if at least one 'engrave-text' has a value, call generate_order_id_costume() method
$order_id = $this->generate_order_id_costume();
} else { // otherwise call generate_order_id() method
$order_id = $this->generate_order_id();
}
First of all, you don't need to check the count to stop the loop and try using isset().
Try this if you want to check if $this->cart->contents(); has at least 1 engrave-text object.
$cart = $this->cart->contents();
foreach ($cart as $cart_value) {
if(isset($cart_value['engrave-text'])){
$order_id = $this->generate_order_id_costume();
} else {
$order_id = $this->generate_order_id();
}
}

Laravel - Display Parent To The Nth Child Values

Please consider the table below
My desired result:
A
---AA1
------AAA1
---------AAAA1
---------AAAA2
---AA2
B
---BB1
---BB2
------BBB1
C
---CC1
------CCC1
---CC2
My problem:
I need to display on the blade file of this parent to nth-child values. The child is dynamic and can be on any level deep.
I have seen that this should be done using recursive function. I have seen some guide online, but it seem not the one i need.
Can anyone give me a hand here?
EDIT: Adding my model
class Type extends Model
{
public function parent()
{
return $this->belongsTo('App\Type', 'parent_id');
}
public function children()
{
return $this->hasMany('App\Type', 'parent_id');
}
public function childrenRecursive()
{
return $this->children()->with('childrenRecursive');
}
}
EDIT 2:
This is to show the (slightly refactored) final code from the accepted answer, hoping that this may help anyone in the future:
public function buildCategoryTreeHtml($types)
{
$html = [];
if($types->count()){
$html[] = '<ul>';
foreach($types as $type) {
$html[] = sprintf(
'<li>%s%s</li>',
$type->name,
$this->buildCategoryTreeHtml($type->children)
);
}
$html[] = '</ul>';
}
return implode($html);
}
I haven't actually tested it, but I'd have one method to build the HTML for the category tree, for example.
public function buildCategoryTreeHtml($categories)
{
$html = [];
if(count($categories))
$html = ['<ul>'];
foreach($categories as $category) {
$html[] = sprintf(
'<li>%s %s</li>',
$category->name,
$this->buildCategoryTreeHtml($category->children);
);
}
$html = ['</ul>'];
}
return implode($html);
}
You would of course need to pass the categories to it.
$categories = Category::with('childrenRecursive')
->whereNull('parent')
->get();
$html = $this->buildCategoryTreeHtml($categories);
That would output the categories in the format you want. Let me know if it works out :)

Joomla 2.5 method save()

Is there a way to show the changed values after saving within the Joomla save method?
For example, when I edit a "maxuser" field and save it, I´d like to show the old and the new value.
I tried this by comparing "getVar" and "$post", but both values are the same.
function save()
{
...
$maxuser1 = JRequest::getVar('maxuser');
$maxuser2 = $post['maxuser'];
...
if($maxuser1 != $maxuser2) {
$msg = "Not the same ...";
}
...
}
It's better to override JTable, not the Model. Heres sample code:
public function store($updateNulls = false) {
$oldTable = JTable::getInstance(TABLE_NAME, INSTANCE_NAME);
$messages = array();
if ($oldTable->load($this->id)) {
// Now you can compare any values where $oldTable->param is old, and $this->param is new
// For example
if ($oldTable->title != $this->title) {
$messages[] = "Title has changed";
}
}
$result = parent::store($updateNulls);
if ((count($messages) > 0) && ($result === true)){
$message = implode("\n", $messages);
return $message;
} else {
return $result;
}
}
This will return message string if there are any, true if there are no messages and save succeeded and false if saving failed. So all you have to do is check returned value in model and set right redirect message.
In the controller you can use the postSaveHook which gives you access to the validated values.

codeigniter - compare values

I need to compare two values in a table: cliente and nro_cuota, if both exist I don't want to add it.
Here is my code
$crud = new grocery_CRUD();
$crud->set_theme('datatables');
$crud->set_table('cobranzas');
$crud->set_subject('Cobranzas');
$crud->set_language('spanish');
$crud->required_fields(
'id',
'cobrador',
'cliente',
'nro_cuota'
);
$crud->columns(
'cobrador',
'cliente',
'nro_cuota'
);
$crud->set_relation('cobrador', 'cobradores', 'apellido_nombre');
$crud->set_relation('cliente', 'clientes', 'apellido_nombre');
$output = $crud->render();
$this->load->view('cobranzas/cobranzas_v', $output);
}catch(Exception $e){
show_error($e->getMessage().' --- '.$e->getTraceAsString());
}
}
and I wrote a model, I`m not sure if this is the right way, but I don't know how I must call it
class Compare_values_model extends CI_Model
{
public function compare($id)
{
$this->db->select('"SELECT * FROM `cobranzas` WHERE `cliente` = '$cliente' AND `nro_cuota` = '$nro_cuota'"');
if ($query->num_rows() > 0) {
return true;
} else {
return false;
}
}
}
Hope can help me I couldn't find some examples on internet to learn more, thanks in advance.
You said I need to compare two values in a table: cliente and nro_cuota, if both exist I don't want to add it. But you are matching the variables with fields. So just check not equal as below:
$query = $this->db->query("SELECT * FROM `cobranzas` WHERE `cliente` <> '$cliente' AND `nro_cuota` <> '$nro_cuota'");
Note: Remove extra single quote in your query

Getting data from model to controller

I do have a question : I cannot pass the data from model to controller
You can see some of my codes, please help me.
It does not work!
this is my model "mymodel.php"
....
$query = $this->db->query("SELECT * FROM `rand` WHERE `used` = 0 LIMIT 0, 1");
if($query){
foreach ($query->result() as $row);
}
$t = "EXAMPLE/{$row->code}";
function wandad() {
return $t;
}
.....
and this is my controller mycont.php
...
$this->load->model('mymodel');
$data['new'] = $this->Mymodel->wandad();
$this->load->view('myview',$data);
...
and this is my view myview.php
....
echo $new;
.....
Clearly you The model is not written properly and to corrent this simple do this
1.) I put a default value on $t
2.) I put the query >> loop on the inside function
wandad
so it can be executed once called from controller
function wandad() {
$query = $this->db->query("SELECT * FROM `rand` WHERE `used` = 0 LIMIT 0, 1");
$t = "";
if($query){
foreach ($query->result() as $row){
$t = "EXAMPLE/{$row->code}".'<br>';
}
}
return $t;
}
Here are several issues into your model
Your Foreach function doesn't do anything
$t is not in the same namespace than wandad()
Function wandad is not defined into your model class
I'm not sure of what you wanna get with wandad() function but here's a pattern.
function yourFunction()
{
/* This will return the full query as an array */
$query = $this->db->query("SELECT * FROM `rand` WHERE `used` = 0 LIMIT 0, 1")->result_array();
/* Store variable in the same class */
$this->t = "EXAMPLE/".$query[0]['code'];
/* Close yourFunction() */
}
public function wandad() {
return $this->t;
}
Then into your controller, do that instead :
$this->load->model('mymodel');
$this->mymodel->yourFunction();
$data['new'] = $this->mymodel->wandad();
$this->load->view('myview',$data);
#Touki his foreach actually does something. It will set the variable $row with the last row that is returned from the query. Not the best way to do it ... But it's a way. Better would be to use a limit in the query.
There is a small mistake in your code #Ernesto.that is
foreach ($query->result() as $row){
$t. = "EXAMPLE/{$row->code}".'<br>';
}
but your code was simply nice

Resources