How To Write An Inner Join With WP Query - sql

I have a ACF relationship field for a custom post type, properties. Moreover, the content of these properties can either be in English or Spanish. When I use a ACF relationship field to associate properties to a user on the user edit page -- /wp/wp-admin/user-edit.php -- everything works as expected, and I can select from the relationship drop down the properties I want for this user.
My question is this: how can I write a query inside this filter such that only the English properties appear, regardless of the language of the page (English or Spanish) which is set by the WPML toggle? I know how to write such a query in SQL:
SELECT *
FROM wp_2_posts
INNER JOIN wp_2_icl_translations
ON wp_2_icl_translations.element_id = wp_2_posts.id
AND wp_2_icl_translations.language_code = 'en'
WHERE wp_2_posts.post_type = 'properties';
But the filter requires that changes be made to $args which adhere to WP_Query. I do not know how to write the above INNER JOIN on wp_2_icl_translations to only show custom post types properties in English. Can someone please instruct me how so that I can get the acf filter to work the way I need it to?

Ok so the way I was able to just show English properties on the user admin page was with this posts_request hook:
add_filter('posts_request', function($sql, $query) {
$is_user_edit_page = (
isset($_SERVER['HTTP_REFERER']) &&
strpos($_SERVER['HTTP_REFERER'], 'user-edit') !== false
);
$is_property_sql = (strpos($sql, 'property') !== false);
if ($is_user_edit_page && $is_property_sql) {
$sql = str_replace("'sp'", "'en'", $sql);
}
return $sql;
}, 10, 2);
In this hook I make sure it only runs on the user-edit page and that the sql it's changing relates to the properties. If all those cases are true, then I just replace the Spanish language code with the English one. And as a result, the SQL used to query the properties is forced to only query for English ones.

Related

How do I implement, for instance, "group membership" many-to-many in Parse.com REST Cloud Code?

A user can create groups
A group had to have created by a user
A user can belong to multiple groups
A group can have multiple users
I have something like the following:
Parse.Cloud.afterSave('Group', function(request) {
var creator = request.user;
var group = request.object;
var wasGroupCreated = group.existed;
if(wasGroupCreated) {
var hasCreatedRelation = creator.relation('hasCreated');
hasCreatedRelation.add(group);
var isAMemberOfRelation = creator.relation('isMemberOf');
isAMemberOfRelation.add(group);
creator.save();
}
});
Now when I GET user/me with include=isMemberOf,hasCreated, it returns me the user object but with the following:
hasCreated: {
__type: "Relation"
className: "Group"
},
isMemberOf: {
__type: "Relation"
className: "Group"
}
I'd like to have the group objects included in say, 'hasCreated' and 'isMemberOf' arrays. How do I pull that using the REST API?
More in general though, am I approaching this the right way? Thoughts? Help is much appreciated!
First off, existed is a function that returns true or false (in your case the wasGroupCreated variable is always going to be a reference to the function and will tis always evaluate to true). It probably isn't going to return what you expect anyway if you were using it correctly.
I think what you want is the isNew() function, though I would test if this works in the Parse.Cloud.afterSave() method as I haven't tried it there.
As for the second part of your question, you seem to want to use your Relations like Arrays. If you used an array instead (and the size was small enough), then you could just include the Group objects in the query (add include parameter set to isMemberOf for example in your REST query).
If you do want to stick to Relations, realise that you'll need to read up more in the documentation. In particular you'll need to query the Group object using a where expression that has a $relatedTo pointer for the user. To query in this manner, you will probably need a members property on the Group that is a relation to Users.
Something like this in your REST query might work (replace the objectId with the right User of course):
where={"$relatedTo":{"object":{"__type":"Pointer","className":"_User","objectId":"8TOXdXf3tz"},"key":"members"}}

typo3 extbase permissions in extensions

