Having problems getting values from foreach - php

trying to get id from each person
$person = $request->input('person');
//values for person: Murdock,Wayne
$values = explode(',' , $person);
if(count($values) > 1) {
//count($values) = 2
foreach($values as $val) {
$get_id = Tag::where('name', $val)->get();
foreach($get_id as $get) {
echo "id=".$get->id;
$result= FileTags::with('file')->where('tag_id', $get->id)->get();
}
}
}
when i do echo $get->id just getting id=1, when is supossed to be id=1 and id=2
Murdock -- id:1
Wayne -- id:2
|table filetags|
| id | tag_id | file_id |
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 2 | 4 |
| 4 | 3 | 1 |
$result = FileTags::with('file')->where('tag_id', $id->id)->get();
I should get files with id 2,3 and 4
Model TAG
public function fileTag() {
return $this->hasMany('App\FileTags');
}
Model Archive
protected $table = 'files';
public function fileTag() {
return $this->hasMany('App\FileTags');
}
Model FileTags
public function tag() {
return $this->belongsTo('App\Tag' , 'tag_id');
}
public function file() {
return $this->belongsTo('App\Archive', 'file_id');
}
Thanks for the help.
EDIT:
|table tag|
| id | name |
| 1 | Murdock |
| 2 | Wayne |
Result from echo $obt_id;
[{"id":1,"name":"Murdock","description":"Description","type":"0","status":"1","created_at":"2016-07-20 18:01:14","updated_at":"2016-07-20 18:01:14"}][]
from var_dump($obt_id)
array (size=1)
0 =>
object(App\Tag)[267]
protected 'table' => string 'tags' (length=4)
protected 'fillable' =>
array (size=4)
...
protected 'connection' => null
protected 'primaryKey' => string 'id' (length=2)
protected 'keyType' => string 'int' (length=3)
protected 'perPage' => int 15
public 'incrementing' => boolean true
public 'timestamps' => boolean true
protected 'attributes' =>
array (size=7)
...
...
...
C:\wamp64\www\Petro\app\Http\Controllers\CatalogedController.php:53:
object(Illuminate\Database\Eloquent\Collection)[272]
protected 'items' =>
array (size=0)

You could create a Variable, $result; initialize it as an Empty Arrayand then simply push all the Results of evaluating the code: FileTags::with('file')->where('tag_id', $get->id)->get() into that the $result Array. And, in the end, Check if the $result Array is not empty. If it's not, you may simply implode it using comma (Assuming it is a String) and echo your Results...
<?php
$person = $request->input('person');
//values for person: Murdock,Wayne
$values = explode(',' , $person);
$result = array(); // <== INITIALIZE TO AN EMPTY ARRAY...
if(count($values) > 1) { //<== $values NOT values...
//count(values) = 2
foreach($values as trim($val)) { //<== TRY TRIMMING OFF WHITE SPACES.
$get_id = Tag::where('name', $val)->get();
foreach($get_id as $get) {
echo "id=".$get->id;
// PUSH THE DATA INTO THE ARRAY...
$result[] = FileTags::with('file')->where('tag_id', $get->id)->get();
}
}
}
// CHECK IF $result IS NOT EMPTY
if(!empty($result)){
// CONVERT THE ARRAY TO A STRING (ASSUMING ITS CONTENT ARE NOT OBJECTS OR ARRAYS)
$result = implode(", ", $result);
// ECHO OUR YOUR RESULT...
echo $result;
}

Related

PHP Navigation with MySQL database

