Extracting image value from Array in Codeigniter - php

I'm having issues extracting a value from an array of images via Codeigniter/MySQL. So i have a table called "image" in my database and if i echo out it i get the following code:
{"f01efdf6fe3b2bb387d3094aa701203f":{"filename":"f01efdf6fe3b2bb387d3094aa701203f.jpg","alt":"","caption":"","primary":true},"b11581adadd1848acb2898e7a284afc1":{"filename":"b11581adadd1848acb2898e7a284afc1.png","alt":"","caption":""},"2cfee6d3c334696833b1cfe13910fcf1":{"filename":"2cfee6d3c334696833b1cfe13910fcf1.png","alt":"","caption":""}}
As you can see there are 3 images there, what i need is to echo out just the image where "primary" value is:true within a foreach loop...
EDIT:
<?php
$query = $this->db->query("SELECT * FROM offers_products WHERE offer_large LIMIT 5;");
?>
<?php foreach ($query->result() as $row): ?>
<li><?=$row->id?></li>
<li><?=$row->name?></li>
<li><!-- THIS IS THE IMAGES TABLE VALUE --> <?=$row->images?> <!-- --></li>
<li><?=$row->description?></li>
<?php endforeach; ?>

Maybe:
$array = json_decode($stringFromDatabase, true);
$primary = false;
foreach ($array as $longStringDontCare => $imageArray) {
if (!empty($imageArray['primary'])) {
$primary = $imageArray;
break;
}
}
if ($primary) {
echo $primary['filename'];// should give: f01efdf6fe3b2bb387d3094aa701203f.jpg
}
To give you one last hint:
<?php
function getPrimaryImageFromJsonString($stringFromDatabase) {
$array = json_decode($stringFromDatabase, true);
$primary = false;
foreach ($array as $longStringDontCare => $imageArray) {
if (!empty($imageArray['primary'])) {
$primary = $imageArray;
break;
}
}
if ($primary) {
return $primary['filename'];
}
return null;
}
?>
<?php foreach ($query->result() as $row): ?>
<li><?=$row->id?></li>
<li><?=$row->name?></li>
<li><?php echo getPrimaryImageFromJsonString($row->images);?></li>
<li><?=$row->description?></li>
<?php endforeach; ?>
L.E: a few edits.

You have to first decode the json encoded string and extract the primary image from there:
Here is small function which you can use to extract the primary image:(You can place this function in Helper if you are using CodeIgniter)
function get_primary_image($encode_json_data)
{
$primary_image = '';
$decoded_json = json_decode($encode_json_data);
foreach($decoded_json as $obj)
{
if(isset($obj->primary) && $obj->primary == 1)
$primary_image = $obj->filename;
}
return $primary_image;
}
You can call above function in your view in following way:
<?php foreach ($query->result() as $row): ?>
<li><?=$row->id?></li>
<li><?=$row->name?></li>
<li> <?=get_primary_image($row->images)?></li><!-- Here, you call above function -->
<li><?=$row->description?></li>
<?php endforeach; ?>

Related

how to add another loop based on the id of the first loop, in codeigniter

I want to display the data of all employees based on places, where data places are looped based on date data, here is the code.
in the model
public function getSchedule()
{
$builder = $this->db->table('tb_dates');
....
$dates = $builder->get()->getResultArray();
foreach ($dates as $key => $value) {
$builder = $this->db->table('tb_places');
$builder->join('tb_dates', 'tb_dates.iddate = tb_places.iddate');
$builder->where('tb_dates.iddate', $value['iddate']);
$result = $builder->get();
$places = $dates[$key]['places'] = $result->getResultArray();
// more looping (this question)
foreach ($places as $key => $value) {
....
}
}
return $dates;
}
and then in controller :
$data['sch'] = json_encode($this->schedule->getSchedule());
return view('admin/index', $data);
in view :
<?php $schedules = json_decode($sch); ?>
<?php foreach ($schedules as $schedule) : ?>
....
<?php foreach ($schedule->places as $key) : ?>
....
**for example, i want an loop for the employee data in here**
.......
<?php endforeach; ?>
<?php endforeach; ?>

php pdo json encode array print

