Add a new view in Openart(4) module - opencart

In Opencart(4) I am developing a new extension called "testimonials". Created the testimonials and working fine. Now I need to add a new page in the module. So I created a folder named "pages" inside the module's admin template and created a new template file inside it.Also added a function called "showTestPage()" to show the newly created page.
My controller file looks like
...
public function showTestPage(){
$this->load->language('extension/testimonials/module/testimonials');
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput($this->load->view('extension/testimonials/module/testimonials/pages/test', $data));
}
When I tried to access the new page using the following url, its showing a permission denied error. Already checked all permissions in "User Group".
http://localhost/op4/admin/index.php?route=extension/testimonials/module/testimonials/showTestPage&user_tok...
Did I missed any steps ? Any idea ?

for the function path in controller do not use slash /
http://localhost/op4/admin/index.php?route=extension/testimonials/module/testimonials/showTestPage&user_tok...
use vertical bar | because framework in OC 4.0.x.x is changed...
http://localhost/op4/admin/index.php?route=extension/testimonials/module/testimonials|showTestPage&user_tok...

Related

How to set Joomla template for user/visit

I want to use specific Joomla template (with no navigation, no top and bottom) for users that connect to website through my mobile app with iframe in it. I assume that this users will start connection from specific address with tmpl param (or something similar) but is there a way to lock this template for these users?
Maybe there is some plugin to set template in session data and override default template choice?
There is a Joomla extension called Template Assigner - http://extensions.joomla.org/extension/template-assigner . It does exactly what you want.
Plugin allows me to set template only for specyfic user group, not to switch template accordingly to url but thanks to Your idea I created very simple plugin to do this, code below:
defined('_JEXEC') or die;
class plgSystemMobiler extends JPlugin
{
public function onAfterInitialise()
{
$app = JFactory::getApplication();
$jinput = $app->input;
if (isset($_REQUEST['mobile'])) $par=(int)$_REQUEST['mobile'];
if (isset($par)) $jinput->cookie->set('mobile', $par, time() + 100000, $app->get('cookie_path', '/'), $app->get('cookie_domain'), $app->isSSLConnection());
$cookie=$jinput->cookie->get('mobile');
if (intval($cookie)>0) JFactory::getApplication()->input->set('templateStyle', intval($cookie));
}
}

Using wildcard route matching in FW/1

I am trying to use the wildcard match on routes in FW/1 v 3.5.
Application.cfc
component extends="framework.one" {
this.name= "Wildcard7";
variables.framework = {
home = 'main.home',
action = 'fuseaction',
baseURL = 'useCgiScriptName',
trace = isDebugMode()
};
variables.framework.routes = [
{ "main/home" = "main/home"},
{ "*" = "main/404"}
];
}
When I run the page, without specifying an action, I get the main/404 page instead of main/home
** FW/1 trace**
How can I get main/404 to run only on invalid pages?
When I run the page, without specifying an action, I get the main/404 page instead of main/home
I assume you are trying to access the page like so - your.domain/index.cfm/main. Note the lack of the home action.
Based on your routes, your first route is saying if the path supplied equals "main/home" then point to the view main/home. If there is an action of home in a main.cfc controller then that will be ran prior to rendering the view.
Leaving off the action, home, would not match any of your current routes; resulting in your wildcard catching it. You would need to handle it by including another route like {"main" = "main"}.
UPDATE:
To access main/home from your.domain/index.cfm, you can try passing a route of {"/" = "main/home"}. I would suggest this being above your wildcard and below any other routes to avoid any freak matches.

How to create a dynamic source for a multilist in Sitecore?

