title: Documentation for Shine PDF

text:
# Question
Title: Documentation for Shine PDF
I'm using Shine PDF for on the fly pdf creation for ExpressionEngine. Documentation is a dead link. My questions:

1. Does anyone know where I can get the documentation? OR
2. has any one tried and tested another PDF generator? (a free one please)

Help appreciated.

# Answer
> 4 votes
**Shine PDF Documentation**

Shine PDF uses the mPDF library to generate a PDF on-the-fly from an ExpressionEngine template.

At its core, Shine PDF is simply a tag pair that accepts channel:entries parameters and outputs entry data accordingly:

```
{exp:shine_pdf:make channel="good" url_title="vibes"} ... {/exp:shine_pdf:make}

```

...but let's take a closer look at just what the mPDF library can do with your templates.

**OUTPUTTING HEADERS AND FOOTERS**

Everything between the bespoke `{pdf_header}{/pdf_header}` and `{pdf_footer}{/pdf_footer}` tag pairs will be extracted from the document and placed in the header and footer areas of every PDF page.

Listen very carefully - any ExpressionEngine data held between these tags will be parsed only once.

**SPECIAL TAGS**

No, these are not standards compliant. At all. However, neither is PDF, so you're quite safe.

`<pagebreak/>` \- Does exactly what it says on the tin - if you're exporting via a WYSIWYG editor you might want to consult the Oracle on how to add custom elements to the editor's formatting toolbar. This is definitely doable with Wygwam (CKeditor) and TinyMCE. Note that this tag is self-closing.

`[page]` \- Prints the current page number.
`[total_pages]` \- Prints the number of pages in the entire document, beginning at 1.

**PARSING CSS**

Just add any CSS files you deem relevant somewhere between the `{exp:shine_pdf:make}` tag pair.

Don't worry about where they are in the code - as mentioned above, we're not relying on any doctype-related standards rules.

**METADATA**

Simply write the document's title in a

`<title></title>` HTML tag pair. Other metadata options to follow.

**PAGE FORMATTING**

This is likely what you've been waiting for. mPDF provides a number of page formatting options, all of which are voluntary. The default document produced comprises portrait-formatted, A4 (210mm x 297mm) pages, with left & right margins of 15mm and top & bottom margins of 16mm. Tag options (and their defaults) are listed below. Units default to millimetres for canvas measurements, and to points for typographical sizes.

Please bear in mind that none of these tags is compulsory, and any & all can be ommitted from the module tag pair as you wish. Please note also that all parameters that can be supplied to the `{exp:channel:entries}` tag pair can be supplied to the `{exp:shine_pdf:make}` tag pair.

```
{exp:shine_pdf:make
    format="A4"
    default_font_size="11"
    default_font="Helvetica"
    margin_left="15"
    margin_right="15"
    margin_top="16"
    margin_bottom="16"
    margin_header="9"
    margin_footer="9"
    orientation="p"
    margin_top_auto="no"
    margin_bottom_auto="no"
}

```

**PARAMETERS UP CLOSE**

**format**

A0, A1, A2, A3, A4 (default), A5, A6, A7, A8, A9, A10
B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10
C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10
4A0, 2A0
RA0, RA4
SRA0, SRA1, SRA2, SRA3, SRA4
Letter, Legal, Executive, Folio Demy
Royal A (Type A paperback 111x178mm), Royal B (Type B paperback 128x198mm)

**default\_font\_size**

Any size in points. Numerical value only. This is the font size that will be defaulted to if none is specified by your CSS.

**default\_font**

Helvetica, Times or Courier accepted. In order to provide a failsafe, please ensure that any custom fonts specified within your CSS are stored locally on your machine as well and referenced by their default family names. The realms of web font embedding remain enemy territory to this day.

**margin\_left**

The left page margin in millimetres. Numerical value only.

**margin\_right**

The right page margin in millimetres. Numerical value only.

**margin\_top**

The top margin down to the page's body content, in millimetres. Numerical value only. If a header is set and margin\_top\_auto is set to "no", ensure that this margin takes into account the height of the header.

**margin\_bottom**

The bottom margin up to the page's body content, in millimetres. Numerical value only. If a footer is set and margin\_bottom\_auto is set to "no", ensure that this margin takes into account the height of the footer.

**margin\_header**

The header's margin from the top of the page in millimetres. Numerical value only, and only pertinent if a header is set.

**margin\_footer**

The footer's margin from the bottom of the page in millimetres. Numerical value only. Only relevant if a footer is set.

**orientation**

Accepts "portrait" or "landscape".

**margin\_top\_auto**

`pad` \- The value for `margin_top` will be used to set a fixed distance between the bottom of the header and the top of the document body.

`stretch` \- The value for `margin_top` sets a minimum distance between the top of the page and the top of the document body.

`no` (default) - `margin_top` and `margin_header` need to be specified explicitly in order for the page to display correctly. If both of the above options do not work for you, rest assured this one will.

**margin\_bottom\_auto**

As above, except applies to the relationship between the footer and the bottom of the document.

**CAVEATS**

All conditionals in your PDF template will only be parsed inside the `{exp:shine_pdf:make}` tag pair.

Also, you will not be able to use `{embed}` tags within the template. Not that they should really be necessary.

# Answer
> 0 votes
Shine PDF no longer appears to work as of EE 2.9.2. For a simple free replacement resource I'd recommend PrintFriendy, https://devot-ee.com/add-ons/printfriendly

---
Tags: plugin
---


# Question
Title: How Do You Kll EE's 40-Headed Error-Reporting Dagon?
Tbe main think I love about errors not displaying them on the screen viewing production systems. My phone rings less, people are happier. Everything is logged, nothing to the screen. We have a great working relationship thoese errors and me

\****Except\**** one of our apps, called EE or \****ExpressionEngine\****.

The documentation is EllisLab's patented sleek, competent-looking airhead documentation It looks sounds great. If they would add the rest of the critical information then it would be good. No hint, except experience tells you, there are well known (but not to you) absolutely critical elements for getting the system work right. Not much is worse than doing a long process to a T, and your system is not working and no have idea why. Most of the these holes in the story are small, that is how they are forgotten and left out. Error handling from Ellis lab is the opposite of small. It is like the Jolly Green Giant, who smiles, but you don't want him overt for dinner, he is to freaking big. EllisLab's error handling is their way making themselves into a Komodo Dragon. The only thing you want from them both is the same thing: to go away and if you never see one or the other again, doesn't matter which, or if it's both, non-contact for the rest of your life will not be the cause of a problem.

If their documentatiin did not double as marketing material, the phony could get edited out. EllisLab's Error reporting documentation is excellent in making me think its all info will put me in control of my system. Error\_display on Error\_display off, sounds easy, display means to the screen so your turn it off, what else is there to know?

"Excuse me, but could tell if you know of any error-message pipelines in the area? Some people are getting error-messages in their water. It looks it would make them sick, "Oh, it's just a php notice.": But I turned those off in the php.ihi file! EE looks at me like that is supposed to mean something, and I it thought. I never was thinking no one should be able to override anything in the app but that comes with responsibility exercised poorly by Ellis lab. So who was begging for error handling that made it became such a big part of their systems? Ellis lab has some kind fetish for error handling. Like most fetishes, I don't care what people do, but when a fetish, no matter what it is, results in foreign goo on computer screens I am responsible for filling with pixel-perfect content, then i have a problem, because it makes my phone ring when I had made plans to move forward, not backward, fixing an unnecessaery broken error handler. The errors are not the problem it i the error handling, especially screen diplay

So my question is: How do you kill EE's 40-headed error-reporting dragon? there must be an addon to fix that parts that don't work but also are not needed.

# Answer
Umm index.php

```
/*
 * --------------------------------------------------------------------
 *  Error Reporting
 * --------------------------------------------------------------------
 *
 * PHP and database errors are normally displayed dynamically based
 * on the authorization level of each user accessing your site.
 * This variable allows the error reporting system to be overridden,
 * which can be useful for low level debugging during site development,
 * since errors happening before a user is authenticated will not normally
 * be shown.  Options:
 *
 *  $debug = 0;  Default setting. Errors shown based on authorization level
 *
 *  $debug = 1;  All errors shown regardless of authorization
 *
 * NOTE: Enabling this override can have security implications.
 * Enable it only if you have a good reason to.
 *
 */
    $debug = 0;

```
> 3 votes

---
Tags: error, php-errors, database-error, config-overrides
---


# Question
Title: Something wrong in Stash usage and cannot figure out what
I have this code

```
{exp:channel:entries channel="katalog" limit="12" dynamic="yes" status="open" show_future_entries="no" orderby="date" sort="desc" disable="member_data" pagination="bottom"}

{!-- if entry has one of those three categories then set variable link to true --}
{categories show="51|50|39"}
      {exp:stash:set_value name="link" value="true"}
{/categories}

{if "{exp:stash:get name='link'}" == "true"}
//then print content1
{if:else}
//print content2
{/if}

{!-- delete stash variable and go for next loop because channel entries will do this 12 times --}
{exp:stash:unset name="link"}

{/exp:channel:entries}

```

what happens is this. If first entry in pagination has some category, then stash variable will be set to true for all 12 entries shown on that pagination page. Likewise, if first entry does not have any category added to itself then variable link will not be set to "true" and other part of if condition will be displayed.

How to make stash to overwrite it's values ... what am I doing wrong? I need categories for this problem, but I am not sure what else to use.

# Answer
> 1 votes
You probably don't need to use stash in this case, and could test if in the categories within the conditional:

```
{if "{categories show='51|50|39' limit='1'}yes{/categories}" == "yes"}
    //then print content1
{if:else}
    //print content2
{/if}

```

Another variation is to use a category count plugin in the same way (in place of the native categories tags above).

---
Tags: channel-entries, stash, entries, variable
---


# Question
Title: Override the Cartthrob license key generation process
Is there a way to override the Cartthrob license key generation process? Currently Cartthrob just defaults to a UUID, but we have a more in-depth license generation process that is required for our project. I can probably hook into `cartthrob_on_authorize`, but am wondering if there is a better way.

# Answer
There is no way to override the built-in key generation. I would recommend turning it off in the settings (by leaving the License Number field mapping empty in the Purchased Items channel). And then using the `cartthrob_on_authorize` hook.

```
foreach (ee()->cartthrob->cart->order('purchased_items') as $entry_id) {
    // generate your own license key
    //$key = ?

    // save the key to the DB, where XXX is your Purchased Items' license number field ID
    ee()->db->update('channel_data', array('field_id_XXX' => $key), array('entry_id' => $entry_id));
}

```
> 0 votes

