View nested objects under Tinker - laravel

On Laravel Tinker when I run this:
>>> $customers = App\Customer::all();
I get a list of objects such as:
=> Illuminate\Database\Eloquent\Collection {#811
all: [
App\Customer {#815
id: 3,
favorite: 6,
user: App\User {#232 ...11},
zip: 11221
}
...
]
My question is how do I expand the user value where it has {#232 ...11}?

the tinker function of artisan is based almost entirely off of the psysh
see: https://github.com/bobthecow/psysh/
also: https://psysh.org/
inside psysh is a command called dump, dump is an implementation of symfony's var-dumper a newer kind of var_dump.
dump -h
shows:
Usage: dump [--depth DEPTH] [-a|--all] [--]
Arguments: target A target object or primitive to dump.
Options: --depth Depth to parse. (default: 10) --all (-a) Include
private and protected methods and properties.
Help: Dump an object or primitive. This is like var_dump but way
awesomer. e.g.
>>> dump $_
>>> dump $someVar
>>> dump $stuff->getAll()
for myself running with the argument --depth does not satisfy my object which is also rather large. so we see that psysh has a dependency on symfony's var-dumper.
see: https://github.com/symfony/var-dumper
also: https://symfony.com/doc/current/components/var_dumper.html
the advanced section states
The dump() function is just a thin wrapper and a more convenient way
to call VarDumper::dump(). You can change the behavior of this
function by calling VarDumper::setHandler($callable). Calls to dump()
will then be forwarded to $callable.
By adding a handler, you can customize the Cloners, Dumpers and
Casters...
A cloner is used to create an intermediate representation of any PHP
variable. Its output is a Symfony\Component\VarDumper\Cloner\Data
object that wraps this representation...
A cloner applies limits when creating the representation, so that one
can represent only a subset of the cloned variable. Before calling
cloneVar(), you can configure these limits:
setMaxItems()
Configures the maximum number of items that will be cloned past the minimum nesting depth. Items are counted using a breadth-first
algorithm so that lower level items have higher priority than deeply
nested items. Specifying -1 removes the limit. setMinDepth()
Configures the minimum tree depth where we are guaranteed to clone all the items. After this depth is reached, only setMaxItems items
will be cloned. The default value is 1, which is consistent with older
Symfony versions. setMaxString()
Configures the maximum number of characters that will be cloned before cutting overlong strings. Specifying -1 removes the limit.
see: https://symfony.com/doc/current/components/var_dumper/advanced.html
so what I am doing is creating a folder inside app named VarDumpFull then adding into file /app/VarDumpFull/VarDumpFull.php the following code
<?php
namespace App\VarDumpFull;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
class VarDumpFull
{
public function __construct($var)
{
$cloner = new VarCloner();
$dumper = new CliDumper();
$cloner->setMaxItems(-1);
$cloner->setMaxString(-1);
$dumper->dump($cloner->cloneVar($var));
}
}
you can run this easily like so:
new VarDumpFull($variable_to_be_dumped);
remember to run to update your classes.
composer dump-autoload

You need to iterate over the collection to work with user property. If you want to do that in Tinker:
foreach ($customers as $customer) {
echo $customer->user->name;
}
If you just want to see the data structure, you can do this in Tinker:
$customers->first()->user

First of all you should load relationship:
$customers = App\Customer::with('user')->get();
but I assume you did it because you have user relationship visible on your output.
To get array representation of your customers together with relationships you should use:
foreach ($customers as $customer)
{
dump($customer->toArray());
}
obviously result won't be the same as you dump the whole collection but you will get all model attributes together with relations and I think this is what you want here.

Related

Powerautomate Parsing JSON Array

I've seen the JSON array questions here and I'm still a little lost, so could use some extra help.
Here's the setup:
My Flow calls a sproc on my DB and that sproc returns this JSON:
{
"ResultSets": {
"Table1": [
{
"OrderID": 9518338,
"BasketID": 9518338,
"RefID": 65178176,
"SiteConfigID": 237
}
]
},
"OutputParameters": {}
}
Then I use a PARSE JSON action to get what looks like the same result, but now I'm told it's parsed and I can call variables.
Issue is when I try to call just, say, SiteConfigID, I get "The output you selected is inside a collection and needs to be looped over to be accessed. This action cannot be inside a foreach."
After some research, I know what's going on here. Table1 is an Array, and I need to tell PowerAutomate to just grab the first record of that array so it knows it's working with just a record instead of a full array. Fair enough. So I spin up a "Return Values to Virtual Power Agents" action just to see my output. I know I'm supposed to use a 'first' expression or a 'get [0] from array expression here, but I can't seem to make them work. Below are what I've tried and the errors I get:
Tried:
first(body('Parse-Sproc')?['Table1/SiteConfigID'])
Got: InvalidTemplate. Unable to process template language expressions in action 'Return_value(s)_to_Power_Virtual_Agents' inputs at line '0' and column '0': 'The template language function 'first' expects its parameter be an array or a string. The provided value is of type 'Null'. Please see https://aka.ms/logicexpressions#first for usage details.'.
Also Tried:
body('Parse-Sproc')?['Table1/SiteconfigID']
which just returns a null valued variable
Finally I tried
outputs('Parse-Sproc')?['Table1']?['value'][0]?['SiteConfigID']
Which STILL gives me a null-valued variable. It's the worst.
In that last expression, I also switched the variable type in the return to pva action to a string instead of a number, no dice.
Also, changed 'outputs' in that expression for 'body' .. also no dice
Here is a screenie of the setup:
To be clear: the end result i'm looking for is for the system to just return "SiteConfigID" as a string or an int so that I can pipe that into a virtual agent.
I believe this is what you need as an expression ...
body('Parse-Sproc')?['ResultSets']['Table1'][0]?['SiteConfigID']
You can see I'm just traversing down to the object and through the array to get the value.
Naturally, I don't have your exact flow but if I use your JSON and load it up into Parse JSON step to get the schema, I am able to get the result. I do get a different schema to you though so will be interesting to see if it directly translates.

Laravel 5.1 translate an array pass to blade

I have this in my controller
public function editProfile(Request $request){
$question1 = Question::where('group',1)->lists('question', 'id');
$question2 = Question::where('group',2)->lists('question', 'id');
return view('user', compact(''question1', 'question2'));
}
$question = {\"1\":\"What is the first name of your best friend in high school?\",\"2\":\"What was the name of your first pet?\",\"3\":\"What was the first thing you learned to cook?\",\"4\":\"What was the first film you saw in the theater?\"}
$question2 = {\"5\":\"Where did you go the first time you flew on a plane?\",\"6\":\"What is the last name of your favorite elementary school teacher?\",\"7\":\"In What city or town does your nearest sibling live?\"}
I would like to translate the value in both question 1 and question 2 and pass it to user blade without changing the key, Any suggestions?
As specified at the localization doc, you need to populate a lang file with translation strings. So, let's say you want to show both Spanish and English strings. In this case you'd need to create two files: /resources/lang/en/messages.php and /resources/lang/es/messages.php. The content of one of those files would be somewhat like this:
<?php
// resources/lang/es/messages.php
return [
'welcome' => 'Bienvenido'
];
This way, you could access the strings in there with the following method: __('messages.welcome'), which would return the string for the language set on your config/app.php -- the default entry is en, by the way, but you can set it to whatever you want. The value in there will define which language will be chosen when selecting strings.
Another method to create translation strings is using the string itself as key, storing them in a JSON file instead of PHP. For example, the following translation string:
{
"I love programming.": "Me encanta programar."
}
would be accessible through this: __('I love programming.').
Having said that, you may solve your problem through the two methods presented above. You could store in your DB keywords for the questions instead of the whole text, and create translation for as many languages as you want. Also, you could keep the questions in your database and create translation strings for those questions. Finally, you'd need to iterate over the fetched entries and translate each one of them, or use some Collection helper to do the hard work for you, like transform or map.

Laravel 5: Library class not found

I've installed this library from github:
https://github.com/robholmes/term-extractor
I placed the files under public/term-extractor.
I tried creating a route to test the results of the library, but I keep getting the error Class 'TermExtractor' not found.
Here is the route:
Route::get('/test', function()
{
require public_path() . '/term-extractor/src/TermExtractor/TermExtractor.php';
$text = 'Inevitably, then, corporations do not restrict themselves merely to the arena of economics. Rather, as John Dewey observed, "politics is the shadow cast on society by big business". Over decades, corporations have worked together to ensure that the choices offered by \'representative democracy\' all represent their greed for maximised profits. This is a sensitive task. We do not live in a totalitarian society - the public potentially has enormous power to interfere. The goal, then, is to persuade the public that corporate-sponsored political choice is meaningful, that it makes a difference. The task of politicians at all points of the supposed \'spectrum\' is to appear passionately principled while participating in what is essentially a charade.';
$extractor = new TermExtractor();
$terms = $extractor->extract($text);
// We're outputting results in plain text...
header('Content-Type: text/plain; charset=UTF-8');
// Loop through extracted terms and print each term on a new line
foreach ($terms as $term_info) {
// index 0: term
// index 1: number of occurrences in text
// index 2: word count
list($term, $occurrence, $word_count) = $term_info;
echo "$term\n";
}
});
What's wrong?
First you should put in your composer.json dependecy for that TermExtractor
"require": {
"robholmes/term-extractor" : "3.*"
}
Inside file app.php you need to do 2 things (something like this, dunno the proper name of alias and provider (be sure to do composer update before doing it)
First add provider
'providers' => [
term-extractor/TermExtractorProvider::class
]
Second add alias
'aliases' => [
'TermExtractor' => term-extractor\TermExtractor\Facades\TermExtractor::class,
]
That should give you alias TermExtractor which u can use in whole app without each time do require public_path() . '/term-extractor/src/TermExtractor/TermExtractor.php';
Hope it helps

three dependent drop down list opencart

I want to make 3 dependents drop down list, each drop down dependent to the previous drop down, so when I select an item from first drop down , all data fetch from database and add to second drop down as item.
I know how to do this in a normal php page using ajax, but as opencart uses MVC I don't know how can I get the selected value
Basically, you need two things:
(1) Handling list changes
Add an event handler to each list that gets its selected value when it changes (the part that you already know), detailed tutorial here in case someone needed it
Just a suggestion (for code optimization), instead of associating a separate JS function to each list and repeating the code, you can write the function once, pass it the ID of the changing list along with the ID of the depending list and use it anywhere.
Your HTML should look like
<select id="list1" onchange="populateList('list1', 'list2')">
...
</select>
<select id="list2" onchange="populateList('list2', 'list3')">
...
</select>
<select id="list3">
...
</select>
and your JS
function populateList(listID, depListID)
{
// get the value of the changed list thorugh fetching the elment with ID "listID"
var listValue = ...
// get the values to be set in the depending list through AJAX
var depListValues = ...
// populate the depending list (element with ID "depListID")
}
(2) Populating the depending list
Send the value through AJAX to the appropriate PHP function and get the values back to update the depending list (the part you are asking for), AJAX detailed tutorial here
open cart uses the front controller design patter for routing, the URL always looks like: bla bla bla.bla/index.php?route=x/y/z&other parameters, x = folder name that contains a set of class files, y = file name that contains a specific class, z = the function to be called in that class (if omitted, index() will be called)
So the answer for your question is:
(Step 1) Use the following URL in your AJAX request:
index.php?route=common/home/populateList
(Step 2) Open the file <OC_ROOT>/catalog/controller/common/home.php , you will find class ControllerCommonHome, add a new function with the name populateList and add your logic there
(Step 3) To use the database object, I answered that previously here
Note: if you are at the admin side, there is a security token that MUST be present in all links along with the route, use that URL:
index.php?route=common/home/populateList&token=<?php echo $this->session->data['token'] ?> and manipulate the file at the admin folder not the catalog
P.S: Whenever the user changes the selected value in list # i, you should update options in list # i + 1 and reset all the following lists list # i + 2, list # i + 3 ..., so in your case you should always reset the third list when the first list value is changed
P.P.S: A very good guide for OC 1.5.x => here (It can also be used as a reference for OC 2.x with some modifications)

How do I create a compound multi-index in rethinkdb?

I am using Rethinkdb 1.10.1 with the official python driver. I have a table of tagged things which are associated to one user:
{
"id": "PK",
"user_id": "USER_PK",
"tags": ["list", "of", "strings"],
// Other fields...
}
I want to query by user_id and tag (say, to find all the things by user "tawmas" with tag "tag"). Starting with Rethinkdb 1.10 I can create a multi-index like this:
r.table('things').index_create('tags', multi=True).run(conn)
My query would then be:
res = (r.table('things')
.get_all('TAG', index='tags')
.filter(r.row['user_id'] == 'USER_PK').run(conn))
However, this query still needs to scan all the documents with the given tag, so I would like to create a compound index based on the user_id and tags fields. Such an index would allow me to query with:
res = r.table('things').get_all(['USER_PK', 'TAG'], index='user_tags').run(conn)
There is nothing in the documentation about compound multi-indexes. However, I
tried to use a custom index function combining the requirements for compound
indexes and multi-indexes by returning a list of ["USER_PK", "tag"] pairs.
My first attempt was in python:
r.table('things').index_create(
'user_tags',
lambda each: [[each['user_id'], tag] for tag in each['tags']],
multi=True).run(conn)
This makes the python driver choke with a MemoryError trying to parse the index function (I guess list comprehensions aren't really supported by the driver).
So, I turned to my (admittedly, rusty) javascript and came up with this:
r.table('things').index_create(
'user_tags',
r.js(
"""(function (each) {
var result = [];
var user_id = each["user_id"];
var tags = each["tags"];
for (var i = 0; i < tags.length; i++) {
result.push([user_id, tags[i]]);
}
return result;
})
"""),
multi=True).run(conn)
This is rejected by the server with a curious exception: rethinkdb.errors.RqlRuntimeError: Could not prove function deterministic. Index functions must be deterministic.
So, what is the correct way to define a compound multi-index? Or is it something
which is not supported at this time?
Short answer:
List comprehensions don't work in ReQL functions. You need to use map instead like so:
r.table('things').index_create(
'user_tags',
lambda each: each["tags"].map(lambda tag: [each['user_id'], tag]),
multi=True).run(conn)
Long answer
This is actually a somewhat subtle aspect of how RethinkDB drivers work. So the reason this doesn't work is that your python code doesn't actually see real copies of the each document. So in the expression:
lambda each: [[each['user_id'], tag] for tag in each['tags']]
each isn't ever bound to an actual document from your database, it's bound to a special python variable which represents the document. I'd actually try running the following just to demonstrate it:
q = r.table('things').index_create(
'user_tags',
lambda each: print(each)) #only works in python 3
And it will print out something like:
<RqlQuery instance: var_1 >
the driver only knows that this is a variable from the function, in particular it has no idea if each["tags"] is an array or what (it's actually just another very similar abstract object). So python doesn't know how to iterate over that field. Basically exactly the same problem exists in javascript.

Resources