How to set routing when index document by ElasticsearchTemplate? - spring-data-elasticsearch

I am using ElasticsearchTemplate to index document into Elasticsearch. Now I have to set custome routing, however, I don't find how to set route in ElasticsearchTemplate.
I am using spring-data-elasticsearch-3.2.0.M4 to support RestClient.
List<IndexQuery> queries = new ArrayList<IndexQuery>();
IndexQuery e = new IndexQuery();
e.setIndexName(map.get("index"));
e.setSource(map.get("source"));
if(map.get("id")!=null) {
e.setId(map.get("id"));
}
queries.add(e );
if(queries.size()>1000) {
esTemplate.bulkIndex(queries);
}
I can find index,type,id,version,source etc in IndexQuery although I didn't find route field in IndexQuery. Does it not support route Or what am I missing ?

No, at the moment this is not supported. I created a Jira issue for this. Pleas feel free to vote or implement.

Related

TYPO3 - Retrieved TypoScript in itemsProcFunc are incomplete

I have following problem:
We are overriding the tt_content TCA with a custom column which has an itemsProcFunc in it's config. In the function we try to retrieve the TypoScript-Settings, so we can display the items dynamically. The problem is: In the function we don't receive all the TypoScript-Settings, which are included but only some.
'itemsProcFunc' => 'Vendor\Ext\Backend\Hooks\TcaHook->addFields',
class TcaHook
{
public function addFields($config){
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
$setup = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
);
}
$setup is now incomplete and doesn't contain the full TypoScript, for example some of the static-included TypoScript is missing.
Used TYPO3 7 LTS (7.6.18), PHP 7.0.* in composer-mode.
Does anybody know where the problem is? Is there some alternative?
You maybe misunderstood the purpose of TypoScipt. It is a way of configuration for the Frontend. The Hook you mentioned is used in the TCA, whích is a Backend part of TYPO3. TypoScript usually isn't used for backend related stuff at all, because it is bound to a specific page template record. Instead in the backend, there is the TSConfig, that can be bound to a page, but also can be added globally. Another thing you are doing wrong is the use of the ObjectManager and the ConfigurationManager, which are classes of extbase, which isn't initialized in the backend. I would recommend to not use extbase in TCA, because the TCA is cached and loaded for every page request. Instead use TSConfig or give your configuration settings directly to the TCA. Do not initialize extbase and do not use extbase classes in these hooks.
Depending on what you want to configure via TypoScript, you may want to do something like this:
'config' => [
'type' => 'select',
'renderType' => 'singleSelect',
'items' => [
['EXT:my_ext/Resources/Private/Language/locallang_db.xlf:myfield.I.0', '']
],
'itemsProcFunc' => \VENDOR\MyExt\UserFunctions\FormEngine\TypeSelectProcFunc::class . '->fillSelect',
'customSetting' => 'somesetting'
]
and then access it in your class:
class TypeSelectProcFunc{
public function fillSelect(&$params){
if( $params['customSetting'] === 'somesetting' ){
$params['items'][] = ['New item',1];
}
}
}
I had a similar problem (also with itemsProcFunc and retrieving TypoScript). In my case, the current page ID of the selected backend page was not known to the ConfigurationManager. Because of this it used the page id of the root page (e.g. 1) and some TypoScript templates were not loaded.
However, before we look at the solution, Euli made some good points in his answer:
Do not use extbase configuration manager in TCA functions
Use TSconfig instead of TypoScript for backend configuration
You may like to ask another question what you are trying to do specifically and why you need TypoScript in BE context.
For completeness sake, I tested this workaround, but I wouldn't recommend it because of the mentioned reasons and because I am not sure if this is best practice. (I only used it because I was patching an extension which was already using TypoScript in the TCA and I wanted to find out why it wasn't working. I will probably rework this part entirely.)
I am posting this in the hope that it may be helpful for similar problems.
public function populateItemsProcFunc(array &$config): array
{
// workaround to set current page id for BackendConfigurationManager
$_GET['id'] = $this->getPageId((int)($config['flexParentDatabaseRow']['pid'] ?? 0));
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$configurationManager = $objectManager->get(BackendConfigurationManager::class);
$setting = $configurationManager->getTypoScriptSetup();
$templates = $setting['plugin.']['tx_rssdisplay.']['settings.']['templates.'] ?? [];
// ... some code removed
}
protected function getPageId(int $pid): int
{
if ($pid > 0) {
return $pid;
}
$row = BackendUtility::getRecord('tt_content', abs($pid), 'uid,pid');
return $row['pid'];
}
The function getPageId() was derived from ext:news which also uses this in an itemsProcFunc but it then retrieves configuration from TSconfig. You may want to also look at that for an example: ext:news GeorgRinger\News\Hooks\ItemsProcFunc::user_templateLayout
If you look at the code in the TYPO3 core, it will try to get the current page id from
(int)GeneralUtility::_GP('id');
https://github.com/TYPO3/TYPO3.CMS/blob/90fa470e37d013769648a17a266eb3072dea4f56/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php#L132
This will usually be set, but in an itemsProcFunc it may not (which was the case for me in TYPO3 10.4.14).