# Answer
No I think creating your extension and hooking that event is the right way forward. This sort of thing is why they put hooks in there after all, do you think that hook will be too late, i.e. after UUID generation?
> 0 votes

---
Tags: cartthrob
---


title: Adding an action to happen at Login

text:
# Question
Title: Adding an action to happen at Login
I am not new to expression engine but the question i have returns no answers in google.

I need to:

@ the time of successful login \- do something outside of expression engine (various external requirements)

Ideally i would like to add an include/function(php/sql) at the right place to run at the time of successful login each new login.

I could achieve this by `if {logged_in}`.

But this is not really the solution i had hoped for.

Is there a place where i can add to the login-complete part of expression engine?

If so, where is it / is there documentation for this?

# Answer
I think you are looking for the session\_start hook.

https://ellislab.com/expressionengine/user-guide/development/extension\_hooks/global/session/index.html#id2
> 1 votes

---
Tags: php, login
---


title: Add Drag/Drop Confirmation to Assets

text:
# Question
Title: Add Drag/Drop Confirmation to Assets
It would be nice to have a config option to control a confirmation dialog before performing a drag and drop operation. There would ideally be two options: one that controls the dialog for folder moves and one that controls the dialog for file moves. When a folder or file is dragged/dropped, a dialog would ask the user to confirm his or her intentions.

While I can't consistently reproduce it, there are times where folders are accidentally dragged/dropped. This appears to occur most often when Assets is busy trying to load its thumbnails and you go to click a different folder. It's as if the first folder selection hasn't released yet, so Assets tries to drop it on the newly selected folder, things go crazy, and now there's an accidental drag/drop.

# Answer
This is a pretty simple hack if you're interested in this functionality. You can add your `confirm()` JavaScript to (in Assets 2.3.2) lines 791 (for folder confirmation) and 1057 (for file confirmation) in expressionengine/themes/third\_party/assets/scripts/assets.js. Then, minimize assets.js to assets.min.js to apply the changes.

```
@@ -788,8 +788,8 @@
                    $('> a.assets-fm-expanded + ul', this.folderDrag.$draggee).show();

                     // Only move if we have a valid target and we're not trying to move into our direct parent
-                   if (
-                        this.folderDrag.$activeDropTarget
+                   if (confirm('Are you sure you want to move the selected folder(s)?')
+                        && this.folderDrag.$activeDropTarget
                         && this.folderDrag.$activeDropTarget.siblings('ul').find('>li').filter(this.folderDrag.$draggee).length == 0)
                    {

@@ -1054,7 +1054,8 @@

                onDragStop: $.proxy(function()
                {
-                   if (this.fileDrag.$activeDropTarget)
+                   if (confirm('Are you sure you want to move the selected file(s)?')
+                        && this.fileDrag.$activeDropTarget)
                    {
                        // keep it selected
                        this.fileDrag.$activeDropTarget.addClass('assets-selected');

```
> 1 votes

---
Tags: assets, feature-request
---


# Question
Title: Freeform Pro - display form results for user to print after submission
I am going to setup a Freeform Pro form on a website to replace a downloadable PDF form. The user will still need to print the form results off, so after a user fills out the large form and submits I want to display the results on a page or in a popup window that the user can then print. But I don't want that page to be accessible to the general public, so maybe it has a obfuscated URL that is time-sensitive or something. Any ideas about how to do this? Thanks for any info!

# Answer
The more recent versions of EE (I think \> 2.7) use CSRF in their forms by default so you automatically get a time sensitive submitted page.

If you want to be more explicit and if the above doesn't work for you (i.e. earlier version of EE), I would add a hidden form field (which Freeform allows) and auto-populate it with a unique value - either a timestamp (epoch seconds) or md5 hash - both of these are standard features in PHP. Then the results page just queries the form entries using that unique identifier in the URL. If you use a timestamp you can make access to the submitted form data even tighter by using the value and adding, say 3600 (1 hour in seconds) after which time the view to the submitted form expires.

Good luck.
> 3 votes

---
Tags: solspace-freeform, solspace
---


# Question
Title: Dealing with Localized/Fixed Dates in EE Module
So I'm working on a module that requires it's own tab in the EE Control Panel edit/publish pages. One of the fields in the module's tab is a date picker.

I've got the module saving the date to my module's DB as well as repopulating the date when editing an entry. However I'm not sure what to do with the "Localized/Fixed" dropdown that appears after the date picker.

**How do I save and repopulate whether the user has selected "Localized" or "Fixed"?**

Thanks in advance!

# Answer
The built-in Localize class documentation will help you here. It is used like this:

```
ee()->localize->now

```

Take a look at your EE source code in many of the core files - one example is the `libraries/Template.php` file - you will see lots of usage of the line of code above. EE handles this internally so you most likely don't need to worry about it.

**EDIT 1: Look at the EE source code for the date fieldtype**

If you look at the following file `fieldtypes/date/ft.date.php` that will show you how to use the Localize class. You need to modify the `$data` array that is saved. Look at the following methods:

* **save**
* **grid\_save:** Look for the `$this->settings['localize'] !== TRUE`
* **display\_field:** That shows you how to pull the localized string (if set)
* **grid\_display\_settings:** Look for the `$data['localize']` var

This is a concrete example of exactly what you are trying to do (based on your question). You might want to just *subclass* the Date fieldtype and add your own customizations where needed - that way your plugin will stay in-line with the Ellis Lab development of the Date field (i.e. future proof it to some degree). Good luck.
> 0 votes

---
Tags: module
---


# Question
Title: expressionengine does not display template page when logged out
in my project i have a products list page and when you click on each product you see the single project page, i have this structure in many projects and working fine, but in this project the single product page displays only when i'm logged in, very weird. i checked admin panel and couldn't find any option for template login or logout permission. my project list url is `mysite.com/projects` and my single project page is `mysite.com/project/project-1`

i don't know what's the problem.

# Answer
Can you check your Template **Access** permissions? These are documented in detail here : https://ellislab.com/expressionengine/user-guide/cp/design/templates/edit\_template.html#access

Also, perhaps you can confirm what version of EE you are running?

Finally, I note from your URL's you are using Freindly URL's, not a problem but can you confirm your routing settings for the single product pages? Also, the state of your Strict URL settings in EE please?
> 0 votes

---
Tags: templates, login, ee, logout
---


# Question
Title: Uncaught TypeError: $.ee_filemanager.toggle_all is not a function
I encountered this bug in a clean install of EE2.9.3, using MSM. I commented out the $.ee\_filemanager.toggle\_all in 'themes/compressed/cp/files/file\_manager\_home.js'.

Is this a bug? Or something I did wrong during installation?

# Answer
This was a bug, and was fixed in 2.10: https://support.ellislab.com/bugs/detail/20866/javascript-error-in-cp-file-manager
> 2 votes

---
Tags: ee2, file-manager, bug, ee2.9.3
---


# Question
Title: Display entry title related to (channel images) image if exists
I have a channel named Projects, and within that channel i have a 'channel images' field (p\_feature). It allow the user to upload one image, and if they do so that image will appear on the Home page as part of a carousel slider. ..So a 'feature' image is not uploaded for every Project entry, but only the ones the user wants featured on the home page.

Below is how the html looks:

```
<div class="slider-wrapper theme-default">
<div class="ribbon"></div>

 <div id="slider" class="nivoSlider">
  <img src="1.jpg" data-thumb="1.jpg" alt="" title="#htmlcaption1"  />
  <img src="2.jpg" data-thumb="2.jpg" alt="" title="#htmlcaption2"  />
 </div>

 <div id="htmlcaption1" class="nivo-html-caption">Title 1 <a href="#">Link 1</a></div>
 <div id="htmlcaption2" class="nivo-html-caption">Title 2 <a href="#">Link 2</a></div>

</div>

```

The Captions appear below the slider div, and also link to the Project.
So my code produces the image, but i'm not sure how to produce the caption (project title & url) that relates to the feature image uploaded.

Plus because the captions (have to) appear outside of the slider div, do i have to open the channel entries tag again?

So something like this:

```
<div class="slider-wrapper theme-default">
<div class="ribbon"></div>

<div id="slider" class="nivoSlider">
 {exp:channel:entries channel="project"}
    {if p_feature}
    {exp:channel_images:images channel="project" entry_id="{entry_id}"}
      <img src="{image:url:carousel}" data-thumb="{image:url:carousel}" alt="" title="#htmlcaption{entry_id}" />
    {/exp:channel_images:images}
    {/if}
 {/exp:channel:entries}
</div>

 {exp:channel:entries channel="project"}
  {if p_feature}
    {exp:channel_images:images channel="project" entry_id="{entry_id}"}
        <div id="htmlcaption{entry_id}" class="nivo-html-caption">{title} <a href="/projects/{url_title}">Read More</a></div>
    {/exp:channel_images:images}
  {/if}
 {/exp:channel:entries}

</div>

```

Plus is there a way to 'automatically' add ascending numbers? I would need that for the #htmlcaption1, #htmlcaption2, #htmlcaption3 etc.

Any help is greatly appreciated!

UPDATE: Code has been updated with working solution.

# Answer
Yup, that's the way. I hope someone can post a better answer, but I have nivoSlider live on several sites, and here is my implemented code off of one of them:

```
<div class="slider-wrapper theme-light">
    <div class="ribbon"></div>
    <div style="width: 100%;" class="nivoSlider" id="slider" style="overflow: hidden">
        {exp:channel:entries channel="homepage_slider"}
            {if link}
                <a href="{link}"
                    {if target}
                        target="_self"
                    {if:else}
                        target="_blank"
                    {/if}
                    >
                    <img src="{image}" title="#nivo_htmlcaption{entry_id}"/>
                </a>
            {if:else}
                    <img src="{image}" title="#nivo_htmlcaption{entry_id}"/>
            {/if}
        {/exp:channel:entries}
    </div>
    {exp:channel:entries channel="homepage_slider"}
    <div id="nivo_htmlcaption{entry_id}" class="nivo-html-caption ">
        <div class="nivo-html-caption-headline slider-title">
            {if link}
                <a href="{link}"
                    {if target}
                        target="_self"
                    {if:else}
                        target="_blank"
                    {/if}
                    >
            {/if}
            {headline}
            {if link}
                </a>
            {/if}
        </div>
        <div class="nivo-html-caption-subtitle slider-subtitle">
            {if link}
                <a href="{link}"
                    {if target}
                        target="_self"
                    {if:else}
                        target="_blank"
                    {/if}
                    >
            {/if}
            {subtitle}
            {if link}
                </a>
            {/if}
        </div>
    </div>
    {if link}
        </a>
    {/if}
    {/exp:channel:entries}
</div>

```