i made a navigation where a MySQL Database is needed.
This is my connection to the database to get all informations.
$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
$primary_nav = [];
foreach ($results as $result){
if($result->sub == 0){
$primary_nav[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
);
}elseif($result->sub == 1){
$primary_nav[] = array(
'name' => $result->name,
'icon' => $result->icon,
'sub' => array(
array(
'name' => $result->name_sub,
'url' => $result->url_sub
)
)
);
}
}
}
This works fine, if I add the navigation into the database everything looks perfect and works amazing.
Now the problem i've now is when I want to a new sub menu than everytime I get a new top menu entrie with just 1 sub menu.
So my question is, how do I get this part working without breaking the code.
Normally the code looks like this:
// first sub
array(
'name' => 'Test1',
'icon' => 'fa fa-bullhorn',
'sub' => array(
array(
'name' => 'First Sub 1',
'url' => 'sub1.php'
),
array(
'name' => 'First Sub 2',
'url' => 'sub2.php'
)
)
),
// second sub
array(
'name' => 'Test3',
'icon' => 'fa fa-bullhorn',
'sub' => array(
array(
'name' => 'Second Sub',
'url' => 'sub1_1.php'
)
)
)
database structure:
|-----name-----|----url----|----icon----|----sub----|----name_sub----|----url_sub----|----category----|
| Dashboard | index.php | icon | 0 | | | |
------------------------------------------------------------------------------------------------------
| Test | test.php | icon | 0 | | | |
------------------------------------------------------------------------------------------------------
| Test1 | | icon | 1 | First Sub 1 | sub1.php | 1 |
------------------------------------------------------------------------------------------------------
| | | icon | 1 | First Sub 2 | sub2.php | 1 |
------------------------------------------------------------------------------------------------------
| Test3 | | icon | 1 | Second Sub | sub1_1.php | 2 |
------------------------------------------------------------------------------------------------------**
So if the category equals the same number as the other it should be doing this:
Test1
-- First Sub 1
-- First Sub 2
Test3
-- Second Sub
but with my code it looks like this:
Test1
-- First Sub 1
Test2 (it would be empty because in the database it is empty just for example I puted Test2)
-- First Sub 2
Test3
-- Second Sub
maybe someone understand what I need, because my english is not the best to explain it. Thanks for any help/solution for this problem.
$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
$categories = [];
$primary_nav = [];
foreach ($results as $result){
if ($result->name) {
if ($result->category) {
$categories[$result->category] = sizeof($primary_nav);
}
$primary_nav[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
);
}
if ($result->name_sub) {
$primary_nav[$categories[$result->category]]['sub'][] = array(
'name' => $result->name_sub,
'url' => $result->url_sub
);
}
}
}
I've added an extra $categories array.
For each "parent" entry with a category, the $categories array stores the category value from the database and the key of the "parent" entry in the $primary_nav array.
The $categories array can then be used to add subsequent subcategories to the correct parent entry using their category value.
In your current setup however, the database allows you to have subcategories without a parent category and (sub)categories without a name.
So I would suggest using a table setup like this instead:
id name url icon parent
1 Dashboard index.php icon null
2 Test test.php icon null
3 Test1 null icon null
4 First sub 1 sub1.php null 3
5 First sub 2 sub2.php null 3
6 Test3 null icon null
7 Second sub Sub1_1.php null 6
Parent categories have the column "parent" set to null, and subcategories have their "parent" column set to the id of their parent entry.
This also allows you to have sub-sub-(and so on)-categories.
You would need to query it recursively:
function buildNav($pdo, $id = null) {
$array = [];
if ($id) {
$stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent = :id");
$stmt->bindValue('id', $id);
} else {
$stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent IS NULL");
}
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if ($stmt->rowCount() > 0){
foreach ($results as $result){
$array[] = array(
'name' => $result->name,
'url' => $result->url,
'icon' => $result->icon,
'sub' => buildNav($pdo, $result->id)
);
}
}
return $array;
}
$primary_nav = buildNav($pdo);

Laravel - Model::create() works, but is missing attributes

