This is an example of my table product and category in database:
tbl_categories
|id_category | name........| slug........|
|1...........| Hanger .....| hanger .....|
|2...........| Lamp .......| lamp .......|
|3...........| Merchandise | merchandise |
|4...........| Storage ....| storage ....|
tbl_products
id_products | id_category | name .....| slug .....| images
1 ..........| 1 ..........| Hanger asd| hanger-asd|json
2 ..........| 1 ..........| Hanger asd| hanger-dsa|json
3 ..........| 1 ..........| Hanger asd| hanger-das|json
4 ..........| 1 ..........| Hanger asd| hanger-sad|json
where the content of images is json_encoded like this one:
id_product : 1
{
"7b8d9fbfe384b1b6e4cfb0da473df8e5": {
"alt": "jhonson hanger",
"caption": "",
"filename": "7b8d9fbfe384b1b6e4cfb0da473df8e5.jpg",
"primary": true
},
"f7d225c85590012f91bad32dd8adaa3d": {
"alt": "jhonson hanger",
"caption": "lorem ipsum lorem ipsum dolor siamet ameticioud",
"filename": "f7d225c85590012f91bad32dd8adaa3d.jpg"
}
}
etc.
First thing I want is to get every product to be shown on my ecommerce product page, so in my controller products:
function index()
{
$data = array(
"keyword" => "sadasdasd",
"description" => "asdasdasd",
"content" => "product",
"title" => "BALOK Official :: Product"
);
$products = $this->model_product->get_all_products();
$data['products'] = $products;
$this->load->view("product", $data);
}
in my model_product:
function get_all_products()
{
$this->db->select
("
tbl_product.name AS prod_name,
images,
tbl_product.slug AS prod_slug,
tbl_categories.slug AS cat_slug
");
$this->db->from("tbl_products");
$this->db->join("tbl_categories", "tbl_categories.id_category = tbl_product.id_category");
$this->db->order_by("prod_name", "ASC");
$query = $this->db->get();
if($query->num_rows() > 0)
{
return $query->result();
}
else
{
return false;
}
}
How to display product name, prod_slug, cat_slug and only one images['filename] for every product in my view, and if "primary = true" than show the primary image else show the first images. example in array maybe images[0];.
I have checked the data from fields images with this code:
foreach ($products as $prod)
{
$prod->images = json_decode($prod->images);
print_r($prod->images);
}
and that shows stdClass Object like this:
stdClass Object
(
[43f8cd2ba0fcb96453b43b36b6a4f759] => stdClass Object
(
[filename] => 43f8cd2ba0fcb96453b43b36b6a4f759.jpg
[alt] =>
[caption] =>
[primary] => 1
)
)
stdClass Object
(
[f7d225c85590012f91bad32dd8adaa3d] => stdClass Object
(
[filename] => f7d225c85590012f91bad32dd8adaa3d.jpg
[alt] => jhonson hanger
[caption] => lorem ipsum lorem ipsum dolor siamet ameticioud
[primary] => 1
)
[7b8d9fbfe384b1b6e4cfb0da473df8e5] => stdClass Object
(
[filename] => 7b8d9fbfe384b1b6e4cfb0da473df8e5.jpg
[alt] => jhonson hanger
[caption] =>
)
)
stdClass Object
(
[29c2100ff85ec538e17c6d68fafbd43d] => stdClass Object
(
[filename] => 29c2100ff85ec538e17c6d68fafbd43d.jpg
[alt] =>
[caption] =>
[primary] => 1
)
[8d4ecb9c4dc369febe70019586f3d570] => stdClass Object
(
[filename] => 8d4ecb9c4dc369febe70019586f3d570.jpg
[alt] =>
[caption] =>
)
[dc4358c470c33f20206afc180a28ae5b] => stdClass Object
(
[filename] => dc4358c470c33f20206afc180a28ae5b.jpg
[alt] =>
[caption] =>
)
)
That stdobject makes me confused.
update.
in view i write this:
foreach ($products as $prod)
{
echo $prod->prod_name.' - '.$prod->prod_slug.' - '.$prod->cat_slug.'<br>';
}
it success display what i want;
Book Cabinets Wood - book-cabinets-wood - storage
Brand New Hanger Jhonson - brand-new-hanger-jhonson - hanger
Flash Wood - flash-wood - merchandise
Gantungan baju dari kayu - gantungan-baju-dari-kayu - hanger
Shaman Lamp - shaman-lamp - lamp
Storage Wood Shelf - storage-wood-shelf - storage
Wood Lamp - wood-lamp - lamp
Wood Lamp Transcending - wood-lamp-transcending - lamp
Yoyo Kayu - boneka-kayu-lucu - merchandise
the images it still in json format, and i dont know how to manipulate it, im just thinking about array_value, to convert json_data after decoded to array, maybe?
If you want to have the first image or the one that has primaryset to true you need to do something like this:
function getPrimaryImage($images) {
//initialize the finalImage with 'null'
$finalImage = null;
//Iterate over all images
foreach( $images as $image ) {
//check if primary is set and if it is true
if( isset($image->primary) && $image->primary ) {
//if primary set the finalImage and exit the loop
$finalImage = $image;
break;
} else if( $finalImage == null ) {
//if primary is not set or false and the finalImage is not set, then set to the current image (first one)
$finalImage = $image;
}
}
return $finalImage;
}
foreach ($products as $prod)
{
$prod->images = json_decode($prod->images);
$prod->primaryImage = getPrimaryImage($prod->images);
}
EDIT
I modified your code above to show the filename:
foreach ($products as $prod)
{
$prod->images = json_decode($prod->images);
$prod->primaryImage = getPrimaryImage($prod->images);
echo $prod->prod_name.' - '.$prod->prod_slug.' - '.$prod->cat_slug.' '.$prod->primaryImage->filename.'<br>';
}
You loop over the whole list having the first image set as your final result. If you find a image that has primary set to true you replace your $finalImage and exit the loop.
You could place this in a function that accepts images as parameters and return $finalImage as result.
Do you have a compelling reason to use JSON data? If not, simply create a new table named tbl_products_images and JOIN it with the previous JOIN.
Related
//controller
$promotion = Promotion::findOrFail($id);
//return
Array
(
[id] => 2
[en_title] => promo1
[game_id] => Array
(
[0] => 3
[1] => 4
[2] => 5
)
[amount] => 100.00
[start_at] => 2021-02-22
[end_at] => 2222-02-22
[status] => 1
)
//model promotion
class Promotion extends Model
{
use HasFactory;
protected $guarded = [];
protected $casts = [
'game_id' => 'array'
];
public function getAllGames()
{
return $this->belongsTo(Game::class, 'game_id', 'id');
}
}
Question:
Currently, I have 2 tables which are games and promotion, but I get trouble when coming into a relationship because the column of game_id inside the promotion table is a JSON, so that is hard to join it. Is there any work around can easily join them together in order to retrieve games data?
make many-to-many relationship between your games and promotion tables,
put your game_ids in pivot table (game_promotion) instead of JSON field,
Many To Many Relationships
I try to execute multiple queries in one php file.
The first query works fine, but the second en third one return an empty array.
$DB_con = new PDO($dsn, $DB_user, $DB_pass, array(
PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION
));
$sql_sel_sponsoring = $DB_con->prepare('CALL SP_SELECT_SPONSORING(:id)');
$sql_sel_sponsoring->execute(array(':id' => $sponsor));
$sql_res_sponsoring = $sql_sel_sponsoring->fetchAll();
$sql_sel_sponsoring_type = $DB_con->prepare('CALL SP_SELECT_SPONSORING_TYPE()');
$sql_sel_sponsoring_type->execute();
$sql_res_sponsoring_type = $sql_sel_sponsoring_type->fetchAll();
$sql_sel_cbo_members = $DB_con->prepare('CALL SP_SELECT_CBO_MEMBERS()');
$sql_sel_cbo_members->execute();
$sql_res_cbo_members = $sql_sel_cbo_members->fetchAll();
With a vardump() I have different objects
var_dump($sql_sel_sponsoring);
var_dump($sql_sel_sponsoring_type);
var_dump($sql_sel_cbo_members);
Results
object(PDOStatement)#6 (1) { ["queryString"]=> string(30) "CALL SP_SELECT_SPONSORING(:id)" }
object(PDOStatement)#7 (1) { ["queryString"]=> string(32) "CALL SP_SELECT_SPONSORING_TYPE()" }
object(PDOStatement)#8 (1) { ["queryString"]=> string(28) "CALL SP_SELECT_CBO_MEMBERS()" }
But 2 of the 3 resultsets are empty
print_r($sql_res_sponsoring);
print_r($sql_res_sponsoring_type);
print_r($sql_res_cbo_members);
Giving:
Array ( [0] => Array ( [SID_SPONSORING] => 70 [0] => 70 [SID_SPONSOR] => 88 [1] => 88 [Jaar] => 2014 [2] => 2014 [Bedrag] => 60.00 [3] => 60.00 [Omschrijving] => Publiciteitsboekje heel A5 [4] => Publiciteitsboekje heel A5 ) )
Array ( )
Array ( )
How can I make it work?
I'm using CakePHP 2.5.2 and having a bit of trouble searching for data efficiently.
In my application I've 3 tables, teams, players, skills... In teams there are 80 records, players 2400 records, skills 2400 records... I want to calculate the average skill of a team...
//Team model
public $actsAs = array('Containable');
public $hasMany = array('Player');
//Player model
public $actsAs = array('Containable');
public $hasOne = array('Skill');
public $belongsTo = array('Team');
//Skill model
public $actsAs = array('Containable');
public $belongsTo = array('Player');
My research is:
$team = $this->Team->find('all', array(
'contain' => array(
'Player' => array(
'Skill'
)
),
));
$this->set('team', $team);
that gives the expected result:
Array
(
[0] => Array
(
[Team] => Array
(
[id] => 1
[name] => my_team_name
)
[Player] => Array
(
[0] => Array
(
[id] => 000000419
[name] => Name
[surname] => Surname
[age] => 21
[team_id] => 1
[Team_id] => 1
[Skill] => Array
(
[id] => 20
[player_id] => 000000419
[skill] => 599
)
), ecc.....
This structure use at least 1680 queries... that are too much for me...
I've tried an other way, that involve just one query, returns a bad data structure but all the information that i need (also redundant). unfortunately follow this way i can not iterate in View to display what i need.
$player = $this->Team->Player->find('all', array(
'contains' => array(
'Skill',
),
that returns
Array
(
[0] => Array
(
[Player] => Array
(
[id] => 000000400
[nome] => my_player_name
[cognome] => my_player_surname
[nation_id] => 380
[age] => 29
[team_id] => 2
)
[Team] => Array
(
[id] => 2
[nome] => my_team_name
)
[Skill] => Array
(
[id] => 1
[player_id] => 000000400
[average] => 632
)
)
ecc.
Is there a way to iterate in VIEV to get the average skill of every team? Any other solutions?
Thanks!
You can use my plugin to solve this issue if you can upgrade CakePHP to 2.6 or later. The plugin has a high compatibility with ContainableBehavior, but generates better queries.
I think that the find operation will execute only 2 queries then.
I would be happy if you try it.
https://github.com/chinpei215/cakephp-eager-loader
Usage
1. Enable EagerLoader plugin
// In your model
$actsAs = ['EagerLoader.EagerLoader'];
If you are afraid that loading my plugin breaks something somewhere, you can also enable it on the fly.
// On the fly
$this->Team->Behaviors->load('EagerLoader.EagerLoader');
2. Execute the same find operation
$this->Team->find('all', ['contain' => ['Player' => ['Skill']]]);
3. See the query log
You will see the query log such as the following:
SELECT ... FROM teams AS Team WHERE 1 = 1;
SELECT ... FROM players AS Player LEFT JOIN skills AS Skill ON Player.id = Skill.player_id WHERE Player.id IN ( ... );
if you feeling that query searching so many tables (ie, models) then
you can unbind those model, before performing search with find()
if you want to fetch some particular column of a table, then remove
others column by selecting "fields" in find().
Hi I am using codeigniter and sheepIt clone forms.(embed forms).
I am trying to insert the data into database after submitting.
The output data is in this format when i used print_r()
Array
(
[project] => Array
(
[0] => Array
(
[module] => Design
[features] => Array
(
[feature_0] => Array
(
[feature] => Login
[Hours] => 10
)
[feature_1] => Array
(
[feature] => Signup
[Hours] => 10
)
)
)
[1] => Array
(
[module] => Development
[features] => Array
(
[feature_0] => Array
(
[feature] => Login
[Hours] => 20
)
)
)
)
[submit] => save
)
I can post the code of sheepIt forms also.
ANSWER:
$arr_data = $this->input->post();
foreach($arr_data['project'] as $prj) {
foreach($prj as $i) {
$arr['module'][] = module = $i['module'];
foreach($i['features'] as $f) {
$arr['feature'][] = $f['feature'];
$arr['Hours'][] = $f['Hours'];
}
}
}
print_r($arr);
Use this processed $arr data for storing or other.
I am trying to run a db query in drupal where, the content type has a node association field, and I am trying to get all notes of that type, where the NID of the current node matches any of the nodes specified in said note association field.
a visual example
Nodetype1
-- Node Association Field
NodeType2
I would like to get all Nodetype1's where Node Association Field matches the NID of Nodetype2 that is currently loaded.
My current db query is like so:
db_query("SELECT * FROM field_data_field_promo_profile WHERE field_promo_profile_nid=".$N->nid);
and this returns nothing, when i know for a fact that such a node exists, I also tried dropping the WHERE statement and it returns an array like this:
DatabaseStatementBase Object ( [dbh] => DatabaseConnection_mysql Object ( [shutdownRegistered:protected] => [target:protected] => default [key:protected] => default [logger:protected] => [transactionLayers:protected] => Array ( ) [driverClasses:protected] => Array ( [SelectQuery] => SelectQuery [DatabaseSchema] => DatabaseSchema_mysql [MergeQuery] => MergeQuery [DatabaseTransaction] => DatabaseTransaction [UpdateQuery] => UpdateQuery [InsertQuery] => InsertQuery_mysql ) [statementClass:protected] => DatabaseStatementBase [transactionSupport:protected] => 1 [transactionalDDLSupport:protected] => [temporaryNameIndex:protected] => 0 [connectionOptions:protected] => Array ( [database] => cityhound_dev [username] => blahblah [password] => blahblah [host] => localhost [port] => [driver] => mysql [prefix] => Array ( [default] => ) ) [schema:protected] => DatabaseSchema_mysql Object ( [connection:protected] => DatabaseConnection_mysql Object *RECURSION* [placeholder:protected] => 0 [defaultSchema:protected] => public [uniqueIdentifier:protected] => 4fd7fba9e563e2.50177866 ) [prefixes:protected] => Array ( [default] => ) [prefixSearch:protected] => Array ( [0] => { [1] => } ) [prefixReplace:protected] => Array ( [0] => [1] => ) ) [queryString] => SELECT * FROM field_data_field_promo_profile )
Any one have some ideas ?
db_query() returns an iterable object, so you just need to iterate over it:
$result = db_query("SELECT * FROM field_data_field_promo_profile WHERE field_promo_profile_nid=".$N->nid);
foreach ($result as $row) {
$entity_id = $row->entity_id;
// etc...
}
You should use parameters in your queries to prevent SQL injections.
For instance the query above should look like this:
$result = db_query("SELECT * FROM {field_data_field_promo_profile} p
WHERE p.field_promo_profile_nid = :nid ", array(':nid' => $N->nid);
foreach ( $result as $row ) {
$entity_id = $row->entity_id;
// etc...
}