It's basically what you already thought of. Two channel entry loops really doesn't cause a huge performance hit. Complicated parsing does but that isn't a big deal (especially if you use something like CE-Cache or CloudFlare, which you should if it's a heavy site with a lot of hits). As for ID's, just wing the entry\_id tag like I did, since it's unique anyways!

**Edit:**

That's a broken way to do that conditional, friend. Do this:

```
{if p_feature}
    <div>{p_feature} goes here</div>
{/if}

```

Here:

```
<div class="slider-wrapper theme-default">
    <div class="ribbon"></div>
    <div id="slider" class="nivoSlider">
    {exp:channel:entries channel="project" dynamic="no" limit="1"}
        {exp:channel_images:images entry_id="{entry_id}"}
        <img src="{image:url:carousel}" data-thumb="{image:url:carousel}" alt="" title="#htmlcaption-{entry_id}" />
        {/exp:channel_images:images}
    {/exp:channel:entries}
</div>

{exp:channel:entries channel="project" disable="categories|category_fields|member_data|pagination|trackbacks" limit="1"}
{if p_feature}
{exp:channel_images:images entry_id="{entry_id}"}
    <div id="htmlcaption-{entry_id}" class="nivo-html-caption" title="slide-{entry_id}">
        Dump whatever channel:images tags you want here.
        {title}
        <a href="/projects/{url_title}">
            Read More
        </a>
    </div>
{/exp:channel_images:images}
{/if}
{/exp:channel:entries}

```

Please refer to:

http://www.devdemon.com/documentation/tag/images/
> 1 votes

---
Tags: conditionals, channel-images
---


# Question
Title: Absolute Results returns one page count when cache is turned on
Anyone else seeing this issue?

This has been this way since at least 2.81 and I just upgraded to 2.92 and it's still happening

Heres what I have:

```
{exp:channel:entries channel="artworks" paginate="both" limit="36" orderby="artwork-end_year|artwork-viewing" sort="desc|asc" cache="yes" refresh="360"}
{if count == 1}
All ({absolute_results})
{/if}
{/exp:channel:entries}

```

This shows "All (36)"

While this:

```
{exp:channel:entries channel="artworks" paginate="both" limit="36" orderby="artwork-end_year|artwork-viewing" sort="desc|asc" cache="no" refresh="360"}
{if count == 1}
All ({absolute_results})
{/if}
{/exp:channel:entries}

```

This shows "All (239)"

I've cleared the cache a number of times but still get the same result? Any ideas?

# Answer
I can't replicate this locally, so I'm not sure it's a bug.

Is that all the code you're actually using to test this? Because if you don't include `{paginate}` tags, then `{absolute_results}` will always be the same (or less than) your `limit` parameter. (The existence of `{paginate}` tags is what actually triggers pagination.)

Add a `{paginate}` loop and see if this issue persist between cached and non-cached.
> 1 votes

# Answer
I am also seeing this issue on EE 2.9.2 as of May 5, 2015. I turned off Channel Caching
(**Admin \> Channel Administration \> Global Preferences \> Cache Dynamic Channel Queries?**) and it seems to have fixed the problem.

If you want to keep caching globally but remove it in a few cases like this one, you can add `cache="no"` as a parameter to the `exp:channel:entries` loop.
> 1 votes

---
Tags: cache
---


# Question
Title: couple Solspace Freeform multi-page form questions
I'm using the multi-page function of Freeform Pro for the first time and I have a couple questions.

* is it possible to have a "back to page X" button on other pages of the form that sends someone back to a previous page in the form? If I do it manually, it will take me to that page, but the data previously entered into the fields is gone.
* most of the fields in the form will be required. I setup inline errors and left a field empty to test. The page refreshed and displayed the error successfully, but I lost all the field date previously entered. Can the inline errors be displayed without removing all the data from fields, or will i have to rely on some JS error detection?

# Answer
> 2 votes
If you're using Freeform's custom field variables such as `{freeform:field:FIELD_NAME}`, returning to a previous page should have its fields populated with previous data since the variable tries to retrieve this data. If your fields are manually-coded in HTML, the data isn't retrievable as easily, although the data should be available using `{freeform:mp_data:FIELD_NAME}`

This should answer both of your sub-questions. :)

---
Tags: solspace-freeform, solspace
---


# Question
Title: expression engine 2.7 channel form tag captcha isn’t working
I have 2 forms that are using the channel form tag, not Freeform, and the CAPTCHA isn’t working. I have made sure all of the preferences have been addressed and that all paths to any images are correct. I AM using a Freeform submission form on another page and the CAPTCHA works fine with the Freeform tag. Does anyone happen to have the same issue and can anyone help me find documentation on why the channel form tag isn’t displaying the CAPTCHA?

Thanks for any help in advance.

# Answer
I figured this out. I simply removed the {if captcha} and {/if} and it showed up. I tested it on desktop and mobile. I also made sure I got an error if all the fields were not filled out. It was the one thing I didn't try.

Our form is creating an entry in a testimonials channel and then outputting on the testimonials page. I have no idea why the example from the EE User Guide did not work but if you ever find yourself in this same scenario try this and it may work :)

(CAPTCHA DOCUMENTATION PAGE)
> 0 votes

# Answer
Are you logged in while viewing the form? Native EE CAPTCHAs don't display for Super Administrators.
> 2 votes

# Answer
For anyone with the same issue, make sure that you go to Admin \> Channel Administration \> Channel Form and then choose Yes for Guest Captcha for the relevant channel.
> 1 votes

---
Tags: channel-form, captcha
---


# Question
Title: Why is a Stash embed rendering within a "if no_reverse_related_entries" tag but a normal embed does not?
I am not sure if I have been staring at the screen too long today or what but I am having a major lapse in brain power. Here's the deal:

* I have a list of images that I relate to specific entries
* I use a reverse\_related\_entries tag to display the images on the related entry
* If an image does not have an entry associated with it I want to randomly pull an image from the images channel and display it on the entry view.

Here is the interesting issue. The {stash:embed} (that is commented out below) gets rendered in the "no\_reverse\_related\_entries" tag (when uncommented) but the normal EE {embed} does not render if there aren't any reverse related entries.

```
{exp:channel:entries
  channel="ch_pages"
  status="open"
  limit="1"
  {global:param_disable_default}
}

  {reverse_related_entries
    channel="ch_page_header_images"
    status="open"
    limit="1"}

    {if no_reverse_related_entries}
      {embed="test/random_header_image"}
      {!-- {stash:embed:includes:em_random_header_image} --}
    {/if}

    <img src="{cf_header_image:medium}" alt="{title}" width="390" id="Header-Image" role="img" />
  {/reverse_related_entries}

{/exp:channel:entries}

```

Stash embeds, unless tweaked with the "parse\_stage" parameter (and with the defaults in place), seem to be parsed like regular embeds in other area of the site (and per the Stash docs). Where am I going wrong here?

# Answer
> 0 votes
This is an interesting colundrum! At times like these i always refer to Low's EE Parse Order Document.

I think you are right that stash embed's *behave* like regular embeds, but they are not *parsed* at the same stage of the parse order. Embeds are parsed after module tags, remember that reverse related entries and channel entries are also technically module tags.

Can I ask, your regular embed, it doesn't actually call stash inside itself does it (i.e. have you tried with simple embed with some test markup in it?) One of the things that sticks in my head is this line from the Stash GitHub homepage :

Stash variables that you create are available to templates embedded below the level at which you are using the tag, or later in the parse order of the current template.

Me'thinks some parsing orde investigation is needed.

---
Tags: stash
---


title: Pre-populate shopping cart?

text:
# Question
Title: Pre-populate shopping cart?
Would there be a way in Expresso Store to pre populate a cart with certain products?

And even better, to populate the cart based on a link? E.g to send a link to a customer and when the customer clicks the link he is taken to the cart with products X, Y and Z already in the cart?

# Answer
> 0 votes
I would recommend populating an Expresso Add to Cart form (Docs), making the form elements hidden and styling the submit button to look like a link, seems the most straight forward way...

Here's an example from the Docs, that I have modified to suit. The below example will add 1 of every product in the channel entry loop :

```
{!-- start the product form --}
{exp:store:product_form}
  {!-- iterates the products channel --}
  {exp:channel:entries channel="products"}
    {!-- individual product form elements --}
    {exp:store:product entry_id="{entry_id}" disable_form="yes"}

      <input type="hidden" name="items[{count}][entry_id]" value="{entry_id}" />
      <input type="hidden" name="items[{count}][item_qty]" value="1" />

    {/exp:store:product}
  {/exp:channel:entries}

  {!-- Form submit, looks like a link --}
  <input type="submit" value="Add to Cart" style="background-color:transparent; text-decoration:underline; border:none; color:blue; cursor:pointer;" />

{/exp:store:product_form}

```

To select the products use the `entry_id` Tag on the `exp:channel:entries` loop.

If you wanted to go 'off the reservation' you could construct the post array in PHP and submit it to the relivent ACTion ID or Expresso Store Model function, put the code on a seperate template and link to that template, but thats another ball game, and Expresso probsbly won't recommend it!! :D

---
Tags: expresso-store, shopping-cart
---


title: Is there a way to "Refresh" Captcha?

text:
# Question
Title: Is there a way to "Refresh" Captcha?
Is there a way to refresh the Captacha value without having to reload the page? If so, how?

# Answer
> 2 votes
You'll need to use some ajax and create an endpoint, ergo refreshing just the captcha.

Fortunatly, once you have that in place actually creating a captcha is totally easy, there's a helper in the system but the function is also available via ee itself :

```
//create a captcha and return the HTML
$captchaHtml = ee()->functions->create_captcha();

```

https://ellislab.com/expressionengine/user-guide/development/usage/functions.html#create-captcha

---
Tags: captcha
---


# Question
Title: Templating in Postmaster / Templating in General (Super Simple)
I am trying to figure out how to simply post channel information in a Postmaster email template and for the life of me I cannot figure out why I cannot. Lets say I have a news channel. Why wont this work?

```
{exp:channel:entries channel="news" limit="10"}
  <h2>{title}</h2>
  {body}
{/exp:channel:entries}

```

I have tried this with many different template variables and I cannot tell if its postmaster or my template code failing.

# Answer
perhaps you need `dynamic="no"` in your channel entries tag?
> 0 votes

---
Tags: templates, postmaster
---


# Question
Title: Help on custom gateway for expresso store with omnipay
I'm trying to understand how to create a new off site payment gateway for Gestpay (Italy premiere Payment Gateway from banca Sella) in expresso store using omnipay library but I really need some guidance.

