Drupal 7 Views Contextual Filters Title Override - drupal-7

I have a view that returns search results via the search API. It performs this use case adequately and I am happy. To crown the deliverable, I need to add a title override of the form Showing search results for '%1' which looks easy enough initially but it isn't working entirely as planned.
For a URL = mysite.com/search/all?search=wombat, where the search value is gathered from an exposed form within a block, I am either getting:
Showing search results for 'Search for "all"'
or, if I enter %1 in the title override for subject not appearing in the URL, I get:
Showing search results for %1". My goal is to get "Showing search results for 'wombat'
The title override works in that it removes the Search for ... part but the substitution picks up on "all" as the exception value (or anything else that I set as the exception value) where I need to be able to pick up the value of the query string (search=wombat).
Can anyone shed some light here?

The problem is that the '%1' and '%2' that you can use to override the title refer to your path's first and second arguments (in Drupal terms) and that would be 'search' and 'all?search=wombat' in your case...
What you need instead is the 'wombat' as a path component in itself.
Perhaps you can achieve that by working that case you're talking about: the case of a "title override for subject not appearing in the URL". There is an option in the contextual filters section (I'm assuming that's where you're working) for providing a default value when one isn't present. Perhaps you can use the 'PHP code' option there, isolate your 'wombat' string and return that as a default contextual filter, and then you can get to it via the '%1'.
The php code to get that portion of the URL should look something like this:
return htmlentities($_GET['search']);
the $_GET() returns the value of that variable in the url, and the htmlentities() is just to keep it safe, since it's using a portion of the url, which is vulnerable to XSS.
See if that combo (1) setting a default argument when one isn't present and 2) using that newly set argument in your title printout) works!

I fixed this issue.
Using following two hooks we can change the defalut value of filter Programmatically.
<?php
/**
* hook_views_pre_view
* #param type $view
* #param type $display_id
* #param type $args
*/
function MODULE_NAME_views_pre_view(&$view, &$display_id, &$args) {
if ($view->name == 'VIEW_NAME') {
$filters = $view->display_handler->get_option('filters');
$view->display_handler->override_option('filters', $filters);
}
}
/**
* hook__views_pre_build
* #param type $view
* #return type
*/
function MODULE_NAME_views_pre_build($view) {
if ($view->name=='VIEW_NAME') {
$view->display['page']->handler->handlers['filter']['filter_field']->value['value'] = 8;
return $view;
}
}
?>
This code worked for me. I am using the drupal 7.

Related

TYPO3 10 and Solr : can't modify the Typoscript config through a Viewhelpers

I'm trying to add search options on my search form that would allow the user to ensure that all the words he searched for are in the results, or at least one, or an "exact match".
I've found MinimumMatch and it's perfect for that.
I've made a custom viewhelper that I placed in my Result.html, it takes as parameter the type of search the user wants (atLeastOne, AllWords, etc...) and I've dug a bit in the source code and it seems I can override values of the current Solr Typoscript by passing an array to a mergeSolrConfiguration function.
So I tried something like that as a draft to see how it works :
public static function renderStatic(array $arguments, Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$previousRequest = static::getUsedSearchRequestFromRenderingContext($renderingContext);
$usedQuery = $previousRequest->getRawUserQuery();
$contextConfiguration = $previousRequest->getContextTypoScriptConfiguration();
$override['plugin.']['tx_solr.']['search.']['query.']['minimumMatch'] = '100%';
$contextConfiguration->mergeSolrConfiguration($override, true, true);
return self::getSearchUriBuilder($renderingContext)->getNewSearchUri($previousRequest, $usedQuery);
}
But it simply doesn't work. Solr keeps using the site's Typoscript config instead of my overriden one.
I saw there was a way to also override the Typoscript of the filters, with setSearchQueryFilterConfiguration so I gave it a try with :
public static function renderStatic(array $arguments, Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$previousRequest = static::getUsedSearchRequestFromRenderingContext($renderingContext);
$usedQuery = $previousRequest->getRawUserQuery();
$previousRequest->getContextTypoScriptConfiguration()
->setSearchQueryFilterConfiguration(['sourceId_intS' => 'sourceId_intS:7']);
return self::getSearchUriBuilder($renderingContext)->getNewSearchUri($previousRequest, $usedQuery);
}
But nope, it keeps using the configuration set in the website's template, completely ignoring my overrides.
Am I going the wrong way with this ? Is the thing I'm trying to do not possible technically ?

clear text field using DELETE or BACK SPACE key in webdriver