Is there a way in deployd to map a collection to a different endpoint?

I have a collection called customer_devices and I can't change the name. Can I expose it via deployd as /devices ? How?
There are a few ways that I can think of. If you really just want to rename the collection, you can do so from the dashboard, as #thomasb mentioned in his answer.
Alternatively, you can create a "proxy" event resource devices and forward all queries to customer_devices. For example, in devices/get.js you would say
dpd.customer_devices.get(query, function(res, err) {
if (err) cancel(err);
setResult(res);
});
Update
Finally, here is a "hack" to redirect all requests from one resource path to a different path. This is poorly tested so use at your own risk. This requires that you set up your own server as explained here. Once you have that, you can modify the routing behaviour using this snippet:
server.on('listening', function() {
var customer_devices = server.router.resources.filter(function (res) {
return res.path === '/customer_devices';
})[0];
// Make a copy of the Object's prototype
var devices = Object.create(customer_devices);
// Shallow copy the properties
devices = extend(devices, customer_devices);
// Change the routing path
devices.path = "/devices";
// Add back to routing cache
server.router.resources.push(devices);
});
This will take your customer_devices resource, copy it, change the path, and re-insert it into the cached routing table. I tested it and it works, but I won't guarantee that it's safe or a good idea...
Can't you change the name via dashboard?
Mouseover your collection customer_devices
Click the down arrow
Select 'Rename'
Enter the new name and click 'Rename'

Umbraco 7 mvc how to get current page id