1) I've understand that I need to make an extension and I've seen the skeleton store\_check

2) I've read the "skinny" Build you own gateway on the omnipay website and the only thing I've understood is to look in the existing packages

3) I've looked in the existing packages and I've understand that I need a gateway.php that extends AbstractGateway and in that class I need to put needed parameters plus getters/setters and also the "charging" functions purchase() and completepurchase().

**here my understanding starts to fail...**

3.1) Ok to the parameters and getters/setters those are the parameters that are editable on Store Payment method configuration page

next there are some methods defined and I understand that purchase() function defines what to do to autorize and capture and that I need a completepurchase() function to handle return from of-site gateway

but next those "official" methods there are other functions in those gateways: for example fetchPaymentmethods() or fetchTransaction() etc etc that are not defined in the omnipay docs...

so I really don't understand if the "standardization" of omnipay is just to have purchase() and completepurchase() and than I can define any other method that I want/need

But also I don't understand who and where those fetch functions are being called

Please HELP!

**IMPORTANT**

I have also found this GitHub repo with all the code needed to make payments with gestpay but haven' managed to understand how to integrate it with omnipay (saddly a very good library with VERY POOR documentation)

# Answer
> 1 votes
You're on the right track. When I was first developing a payment gateway for Store, Adrian (who developed Store and Omnipay) told me this:

> Basically there is a Gateway class to create the requests, then a Request class for each different type of request. The simplest possible implementation would only need a gateway class, a PurchaseRequest class, and a Response class.

You can add anything else you need, like custom methods for manipulating/formatting data, or loading external libraries to handle parts of the request.

(If you want to take a look at a couple of custom gateways I wrote from knowing zero about how Omnipay works, check them out here and here \- though they are both for on-site gateways, and you say that your gateway is off-site, so the implementation may differ a little.)

As for the library you linked to, you'd want to bundle that code in your add-on, then include it, instantiate it, and use the results to tell the required Omnipay methods what to do.

As a starting point, I'd be looking at this example for an idea of what to do in your `purchase()` method, and this example for an idea of what to do in your `completePurchase()` method.

Hope that helps!

---
Tags: expresso-store, omnipay
---


title: Stash memory issue

text:
# Question
Title: Stash memory issue
So, I'm having a multilanguage one-pager website.

I'm opening with `{exp:stash:cache bundle="onepager_{segment_1}"}` so I can have a bundle for each onepager language.

On localhost, every language (in this case nl, de and fr) are getting their own bundle. In my live setup, the first one gets stashed rather quickly, but when I change my url from /nl to /fr for example, it takes ages and I get a memory exhausted error (`Fatal error: Allowed memory size of 201326592 bytes exhausted (tried to allocate 523800 bytes)`). When I refresh again, the fr bundle gets filled, but the nl bundle is gone.

Some important things to know, that might be of importance here. This website is using multi-site manager. Also, the onepager is using switchee. If segment\_2 is empty, it has `{stash:embed:layouts:one_pager}`, otherwise it has `{stash:embed:layouts:detail}`. If it's not, it shows a detail-page of an event. The reason I'm doing it this way, instead of having a different page-type, is multi-language stuff. Every detail-entry is having all fields for every language, rather then splitting it up. But since they're not in structure because of this (as I can not add a listing to a master page) I'm doing it like this.

So, the question is, am I doing something wrong here, or is my server not able to handle this?

Thanks!

EDIT: I changed my approach a bit. I made another page-type specifically for detail-entries and made a hidden page for it. This way, I made sure I only had logic for my onepage in my onepager page-type. Yet, the issue remains.

# Answer
> 0 votes
Well okay. This seemed to be the killer here: `{stash:embed file_name="snippets:document:html_footer_includes"}` rather than `{stash:embed name="snippets:document:html_footer_includes"}`.

So it's fixed, but I'd be good to know the difference between file\_name and name in this context :) And why it does work local, and exhausts my memory in production.

---
Tags: stash, multi-site-manager, memory-limit
---


# Question
Title: Error from YearList plugin: Non-static method Yearlist::usage() should not be called statically
I recently noticed that I was getting an error message from one of my plugins YearList. The page the error occurs on seems to function as expected despite the error, but I would like to resolve the error or at the very least hide it from view.

The error being displayed is:

```
Message: Non-static method Yearlist::usage() should not be called statically, assuming $this from incompatible context

```

And the error says it is occuring on this line of `pi.yearlist.php`

```
$plugin_info = array(
                 'pi_usage'         => Yearlist::usage()
               );

```

Any ideas?

# Answer
Fixed it by changing this line:

```
function usage()

```

To this:

```
public static function usage()

```

Source: https://support.ellislab.com/bugs/detail/20352/plugins-through-php-warning-with-strict-errors-on
> 8 votes

---
Tags: plugin
---


title: How to delete order?

text:
# Question
Title: How to delete order?
How do I delete an order (expresso store) in the control panel? I'd like to be able to delete the tests I'm doing. Even cmd+f "delete" on the pages turns up nothing.

# Answer
The order deletion functionality was removed in Store 2.5 - apparently in error - and will reportedly return in a forthcoming point release.
> 2 votes

---
Tags: expresso-store
---


# Question
Title: Channel displaying on more than one page
I've recently inherited a EE site. I'm a Joomla kid but that doesn't matter. The owner of this website has multiple channels (I guess that's what they're called, such as Residential, Commercial, etc). The channels (residential and commercial) are all showing up on one page, which is what they want. However, the "In Progress" channel is showing up on more than one page. I figured there has to be a simple setting to tell the channel how many entries on one page, sort of like Joomla, but can't seem to find it.

the site, if you want is www.newenglanddesign (.com).

# Answer
> 1 votes
I'm on my mobile so I can't be verbose, but I'd bet you have a channel entries tag living on your templates. They look like this:

```
{exp:channel:entries channel="news" limit="10"}
    {title}
{/exp:channel:entries}

```

You can set what channels get outputted with that channel param, and can put multiple channel names pipe separated.

```
channel="news|weather"

```

Check out the docs:

https://ellislab.com/expressionengine/user-guide/add-ons/channel/channel\_entries.html

---
Tags: channel, entry
---


# Question
Title: Comments Field Is Required Error when Implementing Comment Form
A very quick question, I'm trying to make a comment form but I get an error on submit that the Comment field is required, even though its filled in.

No Idea why as I checked other questions etc code seems fine.

```
          <div class="comment-form">
                <h3> Leave a comment </h3>
                {exp:comment:form channel="blog_post"}
                    <ol>
                        <li>
                            <label>YOUR NAME<span>*</span></label>
                            <input type="text" name="name" value="{name}" />
                        </li>
                        <li>
                            <label>YOUR EMAIL<span>*</span></label>
                            <input type="email" name="email" value="{email}" />
                        </li>
                        <li>
                            <label>YOUR WEBSITE</label>
                            <input type="text" name="url" value="{url}" />
                        </li>
                        <li>
                            <label>YOUR COMMENT<span>*</span></label>
                            <textarea name="comment">{comment}</textarea>

                        </li>
                        <li class="submit"><button type="submit">POST COMMENT</button></li>
                    </ol>
                {/exp:comment:form}
            </div>

```

Can you spot an error? Or maybe direct me the right direction?

Thank you in advance

# Answer
Here are some things that could cause this to fail:

1. Front-end caching such as Varnish or CloudFlare. Make sure that your cache layer is set to not cache URLs with a get parameter named ACT in them, for instance:

http://example.com/index.php?ACT=123

This is the URL format that is used to submit comments. The number will vary depending on the version of EE and other modules installed.

2. Request rewriting that removes POST values. This is fairly common with a few variations of .htaccess / index.php removal floating around. Again you need to make sure that any URL with an ACT get parameter is not rewritten.

If neither of these seem to be the case you can do some more debugging by placing var\_dump() calls in the insert\_new\_comment method of system/expressionengine/modules/mod.comment.php:

```
function insert_new_comment()
{
    $default = array('name', 'email', 'url', 'comment', 'location', 'entry_id');

    foreach ($default as $val)
    {
        if ( ! isset($_POST[$val]))
        {
            $_POST[$val] = '';
        }
    }

    // DEBUGGING
    echo '<pre>';
    echo 'POST:'.PHP_EOL;
    var_dump($_POST);
    echo 'SERVER:'.PHP_EOL;
    var_dump($_SERVER);
    exit;
    // END DEBUGGING

    ....
}

```

You should expect to see these variables populated in the post array, if not, something is removing the values:

* name
* email
* url
* comment
* location
* entry\_id

A few random thoughts:

Make sure the comment is plain text, if you somehow have a WYSIWYG field added to the front-end, this may be inserting markup that is being stripped by the XSS filter.

If you are running certain web servers other than Apache they may be applying security filtering to your form submission. You would need to refer to the server's manual to see how to fix the issue in this case.
> 1 votes

---
Tags: forms, comments, comment-form
---


# Question
Title: URL and Routing Issues, anything other than index gives 404
Hi I am fairly new to ExpressionEngine, but I am having an issue navigating from the Index Page. When ever I click on a link to view an entry it always gives me a 404 error.

I think it might be a configuration issue related to routing, but I am unsure. The message I get is as follows

> The requested URL /~Streel/EE\_Site/Shop/Test was not found on this server.

To my understand that structure is essentially the following:

> /~UserAccount/Website/Channel/Entry

Is that correct? Also what information do I need to supply to help debug this issue?

**Edit 1: Included Index Page**

Below is what I am having the issue with, this is pretty much from the EE Tutorial here

The Goal is to show all Shops and link directly to each shop

```
<body>
    <p>This is my test platform to see how formating works</p>
    <br/>
    {exp:channel:entries channel='shop'}
     <h3><a href="{url_title_path='shop'}">{title}</a></h3>
      <p>{brewery_description}</p>
      {/exp:channel:entries}

</body>

```

**Edit 2: More examples**

Whenever I navigate to a non-home page TemplateGroup or Template, I get 404; (Each Template has a Hello World content in the web page)

1. /~Streel/EE\_Site/Locations/new -\> 404 Response
2. /~Streel/EE\_Site/Locations -\> 404 Response

**Edit 3: Found a way to navigate**

including index.php works

/~Streel/EE\_Site/index.php/TemplateGroup/TemplateName works!

# Answer
Thanks for the feedback, let me break this down somewhat. Firstly we have the server aspect of the URL you're using, namely `/~Streel/EE_Site`