I have written one extension for making service order.
The issue I am facing here is,
There are FE users belong to three FE user groups namely "client", "Admin" and "Employee".
Here the client can make order and he should be able to see only his orders.
And the admin can see all orders done by different clients.
And the employee should be able to see only some clients orders.
Currently I made a order table with N:1 relation with FE user table. So every order should relate with any one client.
So in controller, I am checking the login user and using custom query in repository, I am accessing order related to loggedin client (FE user)
In file OrdersController.php
public function listAction() {
$orders = $this->ordersRepository->orderForLoginUsr();
$this->view->assign('orders', $orders);
}
In file OrdersRepository.php
public function orderForLoginUsr(){
$loggedInUserId = $GLOBALS ['TSFE']->fe_user->user['uid'];
$query = $this->createQuery();
$query->matching(
$query->equals('user', $loggedInUserId)
);
$query->setOrderings(array('crdate' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING));
return $query->execute();
}
But here my question is how to make admin user able to see all the orders done by all clients?
I have to write different template and action that calling function findAll() ?
$orders = $this->ordersRepository->findAll();
And how to set for usergroup Employee ?
Thanks in Advance
I think that the easiest way is to actually implement 3 actions with 3 different plugins, something like: listClientAction, listAdminAction and listEmployeeAction
In each of those action, you implement a method in your repository that fetch the right list of order with the good ordering:
orderForLoginClient(), orderForLoginEmployee(), orderForLoginAdmin()
What does the trick actually is that there will be 3 plugins on your page, one for each action. In each instance of your plugin, you set the access for the right be_group.
Don't forget to add the actions and plugin in the localconf and ext_table files.
I hope it will help!
Olivier
If your view is almost the same for client, admin, employee you should simply add a method like getOrderWithPermissionsForUser($currentUser);
In the method itself you should check for the usergroup and call different queries on your Repo.
If your view is different from usergroup to usergroup, you should use different templates with partials for the same parts.
If the data of the views is the same, just change the template for each usergroup in the action. If not use different actions.
Here is a helper method for easily changing your templatefile.
/**
* This method can change the used template file in an action method.
*
* #param string $templateName Something like "List" or "Foldername/Actionname".
* #param string $templateExtension Default is "html", but for other output types this may be changed as well.
* #param string $controllerName Optionally uses another subfolder of the Templates/ directory
* By default, the current controller name is used. Example value: "JobOffer"
* #param \TYPO3\CMS\Fluid\View\AbstractTemplateView $viewObject The view to set this template to. Default is $this->view
*/
protected function changeTemplateFile($templateName, $templateExtension = 'html', $controllerName = null, AbstractTemplateView $viewObject = null)
{
if (is_null($viewObject)) {
$viewObject = $this->view;
}
if (is_null($controllerName)) {
$controllerName = $this->getControllerContext()->getRequest()->getControllerName();
}
$templatePathAndFilename = $this->getTemplateRootpathForView($controllerName . '/' . $templateName . '.' . $templateExtension);
$viewObject->setTemplatePathAndFilename($templatePathAndFilename);
}

Prestashop - Adding Fields To Address Form To Be Stored In A Different Sql Table

I've recently added Facebook authentication to my site, which results in the user automatically being directed to the Address page once they have authenticated. Those users logging in this way will not be shown the extra questions I had asked them during the normal checkout/registration process ('How did you hear about us ?', etc..).
My question is, how do I add these fields into the Address form and get them to be inserted into the ps_customer table as they would be if a user was registering using the traditional way ? I could add fields to the Address template/controller right now, but they would end up being saved in the ps_address table instead
Any help would be much appreciated,
Thanks
It is possible but will need some work around.
After you added the fields to the address form, you have to overried the Address.php class. Do it as followed.
1) In override/classes folder find the Address.php file, and also open classes/Address.php file .
2) In file classes/Address.php file, find add function which will be as below
/**
* #see ObjectModel::add()
*/
public function add($autodate = true, $null_values = false)
{
if (!parent::add($autodate, $null_values))
return false;
if (Validate::isUnsignedId($this->id_customer))
Customer::resetAddressCache($this->id_customer);
return true;
}
Copy that exact function to override/classess/Address.php file and place it in the class.
3) Just after the below code
if (!parent::add($autodate, $null_values))
return false;
Write down your code to insert the extra fields to another table. Just get the POSTed values and write you won sql query to insert it into customers table or any other tables if you need.
Thank you

How to remove validation on a Select Element in Zend Framework 2

