Basically I want the same result that this SQL would return:
SELECT id FROM property_group_option opt
LEFT JOIN property_group_option_translation tra
ON opt.id = tra.property_group_option_id
WHERE opt.property_group_id = <id> AND tra.name = "<name>"
The way to go described in the Shopware documentation does not seem to get the right result. I have tried the following:
$criteria = (new Criteria())
->addFilter(new EqualsFilter('property_group_id', $propertyGroupId))
->getAssociation('property_group_option_translation')
->addFilter(new EqualsFilter('name', $value));
$result = $this->propertyGroupOptionRepository->search($criteria, Context::createDefaultContext())->first()->getId();
I did find a workaround which does not seem to be the way to go (and is also not the best performing), but it did return the right result.
$criteria = (new Criteria());
$criteria->addFilter(new EqualsFilter('name', $value));
$criteria->getAssociation('property_group_option')
->addFilter(new EqualsFilter('groupId', $propertyGroupId));
$translation = $this->propertyGroupOptionTranslationRepository->search($criteria, Context::createDefaultContext())->first()
if($translation !== null) {
$criteria = (new Criteria([$translation->get('propertyGroupOptionId')]));
$result = $this->propertyGroupOptionRepository->search($criteria, Context::createDefaultContext())->first()->getId();
}
is there a proper solution for that?
You are using the table name. Try to use the model name instead.
You have to use addAssociation() first - getAssociation() seems to return a new Criteria instance which is later not used in the actual query, if the association did not exist before:
See in the code.
public function getAssociation(string $path): Criteria
{
$parts = explode('.', $path);
$criteria = $this;
foreach ($parts as $part) {
if ($part === 'extensions') {
continue;
}
if (!$criteria->hasAssociation($part)) {
$criteria->associations[$part] = new Criteria(); // this is returned, but not stored
}
$criteria = $criteria->associations[$part];
}
return $criteria;
}
Related
I use preg_match_all to find the usernames in the 'body' and save them in a database. How can I find the usernames in several input fields, for example: body, title and article? And how can I save the found references to the database without saving duplicate entries?
if ($post) {
preg_match_all('/\B#(\w+)/', $request->get('body'), $mentionedUsers);
foreach ($mentionedUsers[1] as $mentionedUser) {
$foundUser = User::where('username', $mentionedUser)->first();
if(!$foundUser){
continue;
}
$foundUserId = $foundUser->id;
$mentionedUser_save = new Mentioned_post_user;
$mentionedUser_save->user_id_lead = Auth::user()->id;
$mentionedUser_save->user_id = $foundUserId;
$mentionedUser_save->post_id = $post->id;
$mentionedUser_save->save();
}
}
You can utilize whereIn('user_name', $mentionedUsers) instead of running foreach.
if ($post) {
// assuming this line works and mentioned users are in $mentionedUsers[1]
preg_match_all('/\B#(\w+)/', $request->get('body'), $mentionedUsers);
$foundUsers = User::whereIn('username', $mentionedUsers[1])->get();
if ($foundUsers) {
foreach ($foundUsers as $foundUser) {
$foundUserId = $foundUser->id;
$mentionedUser_save = new Mentioned_post_user;
$mentionedUser_save->user_id_lead = Auth::user()->id;
$mentionedUser_save->user_id = $foundUserId;
$mentionedUser_save->post_id = $post->id;
$mentionedUser_save->save();
}
}
}
Otherwise, you'd need to get unique values of $mentionedUsers[1] with array_unique(). (I'd suggest the solution above)
Edit: Sorry a thought your problem was different. For your solution, the approach I'd use is combine all inputs.
$theString = "$request->body $request->title $request->article";
preg_match_all('/\B#(\w+)/', $theString, $mentionedUsers);
$userNamesArray = array_unique($mentionedUsers[1]);
$foundUsers = User::whereIn('username', $userNamesArray)->get();
$nameTemplate=“prefix_“;
$tables = DB::select(“SHOW TABLES LIKE ‘$nameTemplate%’“);
this returns as prefix_somename, so prefixanothername too. How to do to only first result returns?
$nameTemplate = ‘prefix_‘;
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
$tables = collect($tables);
$tables->contains(function ($item) use ($nameTemplate) {
return (strpos($item, $nameTemplate) !== false);
});
this returns all tables. Where is an error?
You can try to filter the results, like this:
$tables = collect($tables)->filter(function($item) use ($nameTemplate) {
return strpos($item, $nameTemplate) !== false;
});
$tables here should contain only the tables based on your filter.
I found that first part of question expression works if to use backslash before "_"
$nameTemplate=“prefix\_“;
try this
$nameTemplate="prefix_";
$tableNames = \Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
foreach ($tableNames as $tableNameValue)
{
if (strpos($tableNameValue, $nameTemplate) !== false)
{
dd('table found in serach criteria ');
}
else
{
dd('table not found in serach criteria ');
}
}
i have an array with conditions i have already prepared to pass it to the query:
array:
('u.registered = 1','u.active = 0', 'u.gender = M')
when i pass to the query, it works with the number comparison but not with the varchar which is M. The error appears in "gender", it says it is a semantical error. I assume is because i am not using expr()->literal('M'), but i can't do this because the query is "already built"..
Is there an alternative way so i don't have to code all over again?
this is the code:
public function customR($data){
// var_dump($data);die();
$this->qb = $this->em->createQueryBuilder();
$andX = $this->qb->expr()->andX();
$this->qb->select('u')
->from('models\User','u');
foreach ($data as $value){
$andX->add($value);
}
$this->qb->add('where', $andX);
$query = $this->qb->getQuery();
// var_dump($query);die();
$obj = $query->getResult();
var_dump($obj);die();
if (!empty($obj)){
return $obj;
return false;
}
}
I found no way to do this, so i just changed it a little bit.
I send an array with some elements, just to have the reference of what exists and what doesn't.
So, in my Data Service I've created a function and a snippet of that function to solutionate my question was to do this:
if($key == 'gender'){
foreach($value as $key=>&$v){
$condition = ('u.gender = '. $this->qb->expr()->literal($v));
$orX->add($condition);
}
}
Trying to do a dropdown list with this query and trying to return an array with the while to do that and the while don't work :s
static public function getConta() {
$criteria = new Criteria();
$criteria->addSelectColumn(MEMataPeer::CONTA);
$criteria->addGroupByColumn(MEMataPeer::CONTA);
$contas = array();
$stmt = MEMatalPeer::doSelectStmt($criteria);
echo "##".$stmt->rowCount();
while($res = $stmt->fetchColumn(0)) { // <- this while don't work don't know why ?????
$contas[$res] = $res;
echo "<br/>[$res]";`
Your
$stmt->fetchColumn(0)
has a false evaluation (probably a null result). In this case there is nothing to while over.
TL;DR
I have this data: var_export and print_r.
And I need to narrow it down to: http://pastebin.com/EqwgpgAP ($data['Stock Information:'][0][0]);
How would one achieve it? (dynamically)
I'm working with vTiger 5.4.0 CRM and am looking to implement a function that would return a particular field information based on search criteria.
Well, vTiger is pretty weakly written system, looks and feels old, everything comes out from hundreds of tables with multiple joins (that's actually not that bad) etc., but job is job.
The need arose from getting usageunit picklist from Products module, Stock Information block.
Since there is no such function as getField();, I am looking forward to filter it out from Blocks, that is actually gathering the information about fields also.
getBlocks(); then calls something close to getFields();, that again something close to getValues(); and so on.
So...
$focus = new $currentModule(); // Products
$displayView = getView($focus->mode);
$productsBlocks = getBlocks($currentModule, $displayView, $focus->mode, $focus->column_fields); // in theory, $focus->column_fields should/could be narrowed down to my specific field, but vTiger doesn't work that way
echo "<pre>"; print_r($productsBlocks); echo "</pre>"; // = http://pastebin.com/3iTDUUgw (huge dump)
As you can see, the array under the key [Stock Information:], that actually comes out from translations (yada, yada...), under [0][0] contains information for usageunit.
Now, I was trying to array_filter(); the data out from there, but only thing I've managed to get is $productsBlocks stripped down to only contain [Stock Information:] with all the data:
$getUsageUnit = function($value) use (&$getUsageUnit) {
if(is_array($value)) return array_filter($value, $getUsageUnit);
if($value == 'usageunit') return true;
};
$productsUsageUnit = array_filter($productsBlocks, $getUsageUnit);
echo "<pre>"; print_r($productsUsageUnit); echo "</pre>"; // = http://pastebin.com/LU6VRC4h (not that huge of a dump)
And, the result I'm looking forward to is http://pastebin.com/EqwgpgAP, that I've manually got by print_r($productsUsageUnit['Stock Information:'][0][0]);.
How do I achieve this? (dynamically...)
function helper($data, $query) {
$result = array();
$search = function ($data, &$stack) use(&$search, $query) {
foreach ($data as $entry) {
if (is_array($entry) && $search($entry, $stack) || $entry === $query) {
$stack[] = $entry;
return true;
}
}
return false;
};
foreach ($data as $sub) {
$parentStack = array();
if ($search($sub, $parentStack)) {
$result[] = $parentStack[sizeof($parentStack) - 2];
}
}
return $result;
}
$node = helper($data, 'usageunit');
print_r($node);