This part of your URL is clearly routing to a folder in your home directory, if this part is not working this is a server configuration issue and is technichally out of scope of this StackExchange (but we'll help where we can!).

The next part will be the EE Path, here `Shop/Test` are broken down into 2 segments, as per the EE docs, without any special routes ( Docs : Template Routes ) these segments map to `Template Group / Template Name`. This isn't what you're after though! What you want is `Channel/entry_url_title`.

Note : You may wish to check out how EE uses Dynamic Parameters as well, might get you there quicker! however for completeness...

Note : from here on in I'm assuming your E version is \> 2.9.3 so you have template routes!

No problem though, with the EE router we can set up a route on a template to handle this. For example lets set up a template in the Group called `Site` and a template called `EntryDisplay`.

Now lets edit the template and set the route. Here we go to the bottom, open up the "Access" section and in the "Template Route" field enter :

```
{desired_channel:alpha_dash}/{desired_entry:alpha_dash}

```

Also, Make sure 'Require All Segments' is set to 'Yes'. What we've done here is say if we have 2 segments (Shop and Test) and both are alpha\_dash valid, use this template. Of course tyou'll have to review the routing table in `Design -> Templates -> Template Route Manager` to ensure this route is the last on in the list, or it'll try to handle all your 2 segment URLS!

Now for the template itself, on the template your segment/route variables are turned into standard EE variables ( so `{segment:desired_channel}` & `{segment:desired_entry}`), we can feed these into the good old EE Channel Entries tag as so :

```
{exp:channel:entries channel="{segment:desired_channel}" url_title="{segment:desired_entry}" dynamic="no"}
  <h1>{title}</h1>
  {!-- here we send to 404 land if there's no entry for the URL supplied! --}
  {if no_results} {redirect="404"} {/if}
{/exp:channel:entries}

```

**Answer to Edit 1**

Thanks for the further info, just looking at the code (I have a sandbox test set up) I can see 2 things that might be going wrong.

First is if you aren't getting your template displayed at `/shop/`, if the template group this is in is not called Shop this will never work, however you can re-use what we learned about routing above, simply set your template route to `Shop` and thats it! You should get your template appearing at `/~Streel/EE_Site/Shop`

Second is potentually the output of `url_title_path` is not correct. Really I'd need to see the output however I spunthis up on my local and essentually what it does is output {base\_url} / {param1(shop)} / {url\_title}

Therefore if the path before /shop/ is incorrect, please review your `URL to the root directory of your site` setting in `Admin ->General Configuration`, this should be 'localhost/~Streel/EE\_Site'. If its the following parts, perhaps you can let us know the template group, template name and router setting so we can diagnose further...

**Edit 2**

Following investigation it appears the probelm was in fact using friendly URL's without having them set up. It seems the templates work fine when CStreel uses non freindly URL's i.e.

```
/~Streel/EE_Site/index.php/Shop/test

```

For info on setting up Freindly URL's, we refer again tothe EE docs : https://ellislab.com/expressionengine/user-guide/urls/remove\_index.php.html

Here's my working example, it uses a whitelist principle so for any paths you wish to exclude from the friendly URL handling (apart from files and directories see inline comments) add them to the final 2 RewriteCond's :

```
# Enable Rewrite Engine
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    #Exclude file paths
    RewriteCond %{REQUEST_FILENAME} !-f
    #Exclude directory paths
    RewriteCond %{REQUEST_FILENAME} !-d
    #Cant rcall what this excludes, Pagination maybe??
    RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
    #Specific files to exclude
    RewriteCond $1 !^(favicon\.ico|index\.php|path\.php|php\.ini|admin\.php) [NC]
    #Specific directories to exclude (bpath begins with)
    RewriteCond $1 !^(system|sysbase|images|themescss|assets)/ [NC]

    #If the current request is not excluded, insert the index.php
    RewriteRule ^(.*)$ /index.php/$1 [L]

</IfModule>

```

Finally, in order for EE to produce friendly url's from your tags, make sure to goto `Admin -> General Preferences` and set `Name of your site's index page` to '' (blank)
> 0 votes

---
Tags: channel-entries, templates, routing
---


# Question
Title: Does EE do anything fancy with 'smart' quotation marks and apostrophes? It seems to be doing so automatically and is breaking my site
When I add a Channel Entry with a title such as `John's Test Entry`, when EE outputs it to the template, it is outputting it as `John’s Test Entry`.

Notice the difference in the apostrophe? I've tried editing the entry - even in the database - to use a 'regular' apostrophe, but it always outputs like this.

I would like to disable this functionality in EE, as it is causing some internal PHP issues with some templates we are using. Is this possible?

Thanks!

# Answer
It's not going to help you specifically, but titles are put through a typography filter you have no control over. Maybe use the query module to access title data when generating your entries, that should bypass the filter because it's direct from the db.

I had the same issue in reverse. Client wanted proper typography but WYGWAM would strip them and they didn't want to lose the functionality WYGWAM gave them.

Had to add a core hack to WYGWAM ultimately.
> 1 votes

# Answer
The only thing it *might* do is encode the ' character into an entity - which is actually rather desirable behaviour in order to prevent issues outputting content.

Are you feeding the offending text to the PHP to be parsed in some way? i.e. it's *expecting* the ' character but getting the character entity instead?

If you are able to edit the PHP templates then you could do a str\_replace on the entity being created to turn it back into a '
> 0 votes

# Answer
As Steven vsaid, the Typography library in CodeIgnitor is whats transforming it to a curly quote. See the file `/system/codeigniter/system/libraries/Typography.php`, line 270 of the function `format_characters`.

You have 3 options :

1. Just enter the quote encoded in your title

Simple really, instead of typing `John's Test Entry` type `John's Test Entry`, this works a treat if you can manage having pre-encoded characters in your titles, when they are displayed in the CP they are displayed correctly anyway, its just editing the entry.

2. Use a string replace plugin or PHP on template to transform it

You can use a plug in like String Replace Exp, note that this will transform all right curly quotes, so if you are using legit opening closing single quotes you'll ruin these!

```
{exp:strrexp pattern="’" replace="'" string="{title}"}

```

Or turn PHP on (set to Output) and use (`str_replace`)\[http://php.net/str\_replace\] itself like this :

```
<?php echo str_replace("’","'","{title}"); ?>

```
3. Hack the Core <sup>**not recommended**</sup>

If your confident enougth go to work in the `Typography.php` file to suit your needs.

**Edit : And finally...**

In a rare expidition into accuracy, to answer the *exact* OP question... To **disable** the functionality (for titles only) you will need to **hack the core \[NOT RECOMMENDED\]**. To do this you'll need to open up `/system/expressionengine/modules/channel/mod.channel.php` goto line 4551 and patch as so :

```
-   $title = ee()->typography->format_characters($query->row('title'));
+   $title = $query->row('title');

```

Please be sure to add some other validation code though! although this is done at the display stage we still don't want anyone smuggling some unsafe text through via the Entry title!!!
> 0 votes

---
Tags: channel-entries, core
---


title: Custom data in user sesstion

text:
# Question
Title: Custom data in user sesstion
I'm new in Expression Engine, but have a good knowledge of codeigniter framework.

Idea is to store custom value in user session: geolocation data (City name) and put this value to input.

I wrote some javascript code, but it fires every time, when user loading page. I want to do it once and then retrieve location from user session.

I'm not sure that I need modify EE core modules. Is there any standart EE module, which handle user session globally at whole site?

# Answer
Thanks for the question feeedback, I beleive you have 2 options here, it's up to you which you feel is more graceful!

1. Utilise the Server side PHP/EE Session

For this solution, you'll need a special template that you'll call via AJAX, I normally use a template group called 'API', for example lets call the template 'location'.

On the template, we're going to create 2 modes, one that returns the saved field value and one that saves the field value. This is easy as what we can do is look for a post field and if present and correct set the sesion value, if there's no post then return the value.

For seculrity I'd add a check to ensure the request is an AJAX request (you can google this). Now, this template is going to be a PHP template but there's no reason you can't use EE tags and the plugins Nicholas suggests, but for simplicity I'm going to stick with native PHP.

So here's the process that I'd do :

1. Create JS that 'fetches' the saved value, if it's blank (not set yet, new session ect) then create the JS that 'sends' the value. Your JS will query the location object and get the value you want to save, and then AJAX Post it to your template.
2. In the template, use PHP to get the submitted value, be sure to clean it, and save it to the session :

```
//check AJAX request here

//are we getting or setting?
if ( empty ( $_POST ) ) {
    //assume this is the get, make more complex if you wish!
    if ( isset ( $_SESSION['savedvalue'] ) ) {
        echo json_encode(array(
            'savedvalue' => $_SESSION['savedvalue']
        ));
    } else {
        echo json_encode(array(
            'savedvalue' => ''
        ));
    }
} else {
    //were gonna set the value!!
    //use EE to fetch and clean the post
    $postedValue = ee()->input->post('valuename', true);
    //any extra validation here
    $_SESSION['savedvalue'] = $postedValue;
}

```

Thats it, at least in principle, hopefully you get the idea of what I'm doing here and can run with it...

2. Use a cookie on the client side

No need for a PHP template or anything fancy here, as we're not leaving the client side.

What we'll do is create similar JS to before but rather that making AJAX calls to the template (to push the value server side) we replace these calls with JS that sets the session cookie you want. You can use JS like this : http://blog.lysender.com/2011/08/setting-session-only-cookie-via-javascript/

There ya go, you should be able to get either to work for you, the beauty is that the AJAX requests have the PHP SESSION ID in them or at least send it back with the response so you don't need to worry about linking a session to a user. One thing to think about though is the logic to update the saved value if it ever changes, after all I might load your page on my laptop, leave it open, hop in the car, goto work and change location!

Drop us a comment if you have further questions, OR vote up/answer anything that helped you get what you needed...
> 0 votes

# Answer
1. Remember Me

> Save entries for a user during a session. This could be used for a 'add to cart' function or for a 'product compare' function (save entry\_id's for later use). Entries are only stored during a session. As of version 1.0 you can also save the session storage to the database on a per member basis.

2. Session Variables Plugin

> Sometimes you may want to temporarily store a variable for a short amount of time without writing a value to the database. ExpressionEngine's sessions do not allow this, however PHP's native sessions do.

3. You can setup cookies with data using JS and then get this information using Mo’ Variables.

> Add more early-parsed, global variables to your EE installation.
> 2 votes

---
Tags: ee2, plugin, sessions
---


# Question
Title: How complicated would it be to move from grid containing assets to a standalone assets?
I'm updating an old EE1 site that used to use matrix with a file field for downloadable files and a text field for the optional download text. I've successfully migrated the content into a new EE2.10 build and now have a grid field with an assets file field and the text box.

However, thinking about it, the grid is overkill because assets allows you to select multiple files, and the site admins were rarely completing the download text field in the grid.

My question is, how complex is it for me to move away from an *assets field inside a grid*, to a standalone assets field with multiple selections? I realise that a lot of this probably hinges on the exp\_assets\_selection table; could it be a case of updating the fieldtype to be assets (only) and some handy sql to iterate through exp\_grid\_field\_x and somehow populate the exp\_assets\_selection table with the data it needs?

Anyone got any experience of doing this? Or is it a case of 'if it ain't broke...'? :)

# Answer
> 1 votes
I'd recommend doing some trial and error on a copy, howeve your plan is almost right...

You'r right in that you would have to disect how multiple selections are stored in `exp_assets_selection` table, and iterate the grid table, making entries in this table as you go.

Once you're done ther you'll need to iterate your entries on the `exp_channel_data` table, setting the asset's ID in the correct field\_data column, then it should just work...

Never done this myself, but the theory is sound... You could end up wih quite a lot of SQL mashing though, so if it's not cost effective to invest the time I'd go with "Ain't Broke, Don't fix"...

---
Tags: assets, grid
---


# Question
Title: Is WYGWAM 3.3.3 Compatible with EE 2.10.1?
Can't find anything that indicates this in docs.

Thanks

# Answer
Yes,

Wygwams requirements are on the Docs Installation page it just says EE 2.7 or better.

Wygwam 3.X is definatly compatible with EE 2.9.3 and 2.8.1, there have not been any changes to the plugin functionality within EE since 2.8.1 AFAIK.

I note that the Wygwam changelog that patches have been added to support down stream technologies (EE \< 2.5, PHP \< 5.3), their support is done through this site (expect BrandonKelly to chime in soon!!) and I can't find any reports of incompatability.

All indicators point to good support.
> 1 votes

---
Tags: wygwam, ee2-upgrades
---


title: Complex Member permissions

text:
# Question
Title: Complex Member permissions
I have an application being developed that will need some complex member permissions. There is one channel that has an ownership field with a text value that represent a particular department. There will be several hundred users in this system, and most of them should only be allowed to add and edit channel entries that belong to their department.

Adding a simple custom member field is a quick solution, but the problem is that their will be multiple users who need multi-department access (but not full access to all records) as well as some admins who can see all. The template conditionals and all that are easy enough, but this renders using custom member fields useless, and having 3-400 hundred member groups and juggling their permissions means hundreds of conditionals and growing as the member groups grow...

I know their is Zoo Visitor, but I don't know if that has the functionality I'm looking for. Basically I'd think I'd like something along the lines of "permissions tags" for members. Does anyone have this type of user-role control implemented and can suggest something? I've actually only been at EE for as long as I've been a member here (6-8 months), and haven't deployed a lot of popular addons. Thanks.

# Answer
JChrono and I had a nice discussion on this (chat link might still work in comments above), I've taken the opportunity to write up our chat, findings and proposed solution.

Firstly, we discussed the requirement to set the access permissions against a user. There are many many (lets say X number of) departments and each department has its own channel. We discovered that we will need a "member management" role that would grant other members access / posting permissions in the channels they manage. members can be assigned to more than one department, and there will be in excess of 1000 members.

After some discussion we concured that as member fields lack any sort of value|label options that suit, we could leverage Zoo Visitor. Zoo Visitor essentually creates a members channel, with an entry for each user and also links all this up in the CP. With this we also leverage the power of any EE field, and as such a group of checkboxes with values and labels. So now we can save a members access priviledges easily and they are easier for the moderator group to manage.

The next step discussed was applying these permissions. Here some discussion of what areas we are protecting saved us quite a lot of time. We quickly identified we will need to code an extension to hook into various publishing events in order to apply proper server side control.

We determined that the Admin CP was out of scope for this project, this itself saved ALOT of hook planning (see Control Panel Hooks). For both members and moderators all entry posting would be don via the Channel Entry Form (Saef) on the front end. Moderators will have CP access ONLY to manage members, and will have no access to the Publishing options in the CP.

With this knowledge we discussed the implimentation of the SAEF form. We can query the member object before displaying the form, this will tell us what channels or departments the user can post too, populate the channel selector (if applicable) and also hide the form if the user has no posting priviledges.

Lastly we discussed creating an exteension that hooks the `entry_submission_start` event. Here we can re-run the 'has access' logic just in case someone was trying to force a POST to a different channel.

There you have it, having the CP out of scope gave us a much more consise definition of what was needed, We covered how to set permissions safely (Use the CP to stop any injection of priviledge), we covered how to present the publish/edit form allowing membes only the posting options they need and finally we covered how to safeguard the posted SAEF form, in case someone was trying the good old post injection.

I certainly look forward to hearing how JChrono gets on and I'm sure he'll let us know!

Quote of the chat :

> it's like pulling teeth from an already buried horse...

:D
> 1 votes

# Answer
It sounds to me that you need something like hooblong to manage access control, preferably with hookan to manage permissions. See general descriptions

Even with these modules, managing fine-grained permissions can be complex, and these modules provide a number of different approaches, depending on your exact needs. I am happy to help you get up to speed - the modules come with online support to get you started.

Having just finished upgrading hooblong to version 2, the manual is not quite fully up to date and the access logic also needs some more updates - still they cover most of what you need to get started. Download these documents from the documents menu at debeer.com

More info on dealing with large numbers of groups/members combinations
> 0 votes

---
Tags: members, permissions
---


# Question
Title: DevDemon Channel Videos is now returning https://youtube.com/devicesupport
Apparently YouTube has changed their API which seems to have killed Channel Videos. When searching for a video in the add-on, the devicesupport video comes up. I'm really hoping that there's a fix for this!

This post https://support.google.com/youtube/answer/6098135?p=yt\_devicesupport&hl=en&rd=1 indicates that the change to the API was made at the beginning of May.

# Answer
> 1 votes
We have released a new version of Channel Videos:

http://www.devdemon.com/expressionengine-addons/channel-videos

Thanks!

# Answer
> 0 votes
We are aware of the issue and are working on updating the API. We will be releasing an update to the product.

# Answer
> 0 votes
Not sure if this helps but things map pretty well to the new api. Here is the youtubeSearchVideos js function updated and working. I started working on this and thought I should share.

```
function youtubeSearchVideos(params, customField) {
    var i, entry, video_id;
    if (params.author) params.keywords += " " + params.author;
    $.ajax({
        crossDomain: true,
        dataType: "json",
        url: "https://www.googleapis.com/youtube/v3/search/",
        data: {
            part: "snippet",
            type: "videos",
            q: params.keywords,
            key: "AIzaSyBpu8hgnXbkqFVWrAvwRUEz7T13ii3I7WM",
            maxResults: params.limit
        },
        success: function(rdata) {
            var Videos = [];
           /* if (typeof rdata.feed === "undefined") {
                addVideoResults("youtube", Videos, customField);
            }
            if (typeof rdata.feed.entry === "undefined") {
                addVideoResults("youtube", Videos, customField);
            }*/
            for (var i = 0; i < rdata.items.length; i++) {
                entry = rdata.items[i];
                video_id = entry.id.videoId;
                Videos.push({
                    id: video_id,
                    title: entry.snippet.title,
                    img_url: "https://i.ytimg.com/vi/" + video_id + "/default.jpg",
                    vid_url: "https://www.youtube.com/embed/" + video_id
                });
            }
            addVideoResults("youtube", Videos, customField);
        }
    });
}

```

Best, Cory

---
Tags: devdemon, channel-videos
---


title: Multi Languages

text:
# Question
Title: Multi Languages
I have a website I am building. The website needs to be in 7 different languages. I know that I will need to use a language switcher but I am not sure how I set up the different languages/channels in the admin and/or what is the best approach. Can someone please advise?

# Answer
> 0 votes
I have done it several times using these instructions http://www.sidd3.com/multi-language-website-with-expressionengine/

# Answer
> 0 votes
I use republic variable for that. I dont have 7 languages but i think i can work for you. I'm out of the country for now but as i remember, my index.php redirect to language folder (based on browser's language ) on my root. (fr, en etc..) i will post my exact set-up next week. I have a post about that on stack exchange.

# Answer
> 0 votes
Please Do your self a favor... use EEHarbour Transcribe or go with another cms ... every other solution will be a pain.

Transcribe will:

1) create copyes of your entries in any language and link 'em 2) create translations of static text in your templates (without using conditionals in every bit of your code) 3) create translations of template names so for example you have products/watches/mywatch in english and prodotti/orologi/il-mio-orologio in italiano

etc etc...

Expression Engine wasn't done for multilanguage websites but Transcribe is the best way if you have to...

bye Francesco

---
Tags: channel
---


# Question
Title: Store - accessing sale meta information in template
Is there a way of accessing other sale information (other than the sale\_price) in the template? I'd like to be able to display the sale name that the discount relates to...!

# Answer
Assuming you are using a version of Store greater then 2.1 you would be able to use the `{adjustments}` tag pair to loop through all discounts and adjustments to your order. Something along the lines of:

```
{adjustments}
    <tr>
        <td>{adjustment:name}</td>
        <td>{adjustment:amount}</td>
    </tr>
{/adjustments}

```

You can see all of the available tags within the adjustments loop here in the docs.
> 0 votes

# Answer
I think you'll be able to solve this with product modifieres:

```
{modifier_options}
    <option value="{option_id}">
       {option_name}
       {if price_mod_inc_tax_val} ({price_mod_inc_tax}) {/if}
    </option>
{/modifier_options}

```

`option_name` could be Member price, you'd have to make the modifier price `-1.00` for the calculation to be correct.

You could also check the sale tag. You can limit a sale to member group so that seems like something that would be useful for your use case.
> 0 votes

---
Tags: expresso-store
---


# Question
Title: Expresso Store & Zoo Visitors are they playing together during checkout?
I know there are already some questions about this but I need some feedback with the latest configuration of both.

So the latest versions are:

* EE 2.9.3 (I let 2.10 to the more brave out there)
* Expresso Store **2.5.0**
* Zoo Visitor **1.3.32**

**The Question**

Is it possible to register a zoo visitor member during Store checkout?

**What I did:**

1) create all Expresso Store Order fields as native EE member custom fields (e.g. created "billing\_first\_name" as a native member custom field etc etc.)

