Drupal 8 views ui : filter on custom field - drupal-views

I m pretty new to D8 and I m trying to do the following thing :
I have a content type : movie.
In that content type I have a custom field api_id wich is simply an integer.
When I am on a movie page I want to display under the content a block with movies with the same api_id.
I have managed to create block for the same movies from the same author but I can't figure out how to to filter on api_id (I have played so much with contextual filters ...)
Any ideas ? Thx

Ok , I manage to do what I want with hook_views_query_alter() :
function my_module_views_query_alter(\Drupal\views\ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query)
{
if($view->id() == 'my_view' && $view->current_display == 'my_block'){
$movie= Node::load($view->args[0]);
if(is_object($movie)) {
foreach ($query->where as &$condition_group) {
foreach ($condition_group['conditions'] as &$condition) {
if ($condition['field'] == 'node__field_id_movie.field_id_movie_value') {
$condition = array(
'field' => 'node__field_id_movie.field_id_movie_value',
'value' => $movie->get('field_id_movie')->value,
'operator' => '=',
);
}
}
}
}
}
}
To do that you have to first create a view with a simple filter on the field you want to override the filter.

Related

association where clause with array cakephp 3

Basically what i want to do is write this query with cakephp 3 query builder :
SELECT * FROM question as q innerjoin answers as a where q.question = $question AND a.id NOT IN = $avoidedIDs
codes for table class
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use App\Model\Entity\Comlib;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Validator;
use Cake\ORM\TableRegistry;
class ComlibsTable extends Table {
public function initialize(array $config) {
parent::initialize($config);
$this->table('questions');
// join the tables
$this->hasMany('Answers' , [
'foreignKey' => 'question_id'
]);
}
public function LFA( $live_req) {
$query = $this->find()->where(['question' => $live_req])->contain(['Answers'])->LIMIT(6);
$query = $query->toArray();
//include 5 answer
return $query;
}
public function LFM($theid , $avoidedIDs, $question )
{
$query = $this->find()->where(['question' => $question])->contain(['Answers' => function($q){
return $q
->where(['Answers.id NOT IN' => $avoidedIDs] );
}
]);
$query = $query->toArray();
debug($query);
return $query;
}
}
the error that i get is : Impossible to generate condition with empty list of values for field (Answers.id).
but when i print_r($avoidedIDs) i get the values that i passed so im sure that $avoidedIDs is not empty , at least not out of contain function and thats what makes it more complicated for me, but when i put ONE number instead of my variable it will execute , if i put 1,2,3,4 still it will execute only the first one!
what am i doing WRONG for the past 2 days ?????
tnx for any help
It is because you are trying to use $avoidedIDs in an anonymous function (Closure) call, which is not available there.
You should make it available for the function.
->contain(['Answers' => function($q) use ($avoidedIDs){..}
Closures may also inherit variables from the parent scope. Any such
variables must be passed to the use language construct.
http://www.php.net/manual/en/functions.anonymous.php

Add parameter name to gravity forms

I am using Gravity form. I have more 400 forms. I want to add a parameter name in every form and in a particular field. I know how to add the parameter in a Gravity form field.
But i want to add parameter in each form like search replace. Is there any trick available for Gravity form. Because it is so time taking to add a parameter name in each form.
something like this should do it:
add_filter( 'gform_pre_render', function( $form ) {
foreach( $form['fields'] as &$field ) {
// if( field you want ) {
$field->allowsPrepopulate = true;
$field->inputName = 'your_parameter';
// }
}
}, 9 );
You will need to determine the best way to identify the fields you wish to apply this to. You'll see I've left the condition commented out. If they all have the same field ID you could do:
if( $field->id == 1 ) { ... }
If they'll have the same label, you could do:
if( $field->label == 'My Label' ) { ... }

CakePHP SET error => false FOR All Forms

I want to handle application feedback regarding, in this case, form validation.
To do this I check for model validation in controller, using
// VALIDATE
if ($this->Event->validates($this->data))
{
// SAVE
$this->Event->create();
if ($this->Event->saveAll($this->data, array('validate' => false)))
{
$this->Session->setFlash('Evenimentul a fost salvat!', 'flash_admin_success');
$this->redirect(array('action' => 'index', 'admin' => true));
} else {
$this->Session->setFlash('Evenimentul nu a putut fi salvat. Va rugam sa incercati din nou!', 'flash_admin_error');
}
////////
$errors = 'O EROARE';
$this->set(compact('errors'));
}
else
{
// GET ERRORS to display it nicely :)
$errors = $this->Event->invalidFields();
$flash = '';
foreach($errors as $error)
{
$flash .= $error."<br />";
}
$this->Session->setFlash($flash, 'flash_admin_error');
}
I know that there is a way to get rid of form field errors using 'error' => false, but i want to set this for the entire application, thus for all fields in all forms.
It has to be there a way of setting that fot the object itself, and I would be gratefull if someone would tell me.
Thaks a lot!
Edit: This doesn't really disable error output, but will hide the error: go to webroot/css/cake.generic.css add display:none to selector div.error-message. That's the simplest way to achieve what you want that I can think of.
Though it may seem like a bit of an extreme approach to override a single property, you can achieve this by extend the core FormHelper. This will allow you to make Anh Pham's original suggestion the default for all FormHelper instances:
// app/views/helpers/app_form.php
App::import('Helper', 'Time');
class AppFormHelper extends FormHelper {
public $_inputDefaults = array('error' => false);
}
Now to use this as-is in CakePHP 1.3, you would have to use "AppForm" throughout your application to refer to this helper from now on (ie. $this->AppForm->input()). CakePHP 2.0 introduces helper aliasing to overcome this, but for now one has to resort to a bit of trickery to continue using "Form" instead. One blog post I found shows how to backport the functionality and another manages allow the helper to do it itself. I personally use the following without any problems:
// app/views/app.php
class AppView extends View {
function &_loadHelpers(&$loaded, $helpers, $parent = null) {
$return = parent::_loadHelpers($loaded, $helpers, $parent);
# rename App helpers (ie. AppHtml -> Html)
foreach ($return as $helperName => $helper) {
if (substr($helperName, 0, 3) === 'App') {
$newHelperName = substr($helperName, 3);
$return[$newHelperName] = $return[$helperName];
}
}
# done
return $return;
}
}
To use the new created classes above, just add the following to your AppController:
// app/app_controller.php
class AppController extends Controller {
public $helpers = array(/*...*/, 'AppForm');
public $view = array('App');
}

Symfony: exclude empty values from form save

I have a many to many relation between Product and Properties. I'm using embedRelation() in my Product form to edit a Product and it's Properties. Properties includes images which causes my issue. Every time I save the form the updated_at column is updated for file properties even when no file is uploaded.
Therefore, I want to exclude empty properties when saving my form.
I'm using Symfony 1.4 and Doctrine 1.2.
I'm thinking something like this in my ProductForm.class.php, but I need some input on how to make this work.
Thanks
class ProductForm extends BaseProductForm
{
public function configure()
{
unset($this['created_at'], $this['updated_at'], $this['id'], $this['slug']);
$this->embedRelation('ProductProperties');
}
public function saveEmbeddedForms($con = null, $forms = null)
{
if (null === $forms)
{
$properties = $this->getValue('ProductProperties');
$forms = $this->embeddedForms;
foreach($properties as $p)
{
// If property value is empty, unset from $forms['ProductProperties']
}
}
}
}
I ended up avoiding Symfony's forms and saving models instead of saving forms. It can be easier when playing with embedded forms. http://arialdomartini.wordpress.com/2011/04/01/how-to-kill-symfony%E2%80%99s-forms-and-live-well/
Solved it by checking if posted value is a file, and if both filename and value_delete is null I unset from the array. It might not be best practice, but it works for now.
Solution based on http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms
class ProductPropertyValidatorSchema extends sfValidatorSchema
{
protected function configure($options = array(), $messages = array())
{
// N0thing to configure
}
protected function doClean($values)
{
$errorSchema = new sfValidatorErrorSchema($this);
foreach($values as $key => $value)
{
$errorSchemaLocal = new sfValidatorErrorSchema($this);
if(array_key_exists('value_delete', $values))
{
if(!$value && !$values['value_delete'])
{
unset($values[$key]);
}
}
// Some error for this embedded-form
if (count($errorSchemaLocal))
{
$errorSchema->addError($errorSchemaLocal, (string) $key);
}
}
// Throws the error for the main form
if (count($errorSchema))
{
throw new sfValidatorErrorSchema($this, $errorSchema);
}
return $values;
}
}

Drupal - Set default value in hook_form_alter?

Trying to prepopulate some of my form fields, and am using hook_form_alter(). I've tried a couple of different ways, but in both cases, the fields still come up empty. I'm assuming that I need to set default_value and not value because if the user changes what's in the field, I want that to update correctly. Is that right?
Here's what I've been trying:
function mymodule_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'user_profile_form') {
if(arg(0) == 'user' && arg(1)) {
$user = user_load(arg(1));
$form['profile_company_site']= array('#default_value' => $user->profile_company_site);
$form['profile_blog_url']= array('#default_value' => $user->profile_blog_url);
$form['profile_my_website_url']= array('#default_value' => $user->profile_my_website_url);
$form['profile_first_name']= array('#default_value' => $user->profile_first_name);
$form['profile_last_name']= array('#default_value' => $user->profile_last_name);
}
}
}
I also tried it this way:
function mymodule_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'user_profile_form') {
if(arg(0) == 'user' && arg(1)) {
$user = user_load(arg(1));
$form['profile_company_site'][#default_value'] = $user->profile_company_site);
$form['profile_blog_url'][#default_value'] = $user->profile_blog_url);
$form['profile_my_website_url']['#default_value'] = $user->profile_my_website_url);
$form['profile_first_name']['#default_value'] = $user->profile_first_name);
$form['profile_last_name']['#default_value'] = $user->profile_last_name);
}
}
}
Both seem to be in the correct format, but your first one will overwrite all the other items you set for the field. So you are better going off with the second and adding them piece meal.
On the second one, you are missing some single quotes on a couple.
$form['profile_company_site']['#default_value'] = $user->profile_company_site);
Are you sure you are getting into loop?
You are missing one array level. The profile form fields will not be at the top level in the $form array, but in a subarray keyed by the category name. So if you assigned your fields a category of 'example category', your code should look like this:
function mymodule_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'user_profile_form') {
if(arg(0) == 'user' && arg(1)) {
$user = user_load(arg(1));
$form['example category']['profile_company_site']['#default_value'] = $user->profile_company_site);
$form['example category']['profile_blog_url']['#default_value'] = $user->profile_blog_url);
$form['example category']['profile_my_website_url']['#default_value'] = $user->profile_my_website_url);
$form['example category']['profile_first_name']['#default_value'] = $user->profile_first_name);
$form['example category']['profile_last_name']['#default_value'] = $user->profile_last_name);
}
}
}
You should use a debugger (or at least a var_dump()) to inspect the form array you want to manipulate - saves a lot of time.