When I pull data from the hello database, it just writes the first line, not the other lines, what could be the reason?
I did not know much about php json but did not get any results.
İD 88 NOT FOUND
**database print **
[{"title":"facebook","contact":"facebook adres"},
{"title":"twitter","contact":"twitter adres"}]
database data
id:87 [{"title":"facebook","contact":"facebook adres"},
{"title":"twitter","contact":"twitter adres"}]
id:88
[{"title":"instagram","contact":"instagram adres"},
{"title":"google","contact":"google adres"}]
database function
function menu($menu_title)
{
global $db;
$query = $db->prepare('SELECT * FROM menu WHERE menu_title = :menu_title');
$query->execute([
'menu_title' => $menu_title
]);
$result = $query->fetchAll(PDO::FETCH_ASSOC);
if ($result) {
$data = [];
foreach ($result as $key => $value) {
$data += json_decode($value['menu_content'], true);
}
return $data;
}
return null;
}
socialmedia foreach
<?php foreach (menu('sosyalmedya') as $key => $menu): ?>
<?= $menu['title'] ?><br>
<?= $menu['contact'] ?><br>
<?php endforeach; ?>
You're only returning the first element of each JSON array. Append the whole array to the result.
foreach ($result as $value) {
$data = array_merge($data, json_decode($value['menu_content'], true));
}
BTW, don't use SELECT * if you only want the menu_content column. Use SELECT menu_content.

PHP Set array of values to the key and echo out all the values out

I'm using a simple PHP template script which has a function sets the values to the key and later replace the template tags with the key.
<?php
class Template {
protected $file;
protected $values = array();
public function __construct($file) {
$this->file = $file;
}
public function set($key, $value) {
$this->values[$key] = $value;
}
public function output() {
if (!file_exists($this->file)) {
return "Error loading template file ($this->file).<br />";
}
$output = file_get_contents($this->file);
foreach ($this->values as $key => $value) {
$tagToReplace = "[#$key]";
$output = str_replace($tagToReplace, $value, $output);
}
return $output;
}
?>
Then I have this foreach loop, I wanted to set all of the $post_title data to post_title, then output all the values, but I only got one element of data within the foreach loop.
<?php foreach ($post_titles as $post_title): ?>
<?php $data->set("post_title", $post_title['post_title']); ?>
<?php endforeach; ?>
<?php echo $data->output(); ?>
If I edit above code in the foreach loop to <?php echo $post_title['post_title']; ?> I will get all of the elements from the variable $post_titles which is an array, however, other ways like using return or set values to post_title will only get me one element from the array.
How can I get all of the data elements within the foreach loop, not by immediately echoing out, but saved into a variable for later use outside of the foreach loop.
Edited: You have to call output function in foreach
<?php foreach ($post_titles as $post_title): ?>
<?php $data->set("post_title", $post_title['post_title']); ?>
$allData[] = $data->output();
<?php endforeach; ?>
<?php print_r($allData); ?>
Call output function in foreach with set function.
Remove square brackets from $output variable.

PHP: Best practice with repeating lines of code without a clear input/output (DRY)

I have an HMVC webapplication developed in PHP.
In my controller and in my view, I need to iterate over multiple arrays. Between the iterations I need to use/echo some values out of the array. The problem is that my code is a mess and I was wondering if there are better best practices to do this kind of loops.
For the following examples: $header has 15 values and $groups has 1000 values.
I have the following (simplified) example of code in my view:
<? foreach($headers as $header) { ?>
<div class="header"><?= $header->number ?></div>
<? $i = 0; ?>
<? foreach($groups as $group) { ?>
<? $part_letter = $group->part->letter ?>
<? if ($group->number !== $header->number) { continue; } ?>
<? $i++; ?>
<? if ($i === 1) { $first_group = true; } else { $first_group = false; } ?>
<div class="<?= $first_group ? 'colored' : ''>
<?= echo $group->name ?>
<?= echo $part_letter ?>
</div>
<? } ?>
<? } ?>
I have the following (simplified) example of code in my controller:
foreach($headers as $header) {
$pdf[] = $header->number;
$i = 0;
foreach($groups as $group) {
$part_letter = $group->part->letter;
if ($group->number !== $header->number) { continue; }
$i++;
if ($i === 1) { $first_group = true; } else { $first_group = false; }
$pdf['first_group'] = $first_group;
$pdf['group_name'] = $group->name;
$pdf['part_letter'] = $part_letter;
}
}
My thoughts
My first thought was, since the iteration in the controller and view are the same, to move this to a separate function where input would be $headers and $groups, but what would be the output? In the view I need some array values between HTML code and in the controller I need to save them in the $pdf array.
My second thought was to create a separate function to iterate over both arrays to create a 3rd and 4th array with all significant values in it. That 3rd and 4th array would look something like this:
$header_values[$id] = $number;
$group_values[$id] = array($part_letter, $group_equals_header_number, $is_first_group);
Then my controller would look like this:
foreach($header_values as $header_value) {
$pdf[] = $header_value;
foreach($group_values as $group_value) {
if (!$group_value['group_equals_header_number']) { continue; }
$pdf['first_group'] = $group_value['is_first_group'];
$pdf['group_name'] = $group_value['group_name'];
$pdf['part_letter'] = $group_value['part_letter'];
}
}
And my view would look like this:
<? if (!$group_value['group_equals_header_number']) { continue; } ?>
<div class="<?= $group_value['is_first_group'] ? 'colored' : ''>
<?= echo $group_value['group_name'] ?>
<?= echo $group_value['part_letter'] ?>
</div>
It looks a bit better, the downside is that I need an extra iteration.
What is best practice with this kind of repeating loops / repeating code, while keeping my code DRY?
sorry for my too quick comment, i don't have seen that the "group loop" is not a children of $header then in this case, you can waste time if you have lots of headers and lots of groups in differents headers
you can try this code, it will use a little more time for the first task but it will spare more time for the second task
<?php
////////////////////////////////////////////////////
// *** first task : grouping "groups" by header
$listHeaders = [];
// searching all the headers numbers
foreach ($headers as $header)) {
$listHeaders[$header->number] = $header;
}
// associating groups with header
foreach ($groups as $group) {
$headerNumber = $group->number;
if (!isset($listHeaders[$headerNumber])) {
continue;
}
if (!isset($listHeaders[$headerNumber]->listGroups)) {
$listHeaders[$headerNumber]->listGroups = [];
}
$listHeaders[$headerNumber]->listGroups[] = $group;
}
////////////////////////////////////////////////////
// *** second task : display
foreach ($listHeaders as $headerNumber => $header) {
?>
<div class="header">
<?php echo $headerNumber;?>
</div>
<?php
foreach ($header->listGroups as $index => $group) {
?>
<div class="<?php echo (0 !== $index) ? "" : "colored";?>">
<?php echo $group->name;?>
<?php echo $group->part->letter;?>
</div>
<?php
} // END foreach ($header->listGroups as $index => $group) {
} // END foreach ($listHeaders as $headerNumber => $header) {
just do benchmarks to choose wich code take less time with your datas