I am trying to clear a text field using this action:
emailField.sendKeys("gmail.com");
emailField.sendKeys(Keys.CONTROL,"a",Keys.DELETE);
In above code, the last line only selects the text, does not delete it, but if I separate the actions it works.
emailField.sendKeys(Keys.CONTROL,"a");
emailField.sendKeys(Keys.DELETE);
From the JavaDoc for WebElement.clear():
If this element is a text entry element, this will clear the value.
Has no effect on other elements. Text entry elements are INPUT and
TEXTAREA elements. Note that the events fired by this event may not be
as you'd expect. In particular, we don't fire any keyboard or mouse
events. If you want to ensure keyboard events are fired, consider
using something like sendKeys(CharSequence) with the backspace key. To
ensure you get a change event, consider following with a call to
sendKeys(CharSequence) with the tab key.
Most likely you simply need to call:
emailField.sendKeys("gmail.com");
emailField.clear();
But if you need the clearing to be done via the keyboard for some reason, use Keys.BACKSPACE.
keys.DELETE can not work to delete the input text,you should use keys.BACKSPACE.
emailField.sendKeys(Keys.BACKSPACE)
From the JavaDoc for Keys.chord
chord(java.lang.CharSequence... value)
Simulate pressing many keys at once in a "chord".
You should be able to use
emailField.sendKeys(Keys.chord(Keys.CONTROL,"a",Keys.DELETE));
Tested in chrome driver
WE.send_keys(' \b')
This will add space then delete it (backspace)
I use in javascript and it's working fine:
await textBox.sendKeys(value);
await textBox.sendKeys(Key.BACK_SPACE);
emailField.sendKeys(Keys.BACKSPACE)
doesn't worked for me .
I used 'Key' instead of 'Keys'
emailField.sendKeys(protractor.Key.BACKSPACE)
emailField.sendKeys(Keys.CONTROL + "a",Keys.DELETE);
In PHP:
if you use php-webdriver (https://github.com/php-webdriver/php-webdriver) you must:
use Facebook\WebDriver\WebDriverKeys AS Keys;
.
.
.
$this->driver->findElement(By::id('demo'))->sendKeys([Keys::BACKSPACE,'Any other text']);
Just adding another working C# example using the Google Chrome webdriver.
SendKeys only takes one parameter so created a string with the Crtl + A. This code sequence will select the current text in the field then delete the text.
Code example:
var crtlA = Keys.Control + "a";
driver.FindElement(By.XPath("//div[3]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/span/input")).SendKeys(crtlA); Wait(5000); // Select current text
driver.FindElement(By.XPath("//div[3]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/span/input")).SendKeys(Keys.Delete); Wait(5000); // Clear current text
driver.FindElement(By.XPath("//div[3]/div[1]/div[2]/div/div[2]/div[2]/div/div/div[1]/div/span/input")).SendKeys(newItemSku); Wait(5000); // Input SKU name
1. in WebdriverIO, i tried to edit the text by clear text (which contains special charactes like #, +, _) in text field by below following step. Eventhough it was not successful.
example: text=> abc+1234#gmail.com
step1:browser.clearElement(selector);
step2:browser.execute(function () {
document.querySelector(>>>Cssselector<<<).value="";
});
step3: browser.doubleClick(selector);
browser.keys("Delete");
step4: browser.click(selector);
browser.keys(['Meta',a]);
browser.keys('Meta');
browser.keys('Delete');
Note: below step is resolved this issue.
var count= browser.getAttribute(selector, value).length;
for (var i=0;i<count;i++)
{
if (browser.getAttribute(selector, value)=='')
break;
}
else
{
browser.doubleClick(selector);
browser.keys("Delete");
}
browser.pause(200);
// it will clear your text field easily.
Note:
You can add the new text now.

Symfony CMF RoutingBundle - PHPCR Route Document - Multiple Parameters

Tried to find a solution, but I got always stuck a the docs or at answers include other bundles. In the documentation of the dynamic router you can find the hint:
"Of course you can also have several parameters, as with normal Symfony routes. The semantics and rules for patterns, defaults and requirements are exactly the same as in core routes."
Thats it.
...
/foo/{id}/bar
I tried (seems not) everything to get it done.
Same for all tries:
I tried it to apply a variable pattern and a child route.
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route as PhpcrRoute;
$dm = $this->get('cmf_routing.route_provider');
$route = new PhpcrRoute();
$route->setPosition( $dm->find( null, '/cms/routes' ), 'foo' );
$route->setVariablePattern('/{id}');
$dm->persist( $route );
$child = new PhpcrRoute();
$child->setPosition( $route, 'bar' );
$dm->persist( $child );
$dm->flush();
With or without default value and requirement only '/foo/bar' and '/foo/*' return matches, but '/foo/1/bar' prompts me with a 'No route found for "GET /foo/1/bar"'.
...
Just now I nearly got it done.
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route as PhpcrRoute;
$dm = $this->get('cmf_routing.route_provider');
$route = new PhpcrRoute();
$route->setPosition( $dm->find( null, '/cms/routes' ), 'example_route' );
$dm->persist( $route );
$route->setPrefix( '/cms/routes/example_route' );
$route->setPath( '/foo/{id}/bar' );
$dm->flush();
If prefix is '/cms/routes' and name is 'foo' everything works fine. But now that I got this far, assigning a speaking name would round it up.
Thanks in advice!
You got quite close to the solution, actually!
When using PHPCR-ODM, the route document id is its path in the repository. PHPCR stores all content in a tree, so every document needs to be in a specific place in the tree. We then use the prefix to get a URL to match. If the prefix is configured as /cms/routes and the request is for /foo, the router looks in /cms/routes/foo. To allow parameters, you can use setVariablePattern as you correctly assumed. For the use case of /foo/{id}/bar, you need to do setVariablePattern('/{id}/bar'). You could also have setVariablePattern('/{context}/{id}') (this is what the doc paragraph you quoted meant - i will look into adding an example there as its indeed not helpful to say "you can do this" but not explain how to).
Calling setPath is not recommended as its just less explicit - but as you noticed, it would get the job done. See the phpdoc and implementation of Model\Route::setPattern:
/**
* It is recommended to use setVariablePattern to just set the part after
* the static part. If you use this method, it will ensure that the
* static part is not changed and only change the variable part.
*
* When using PHPCR-ODM, make sure to persist the route before calling this
* to have the id field initialized.
*/
public function setPath($pattern)
{
$len = strlen($this->getStaticPrefix());
if (strncmp($this->getStaticPrefix(), $pattern, $len)) {
throw new \InvalidArgumentException('You can not set a pattern for the route that does not start with its current static prefix. First update the static prefix or directly use setVariablePattern.');
}
return $this->setVariablePattern(substr($pattern, $len));
}
About explicit names: The repository path is also the name of the route, in the example /cms/routes/foo. But it is not a good idea to use a route name of a dynamic route in your code, as those routes are supposed to be editable (and deletable) by an admin. If you have a route that exists for sure and is at a specific path, use the configured symfony routes (the routing.yml file). If its dynamic routes, have a look at the CMF Resource Bundle. It allows to define a role for a document and a way to look up documents by role. If you have a route with a specific role that you want to link to from your controller / template, this is the way to go. If you have a content document that is linked with a route document and have that content document available, your third and best option is to generate the URL from the content document. The CMF dynamic router can do that, just use the content object where you normally specify the route name.

Drupal 7 hook_node_access not allowing "deny"?

I created a simple module:
function hook_node_access($node, $op, $account)
{
return NODE_ACCESS_DENY;
}
It does block the access to the node, but I get this error when visiting that page:
Notice: Trying to get property of non-object in node_node_access() (line 3089 of \www\modules\node\node.module).
This line reads:
3088. function node_node_access($node, $op, $account) {
3089. $type = is_string($node) ? $node : $node->type;
So basically, when I do this, $node is NOT a string, but also doesn't have a "type" value. I can only imagine that $node is a blank object when it hits this part of the code. But why?
UPDATE
I did a var_dump of the "node" object and I believe this is the contents:
int(436)
So, somehow the node id is getting pushed into this function, but not the node, AND the is_string function is not picking up that it's a string (because it isn't, it's an INT).
Any ideas?
UPDATE 2:
What makes all of these really bad for me, is that even though I'm logged into Drupal as a user that does not have access to these nodes, they still see them if they go to /node and scroll through the pages.
Am I missing something, because surely hook_node_access should block the nodes from being seen at /node ?
When implementing Drupal hooks, you should always replace 'hook' with your custom module name. For example:
function mymodule_node_access($node, $op, $account)
{
return NODE_ACCESS_DENY;
}
Also, you will need to clear out the Drupal cache each time you implement a new hook by going to admin/config/development/performance

More clarity needed on the usage assertText() function?

I have written automation test cases for my application.Below is the sample code i have used for web testing.
class UserWebTestcase extends CakeWebTestCase{
var $name='UserWebTestcase';
function testLogin001()
{
//Test if new user registration form works as intended when all the inputs are given properly.
$this->get(Configure::read('url'));
$this->setField('email', 'admin45#gmail.com');
$this->setField('tmppassword', 'admin123');
$this->setField('password_confirm', 'admin123');
$this->clickSubmit('SUBMIT');
$this->assertText('login');
}
}
In test case it always gives false even though the inputs for fields are correct.The error i got like this
(Failed
C:\xampplite\htdocs\spotchase\app\tests\cases\models\user.test.php -> UserWebTestcase -> testLogin001).
Im really confused while using the assertText() method.How should i use this assertText() method and what parameters should i pass to this method. Please help.
this is not a cakephp method, but a simpletest one.
below is the actual method
/**
* Will trigger a pass if the text is found in the plain
* text form of the page.
* #param string $text Text to look for.
* #param string $message Message to display.
* #return boolean True if pass.
* #access public
*/
function assertText($text, $message = '%s') {
return $this->assert(
new TextExpectation($text),
$this->_browser->getContentAsText(),
$message);
}
So it seems that it is just looking for the actual text within the page, not a button or other element. maybe 'welcome bob' would be a better search

Resources