Drupal 8 | Wrong alias used - drupal

Bonjour,
I have a problem on Drupal 8 that I can't solve, that's why I'm calling on you.
I have 2 aliases for the same node :
/public/event/10
/pro/event/10
I have a block_1 that only appears on the " /public/* " pages and a block_2 on the " /pro/* " pages.
When I access to the url "/pro/event/10", block_1 is displayed and not block_2.
I conclude that Drupal selects the alias "/public/event/10" (probably the first one he finds) while I'm on the page "/pro/event/10".
How can I programmatically tell Drupal the right alias to use?
Thank you in advance for your help.

Here is the code if it can help someone
class OOutboundPathProcessor implements OutboundPathProcessorInterface
{
function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL)
{
// Only for nodes
if (!isset($options['entity_type']) OR $options['entity_type'] !== 'node')
{
return $path;
}
// Get current 'space'
$espace = \Drupal::service('session')->get('espace');
// Get the node to process
$node = $options['entity'];
// New path
$str_path = "/%s/%s/%s";
$new_path = sprintf($str_path, $espace, $node->bundle(), $node->id());
// Check new path
$isValid = \Drupal::service('path.validator')->isValid($new_path);
if ($isValid === true) return $new_path;
return $path;
}
}

You might want to create your own path_processor_outbound service by implementing OutboundPathProcessorInterface.
This implementation may work on /node/{id} paths if the current requests path matches /public/event/** or /pro/event/**.
Analyzing the node entity for it's type (bundle): If it is event generate and return your desired path; if it is not event don't manipulate the path and return the original.
Writing the actual implementation in PHP code may be your own pleasure ;-)

Related

Not able to get organization form node in alfresco

Using Alfresco Community 5.0.d and not able to get organization from node.
File: pickerresults.lib.js
Method: createPersonResult(node)
function createPersonResult(node)
{
var personObject =
{
typeShort: node.typeShort,
isContainer: false,
properties: {},
displayPath: node.displayPath,
nodeRef: "" + node.nodeRef
}
// define properties for person
personObject.properties.userName = node.properties.userName;
// defining new property for the personObject but
// but not getting any value
personObject.properties.companyname = (node.properties["cm:organization"] ? node.properties["cm:organization"] : "");
personObject.properties.companyname = (node.properties.organization ? node.properties.organization : "");
return personObject;
}
Override the pickerresults.lib.js file by copying it to location as below.
/Applications/alfresco-5.0.d/tomcat/shared/classes/alfresco/extension/templates/webscripts/org/alfresco/repository/forms/pickerresults.lib.js
how could I get organization name?
also how could I debug the node properties like logger.log is there but does not work here.
Thanks.
please try to get properties without extra "." in
node.properties.["cm:organization"]
like:
node.properties["cm:organization"]
please refer this doc link
http://docs.alfresco.com/4.0/references/API-JS-ScriptNode.html
properties
Provides access to all the properties of this node. The properties returned are accessed via an associative array. Properties of a node can be accessed in the following ways:
Example: node.properties["name"]
Example: node.properties.name
example i have tried:
var node =people.getPerson("admin");
logger.log(node.properties["cm:email"]);
logger.log(node.properties.email);

how to read additional parameters in alfresco 5.1.1- aikau faceted search

Custom Search UI will be populated when user selects Complex asset in the Advance search screen drop down(apart from Folders,Contents) where 12 fields will be displayed .So when user clicks search button ,need to read those values and redirect to the alfresco repo files(org/alfresco/slingshot/search/search.get.js).We have already customized these files(search.get.js,search.lib.js) existed in the repository to suit out logic and working fine in 4.2.2;As we are migrating to 511,so we need to change this logic in customized faceted-search.get.js to read these values.How to write this logic in customized facted-search.get.js?
It's not actually possible to read those URL hash attributes in the faceted-search.get.js file because the JavaScript controller of the WebScript does not have access to that part of the URL (it only has information about the URL and the request parameters, not the hash parameters).
The hash parameters are actually handled on the client-side by the AlfSearchList widget.
Maybe you could explain what you're trying to achieve so that I can suggest an alternative - i.e. the end goal for the user, not the specifics of the coding you're trying to achieve.
We will be reading the querystring values something like below in the .get.js file.
function getNodeRef(){
var queryString = page.url.getQueryString();
var nodeRef = "NOT FOUND";
var stringArray = queryString.split("&");
for (var t = 0; t < stringArray.length; t++) {
if (stringArray[t].indexOf('nodeRef=') > -1) {
nodeRef = stringArray[t].split('=')[1];
break;
}
}
if (nodeRef !== "NOT FOUND") {
nodeRef = nodeRef.replace("://", "/");
return nodeRef;
}
else {
throw new Error("Node Reference is not found.");
}
}
It may be help you and we will wait for Dave Drapper suggestion also.

Send Gravity Forms data to redirection page

I have a very simple form created with Gravity Forms;
It submits two numbers and then redirects to a different result page.
How do I retrieve those two numbers on the result page?
add_filter("gform_confirmation_4", "custom_confirmation", 3, 4 );
function custom_confirmation($confirmation, $form, $lead, $ajax)
Gives a custom confirmation. Each field value can be retrieved by using $lead[{field ID}]
I have a solution for this based on using a combination of form submission hooks and the GForms API. It's a horrible plugin so I apologise for the messiness of the logic flow. It's important to use the framework methods rather than processing the data yourself since there are a good amount of hacks and shonky things going on in there to correctly match field IDs and so forth.
I will provide a solution to pass a submission from one form to pre-populate another. Changing the destination for POST data is pretty straightforward, they have an example for it on their gform_form_tag hook documentation page. Yes, that really is the only way of doing it.
Without further ado here is the code. I've set it up to work off form configuration to make things simpler for the end user, so it works like this:
Select "allow field to be populated dynamically" in your destination form field's advanced settings and choose a parameter name for each.
Add matching CSS classes on the source fields of the other form(s) to setup the associations.
Add a CSS class to the source forms themselves so that we can quickly check if the redirection is necessary.
.
$class = 'GForms_Redirector';
add_filter('gform_pre_submission', array($class, 'checkForSubmissionRedirection'), 10, 1);
add_filter('gform_confirmation', array($class, 'performSubmissionRedirection'), 10, 4);
abstract class GForms_Redirector
{
const SOURCE_FORMS_CLASS_MATCH = 'submission-redirect';
const DEST_PAGE_SLUG = 'submit-page-slug';
const DEST_FORM_ID = 1;
protected static $submissionRedirectUrl;
// first, read sent data and generate redirection URL
function checkForSubmissionRedirection($form)
{
if (false !== preg_match('#\W' . self::SOURCE_FORMS_CLASS_MATCH . '\W#', $form['cssClass'])) {
// load page for base redirect URL
$destPage = get_page_by_path(self::DEST_PAGE_SLUG);
// load form for reading destination form config
$destForm = RGFormsModel::get_form_meta(self::DEST_FORM_ID, true);
$destForm = RGFormsModel::add_default_properties($destForm);
// generate submission data for this form (there seem to be no hooks before gform_confirmation that allow access to this. DUMB.)
$formData = GFFormsModel::create_lead($form);
// create a querystring for the new form based on mapping dynamic population parameters to CSS class names in source form
$queryVars = array();
foreach ($destForm['fields'] as $destField) {
if (empty($destField['inputName'])) {
continue;
}
foreach ($form['fields'] as $field) {
if (preg_match('#(\s|^)' . preg_quote($destField['inputName'], '#') . '(\s|$)#', $field['cssClass'])) {
$queryVars[$destField['inputName']] = $formData[$field['id']];
break;
}
}
}
// set the redirect URL to be used later
self::$submissionRedirectUrl = get_permalink($destPage) . "?" . http_build_query($queryVars);
}
}
// when we get to the confirmation step we set the redirect URL to forward on to
function performSubmissionRedirection($confirmation, $form, $entry, $is_ajax = false)
{
if (self::$submissionRedirectUrl) {
return array('redirect' => self::$submissionRedirectUrl);
}
return $confirmation;
}
}
If you wanted to pass the form values someplace else via the querystring then you'd merely need to cut out my code from the callback and build your own URL to redirect to.
This is a very old question, now you can send it using a Query String on the confirmation settings.
They have the documentation on this link:
How to send data from a form using confirmations
Just follow the first step and it will be clear to you.

Cannot implicitly convert type 'System.Linq.IQueryable to System.Data.Entity.DbSet<>

I receive the following error when I try to run my code. I haven't managed to solve it yet, please Help:
edit: Marked with * where it fails.
>
public IQueryable<Video> GetVideos([QueryString("id")] int? categorieId)
{
var _db = new TeleviziuneAcademicaAspSilverlight.Models.VideoContext();
IQueryable<Video> query = *_db.Videos;*
if (categorieId.HasValue && categorieId > 0)
{
query = query.Where(v => v.CategorieID == categorieId);
}
return query;
Change
IQueryable<Video> query =
to
IQueryable<Appname.Models.Video> query =
The reason for your error is that you have the type Video defined twice and because of using a short type name you accidentally reference not the one Video you should.
Also change it in the method's return value
public IQueryable<Appname.Models.Video> GetVideos( ... )
You seem to have two classes called Video. If you need both, you'll need to project from one to the other before your return statement:
return query.Select(dbVideo => new Appname.Video()
{
Prop1 = dbVideo.Prop1,
Prop2 = dbVideo.Prop2,
// etc.
});
Though you'll probably need to change the return type to an IEnumerable<> if you do that.
If you can just work with Appname.Models.Video, change IQueryable<Video> to IQueryable<Appname.Models.Video> in the method signature and the method body.

How should I get and set a folder's group and user permission settings via Core Service?

I can get strings representing group and user permissions for a given folder with the following.
Code
// assumes Core Service client "client"
var folderData = client.Read("tcm:5-26-2", new ReadOptions()) as FolderData;
var accessControlEntryDataArray =
folderData.AccessControlList.AccessControlEntries;
Console.WriteLine(folderData.Title);
foreach (var accessControlEntryData in accessControlEntryDataArray)
{
Console.WriteLine("{0} has {1}",
accessControlEntryData.Trustee.Title,
accessControlEntryData.AllowedPermissions.ToString());
}
Output
Some Folder
Everyone has Read
Editor has None
Chief Editor has None
Publication Manager has None
Interaction Manager has None
T2011-CB-R2\areyes has All
[scope] Editor 020 Create has Read, Write
T2011-CB-R2\local1 has Read, Write, Delete
[rights] Author - Content has None
Seems like the four possible values for `AllowedPermissions are:
None
Read
Read, Write
Read, Write, Delete
All
This works great for my use case to create a folder permissions report. I can .Replace() these to a familiar notation (e.g. rw-- or rwdl).
But is manipulating these string values the right approach to set permissions as well? I'd imagine I'd want objects or maybe enums instead. Could someone point me in the right direction?
Also I noticed I get some, but not all non-applicable groups set as None. I don't specifically need them here, but I'm curious at what determines whether those get returned--did I miss something in my code?
Rights and Permissions are enums, indeed. You can set using the method below. If you want to set multiple rights you should do something like "Rights.Read | Rights.Write"
Keep in mind that this method will return you object that you have to save \ update \ create after
public static OrganizationalItemData SetPermissionsOnOrganizationalItem(
OrganizationalItemData organizationalItem,
TrusteeData trustee,
Permissions allowedPermissions,
Permissions deniedPermissions = Permissions.None)
{
if (organizationalItem.AccessControlList == null)
{
organizationalItem.AccessControlList
= new AccessControlListData
{AccessControlEntries = new AccessControlEntryData[0]};
}
var entries = organizationalItem.AccessControlList
.AccessControlEntries.ToList();
// First check if this trustee already has some permissions
var entry = entries.SingleOrDefault(
ace => ace.Trustee.IdRef == trustee.Id);
if (entry != null)
{
// Remove this entry
entries.Remove(entry);
}
entries.Add(new AccessControlEntryData
{
AllowedPermissions = allowedPermissions,
DeniedPermissions = deniedPermissions,
Trustee = new LinkToTrusteeData { IdRef = trustee.Id }
});
organizationalItem.AccessControlList.AccessControlEntries
= entries.ToArray();
return organizationalItem;
}

Resources