So, I have the following Models:
class Recursive extends Model {
public function __construct() {
parent::__construct();
}
// ...
}
class Place extends Recursive {
protected $table = 'places';
protected $fillable = ['name', 'parent_id'];
// ...
}
The following code is used to create a new Place:
$place = Place::create([
'name' = 'Second',
'parent_id' => 1
]);
This results in the following record in the database:
| Actual | Expected |
---------------------------------------------------------
| id | name | parent_id | id | name | parent_id |
| 1 | 'Top' | NULL | 1 | 'Top' | NULL |
| 2 | NULL | NULL | 2 | 'Second' | 1 |
As you can see, the only value being set is the Auto-incrementing id column. The 2 columns I'm trying to create are in the fillable array, and the model is created, but it's not associated correctly.
Has anyone come across this issue before? I know I can use another method, such as
$place = new Place();
$place->name = 'Second';
$place->parent_id = 1;
$place->save();
But this isn't the only spot I'm using this code, and I'd prefer to not lose functionality like this.
Edit: Enabling the query log shows the following for the create() call:
array (
'query' => 'insert into `places` () values ()',
'bindings' =>
array (
),
'time' => 1.26,
),
Further edit: Enable MySQL log has the same output as above. Following Miken32's suggestion of reverting the extends to Model works as expected:
array (
'query' => 'insert into `places` (`name`, `parent_id`) values (?, ?)',
'bindings' =>
array (
0 => 'Second',
1 => '1'
),
'time' => 1.21,
),
Checking the Illuminate\Database\Eloquent\Model class, the constructor looks like this:
public function __construct(array $attributes = [])
{
$this->bootIfNotBooted();
$this->initializeTraits();
$this->syncOriginal();
$this->fill($attributes);
}
However, you overrode this in your Recursive class:
public function __construct()
{
parent::__construct();
}
The attributes were not being passed to the constructor, so it was not able to successfully build the query. You could remove the constructor since it's not doing anything, or use this instead:
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
}

Yii2: Kartik DepDrop widget without child value show up

I'm new in Yii2. I am using the DepDrop widget provide by Kartik. Now, I can pick data from column1, however, the related data in column2 doesn't show up. I can't even click on it.
Here is partial of the content of mysql table.
ID | name | sub_ID | category
1 | up | 11 | T-shirt
1 | up | 12 | jet
2 | shoe | 21 | nike
2 | shoe | 22 | adidda
Here is my _form.php code
<?= $form->field($model, 'category')->dropDownlist(
ArrayHelper::map(itemcategory::find()->all(), 'ID', 'name'), ['id' => 'cat_id', 'prompt' => 'Select…']
);?>
<?= $form->field($model, 'subcategory')->widget(
DepDrop::classname(), [
'options' => ['id' => 'subcategory', 'placeholder' => 'Select…'],
'pluginOptions' => [
'depends' => ['cat_id'],
'url'=>\yii\helpers\Url::to(['/positemcategory/Subcat'])
]
]
)?>
Here is my model ItemCategory.php code
public function getSubCatList($cat_id)
{
$data = self::find()->where(['ID' => $cat_id])->select(['sub_ID AS id', 'subcategory AS name'])->asArray()->all();
return $data;
}
And here is the controller Itemcategory.php code
public function actionSubcat()
{
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
// $out = \app\models\ItemCategory::getSubCategoryList($cat_id);
$out = self::getSubCatList($cat_id);
echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
echo Json::encode(['output'=>'', 'selected'=>'']);
}
I want to let user pick the item by its name, and save only the ID in another table in mysql instead of the full name.
Use ArrayHelper of Yii2.
$out = self::getSubCatList($cat_id);
echo Json::encode(['output'=>ArrayHelper::map($out,'id','name'),'selected'=>'']);
As a result you will get array with id as key and name as value.

Doesn't choose records

author id | name
1 Mike
2 Dive
3 Stiv
book id | title
1 ABC
2 War
book_author id_book | id_author
1 1
1 2
2 3
app/models/Book.php
public function getAuthors()
{
return $this->hasMany(Authors::className(), ['id' => 'id_author'])->viaTable('book_author',['id_book' => 'id']);
}
In view:
foreach (Books::findAll([1, 2]) as $book)
{
echo sprintf('%s | %s',
$book->title,implode(', ',
$book->getAuthors()));
}
Always returned implode(): Invalid arguments passed in $book->getAuthors()));
getAuthors() - doesn't choose author, why?
Need:
ABC | Mike, Dive
War | Stiv
$book->getAuthors() get object arrays. You should get simple array. Try this code:
foreach (Books::findAll([1, 2]) as $book)
{
$authors = ArrayHelper::toArray($book->getAuthors()->all(), [
'app\models\Authors' => [
'name', 'id'
]
]);
echo sprintf('%s | %s',
$book->title,implode(', ',
ArrayHelper::map($authors, 'id', 'name')));
}

