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

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 ?

Related

Use content of a tuple as variable session

I extracted from a previous response an Object of tuple with the following regex :
.check(regex(""""idSc":(.{1,8}),"pasTemps":."codePasTemps":(.),"""").ofType[(String,String)].findAll.saveAs ("OBJECTS1"))
So I get my object :
OBJECTS1 -> List((1657751,2), (1658105,2), (4557378,2), (1657750,1), (916,1), (917,2), (1658068,1), (1658069,2), (4557379,2), (1658082,1), (4557367,1), (4557368,1), (1660865,2), (1660866,2), (1658122,1), (921,1), (922,2), (923,2), (1660875,1), (1660876,2), (1660877,2), (1658300,1), (1658301,1), (1658302,1), (1658309,1), (1658310,1), (2996562,1), (4638455,1))
After that I did a Foreach and need to extract every couple to add them in next requests So we tried :
.foreach("${OBJECTS1}", "couple") {
exec(http("request_foreach47"
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
.headers(headers_27))
}
But I get the message : named 'couple' does not support index access
I also though that to use 2 regex on the couple to extract both part could work but I haven't found any way to use a regex on a session variable. (Even if its not needed for this case but possible im really interessed to learn how as it could be usefull)
If would be really thankfull if you could provided me help. (Im using Gatling 2 but can,'t use a more recent version as its for work and others scripts have been develloped with Gatling2)
each "couple" is a scala tuple which can't be indexed into like a collection. Fortunately the gatling EL has a function that handles tuples.
so instead of
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
you can use
.get("/ctr/web/api/seriegraph/bydates/${couple._1}/${couple._2}/1552863600000/1554191743799")

ControlPath equivalent from DotNetNuke DnnApiController ActiveModule

Is there a way to get the module root folder (folder under DesktopModules) of the ActiveModule from a DnnApiController?
In PortalModuleBase I would use the ControlPath property to get to the same root folder I'm looking for.
As #MitchelSellers points out, it doesn't appear to be in the API so you have to figure it out yourself.
Since the API gives us the ActiveModule which is a ModuleInfo that's probably the best way to get at it.
If your modules use a pretty standard consistent naming then the following "best guess" method should work pretty well
public static string ControlPath(ModuleInfo mi, bool isMvc = false)
{
return isMvc
? $"/DesktopModules/MVC/{mi.DesktopModule.FolderName}"
: $"/DesktopModules/{mi.DesktopModule.FolderName}";
}
The other way is to look at the ModuleDefinitions of our module and grab the first ModuleControl and look at it's ControlSrc to see it's path.
public static string ControlPath(ModuleInfo mi)
{
var mdi = mi.DesktopModule.ModuleDefinitions.First().Value;
var mci = mdi.ModuleControls.First().Value; // 1st ModuleControl
return Path.GetDirectoryName(mci.ControlSrc);
}
The second method is really messy (and untested) but should give you the actual folder path where the controls are installed, over the other best guess method above.
From the API's it doesn't appear so, you should know the path for this though since you are inside of your module, the only concern is if you are inside of a child portal you need the prefix, which you should be able to get. I'd just use Server.ResolveClientUrl() to get it.

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.

How can i achieve dictionary type data access in Chromium embedded CEF1

I would like to achieve dictionary like data pattern that can be accessed from the
java script. Something like this:
pseudo Code:
for all records:
{
rec = //Get the Record
rec["Name"]
rec["Address"]
}
I am trying to achieve with CefV8Accessor, but i am not getting near to the solution.
Kindly provide few links for the reference, as i see the documentation is very less from chromium embedded.
If I understand correctly, you're trying to create a JS "dictionary" object for CEF using C++. If so, here's a code snippet that does that:
CefRefPtr<CefV8Value> GetDictionary(__in const wstring& sName, __in const wstring& sAddress)
{
CefRefPtr<CefV8Value> objectJS = CefV8Value::CreateObject(NULL);
objectJS->SetValue(L"Name", sName, V8_PROPERTY_ATTRIBUTE_NONE);
objectJS->SetValue(L"Address", sAddress, V8_PROPERTY_ATTRIBUTE_NONE);
return objectJS;
}
The CefV8Accessor can also be used for that matter, but that's only if you want specific control over the set & get methods, to create a new type of object.
In that case you should create a class that inherits CefV8Accessor, implement the Set and Get methods (in a similar way to what appears in the code above), and pass it to the CreateObject method. The return value would be an instance of that new type of object.
I strongly suggest to browse through this link, if you haven't already.

Drupal 7 Views Contextual Filters Title Override

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.

Resources