I have a custom controller to send message. So I need to get the value of property field name and alias = "email", this will be used to send the email to.
this code below works
var id = umbraco.uQuery.GetNodeByUrl("/contact-us");
IPublishedContent root = Umbraco.TypedContent(id.Id);
return root.GetProperty("email", true).Value.ToString();
However the problem here is if the page name changes, the url will change and the code will break.
So how can I change the code above to get the current page id and insert it here (???);?
I think the code should be something like this:
IPublishedContent root = Umbraco.TypedContent(???);
return root.GetProperty("email", true).Value.ToString();
Any help will be apprecciated
Your solution will bring a problem if you have more than 1 'ContactUs' node, or none. Then you don't know which one is going to be get.
(Actually it's the first one found in the node tree, but then someone can change the order of them...)
Is your controller a Surface controller? You can just do this:
IPublishedContent currentNode = Umbraco.TypedContent(CurrentPage.Id)
Ok, I found the solution for my question.
var nodes = umbraco.uQuery.GetNodesByType("ContactUs");
if (nodes.Any())
{
IPublishedContent node = Umbraco.TypedContent(nodes.First().Id);
return node.GetProperty(property, true).Value.ToString();
}
Hope this will help somebody with the same problem.

Zend Framework 2 Get controller name from layout

I have the follow routes to different controllers and actions, that all shows the same layout and different views, example:
http://<my domain>/controllername1/action1
http://<my domain>/controllername1/
http://<my domain>/controllername2/action1
http://<my domain>/controllername3/action1
How can I get the controller name that loads the Layout in the Layout code?, something that returns: "controllername1", "controllername2" or "controllername3"
The goal is to identify in which section I'm of my site and make some customization in layout.
I checked similar replies but are for old versions of Zend Framework.
Clarification:
The idea is to get the controller name from the Layout code, not pass it from the controller code. Maybe isn't possible? Other answers are for older versions of ZendFramework (beta versions), and maybe is a more straightforward way now.
Edited: more information
I can set in my Module.php file the follow code on onBootstrap($e):
public function onBootstrap($e)
{
// (...) Other code
$application = $e->getParam('application');
$viewModel = $application->getMvcEvent()->getViewModel();
// Parsing URI to get controller name
$viewModel->controllerName = trim($_SERVER['REQUEST_URI'],'/');
if (substr_count($viewModel->controllerName, '/')) {
$viewModel->controllerName = substr($viewModel->controllerName, 0, strpos($viewModel->controllerName, '/'));
}
}
And then from the Layout code use it as follow:
echo $this->layout()->controllerName;
The first problem is that the follow piece of code should be replaced with something (more "beautiful") using ZF2 functions to get Controller name:
(...)
// Parsing URI to get controller name
$viewModel->controllerName = trim($_SERVER['REQUEST_URI'],'/');
if (substr_count($viewModel->controllerName, '/')) {
$viewModel->controllerName = substr($viewModel->controllerName, 0, strpos($viewModel->controllerName, '/'));
}
I want to avoid inject the Controller name from all controllers/actions: that is solved by using Module.php, but maybe is a more direct way.
Thanks!
You're looking for this link: How to get the controller name, action name in Zend Framework 2
$this->getEvent()->getRouteMatch()->getParam('action', 'index');
$this->getEvent()->getRouteMatch()->getParam('controller', 'index');
Otherwise you have the same question (and answer(s)) here : ZF2 - Get controller name into layout/views
MvcEvent – get NAMESPACE / Module Name from Layout
http://samsonasik.wordpress.com/2012/07/27/zend-framework-2-mvcevent-layout-view-get-namespace/
I didn't test but it seems correct : http://pastebin.com/HXbVRwTi
I know that this is an old question but there is a simple answer that should be noted here:
$this->getHelperPluginManager()->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getParam('action')
this will return any route param, 'action' in this case.
This code can be used in view or in layout.

How to get the comments of a JIRA issue in a custom release note template

We upgraded our jira to version 5.0.5 today, before we were running version 4.2.4. In that version we had made a custom release notes template that would also show all comments made on an issue. To do that we had to be able to get a CommentManager object. We did this like this:
#foreach ($issue in $issueType.issues)
#if($issueType.issues.size() > 0)
#set ($comments = $action.ComponentManager.CommentManager.getComments($issue))
#if ($comments)
#foreach ($comment in $comments)
...
That worked fine in JIRA 4.2.4 however it isn't working anymore in jira 5.0.5, does anyone know how i can get a CommentManager object again when creating a custom release notes template in JIRA 5.0.5 or how to get a CommentManager object some other way, without using $action for example?
In your vm template, write this:
#set ($componentAccessorClass = $constantsManager.getClass().getClassLoader().findClass('com.atlassian.jira.component.ComponentAccessor'))
#set ($componentAccessorConstructor = $componentAccessorClass.getConstructor())
#set ($componentAccessor = $componentAccessorConstructor.newInstance())
Now you have access to the Component Accessor which can get you pretty much anything you want, including the Comment Manager.
Now, all you have to do is call getCommentManager() on your Component Accessor variable.
#set($commentManager = $componentAccessor.getCommentManager() )
Hope that helps ! :)
JiraWebActionSupport has the following deprecated method that provided the component manager object.
#Deprecated
public ComponentManager getComponentManager()
{
return ComponentManager.getInstance();
}
and https://developer.atlassian.com/display/JIRADEV/Creating+a+Custom+Release+Notes+Template+Containing+Release+Comments
has some Velocity code but looking at the 5.0.1 source it looks like Velocity is no longer being used?
I would file an Improvement at https://jira.atlassian.com/browse/JRA to add a getCommentManager method to JiraWebActionSupport.java
this is the way i used in jira to get a componentmanager object, once you have the componentmanager object it's rather easy to do the rest:
#set ($componentManagerClass = $constantsManager.getClass().getClassLoader().findClass('com.atlassian.jira.ComponentManager'))
#set ($method = $componentManagerClass.getDeclaredMethod('getInstance', null))
#set ($componentManager = $method.invoke(null, null))
i'm using this solution now, and it can be rather helpfull to others to almost get any kind of class using the constantsmanager.

Resources