Sorting and storing array returned by a method as parent and child data for displaying nested/multi level comments in codeigniter 2.0

Hey guys I'm trying to learn codeigniter, but once again I'm STUCK and I seek help (as usual :P )
What I need to do?
-> I need to get the data related to a article from the database along with other stuff like the tags for the article and all the comments. I'm thinking of keeping single level nested comments for the article.
Well I'm done with the tag part [link to the answer which helped me with the same : Returning and using multidimensional array of records from database in CodeIgniter 2.0 ] but the comment part is driving me nuts.
Well to get started here is my comments table
Comments
+---------------+-------------+
| Field | Type |
+---------------+-------------+
| commentId | int(10) |
| PostId | int(10) |
| author | varchar(30) |
| email | varchar(30) |
| url | varchar(50) |
| date | datetime |
| comment | text |
| parent | int(10) |
+---------------+-------------+
I'm using the parent field to keep a track of the parent for a nested child comment. By default the value is 0 which means it the parent. Child comment will have the commentid of its parent comment
public function getPost($postName = NULL , $year = NULL, $month = NULL ){
if($postName != NULL && $year != NULL && $month != NULL){
//single post
$this->load->model('comment_model');
$this->db->where('postName',$postName);
$this->db->where('year(date)',$year);
$this->db->where('month(date)',$month);
$q = $this->db->get('mstack_Post');
if($q->num_rows()>0){
$post = $q->result();
foreach ($post as &$p) {
$p->tags = $this->getAllTags($p->postId);
/* getting the comments */
$com = $this->comment_model->getComments($p->postId);
/*echo count($com).' is the total count'; output= 4 */
foreach ($com as &$c) {
/* trying to filter the comment. but all I get is 1 comment as the output*/
if($c->parent==0){
$p->comments->parentComment = $c;
}elseif($c->commentId==$c->parent){
$p->comments->childComment = $c;
}
}
}
return $post;
}else{
return array();
}
}
}
Any help will surely be appreciated.
If you have any other technique /idea to display multi level comments then do let me know. :)
Here is the solution that might be helpfull:
First you need 2 helper recursive function:
// Building comments.
function buildComments($list, $parent = 0)
{
// Creating result array.
$result = array();
//looping...
foreach ($list as $item)
{
//iteration starts with 0 as default.
if ($item->parent == $parent)
{
// add to the result
$result[$item->commentId] = array(
'author' => $item->author,
// ... other definitions
'child' => buildComments($list, $item->commentId) //execute this function for child.
);
}
}
return $result;
}
function printComments($arg, $depth = 1)
{
foreach ($arg as $item)
{
// Printing comment...
echo str_repeat(' ', $depth) . $item['author'] . "<br />\r\n";
// extra echoes...
// if it has a child comment...
if (count($item['child'] > 0))
{
printComments($item['child'], $depth + 1);
}
}
}
A little explaining:
The buildComments() function will starts with rows that parents has 0. Then it will execute itself for child. if child as a child, it will add it. In the end, result will be like this:
$result = array(
1 => array(
'author' => 'John',
'child' => array(
8 => array(
'author' => 'Jane',
'child' => array(
3 => array(
'author' => 'Jamie',
'child => array()
)
)
),
6 => array(
'author' => 'Jackie',
'child => array()
),
9 => array(
'author' => 'Harry',
'child => array()
)
)
),
4 => array(
'author' => 'Jack',
'child' => array()
),
10 => array(
'author' => 'Clark',
'child' => array(
11 => array(
'author => 'Lois',
'child' => array()
)
)
),
12 => array(
'author' => 'Luthor',
'child' => array()
)
);
In the printComments() function we are printing results recursive. for each child, function repeats itself. You will get result like this:
John
Jane
Jamie
Jackie
Harry
Jack
Clark
Lois
Luthor
For more information about recursive functions Look this answer
USAGE
$this->db->where('postName',$postName);
$this->db->where('year(date)',$year);
$this->db->where('month(date)',$month);
$this->db->order_by('parent', 'asc');
$query = $this->db->get('comments');
$comments = buildComments($query->result());
printComments($comments);
that'is that simple...

Categories