I have the following content tree structure:
Home
Products
Product A
Product B
Organizations
Org 1
Org 2
Org Config X
Org Config Y
Each Organization beneath Organizations has a field called "Associated Products" which is a multilist. This tells the system which Products go with each Organization. The Org Config data template has a field called "Selected Products". When I add a new Org Config content item (which always lives directly beneath an Organization) I would like to be able to restrict the items that are displayed in the "Selected Products" field (which is a multilist) to only display Products that are already associated with the parent Organization. I am thinking there might be a way to do this with Sitecore Query but I can't figure it out. Any ideas?
With the help of Sitecore I figured it out. Basically you have to create a custom control that inherits from MultilistEx. Then you need to override the DoRender() event. Before you call base.DoRender() you must change the source (this.Source) to use a Sitecore query. Previously I was trying to do it in the OnLoad event. So my code now looks like this:
public class CustomMultiList : MultilistEx
{
private void ExcludeItems()
{
...custom code here that builds a list of Item IDs to exclude from the Multilist source...
...list should look like this "##id != 'some guid' and ##id != 'some guid' and so forth...
...you could also build a list of item ids to include. Any Sitecore query will do...
...you can use this.ItemID to get a reference to the current item that is being edited in the Content Editor...
this.Source = "query:" + this.Source + "/*[" + myListOfItemIdsToExclude + "]";
}
protected override void DoRender(output)
{
this.ExcludeItems();
base.DoRender(output);
}
}
I think you'll probably need to create a custom field for this. Here's some articles related to the subject:
http://www.sitecore.net/unitedkingdom/Community/Best-Practice-Blogs/Martin-Knudsen/Posts/2012/09/Creating-a-custom-Sitecore-Field.aspx
http://gettingtoknowsitecore.blogspot.co.uk/2010/03/custom-fields-part-1.html
http://sitecoreblog.blogspot.co.uk/2012_04_01_archive.html

How to generate media item link with id instead of path in Sitecore