I wanted to bypass the annoying validation for the Select Element in Zend Framework 2. My requirement is that I have two select drop down boxes where I pass the values from the left select box to right select box and finally when I click the submit button, I post the values from right select box.
So basically the left select box is there to show the values to the user, my problem is that in the left select box as no value is selected it throws this error:
["selectAll"] => array(1) {
["isEmpty"] => string(36) "Value is required and can't be empty"
}
I have seen some old posts from Stackoverflow, where this is possible in Zend Framework 1 like one can disable the validation for the particular select element´
Examples:-
$selectAllElement->setRequired(false);
or
$selectAllElement->removeDecorator('Errors');
which some how these methods are not available in Zend Framework 2. In case if somebody has a solution of how disable the validation for a particular select element, please do share your knowledge, will be hepful for people getting into Zend Framework 2.
EDIT:
In my Form-
$select = new Element\Select('selectAllElement');
$select->setAttribute('title', 'Select a Value')
->setAttribute('id', 'id');
$options = array(
array(
//Fetching the values from database
),
);
$select->setAttribute('multiple', 'multiple')
->setAttribute('required', false)
->setValueOptions($options);
$this->add($select);
As per request from Sam, I have provided the code how I am adding the select element to my form and setting the attributes.
NOTE: I am not using any FIELDSETS
To clarify this as an answer, using the setRequired()-Method on any Zend\Form\Element only declares if the HTML-Attribute required="(bool)" should be rendered or not.
If you want to exclude a Field/Element from Validation you need to define this inside your InputFilters setting 'required' => false
Sometimes with me, the setRequired(false) not works when working with select multiple or checkbox that is not in the view, and so, i just override the isValid method and remove the validator as the code above:
public function isValid() {
$this->getInputFilter()->remove('alterarsenha');
$this->getInputFilter()->remove('usuario_perfis');
return parent::isValid();
}
I know this topic is most probably very outdated, but still maybe one consider this as useful.
In version of zf2 which I'm using there is a bug in class Zend\Form\Element\Select, this class provides InputProviderInterface, especially method getInputSpecification(), in this method option
$spec = array(
'name' => $this->getName(),
'required' => true,
);
So if you redefine method getInputSpecification it should works.

kohana ORM question

i am using kohana ORM in order to get some results from the database. My problem is: even though i have consulted the documentation, i can't find a way to select only the column i am interested in. To be more explicit, i have:
$sale_stock = Model::factory('product_type')
->where('product_type_id','=', $id )
-> find_all();
var dumping it, it selects me all the "SELECT product_type.* from product_type where etc".
But i want to select only the 'stock' field from the salestock table. doing find('stock') instead find_all() returns a weired object... Where am i wrong, and how can i actually select only the column 'stock' using kohana orm?
thank you!
ORM methods find() and find_all() always select all table columns, so there is two ways to get specified fields:
Load full table rows and get columns
from it:
$sale_stock = Model::factory('product_type')
->where('product_type_id','=', $id )
-> find_all();
// get array of id=>stock values
$columns = $sale_stock->as_array('id', 'stock');
Create special method in model using
Query Builder:
// model Model_Product_Type
public function get_stocks($product_type_id)
{
return DB::select(array('stock'))
->from($this->_table_name)
->where('product_type_id', '=', $product_type_id)
->execute($this->_db);
}
I realise this isn't exactly what you're looking for, but I've pulled the following from the Kohana documentation ...
$articles = ORM::factory('article')->select_list('id', 'title');
foreach ($articles as $id => $title)
{
// Display a list of links
echo html::anchor('articles/'.$id, $title);
}
// Display a dropdown list
echo form::dropdown('articles', $articles);
You could think of it as a discount, two fields for the price of one.
It's common practice for ORMs to return a 'non-standard' object when partial model or merged model fields are requested. This prevents confusing operations using the original object (ie. how do you save an object when it contains only 2 of 8 fields, plus maybe some fields from another model?).
If you print_r the object, and give me an indication of how that looks ... it might be just what you want.
I know this is an old question, but i found maybe easier solution:
$sale_stock = ORM::factory('product_type')
->where( 'product_type_id','=', $id )
->find_all();
die($sale_stock->stock);