Pass single OR multiple URI segments to function (code igniter)

Currently I have this url to view an image from the db (codeigniter) domain.com/view/id
I'd like to be able to accept multiple ids comma separated domain.com/view/id,id,id
Any idea how to go about it? Thanks
view controller part:
function view() {
$id = alphaID($this->uri->segment(1) ,true);
$this->load->model('Site_model');
if($query = $this->Site_model->get_images($id)) {
$data['records'] = $query;
}
$this->load->view('view', $data);
}
<?php if(isset($records)) : foreach($records as $row) : ?>
<?php if($row->alpha_id == $this->uri->segment(1)): ?>
<h1><?php echo $row->alpha_id.$row->file_ext; ?></h1>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
Use this in your controller
function view() {
$id = $this->uri->segment(1);
$id_array = explode(",", $id);
$this->load->model('Site_model');
foreach ($id_array as $key => $id) {
// use alphaID function
$id = alphaID($id ,true);
if($query = $this->Site_model->get_images($id)) {
$data['records_array'][$key] = $query;
// added second array for comparison in view
$data['id_array'][$key] = $id;
}
}
$this->load->view('view', $data);
}
For your view:
<?php
foreach ($records_array as $key => $records) {
if(isset($records)) : foreach($records as $row) : ?>
// removed uri and added array
<?php if($row->alpha_id == $id_array[$key]): ?>
<h1><?php echo $row->alpha_id.$row->file_ext; ?></h1>
<?php endif; ?>
<?php endforeach; ?>
<?php endif;
}
?>
Because commas aren't valid path elements you won't be able to get this to work without having your delimited data on the right side of a ? character. You'll need to come up with another scheme or go with the comment from #jprofitt.
You are right, you can add a comma in $config['permitted_uri_chars'] but you'll have to manipulate with that segment every time you need it, unless you hook into the system core.
Haven't tested this code but you'll get an idea:
<?php
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-,'; // Note a comma...
// Controller
class Blog extends CI_Controller
{
public function posts($ids = NULL)
{
// Check if $ids is passed and contains a comma in the string
if ($ids !== NULL AND strpos($ids, ',') !== FALSE)
{
$ids = explode(',', $ids);
}
// Convert $ids to array if it has no multiple ids
is_array($ids) OR $ids = array($ids);
// $ids is an array now...
}
public function new_posts()
{
// Check if $ids is passed and contains a comma in the string
$ids = $this->uri->segment(1);
if (!empty($ids) AND strpos($ids, ',') !== FALSE)
{
$ids = explode(',', $ids);
}
// Convert $ids to array if it has no multiple ids
is_array($ids) OR $ids = array($ids);
// $ids is an array now...
}
}
?>
example.com/index.php/blog/posts/2,4,6,8
Please note once again, code may not be accurate because I haven't tested it but think it will help you.

Categories