Anyone knows how to generate links in sitecore with ID instead of item path?
If you use GetMediaUrl method from the API, I can get this URL:
/~/media/Images/Archive/content/News and Events/News_and_Events_Level2/20070419162739/iwhiz3.jpg
The problem with this approach is that if someone changes the media item name, removes it somewhere or deletes it, the above link will break.
I notice if I insert a media link from rich text editor, I get the link as below:
/~/media/14BDED00E4D64DFD8F74019AED4D74EB.ashx
The second link is better because it's using the item id, so if the actual media item is renamed, removed, or deleted, all related links will be updated too. On top of that, when Sitecore renders the page, it will actually convert the above link and display the item path so it's readable.
I'm using Sitecore 6.5 and currently doing content migration so I need to make sure all internal links are updated properly.
May I know if there is a method to generate the second link by using sitecore API?
Thanks!
The GetMediaItemUrl extension method seems to give you what you want.
public static class ItemExtensions
{
public static string GetMediaItemUrl(this Item item)
{
var mediaUrlOptions = new MediaUrlOptions() { UseItemPath = false, AbsolutePath = true };
return Sitecore.Resources.Media.MediaManager.GetMediaUrl(item, mediaUrlOptions);
}
}
[TestFixture]
public class when_using_items_extensions
{
[Test]
public void a_url_based_on_media_item_id_can_be_generated()
{
// Arrange
Database db = global::Sitecore.Configuration.Factory.GetDatabase("master");
Item item = db.GetItem("/sitecore/media library/Images/MyImage");
// Act
var mediaUrl = item.GetMediaItemUrl();
// Assert
Assert.That(mediaUrl, Is.EqualTo("/~/media/17A1341ABEEC46788F2159843DCEAB03.ashx"));
}
}
These are called dynamic links and you can normally generate them using the LinkManager e.g:
Sitecore.Links.LinkManager.GetDynamicUrl(item)
.. but I'm not sure of the method to do this with Media links (there probably is one but I cant seem to find it and its not on MediaManager) but the basic syntax is:
"/~/media/" + item.ID.ToShortID() + ".ashx"
If you always want to use ID's instead of paths, you can change this setting in webconfig to false (like this):
<setting name="Media.UseItemPaths" value="false"/>`
Here is what the webconfig describes about it:
MEDIA - USE ITEM PATHS FOR URLS
This setting controls if item paths are used for constructing media URLs.
If false, short ids will be used.
Default value: true
Then you can use the default implementation (without additional parameters):
Sitecore.Resources.Media.MediaManager.GetMediaUrl(item);
This is what I use:
var imgField = ((Sitecore.Data.Fields.ImageField)currentItem.Fields["Icon"]);
MediaUrlOptions opt = new MediaUrlOptions();
opt.AlwaysIncludeServerUrl = true;
// Absolute Path works as well. So either use AbsolutePath or AlwaysIncludeServerUrl
opt.AbsolutePath = true;
string mediaUrl = MediaManager.GetMediaUrl(imgField.MediaItem, opt);

EventReceiver not Firing on SharePoint List

I am trying to create an EventReceiver for a blog site (for the Posts list) and am having some trouble getting it working. I want to change the Created By column to Anonymous. Basically I have this whole thing working in a console application, however, that will only change the Created By column names when the console application is executed.
I need it to change the Created By whenever a new item is added to the list. My code is below....how do I modify this to use in an EventReceiver project??? Since I already tell the EventReceiver project the URL I want the EventReceiver attached to, I'm not sure what I can remove from this code, right now it just doesn't do anything, no error and no changing of the Created By column when I debug.
using (SPSite site = new SPSite("http://test-sharepoint/subsite/"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["Posts"];
SPListItemCollection listItemCollection = list.Items;
foreach (SPListItem listItem in listItemCollection)
{
SPFieldUserValue userName = new SPFieldUserValue(web, 22, "Anonymous");
listItem["Author"] = userName;
listItem["Editor"] = userName;
listItem.Update();
}
web.Update();
}
}
EDIT: Code is in ItemAdded method
EDIT #2: This is trying the same code except without the loop and using properties.ListItem, this was my attempt in a Event Recevier project but no luck. It just doesn't change the Created By field, or any field for that matter (I tried the Title as well)
SPSite site = new SPSite("http://test-sharepoint/subsite/");
SPWeb web = site.OpenWeb();
SPFieldUserValue userName = new SPFieldUserValue(web, 22, "Anonymous");
properties.ListItem["Author"] = userName;
properties.ListItem["Editor"] = userName;
properties.ListItem.Update();
*Also from my understanding the SPFieldUserValue will grab either a User or a SharePoint User Group (Permissions) so in my code, the 22 grabs the SharePoint User Group that I want and "Anonymous" is the user from that group...
EDIT #3: More progress, this code works without issues for a list, however, not for the Posts or Comments lists, for those it does not change the Created By field. Could it be because of the approve/reject for all items??? Whether approved orpending it still does not show annonymous, BUT like I mentioned, it works fine in a different list.
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
SPSite site = new SPSite("http://test-sharepoint/hr/blog/"); //SPContext.Current.Site;
SPWeb web = site.OpenWeb();
SPFieldUserValue userName = new SPFieldUserValue(web,22,"Anonymous");
SPListItem currentItem = properties.ListItem;
//currentItem["Title"] = userName; //DateTime.Now.ToString();
currentItem["Author"] = userName;
currentItem["Editor"] = userName;
currentItem.SystemUpdate();
}
**EDIT #4: Alright I found my issue, when creating the project I chose Custom List as my list to attach to but I needed to choose Posts or Comments and now the above code works!!!
But now I have another problem, all posts on the blog are first submitted for approval...and due to this the event receiver doesn't seem to work for users other than the admin. It works fine for the admin account where I can just directly publish a post or comment but for a user with Contribute permissions whose posts are submitted for approval still shows their name on the Manage Posts page...what could I do about this? Any ideas?**
The code that works:
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
SPSite site = new SPSite("http://test-sharepoint/hr/blog/"); //SPContext.Current.Site;
SPWeb web = site.OpenWeb();
SPFieldUserValue userName = new SPFieldUserValue(web, 23, "Anonymous");
SPListItem currentItem = properties.ListItem;
currentItem["Author"] = userName;
currentItem["Editor"] = userName;
currentItem.SystemUpdate();
}
In response to edit #4, when working with SharePoint, if code works when executed by the administrator account, but does not work when executed by a "normal" account, permissions are likely to blame.
See the answer to the question SharePoint/WSS: Modify “created by” field? for an example of an SPItemEventReceiver that modifies the Author field.
Note: Many SharePoint developers recommend against the use of RunWithElevatedPrivileges and suggest using impersonation instead. See my answer to the question In which situation use SPSecurity.RunWithElevatedPrivileges with superusertoken? for more details.