2) Delete all default Zoo Visitor fields except the first one (member\_account) and recreate all fields but **using "member\_" prefix to get automatic sync**. (e.g. created "member\_billing\_first\_name")

3) In Store \> Settings \> Order Fields MAPPED all fields to Zoo Visitor custom fields

4) register\_member="yes" to the exp:store:checkout

5) Added {field:password} and {field:password\_confirm} to checkout

**What Happens?**

1) I'm able to complete order but I only get a native member WITHOUT any custom field populated... 2) Also receive the "Member Account Activation Instructions" native email

Thanks Francesco

**EDIT:**

want to reference this workaround (that I haven't tried yet) just to ask if it is still actual: https://devot-ee.com/add-ons/support/zoo-visitor/viewthread/14068

Or maybe this is the only way? Using Store + Zoo Visitor to create a member and store order details in related entry

# Answer
> 1 votes
I've read through your links in your edit and they seem relivent still. Your first link evolves into the second link anyway, but the method described (make sure you work through the whole thread) looks ok to me. The only thing I would do is avoid the optional membership thing on the store if you possibly can.

Also, see here (Is alomost a duplicate of your post), This post goes into the field mappings a bit more. : Expresso Store 2: not mapping to Zoo Visitors fields on checkout (and remember to call `{exp:zoo_visitor:sync}` on success to push the data to the Zoo Visitor Channel.

See also :

---
Tags: expresso-store, zoo-visitor
---


# Question
Title: Freeform Pro: intermittent error "Invalid form id(s) submitted"
I have a Freeform Pro standard (non-composer) form. I cannot reproduce the issue, but I have gotten a report of this error: "Invalid form id(s) submitted".

Secure forms is already turned off for this site, so we can rule out XID issues. My form tag looks like this:

```
{exp:freeform:form
  form_id="3"
  required="lastname|firstname|address|city|state|zip|phone_number"
  form:class="freeform"
  inline_errors="yes"
  return="{current_url}"
}

```

Yes, there is a form with an ID of 3 in the system. I have been able to submit the form myself with no issue.

Most of my research on this error reveals that it's either an XID or htaccess issue. But I don't think either of those apply in my case, since the form works most of the time, and since secure forms are turned off. What other reasons would this error occur?

EE 2.5.5 Freeform Pro 4.0.12

There is no budget for upgrading EE.

EDIT: There's also no caching on this form, no tag caching, no CE Caching, no Stash caching.

# Answer
> 1 votes
I had a similar error, and it was distinctly user-error. But here are two items which might help.

Do you have any sort of caching turned on? It could potentially be that. If so, try disabling the caching for that particular page.

Also, try this: Fill out the test form, hit submit. Hit the 'back' button, and submit the form again. I know Freeform will spit out an error when you do that. I don't remember exactly what that error message is, but it's related.

But this is also cache related - if you submitted a form, when you hit 'back' to go back a step, you're going to a locally cached page, which would have an ID of the one you already submitted.

# Answer
> 0 votes
Hmm, I had a similar issue. I was using AJAX to submit a Freeform form and then wanted to offer the user the ability to re-submit again after for a colleague without reloading the page but I was getting the below on the 2nd submit:

```
{"success":false,"errors":["Invalid form id(s) submitted."]}

```

It transpired that my JS which was clearing the form inputs after the first submit was also clearing the hidden inputs generated by Freeform (params\_id and CSRF), hence the error. Might not help but hey...

---
Tags: solspace-freeform, solspace
---


# Question
Title: Removing index.php but leaving subdirectory
We're working on a site that has Wordpress installed as the main CMS. EE is installed in subdirectory, and I am wanting to remove index.php. Everything I have tried removes both index.php and the subdirectory, but I need that subdirectory to stay in place, so WP will leave it alone.

So an address like: site.com/EE\_subdirectory/index.php/site/page-url

Needs to change to: site.com/EE\_subdirectory/site/page-url

I tried this .htaccess to my EE subdirectory:

```
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    # Removes index.php from ExpressionEngine URLs
    RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
    RewriteCond %{REQUEST_URI} !/system/.* [NC]
    RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]

    # Directs all EE web requests through the site index file
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php/$1 [L]

```

But it took out both the subdirectory and index.php. Do I need to do something to the WP .htaccess instead? Any ideas?

# Answer
> 1 votes
The documented approach to running EE from a subdirectory rather than the root, is to just remove the slash preceding `index.php` like so…

`RewriteRule ^(.*)$ index.php/$1 [L]`

Further, the documentation notes you might have to specify the sub-directory depending on your server config, so try this…

`RewriteRule (.*?)index\.php/*(.*) EE_subdirectory/$1$2 [R=301,NE,L]`

I’m also going to note that I suggest these rules should be in your (as you call it) *WP .htaccess* file, i.e. the one .htaccess file at the web root.

# Answer
> 0 votes
Please try this in `EE_subdirectory/.htaccess`

```
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond $1 !^(index\.php) [NC]
    RewriteRule ^(.*)$ /EE_subdirectory/index.php/$1 [L]
</IfModule>

```

# Answer
> 0 votes
It might help if you post your WP htaccess as well if possible.

Your EE .htaccess looks a bit different to the 'copy and paste' version we use on many production sites, I'm not saying it's wrong just different! Here's a copy of our standard fare (i've altered to match your needs):

```
# Enable Rewrite Engine
<IfModule mod_rewrite.c>

    #Go go gadget
    RewriteEngine On
    RewriteBase /

    #Exclude file paths, directory paths
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$

    #file whitelist, do not rewrite if file is root & name is ...
    RewriteCond $1 !^(favicon\.ico|index\.php|path\.php|php\.ini|admin\.php) [NC]

    #directory whitelist, do not rewrite if path begines with ...
    RewriteCond $1 !^(system|sysbase|images|themes|css|assets)/ [NC]

    #Rewrite what needs rewriting
    RewriteRule ^(.*)$ /EE_subdirectory/index.php/$1 [L]

</IfModule>

```

Also, you have set your base URL (`Admin -> General Configuration`) in the CP with the subdirectory and the index.php to blank right? this will help EE serve proper links (once you get there!)

Give that a go and if it doesn't work share your WP .htaccess in case thats playing with the request URL before the EE .htaccess gets to it...

---
Tags: htaccess
---


# Question
Title: Using Transcribe for EE, can I fall back to the default language where no translation exists?
Im using Transcribe 1.6.1 on EE 2.9 – is it possible to fall back to the default language where no translation is provided?

# Answer
You can use the parameter transcribe="disable" in the channel entries tag
> 1 votes

---
Tags: transcribe
---


title: Unable to change control panel theme

text:
# Question
Title: Unable to change control panel theme
I installed the Nerdery control panel theme. Followed the instructions. The theme shows in the drop down but it doesn't stay selected after I save. Any ideas what could be happening? Tks!

# Answer
Is the theme being over written?

https://ellislab.com/expressionengine/user-guide/general/system\_configuration\_overrides.html#cp-theme

$config\['cp\_theme'\] = 'default';

The nerdery directions tell you how to set this.
> 1 votes

---
Tags: cp-themes
---


# Question
Title: how can i get ee global vars outside of ee?
I have tried something along the lines of

`$email = ee()->....`

and with a hope to include/require the page at the top of an external php page and then echo the value of $email.

This doesn't appear to work.

I need to gain access to the ee session class outside of the cms but still based on user logged in status.

How could i achieve this?

# Answer
Well the short answer is you can't*shouldn't* easily, it raises all sorts of questions regarding the security model!

However there may be alternatives. You could for instance write an extension for EE that exposes an ACTion (as Derek said), or more simply just write a template, and then get your information through AJAX/curl from your other external page.

for instance suppose you had a template living at `API/getUserEmail`, on that template you could do :

```
<?php
    //is the AJAX request from the known source?
    //here you can add code to ensure its just YOUR external site getting to this api
    if ( $legitRequest ) {
        //is the user logged in
        $memberId = ee()->session->userdata('member_id');
        if ( $memberId != 0 ) {
            return json_encode(array('success' => ee()->session->userdata('email');));
        } else {
            return json_encode(array('error' => 'no user logged in'));
        }
    } else {
        return json_encode(array('error' => 'permission denied'));
    }
?>

```

Also, to get the ajax return with curl there's an example in the answer to this question : https://stackoverflow.com/questions/3928228/php-and-curl-get-ajax-data

Another alternative is to query the database directly, though you can't check if the user is logged in *easily* via a striaght database call.

If you wanted to go down the "instansiate the entire application" route check out the code in index.php (on the EE site) and try to replicate this bootstrap in your code, this could instansiate the EE object if you get it right, but that is a complicated affair!
> 2 votes

---
Tags: sessions, global-variables
---


title: Expresso Store - Random products

text:
# Question
Title: Expresso Store - Random products
is there a way to show a random product using Expresso Store? The product tag seems to require entry\_id="{entry\_id}"

# Answer
> 1 votes
You would just need to wrap the product tag in a channel entries tag with `orderby="random"` and whatever limit you wanted. Something along the lines of:

```
{exp:channel:entries channel="products" orderby="random" limit="5"}
 {exp:store:product entry_id="{entry_id}"}
  {title}
  You other fields
 {/exp:store:product}
{/exp:channel:entries}

```

---
Tags: expresso
---


# Question
Title: Expresso Store: Search by SKU in control panel
My client would like to be able to search products by entering it's SKU, however this doesn't seem to be supported in the search in `Content > Edit` or `Store > Inventory`. Is there any way to search for a SKU in the control panel? If not how would I go about adding this functionality?

# Answer
You could add this functionality with Zenbu, this module extends the Content \> Edit display so you can add the columns you wish for the channels you wish, and ultimately sort and filter on them too.

Used it before, will do the job and you'll get your 30 day money back guarantee if its not quite right for you.
> 1 votes

---
Tags: expresso-store
---


title: Expresso store delete one item per time

text:
# Question
Title: Expresso store delete one item per time
I have a cart with a delete button in it. It works fine when I have 1 item in my cart, but when I have an item in my cart with a quantity of more then one, it deletes all the quantities of that item. So when I have an item in my cart 2 times and I delete it, it deletes all 2 of them.

This is my delete button:

```
<input type="submit" name="remove_items[{key}]" class="remove" value="" />

```

It has `{items}` tags above and under it.

# Answer
> 0 votes
This is the default functionality of the remove items tag, it's an all or nothing kind of tag. You should look at adding a quantity drop down or input field and use the Update Cart button if you are wanting to change quantities of items in your cart.

---
Tags: expresso-store, shopping-cart
---


# Question
Title: Store 2.5 - updating orders within the control panel
With the last release of Store, the ability to edit an order within the control panel was added. Is there a hook which can be used to do something once an order has been updated?

# Answer
> 1 votes
Depend on what are you trying to do. A safe hook is on the store\_order\_recalculate\_end hook, since the $order object is passed and you can check the status.

When you update the order in the CP the last thing that happens is that hook.

---
Tags: expresso-store
---


title: updater FTP: Failed to create the dir:

text:
# Question
Title: updater FTP: Failed to create the dir:
Trying to use UPDATER to update my EE from 2.7 to 2.9

Test settings and everything passes but during the update I get the error that it cannot create the back up directory.FTP: Failed to create the dir:

Updater is the current 3.3.0 version

# Answer
> 2 votes
Check that the user that PHp executes under (could be www-data, could be the home user for the site) has execute and write permissions in the directory above the one the FTP folder needs to be created in. Also it's worth checking who the owner of the directories is compared to the executing user.

---
Tags: devdemon, devdemon-updater
---


# Question
Title: Disallowed Key Characters in CP - only one user
I've got an EE 2.8.1 site where one user cannot access a specific channel. He gets the message "Disallowed Key Characters". It only happens for this single user. Highlights:

* Only happens for the one user
* User is part of a member group and no one else in the member group has the issue
* I've walked him through clearing all of his cache, cookies, history, everything. switched from his ISPs DNS to Google helped flused his local DNS hoping to clear everything out, all with no success.
* Tried multiple browsers and two machines.
* We are using Zoo Flexible Admin, and it happens when he clicks a link we setup to directly create an entry for a specified channel (again though, others use that same menu with no issues)
* I administer about 50 EE installs and I've always been able to fix this by clearing cache, cookines, or permission issue. None of those seem to work this time.

any ideas? thanks

UPDATES based on comments below: \- while navigating the control panel, I only get this while on his machines. I can log in as the user just fine

\- offending url is : http://www.domainname.com/system/admin.php?/cp/content\_publish/entry\_form?channel\_id=1

\- htaccess:

```
#secure .htaccess file
<Files .htaccess>
  order allow,deny
  deny from all
</Files>

# EE 404 page for missing pages
ErrorDocument 404 /index.php/site/404

#Block Access to directories with no index file
Options -Indexes

# Simple 404 for missing files
<FilesMatch "(\.jpe?g|gif|png|bmp|css|js|flv)$">
  ErrorDocument 404 "File Not Found"
</FilesMatch>

# Although highly unlikely, your host may have +FollowSymLinks enabled at the root level, yet disallow its addition in .htaccess; in which case, adding +FollowSymLinks will break your setup (probably a 500 error), so just remove it, and your rules should work fine.
#Options +FollowSymlinks
RewriteEngine On
RewriteBase /

RewriteCond %{THE_REQUEST} ^GET
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteRule ^index\.php(.+) $1 [R=301,L]

# Add the www
RewriteCond %{HTTP_HOST} ^domainname\.com
RewriteRule ^(.*)$ http://www.domainname.com/$1 [R=permanent,L]

#Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]

#RewriteCond %{HTTP_HOST} ^(blog|news).domain.com$ [NC]
#RewriteRule ^$ %1/ [L]

```

# Answer
From this post over on EllisLabs : https://ellislab.com/forums/viewthread/81867/

What is happening when that message displays (as you will probably know) is that there is something that is setting cookie/post/session variable with a key that contains a character in the dis-allowed list.

Are you sure there's no dodgy characters in the users username or something like that?

What you could do is apply the patch in the post above, copied below, this might tell you the string (or key) that is causing the offence at least, and help you narrow it down.

/system/codeignitor/system/core/input.php, around line 728 (on EE2.10.1) look for the below if statement and replace with the below :

```
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
    set_status_header(503);
    exit('Disallowed Key Characters. The offending key is : '.$str);
}

```

**DO NOT leave this code in, it doesn't clean the offending string just echoes it so it's potentually dangerous, only use for debugging**

The process of ellimination tells us it is something specific to the user, ie the user data or something in the users cookies, you tried different browsers so it's not likely to be that, perhaps you've managed to get a disallowed character into the session ID? Have you cleared the exp\_sessions table and checkthe the user in quesiton (in exp\_members) for anything that looks 'funky'?? I seem to recall triggering this erro when I tried to overwrite a users hashed password once...

Also see this post : https://ellislab.com/forums/viewthread/84889/ seems there can be some come-uppance with 3rd party cookies, especially if they have the dollar symbol in their key...

**Edit : Update following feedback below**

Ok, the string reported points to a GET parameter, from what you've posted it looks like he's calling a URL with an EE path (`/cp/content_publish/entry_form`) and get parameters `?channel_id`).

If we put it all together with a fake domain seems he's calling `your.comain.com/cp/content_publish/entry_form?channel_id`. Now, if we assume your using friendly URL's (***please share your `.htaccess`***) the .htaccess will add `/index.php/` to your url making `your.domain.com/index.php/cp/content_publish/entry_form?channel_id`, doesn't strike me as too strange however we know that what he reported is JUST the key, so we know that the parameter boundry (`?`) is getting applied *before* the path, after the domain, something like this : `your.domain.com/index.php?/cp/content_publish/entry_form?channel_id=Summin`

The above string makes sense in that the URL is `your.domain.com/index.php` then the parameter boundry, then the next part is the first 'key' (i.e. `/cp/content_publish/entry_form?channel_id`) and the value following the = is the value, the next parameter being split by an ampersand `&`. I **suspect** that the link being created is malformed for some reason.

What we need to see is 1. The URL being produced and 2. The URL actaully being processed. For one you'll have to ask your user to copy the link location on the link or log in as him and get it yourself (check his browser too). 2 can be taken care of with this modification in the same place as above :

```
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
    $port = $s['SERVER_PORT'];
    $host = empty($_SERVER['HTTP_X_FORWARDED_HOST']) : $_SERVER['http_host'] ? $_SERVER['HTTP_X_FORWARDED_HOST'] ;
    $reqUrl = "http";
    if ( !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ){
        //ssl
        $reqUrl .= 's://' . $host . ($port=='443' ? '' : ':' . $port);
    } else {
        $reqUrl .= '://' . $host . ($port=='80' ? '' : ':' . $port);
    }
    $reqUrl .= $_SERVER['REQUEST_URI'];

    set_status_header(503);
    exit('Disallowed Key Characters. The offending key is : '.$str
    . "<br />The URL requested was : <pre>" . $reqUrl . "</pre>" );
}

```

Again, don't leave this in place, pop it in, get a test result and take it out.

**Edit 2 : Following reveal of Generated URL and `.htaccess`**

Looks like the link you're creating in the CP is not valid. Modern browsers ***may*** interfere/correct this, some browsers may not. Notice the 2 question marks in your URL??

Good news is (thanks for the extra info btw :) ) I can test this URL in my sandbox! Looks like we're missing a number of things from the URL...

Firstly is the CP Session ID, I realise you could be using the 'non' Session ID type of session type (`Admin > Security & Privacy > Security and Sessions > Control Panel Session Type`) however if you're default you'll need the S parameter...

Also related to this is if your user is deliberately blocking cookies, if you have Cookies Only as your CP session type and the user's blocking cookies then we've an issue.

Next, thanks again for sharing the .htaccess, but is this the .htaccess from inside the system directory?? if you look at your URL you'll see the path is `/system/admin.php`, ergo we're browsing a sub directory. you should have admin.php in the site root?*May not be relivent against the EE version, please ignore*

Finally, can you share the *code* that creates your link please???

Finally, regardless of all the above questions, here's my stab at creating your link, this should deal with the session variables and your 'double parameter marker' issue...

```
//Create link to content_publish controller, entry_form method, channel_id of 1
$urlToEntry = BASE . AMP .
              'C=content_publish' . AMP .
              'M=entry_form' . AMP
              'channel_id=1';

```

Try this as a 'drop in' replacement and see if you get further with it? Let us know if this changes the generated link and if it works as the other link does (it should!)

Here the `BASE` definition in the EE CP is the whole base URL for the CP, including the session id if applicable and the cp indicator, the rest is the MVC style of call in the CP. Tested on EE 2.7.1 & 2.10.1.
> 3 votes

# Answer
Found some suggestions in the EllisLab Forums that might help.

> In the system/codeigniter/system/core/input.php file:
>
> Find the function \_clean\_input\_keys($str)
>
> Change:
>
> exit(‘Disallowed Key Characters.’);
>
> to:
>
> exit(‘Disallowed Key Characters.’. $str);
>
> This will tell you what characters are causing you problems. Then you can follow the suggestions above to add them to the regex string. In my case, I just changed the input’s name.

Once you know what the offending character is you may choose to allow it.

In the `system/codeigniter/system/core/input.php` file see the the `_clean_input_keys function` to add the offending character. This may have security implications.

Other suggestion from the same source is to add a cookie prefix.

> $config\['cookie\_prefix'\] = 'im\_';
> 3 votes

---
Tags: control-panel, error, zoo
---


title: Session ID mode and internal links

text:
# Question
Title: Session ID mode and internal links
My site uses a "guest" account and therefore needs to allow multiple simultaneous logins from different IPs. So I'm using "Session ID Only" for my Website Session Type.

Is there any good documentation about keeping preserving the Session ID string (`S=d571da22a6...`) when generating internal links in templates? Through trial and error I've found that when looping through entries, the `{url_title_path='group/template'}` format will output the Session ID string (thus keeping the user logged in when they click one of them), whereas `{comment_url_auto_title_path}` does not.

But for the life of me though I can't figure out how to link to the home page and output the Session ID string. `{site_url}` doesn't do it, and `{cp_session_id}` only applies to users who have access to the control panel.

Am I missing something? Is it the expected behavior that clicking any link without the Session ID string will log the user out (or at least display the page as if the user is logged out)?

# Answer
> 1 votes
Have you tried outputting the session \> userdata \> fingerprint on the template. I've used this in addons to recreate the session ID in the control panel.

```
ee()->session->userdata['fingerprint']

```

I haven't accessed or tried this on a template though, but it might point you a the right direction.

# Answer
> 0 votes
Yea without the session id in the URL it would not keep the user logged in, have you tried the standard `{path}` and `{route}` tags? these should maintain the Session ID in the url it puts out.

# Answer
> -1 votes
You could always get $\_COOKIE\['PHPSESSID'\] or call session\_id() by enabling PHP in your template.

```
<a href="http://yourdomain/SID=<?php echo $_COOKIE['PHPSESSID'] ?>">
<a href="http://yourdomain/SID=<?php echo session_id() ?>">

```

I hope this could help.

References: \- ExpressionEngine User Guide: PHP In Templates \- PHP session\_id()

---
Tags: sessions, logout, guest
---