Where do I put code to use hooks and events from Squarebit's 'Charge' plugin?

You'd listen to Charge's onCharge event just like you'd listen to any of Craft's own events, using a plugin.

Your plugin's init() method, for example could do this:

craft()->on('charge.onCharge', function(Event $event) {
    // ...
});

There's a nifty Craft plugin scaffold generator to get you started here, too.


Prevent adding users with same email addresses

You're passing false as the second parameter of your saveElement call... that parameter means you're skipping the built-in validation which should catch this error for you. If you get rid of that you should then receive a warning in the logs when processing existing users, but it shouldn't halt execution of the script.


How can I return HTTP 403 from a template?

Exit tag is what you're looking for.

{% exit 403 %}


It looks a bit awkward, but to append items to an array you have to use Twig's merge filter, merging the feeds_array with itself for each new item. Here's how I'd do it if you need different logic for each feed:

{% set feeds_array = [] %}

{% for node in craft.feedme.feed(my_rssfeed) %}
    {% set feeds_array = feeds_array|merge([{ title: node.title }]) %}
{% endfor %}

{% for node in craft.feedme.feed(my_otherfeed) %}
    {% set feeds_array = feeds_array|merge([{ title: node.whateverField }]) %}
{% endfor %}

{% for post in feeds_array %}
    {{ post }}
{% endfor %}


Access optimizedTitle field within Twig template

So to update this question incase someone happens to stumble across it.

With Sprout SEO you need to enable the Enable custom metadata variable option under 'Advanced' in the settings menu.

From there I set a twig variable with the value of my metadata title, in this case {%- set metaTitle = entry.metadata.title -%} and attach it to my AJAX wrapper element with something like data-title="{{ metaTitle }}".

Now when I load each page via javascript I just do a little something like this document.title = $('<div />').append(html).children('.js-ajax-wrapper').data('title'); once the content is loaded in and my page title is updated.


How to process POST and entry fields when using same form for Add as Edit on front end?

This may not be possible but can you not just make your form itself an include and have a "create" template and another "edit" template which have their own logic but include the same base form?


Folders need to be executable for Apache/PHP to be able to open them and read their contents.

I'm guessing it's more of a a case of our build script being overly aggressive and setting the execute bit on files.

From what I can tell, though, setting the execute bit on a PHP script is effectively pointless.


is it posible to have dynamic Title for my article image grid?

I hope I got your issue right. For the brand I'd use a category. So each article can be assigned to a category brand.

You can then group your entries by category:

{# Save entries, group by category #}
{% set entries = entry.children | group( 'entryCategory.first().title' ) %}

{# Get all category logos for the category group "yourEntryCategoryHandle" #}
{% set brands = craft.categories.group( 'yourBrandCategoryHandle' ).titles %}

{# Loop through the category title array #}
{% for brand in brands %}

    {# Get the entries grouped under the current brand title #}
    {% set brandEntries = entries[ '' ~ category ] | default( [] ) %}

    {# Print the category title and entries #}
    {% if brandEntries | length %}

        {% for entry in brandEntries %}
            ...
        {% endfor %}

    {% endif %}

{% endfor %}

This is a modification from this issue: How Do I group entries by Category and retain fixed Category Order?


You can do this with CSS, or with Twig.

CSS:

ul.crumbs li {
  text-transform: lowercase;
}

…or, if you need to start after a particular index…

ul.crumbs li:nth-child(n + 2) { /* Start with the 2nd `li` */
  text-transform: lowercase;
}

Twig:

{% if entry.level > 1 %}

    {% for crumb in entry.getAncestors() %}
      {# Build the link yourself, passing just the title through the `lower` filter: #}

{{ crumb.title | lower }}

    {% endfor %}

{% endif %}


Yes you can. I use Craft 3 as an headless CMS for React or for any other javascript framework.

You have various options to do this, the most know ones are described here: https://docs.craftcms.com/v3/dev/headless.html#app

I would recommend you to use the CraftQL plugin. My example below is using ReactJS, Axios and CraftQL within CraftCMS. This plugin (CraftQL)  allows you to access your Sections, Entries, Categories, etc... by doing queries to a GraphQL api endpoint in Craft CMS.

See more about the plugin here:
https://github.com/markhuot/craftql

This is an example for ReactJS and with Axios on componentDidMount:

  componentDidMount() {
    // data query
    // your GraphQL query should go here!!
    const queryData = {
      query: `{
        helloWorld
      }`
    };

    // GraphQL API headers
    // The values for craftql_token_type and craftql_token_value are in
    // the settings of the plugin in Craft CP (Control Panel).
    // You can update the access to the GraphQL api endpoint there
    const queryHeaders = {
      headers: {
        'Authorization': `craftql_token_type craftql_token_value`
      }
    };

    // Axios POST request to GraphQL API url
    axios
      .post(api_url, queryData, queryHeaders)
      .then((response) => {
        if (response.data.data.errors) {
          // do something
        } else {
          // do something
          this.setState({
            data: response.data
          });
        }
      })
      .catch(error => {
        this.setState({
          error: true
        });
      });
  }

Hope this helps!

:)


Setting body ID from includes does not work

So Twig has a particular processing order for things like variables, includes, extends and all that sort of stuff. Basically, you can't set a variable in an included template and then use that in an extended template.

Here's a great article that goes into this topic in a little more depth: https://nystudio107.com/blog/twig-processing-order-and-scope - I'd highly recommend you give it a read.


Your best bet for a quick hacky solution would be to interrupt the indexing process, take a look at craft_assetindexdata table and then write a small plugin that calls craft()->assetindexing->processIndexForSource().

You would get the sessionId from the craft_assetindexdata table and you'd be able to deduce how far the indexing has gotten by looking at the same table. All the entries that have recordId field set to a value have been processed already.

This way you can batch it up however you want.


Rich Text field is producing weird space character instead of

I did contact Craft about this near the time this question was posted, they were not sure why it was occuring.

I found that this issue was environment specific, it was specifically happening locally on MAMP4, with 5.6.* using NGINX.

I was unable to find the cause of the issue, but, in the end it was not happening on server environments so I decided to give up.


Storing multilingual content that is used across sections

I am fairly new to Craft myself but I think the best approach for that type of content would be to set up Globals I think you can then make them translatable and common translations can be added to in a translations file. Have a look at the HappyLager site to see how that works. I have found it really useful.


How to find pros to take on maintenance/improvement of pre-existing sites built with Craft?

As of this posting, there isn't another reliable source for Craft professionals. The CMS is so new compared to other systems that a 'base' of well-known, reliable companies/developers hasn't had the chance to form yet.

You could google and find a few, but they're spread out among developers that most likely wouldn't give you good results. I'd stick with the Straight Up Craft list, since you're at least sure they've seen/read about best practices on the Straight Up Craft site.

You could also post jobs to places like Authentic Jobs, and specifically ask for Craft experience, or Straight Up Craft's Job Board.


'An unknown error occurred.' when trying to add new custom widget

I feel quite embarrassed, but I have finally got this thing working. The error that I had made was within AdLister_AluWidget.php. I had written at line 4: class Adlister_AluWidget extends BaseWidget instead of what it should have been: class AdLister_AluWidget extends BaseWidget. So, AdLister should have been written with an UPPER-CASE 'L' and not lower-case. If anyone else is struggling, hopefully my error will help them.

The correct code in full:

<?php
namespace Craft;

class AdLister_AluWidget extends BaseWidget
{
    public function getName()
    {
        return Craft::t('Adlister Update');
    }

    public function getBodyHtml()
    {
        return craft()->templates->render('adlister/AluWidget');
    }
}


Entries form in control panel won't display if I have a Matrix field enabled

This usually happens if xdebug is installed with the default nesting limit. You can either disable xdebug as PHP itself does not have a function nesting limit,

change the setting in your php.ini:

xdebug.max_nesting_level = 400

or in your PHP code:

ini_set('xdebug.max_nesting_level', 400);


Only allow one Lightswitch to be active at a time

You'd have to write a custom plugin that added an event listener for the  entries.saveEntry event.

Inside the event listener, you could check if the entry being saved has a true value for the featured Lightswitch field, and if so – pull all other entries with a true value for that same field (in the same section), setting their featured attribute to false before re-saving them.

Something like the below would go into your plugin's primary class:

public function init()
{
    parent::init();

    craft()->on('entries.saveEntry', function (Event $event) {

        $entry = $event->params['entry'];

        if ($entry->section->handle !== 'news' || !$entry->featured) {
            return false;
        }

        // Get all entries from the same section with a `true` value for the Lightswitch field
        $entries = craft()->elements->getCriteria(ElementType::Entry, array(
            'section' => 'news',
            'featured' => true,
            'id' => 'not ' . $entry->id,
            'limit' => null,
        ))->findAll();

        // Update all other entries' Lightswitch field value to `false`
        foreach ($entries as $entry) {
            $entry->getContent()->setAttribute('featured', false);
            craft()->entries->saveEntry($entry);
        }

    });

}

If you're new to plugin development in Craft, I'd suggest looking at the Business Logic plugin template or the pluginfactory.io app – also it'd be a good idea to read the official docs on the subject.

If you don't want to write a plugin, you could also solve this by foregoing the featured field for the entries. If you added a featuredNewsStory Entries field to a Global Set instead (and limited the Entries field to 1 entry), you'd make sure that there was only ever one featured news story in the system. The editiorial workflow would suffer, though – publishing a new, featured news story in this manner would mean that the editor would first have to create the story, then pop into the Global Set after saving the entry to actually mark it as "featured".

Anyway, here's how you could pull the featured news story from a global, as well as the other news stories that aren't featured:

{% set featuredNewsStory = yourGlobalSetHandle.featuredNewsStory.first() %}
{% set otherNewsStories = craft.entries.section('news').id(featuredNewsStory ? 'not ' ~ featuredNewsStory.id : null) %}

Of course, there is another possible "workaround" here: continue with your current solution, but add another clause; making sure that the featured news story pulled is the newest one only:

{% set featuredNewsStory = craft.entries.section('news').featured(1).order('postDate desc').limit(1).first() %}
{% set otherNewsStories = craft.entries.section('news').id(featuredNewsStory ? 'not ' ~ featuredNewsStory.id : null) %}

With the above in place, you could just communicate to your client that "if you set more than one entry to be featured, only the newest one will actually display as featured" or the like.


MVC - Should these be seperate controllers/models etc

Well, it looks like Sprout Forms itself prefers separate services for everything (they'd be some big services if they weren't,) but Craft does bundle closely-related things together sometimes - FieldsService deals with both fields and groups, TagsService with both tags and tag groups for example.

Personally I just look at how much code there is, if I start getting lost/sick of scrolling and there's more than one 'thing' I'm dealing with, or if the existing service is already pretty big, then I break it out into separate services.


Twig: Parent template does not inherent what's ever inside the child template even using extends in the child

You aren't able to nest blocks in the template where that block is output - all content inside a block in the parent template is replaced by the child templates content, hence why you don't see your content block being output inside your head block. Likewise you can't use multiple extends within one template.

You can however nest blocks in a child template and output them in your extended template.

Base.twig (main template)

// Will display "content" and "sidebar content"
{% block content %}{% endblock %}

// Will only display "sidebar content"
{% block sidebar %}{% endblock %}

Child.twig

{% extends "Base.twig" %}

{% block content %}
  Content
  {% block sidebar %}
    Sidebar content
  {% endblock %}
{% endblock %}

More info on the topic can be found in Twigs documentation.


Showing a generic image when no image is chosen

You may want to try this:

{% for image in entry.illustration %}
  {% if image %}

  {% else %}

No image.

  {% endif %}
{% endfor %}

(Assuming the altText field is an entry field.) :)


Is it possible to use percentage values for width and height in image transforms?

It’s possible to do this from your templates:

{% for image in entry.myAssetsField %}

    {% set half = {
        width: (image.width/2)|round,
        height: (image.height/2)|round
    } %}

    {% set halfUrl = image.getUrl(half) %}

    <img src="{{ halfUrl }}" srcset="{{ image.url }} 2x" width="{{ half.width }}" height="{{ half.height }}">

{% endfor %}


The template and CSS code cannot be accessed from the admin. You'll need to gain access to the git repository that (hopefully) exists with your site's code.

Or in a less-preferable scenario, you could access the server via FTP and modify the templates and CSS there.

You might want to take a read through the Craft CMS docs as a starting point to get a little better idea of how the files are structured.


Elegant Way To Pass Configuration To yiic?

ok i used the answer brad bell posted above and enhanced it slightly. i wanted to be able to specify the target environment on the command line, and i didn't want to edit a framework file to do it.

so i created the following file, yiic_frontend.php, placed it in $root/utils (a new dir), and call it using php $root/utils/yiic_frontend.php --env=envname plugin cmd:

<?php

/**
 * a front end for yiic.php that looks for env on cmdline and sets CRAFT_ENVIRONMENT
 * accordingly. I put this script in a folder called "utils" in the root of my website
 * install. So instead of doing something like
 *     php $root/craft/app/etc/console/yiic.php plugin cmd
 * you would call
 *     php $root/utils/yiic_frontend.php --env=envname plugin cmd
 * where "envname" is the config environment you wish to use.
 */

for ($i = 1; $i < count($_SERVER['argv']); $i++) {
    $arg = $_SERVER['argv'][$i];
    if (strpos($arg, '--env=') === 0) {
        $env = explode('=', $arg)[1];
        printf("---- setting env \"%s\"\n", $env);
        define('CRAFT_ENVIRONMENT', $env);
        array_splice($_SERVER['argv'], $i, 1);
        break;
    }
}

require(__DIR__ . '/../craft/app/etc/console/yiic.php');


You missed to filter for entries related to your "Canton" category only within your cantons loop.
Add another ElementCriteriaModel and get entries related to both membersCat and canton:

{% for canton in cantonsCat %}
    {% set entriesInCanton = craft.entries.section('listeMembres').relatedTo('and', membersCat, canton) %}
    {% for row in entriesInCanton|batch(3) %}
        ...
    {% endfor %}
{% endfor %}

Another approach (only works if there's one "Canton" max per entry!) would be to make use of Craft's group filter. This is probably the better way to solve your problem, because it doesn't add extra DB queries for each "Canton" iterated over in your loop.

{% set membersCat = craft.categories.group('categoriesMembres').title('Membre').first() %}
{% set cantonsCats = craft.categories.group('cantons') %}
{% set cantonsCatsInUse = craft.categories.group('cantons').relatedTo(entries) %}

{% set entries = craft.entries.section('listeMembres').relatedTo('and', membersCat, cantonsCats) %}
{% set entriesByCanton = entries|group('myCantonCategoryField.first()') %}

{% for canton, entriesInCanton in entriesByCanton %}
    {% for row in entriesInCanton|batch(3) %}
        ...
    {% endfor %}
{% endfor %}

This probably won't output the cantons in the sort order you whish, but this fortunatelly can be solved easily.

{% set entriesByCanton = entriesByCanton|supersort('ksort') %}


Is it possible to create a 3 month membership instead of a subscription using Charge 2 for Craft CMS?

You could have them make a one-time payment, then generate a gift code that can be redeemed when a user fills out the subscription payment form.

I did that by creating a plugin and utilizing the charge.onCharge event, it makes sure it was a gift code purchase, then generates a code that is stored in the charge's coupon code table and you can either have it send an email with the code to person who is to redeem it or just display it on the screen.


If you want live and pending entries, you would need to pass status to your query with the values you want (docs).
query yourQuery {
  entries(section: "yourSectionHandle", status: ["live", "pending"]) {
    title
  }
}

Or if you want to use variables:
query yourQuery($section: [String], $status: [String]) {
  entries(section: $section, status: $status) {
    title
  }
}

# query variables:
{
  "section": "yourSectionHandle",
  "status": ["live", "pending"]
}

If you want all entries, (disabled and expired included) you can use status:null.


MySQL 5.6 backup to MySQL 5.7... what to do

You're fine. An export and subsequent import would have highlighted any incompatibilities.
Different story going to MySQL 8 though, that was a whole world of pain last time I tried it. Yii may have been updated since then, though.


Is it possible to change the default feed widget settings?

I have just made a plugin to do a similar thing it duplicates a selected users dashboard see https://github.com/james1238/duplicateuserdashboard


It would be worth checking craft/storage/runtime/logs/craft.log, it's very likely there's a clue in there.


Better way to group by category and include full category entry

Your actual code is pretty effective – the problem is that it's potentially going to result in a lot of queries.

This is a good example of the so-called N+1 query problem, where each iteration over the result set of a single query generates an additional number of queries. Depending on the number of elements involved, this issue can easily result in hundreds of queries, which can be a huge problem for performance.

The solution to the N+1 query problem is eager loading. With eager loading, you explicitly tell Craft which relational data it should include with the first query, unlike with the common "lazy loading" pattern where relational data is queried on a "need to use" basis.

Here's how your code could look, refactored to use eager loading:

{% set results = block.result.find({
    with: ['infographicSection']
}) %}

{% for category, catEntries in results|group('infographicSection[0].title') %}
    {% set fullCat = catEntries[0].infographicSection[0] %}

{{fullCat.title}}

{{fullCat.body}}

        {% for entry in catEntries %}

{{entry.title}}

        {% endfor %}

{% endfor %}

With something like the above, you should see the number of queries drop drastically (remember to turn on devMode in development and you'll see a profiling report in your browser's dev tools console, containing the total number of queries).


Building off of Brad's answer, you might consider using a for loop to render your markup, instead of setting all of those variables:

{% set range = range(10, 90) %}
{% set totalDivs = 5 %}

  {% for i in 1..totalDivs %}

  {% endfor %}


How do I format the date and time I got from an entry?

You can use the Twig .format() filter to achieve exactly what you are looking for, the reference page for date and time values is here.

So if you would like the date format to show 15:00, you can use:

{{ entry.lorem.format('H:i') }}

And the date format for 1 Januari 2015 will be as follows:

{{ entry.lorem.format('j F Y') }}

As I say, you can reference the website for which values to use.


A User's first and last name fields don't need the fields[] prefix as they aren't custom fields added to the user field group.

So using the following should work:

{{"voornaam"|title}}
<input type="text" id="voornaam" name="firstName"
{% if currentUser.firstName %}value="{{ currentUser.firstName }}"{% endif %}>

{{"achternaam"|title}}
<input type="text" id="achternaam" name="lastName"
{% if currentUser.lastName %}value="{{ currentUser.lastName }}"{% endif %}>


How to get the Twig Text extension loaded

Check out the Craft Plugin documentation on adding a Twig extension with a plugin. There is no clean way to add extensions manually without a plugin, as the changes might be overridden with Craft updates.


How to access a freeform field object's properties from an event

To answer my own question, this is what I found.
The answer is to use get... methods.

craft()->on(
    "freeform_submissions.onBeforeSave",
    function (Event $event) {
        $submission = $event->params["model"];
        $field_item = $submission->fieldMetadata['field_handle'];
        $field_value = $field_item->getValue();

    }
);

The $field_item->getValue() can be $field_item->getId() or $field_item->getHandle() and so on.

The properties listed here: https://solspace.com/craft/freeform/docs/field/ can be used by turning the property into a method and prepending get.


The easiest way would be to check craft.request.urlReferrer and see if they just came from the entry index page. If so, provide a link to send them back.

{% set referrer = craft.request.urlReferrer %}
{% set indexBaseUrl = url('articles') %}

{% if referrer and referrer|slice(0, indexBaseUrl|length) == indexBaseUrl %}
    Go back
{% endif %}

Another, more explicit way to do it would be to actually pass the current page in the query string of the entry URLs, from the entry index page.

{% for entry in entries %}
    {% set url = url(entry.uri, { page: craft.request.pageNum }) %}
    {{ entry.title }}
{% endfor %}

Then you could check for that “page” query string param in the single entry template:

{% set indexPage = craft.request.getQuery('page') %}
{% if indexPage %}
    {% set indexUrl = url('articles/' ~ craft.config.pageTrigger ~ indexPage) %}
    Go back
{% endif %}


Multilang Bug with Matrix, Neo, SuperTable (with Video)

You're essentially running into this bug: https://github.com/craftcms/cms/issues/16

It has been fixed for the upcoming Craft 3, but the fix was involved likely won't be backported to Craft 2.


My license.key file missing. How do I transfer the license to other servers?

The Craft .zip does not come with the license.key file. From the Craft docs: "It doesn’t get one until you have finished installing Craft and it has made its first call to our web service to check for updates."

Make sure your Craft edition upgrade went through, it seems a bit odd that you upgraded editions and you don't have a license.key file.

Double check that it's not there (craft/config/license.key), maybe by using a search tool on the whole Craft install.

Also try checking for Craft updates to see if that triggers the generation of a license.key file. Restarting the server may help, but you did say it was a production server so that might not be convenient.

If all else fails, I'm sure if you contact P&T (support@buildwithcraft.com) they can sort it out.


How do I upgrade the MYSQL database from Craft 2 to Craft 3 on GoDaddy

Generally speaking:

Get the Craft 2 site running locally.
Perform the upgrade to Craft 3 locally according to the docs: https://docs.craftcms.com/v3/upgrade.html
Test and make sure everything works as you'd expect.
Upload all fo the files to your web server via FTP (including composer.json, composer.lock, the vendor folder, etc.).
Once load, load the Craft control panel, you'll be prompted to let Craft update the database.
Let Craft update the database.
Done!

Specifics may vary depending on the site and your actual requirements.


$order->dateOrdered returns a string value the first time and DateTime after that. [Order got through event]

The problem was occurring because the order was retrieved through the EVENT_AFTER_ORDER_PAID event. Therefore, the dateOrdered was still not processed (passed through mutations).

What we ended up doing is using $event->sender only to know what order we are looking for and then retrieve the order anew.

I hope this saves someone's life someday! I'll mark this question as solved in 2 days.


There is a tables plugin for Redactor, to easily create tables direct in the editor. On top of that, I think I'd approach this using the Redactor Clips plugin to pre-create a number of tables that cover the client requirement, as that will also allow you to better control the way tables are created and also set up some client-friendly table styles.


Error with uploading Asset Files: net::ERR_EMPTY_RESPONSE

That usually means "something fatal happened" when trying to upload the file.  The usual culprits are the php.ini max_execution_time and memory_limit settings, but if it's happening for small files too, something else could be going on.

Have also seen it happen when you're uploading an image in a format your underlying image processing library doesn't support.  i.e. your server has GD installed, but you're trying to upload a 32-bit PNG.  Or you're running an older version of GD or Imagick that has a bug you're hitting.

Check if you have a craft/storage/runtime/logs/phperrors.log file.  Any PHP fatal errors will be logged there.  If not, then check the Apache error logs to see if it's an Apache problem.


Append a placeholder value to a text input field when form is submitted

You could either do this the JavaScript way (listen to onSubmit, grab DOM values, append if necessary, otherwise remove), or the PHP way (from a plugin).

I'll pseudocode the latter because I hate the former.

Generate a Craft plugin.
Have it listen for the onBeforeSaveEntry event.
Inside that event listener, you can check if the entry being saved belongs to the section you're interested in.
If so, check your Fetal Heart Rate field.
If its value is "bpm", set it to null or an empty string.
If it's anything other than "bpm", append " bpm" to its existing value.
Repeat 4-6 for the "Estimated Gestational Age" field.
Bob's your uncle.


How do you template an IF statement to avoid an error if an image is not assigned

You're close...

{% set programImage = entry.programImage.one() %}
{% if programImage %}
    <img src="{{ programImage.getUrl() }}" alt=""/>
{% endif %}

You get the the asset model (or null), then check if you actually have it, then finally use it.

It's essentially the same in Craft 2.


Pass radio button values to invisible field in Sprout forms

Two potential ways to address this:

Setup a Sprout Fields Hidden Field and add javascript to your page (or in your form template using Template Overrides) to calculate the values and submit the calculated value with the rest of the form.
Create a custom front-end field integration that is aware of the Radio Button fields that you need to process and have that field calculate and display the result of those values.

The first approach is probably the easiest approach and should work fine if you're sending your submissions via email and if it's unlikely that anybody will be editing the Radio Button fields in the CP.  The second approach may be more robust if there is a chance the Radio Buttons ever get edited and the Total Field needs to get recalculated.

Side Note: The Invisible Field won't work in this use case right now as you want to calculate values based on the submitted form values. The Invisible Field lets you pass it dynamic values as the page loads but at that time the page would not have any info on the values of the Radio Buttons.


Crossdomain ajax request to controller with requireAjaxRequest()

Looking further into the problem, I've found that the page tries to do a post request to the other domain. It calls upon the action function in the UsersController.php file (Location: /craft/app/controllers/)

But because the user isn't logged in on the other domain and anonymous access isn't allowed for this action. You get redirected to /login to login on that domain.

https://craftcms.stackexchange.com/a/12268/635

The developers managed to solve this problem? This applies to almost all controllers require session.


Migrations: What's the right way to rename a Foreign Key?

The 2nd method you tried is the correct order to do it in.

Call BaseMigration->dropForeignKey() ($this->dropForeignKey from within the context of a migration).
Call BaseMigration->renameColumn() ($this->renameColumn).
And add the column back with with BaseMigration->addForeignKey() ($this->addForeignKey).

If you received an error during any of those steps, it's likely because MySQL is complaining about inconsistent data among the FK endpoints or the endpoints are of different data types.

EDIT BY OP

The final version of the code looked like this:

$table = 'myplugin_mytable';
$this->dropForeignKey($table, 'oldId');
$this->renameColumn($table, 'oldId', 'newId');
$this->addForeignKey($table, 'newId', 'myplugin_related', 'id', 'CASCADE', 'CASCADE');


I would say that the index.html should be within your templates folder. Is it?
And make sure that you Homepage section is actually pointing to that template. Look at your sections part within Craft CMS.


If you're running MAMP (and even if you're not, but it's common you are) and you're getting this error when connecting to Craft's web services:

  cURL error 35: Unknown SSL protocol error in connection to craftcms.com:443

Then you're running an older version of MAMP and you need to upgrade to the latest.

The older versions are trying to connect over https using an older SSL protocol (TLS 1.0) that is no longer supported.


Is there a way to determine if an order requires shipping?

Commerce_OrderModel has a getShippingMethod() that will return a Commerce_ShippingMethodModel class of the current shipping method, or null if nothing has been set.

If you've already got the order in the template is should be as simple as:

{% if order.getShippingMethod() %}
    Shipping.
{% else %}
    No shipping.
{% endif %}


Error when outputting assets from a field within a Neo field

You'll need to reference the field handle within asset.
For instance > {{ asset.imageHandle.getUrl('square') }}.
I'm guessing you aren't seeing {{ asset.title }} either?


How can I make an oversized chalkboard organiser?


FeedMe + Google Maps plugin Address fields missing

Good news! The two plugins are now fully compatible as of Feed Me v4.3.6.
Update to the latest version of Feed Me, and give it another shot!


You can remove a line item by including a remove parameter in the request. This example adds a checkbox the customer can use to remove the line item from the cart:
{% set cart = craft.commerce.carts.cart %}
<form method="post">
    {{ csrfInput() }}
    {{ actionInput('commerce/cart/update-cart') }}
    {% for item in cart.lineItems %}
        <input type="number" name="lineItems[{{ item.id }}][qty]" min="1" value="{{ item.qty }}">
        <input type="text" name="lineItems[{{ item.id }}][note]" placeholder="My Note" value="{{ item.note }}">
        <input type="checkbox" name="lineItems[{{ item.id }}][remove]" value="1"> Remove item<br>
    {% endfor %}
    <button type="submit">Update Line Item</button>
</form>

You can check more on this on craft commerce documentation by using below link.
https://craftcms.com/docs/commerce/3.x/orders-carts.html#carts


You could try using the attribute function in twig, this should let you call dynamic properties.

Something like:

{{ attribute(currentUser, question.fieldName) }}


How can you retrieve entries with a specific locale in a plugin?

You'll want to use an ElementCriteriaModel:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->id = $entryId;
$criteria->locale = $lang;
$entry = $criteria->first();

if ($entry)
{
    $response = array(
        'titre' => $entry->typeChambre,
        'etage' => $entry->etage->label,
        'surface' => $entry->surface,
        'loyer' => $entry->loyer,
        'charges' => $entry->charges,
        'description' => $entry->description,
        'photos' => $entry->photosChambre
    );

    $this->returnJson($response);
}


Search for Matrix Block by Date in plugin

You need to add a fieldId param to make Craft join the content table.

$criteria->fieldId = $matrixFieldId;


Joining two plugin tables by reference Id causes duplicates

You're probably looking for an inner join (which Yii just calls a join)instead of a leftJoin: https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/


Changing the asset url for the Control Panel

I can't think of a way to do this.

Problem #1: the URLs generated for control panel resources are based on the Craft install's Site URL (whether that's defined in Settings->General or via the config setting and that is taken into account when creating all links in Craft, not just for control panel resources requests.

Problem #2: in Craft 2, all control panel resources are actually served through PHP, not the web server.  I suspect even if you found a way around #1, this would cause separate issues.


Assign a user group to a structure entry. Restrict permission front end page to that same group

As far as I know there is no way to assign a 'group' using an entries fieldType. What I would likely do is create a category group called 'User Groups' (userGroups) that mirror my groups, with fields for 'title' and 'groupId'.

Group Title 1 -> 1,
Group Title 2 -> 2,
Group Title 3 -> 3,
etc.

(Unfortunately, I think the only way to get the groupId is to look in the database craft_usergroups table. Although the code below could probably be adapted to use the group handle if needed.)

Then create a categories fieldType called 'authorizedGroups', and add it to the video channel's fieldLayout (or wherever else you need it). The client would then be able to select groups via the authorizedUserGroups field that have authorization to the video.

In your template(s) you can then check for videos related to the authorizedGroups that match the currentUser.group and display content accordingly.

First, on your videos index page you would only want to only show links to the videos that the user has authorization to view.

{% if currentUser %}
    {# create an array of the currentUser.groups Ids #}
    {% set currentUserGroupIds = [] %}
    {% for group in currentUser.groups %}
        {% set currentUserGroupIds = currentUserGroupIds|merge([group.id]) %}
    {% endfor %}

    {# find all userGroupCategories that match currentUserGroupIds #}
    {% set userGroupCategories = craft.categories.group('userGroups').find({
        groupId: currentUserGroupIds
    }) %}

    {# find all the videos related to userGroupCategories #}
    {% set entries = craft.entries.section('videos').relatedTo(userGroupCategories) %}

    {% for entry in entries %}

{{ entry.title }}

    {% endfor %}

{% endif %}

Then on the video detail page you would use a conditional that redirects any unauthorized users to a 401 page (or to any other page that you choose).

{% set userIsAuthorized = false %}
{% for group in entry.authorizedUserGroups %}
    {% if currentUser.isInGroup( group.groupId ) %}
        {% set userIsAuthorized == true %}
    {% endif %}
{% endfor %}

{% if not userIsAuthorized %}
    {% redirect 401 %}
{% endif %}

{# display video #}
...

Update: There was a significant code error that did not account for the fact that user.groups returns an array of groups rather than a single group. I rewrote the code to handle this. Untested, and probably still contains errors, but should be closer at least.


User Registration Form Redirect not working Craft 2.5

For Craft 2.6, if a hidden redirect input is set, Craft will now follow it first and fallback to the activateAccountSuccessPath if it's not available.


Output DateTime in that timezone related to the current locale?

You can set the site's timezone in Craft, but you won't get different timezones for your locales with that (locales != timezones btw.). But what you can do is to use Twig's |date filter which allows you to specify a different timezone for the output (list of supported timezones). If you create your own DateTime object by joining strings, you have to add a timezone here to give the filter a basis for its calculations. Make this match your Craft settings.

The following example works without the Localization package.

{# Set locale time to GMT+2 #}
{% set localeTime = "0:00 +0200" %}

        Local Time	Sao Paulo	Manaus

    {% for hour in 0..23 %}
        {% for min in [0, 15, 30, 45] %}

                {# Join time segments in a format supported by strtotime #}
                {% set timeStep = ['+ ', hour, ' hours ', min, ' minutes']|join() %}

                {# Modify the locale time and output in chosen timezone #}
                {{ localeTime|date_modify(timeStep)|date('H:i') }}
                {{ localeTime|date_modify(timeStep)|date('H:i', "America/Sao_Paulo") }}
                {{ localeTime|date_modify(timeStep)|date('H:i', "America/Manaus") }}

        {% endfor %}
    {% endfor %}

To bring the site's currently requested locale into the game, just do some comparisons on craft.locale.

{{ craft.locale == 'de-DE' ? localeTime|date('H:i') }}
{{ craft.locale == 'pt-BR' ? localeTime|date('H:i', "America/Sao_Paulo") }}


Plugin using event listener throws error using $this

Seem to be doing well at asking and then answering my own questions.
If anyone has the same issue as me, it is because you cannot use an anonymous function in the callback. With my example above, the correct way is thus:

craft()->on('capture_submissions.onBeforePost', array($this, 'onCaptureListener'));

public function onCaptureListener(Event $event) {
 ...
}


CBdException: Column 'id' cannot be null

Turns out this was because several tables were missing the MySQL auto-increment flag for their id integer primary keys.


It's order('sortOrder') instead of fixedOrder(true).

{% set entries = craft.entries({
    relatedTo: { sourceElement: entry, field: 'entriesFieldHandle' },
    order: 'sortOrder',
    limit: null
}) %}

If you don't make any further modifications to the params (i.e. reverse order, other limit) there's also the short syntax for the above that Jamie already suggested:

{% set entries = entry. entriesFieldHandle %}


When using Active Record with a View (instead of Table) the primary key is not set in the record after save

This should do what you're looking for:

if ($test_record->save())
{
    // update Member_ID on model (for new record)
    $test_model->setAttribute('Member_ID', craft()->db->getLastInsertId());

    ...
}


If I understand correctly, you want to create a <select> element with options from fields you already setup in the CMS. In that case you can use something like this to get the data for the field:

<label for="yourField">Your Field</label>
<select id="yourField" name="yourFieldHandle">

  {% set dropdownField = craft.fields.getFieldbyHandle('yourFieldHandle') %}
  {% for option in dropdownField.settings.options %}
    <option value="{{ option.value }}">{{ option.label }}</option>
  {% endfor %}

</select>

…replacing yourFieldHandle with the handle of your field, e.g.: children.


What's the purpose of multiple asset sources?

You should use the bucket directory structure for the different asset types; you're right, they are all coming from the same source, really, so separete asset sources wouldn't be correct.

Another asset source would be simply another bucket, or another type of source such as Google Cloud or Rackspace.

You could have an asset source called Web S3 Assets, which connects to your bucket.

As an example, you could have these directories within that bucket for all the types of assets you need to store.

<bucket-url>/images/icons/
<bucket-url>/images/illustrations/
<bucket-url>/images/screenshots/
<bucket-url>/videos/marketing/
<bucket-url>/videos/support/

Use Assets Fields to force usage, upload restrictions on these directories.


Search query: grouping and merging multiple searches

You can combine ORs within the same column but you can't easily combine multiple columns with an OR statement.

craft.entries.yourFieldHandle('OR, x, y, z').anotherFieldHandle('OR, d, e')


Problem adding new locale / Resaving matrix blocks Failed / Table 'matrixcontent_files' doesn't exist

I had a field called files, it did not belong to matrix. After deleting it (tried also simply renaming), the problem disappeared.

After that I created a field with the same name and that did not cause any problems.

Still do not know the exact reason, but later will have time dig a bit deeper, so if get some results will post them.


Template logic to address a third URL segment

I would suggest you look into using Craft's Advanced Routing functionality to accomplish this.

For instance, add the following to your config/routes.php:

'stories/<slug:\w+>/?<option:\w+>?' => ['template' => '_extract'],

This will then populate the _extract template with the twig variable {{ slug }} and also the {{ option }} variable, if it exists.

Then in your twig template you can grab the entry and check for the existence of the option variable thus:

    {% set entry = craft.entries.section('stories').slug(slug).one() %}

    {% if entry %}

Entry title is: {{ entry.title }}

    {% endif %}

Slug is: {{ slug }}

    {% if option is defined %}

Option is: {{ option }}

    {% endif %}

I'd recommend reading the docs on Advanced routing as it's quite a powerful feature: https://docs.craftcms.com/v3/routing.html#advanced-routing


Not quite sure what happened here; Brandon over at EngineHosting re-ran the installation and now I see my info in RPM.

So for future New Relic users that want to integrate with Craft on EngineHosting - at its most basic, ask EH to get New Relic installed for you.

Exciting!  Thanks @joshangell for the help.  Sometimes knowing it should just work is the key. :)

__

Editing as requested.  EngineHosting fully manages my site/server.  I don't have root via SSH so asked them to get the New Relic PHP agent installated (the agent installation requires root).  EH did install NR for me, but the first installation did not work and I do not know why.  When EngineHosting re-ran the installation, the PHP agent worked and Craft (and other PHP apps, mostly the 'index.php' file for each) started reporting to APM.

That's not helpful for people on cPanel or Plesk hosts, admittedly, nor is it helpful for people with root access doing their own installations.  But if you can get the New Relic PHP agent installed where Craft is, then it will report to APM.  Looking forward to getting more specific metrics from Craft to New Relic down the line, but that is not likely to come from me :)

With that very basic installation I get information like this:

I hope that helps.


Thanks Ben. Thought I had very latest version of the plugin, but just updated both Craft and plugin, and problem solved!


No index.php file created during install using composer

Your index.php file should be found under the web directory. All of the other files and folders installed by composer are considered to be above the root which is recommended for security reasons.

Place all of your css, js, images, etc into the web folder and create your twig files in the templates folder and you shouldn't need to edit your index.php file, but web is essentially where it lives. This folder can be renamed to public, httpdocs, or anything you wish. It will be used by your set up as the public root of the domain. I hope that helps.


Commerce: How can I dynamically create a discount for any given product?

I would turn this on it's head slightly (assuming you can express the discount itself, i.e. what it does specifically to the discount item, using normal Commerce discount rules).

If you can, then you can basically make the application of the discount conditional based on what's in the cart.

Here's some sketch code - obviously you might need to change the logic etc

public function onBeforeMatchLineItemHandler($event){

$lineItem = $event->params['lineItem'];
$discount = $event->params['discount'];

$cart = craft()->commerce_cart->getCart();

$idOfItemToPossiblyDiscount = whatever;
$idOfParentItem = whatever;
$idOfDiscount = whatever;

/First check which discount we're thinking about applying
if($discount->id == $idOfDiscount){

    $shouldDiscount = false;
    if ($lineItem->purchasable instanceof Commerce_VariantModel){
        //First check if this is the item that might get discounted
        if($lineItem->purchasable->id) == $idOfItemToPossiblyDiscount)){
            //Ok, so we have that item in the cart now loop through $cart to see if the 'parent' item is in the cart
            foreach ($cart->lineItems as $item){
                if ($item->purchasable->$id) == $idOfParentItem){
                    //do nothing, but finish here - Commerce will carry on and apply the discount as long as
                    //we dont set event->performAction = false;
                    $shouldDiscount = true;
                    break;
                }
            }

        }

    }

    if(!$shouldDiscount){
        $event->performAction = false;
    }

}

Obviously at the template end of things you can loop through what's in the cart and do similar logic to show messages etc - e.g. if parent item is in, and not the discount item, present the offer, etc....


Reverse it!

    {% for row in entry.myTableFieldHandle|reverse %}

{{ row.columnHandle }}

    {% endfor %}


Is there some way to create sections inside static translations? (craft v3)

You can include custom translation categories within your config/app.php

return [
    'modules' => [
        'my-module' => \modules\Module::class,
    ],
    'components'    => [
        'i18n' => [
            'translations' => [
                'foo'  => [
                    'class'            => \craft\i18n\PhpMessageSource::class,
                    'forceTranslation' => true,
                    'basePath'         => '@translations',
                ],
            ]
        ]
    ]
    //'bootstrap' => ['my-module'],
];

This will include the custom group foo to your app, make sure to change the basePath variable to a path you like

That being said your folder structure will look like

-your base path
|-- en-US
|-----> foo.php
|-- de-DE
|-----> foo.php

within these files you can create your custom translations

return [
    'foo' => 'bar'
];

{{ 'foo'|t('foo') }} -> will now display bar
{{ 'foo'|t('site') }} -> will still show foo


How do I combine search for categories and entries into one set of search results?

The reason you're getting an error when trying to merge the two search results is that they are not technically arrays, but elementCriteriaModels. To convert them to actual arrays you would need to use the find() method.

{% set entries = craft.entries.search(query).order('score').find() %}
{% set categories = craft.categories.search(query).order('score').find() %}
{% set results = categories|merge(entries) %}

The problem with this is that the sort order will be wrong (showing all categories and then all entries). Although you could potentially sort the results array using something like the supersort plugin.

The other option to consider is redesigning the database so that there is nothing in categories that needed to be searched for, which might simplify things in the end.


Validating Date of Birth format from a form field value

Would it be worth doing some client-side validation first using javascript to check the date of birth field is entered correctly? You can use an onChange event on your field and then split the string on "/" and check each part is within a valid range 0-31, 1-12, 1900-2016.

For serverside checking, you can use strtotime() and check that the return isn't false.


Anyway to programmatically add default fields to a layout?

After hours of perusing, I managed to find a working solution to this issue.  I threw this implementation from InstallService located in craft/app/services.

I realized that CommerceProduct and Variant Field Layouts were set into the Commerce Product Type Model via setFieldLayout() function, therefore all I would need to do is create a new Field Layout with the fields that I required and set them into defaultProductTypes().

    //Write this code in between CommerceProductFieldLayout and Variant type field Layout

    //Any custom fields for your products go here.
    //Format: $yourFieldName = FieldsVariable::getFieldByHandle("Your field's
handle");
    $bodyField = FieldsVariable::getFieldByHandle('body');
    $tagsField= FieldsVariable::getFieldByHandle('tags');

    //Assemble a new layout that contains the fields you need.
    $infoLayout = craft()->fields->assembleLayout(
        array(
            'Content' => array($bodyField->id, $tagsField->id) //Add fields into this array to display your plugins. (e.g. - $YourFieldVariable->id)
        ),
        array($bodyField->id) //Add any required fields here.
    );

    // Save Layout into specified product type.
    $productType->setFieldLayout($infoLayout);


As per the Craft Docs at https://craftcms.com/docs/multi-environment-configs#environment-specific-variables, add a basePath (or other name) variable to you config. For MAMP, it should look something like:

'basePath' => '/Applications/MAMP/htdocs/example.dev/public/'

Then in your asset source settings, change File System Path to:

{basePath}assets/images/hero-images/


Can we define routes (non-CP) in plugins?

Is the registerSiteRoutes hook what you're looking for?


Is there a JS event triggered when a new widget is created?

It appears when a new widget is created it has a variety of classes (such as new and loading-new) that don't exist on established widgets:

class="widget new loading-new myplugin_mywidget flipped last"

It's also possible to add javascript to the widget settings file that gets rendered for your widgets settings. In the admittedly lame (but illustrative) example below, your new widget will get the text color of red, and after it is saved and the page reloads, no red color will be applied.

{% includejs %}
(function(){
    $('.widget.new.myplugin_mywidget').css('color', 'red');
})();
{% endincludejs %}


Craft CP showing plugin updates, but already updated

There was something wrong inside the vendor folder. Couldn't find what. What I did to solve it (thanks to Craft support):

Rename vendor folder to vendor-old
Ran composer clearcache to delete all content from Composer's cache directories
Ran composer install to install all depencies in composer.json
Deleted vendor-old folder


How to send email from Craft 3 custom plugin?

Edit: After the migration to Craft 3.1.x you should rather use this Code
/**
 * @param string                            $html
 * @param string                            $subject
 * @param array|string|\craft\elements\User $mail
 *
 * @return bool
 */
public function sendMail(string $html, string $subject, $mail): bool
{
    return Craft::$app
        ->getMailer()
        ->compose()
        ->setTo($mail)
        ->setSubject($subject)
        ->setHtmlBody($html)
        ->send();
}

Edit: this is my old answer, valid for Craft 3.0.x
This is my code to send emails in Craft 3. Let me know if you have any questions.
use craft\mail\Message;

/**
 * @param $html
 * @param $subject
 * @param null $mail
 * @param array $attachments
 * @return bool
 */
private function sendMail($html, $subject, $mail = null, array $attachments = array()): bool
{
    $settings = Craft::$app->systemSettings->getSettings('email');
    $message = new Message();

    $message->setFrom([$settings['fromEmail'] => $settings['fromName']]);
    $message->setTo($mail);
    $message->setSubject($subject);
    $message->setHtmlBody($html);
    if (!empty($attachments) && \is_array($attachments)) {

        foreach ($attachments as $fileId) {
            if ($file = Craft::$app->assets->getAssetById((int)$fileId)) {
                $message->attach($this->getFolderPath() . '/' . $file->filename, array(
                    'fileName' => $file->title . '.' . $file->getExtension()
                ));
            }
        }
    }

    return Craft::$app->mailer->send($message);
}


Craft 3 - Searching by date field - Calling unknown method: craft\behaviors\ElementQueryBehavior

Was missing the square brackets

{% set groupedEvents = craft.entries(params).eventDate(['and', '>= ' ~ startdate, '<= ' ~ enddate]) | group('eventDate|date("Y-m-d")') %}


Untested but you might want to try setting CRAFT_EMPEMERAL to true to skip the filesystem checks.
You can also opt out of automatic project config creation using the Manual YAML File Generation method found in the docs.


Access the site when the system is off means that a logged in user with that permission can view the website front end (I think - never actually used this). You can set the system status in Settings > General, or via the craft/config/general.php file using 'isSystemOn' => true/false.

If a user doesn't have "Publish live changes" it means that the user can create new entries, but they can't appear on the front end of the site because they can't set the entry status to be published (the green lightswitch button on all Entries). This means you can review their content as a more privelidged user before they get made public.


How flexible is tying content to a structure?

Structures simply add an extra bit of sorting and querying. You can look for entries in a structure the same way you look for entries in a channel. The difference is that you can also have parents and children in a structure with a manually set order.

If you look at the section page for a structure and hover over an entry, you will see a move handle. You can use that to resort your entries in any order you wish. You can also move the entries to become the child of any other entry. Taking three child entries of a top-level nav and moving them to another top-level nav is no problem.

How you organize your content is highly contextual. I don't know what kind of site you're building, so I can't say what's best for you. Most sites I've built thus far have only needed channels save for one. And for that one, I have two structures and two channels. I'm using one channel for news entries, and the other for event entries. I'm using a structure for static pages so I can sort them into a hierarchy (and it gives me breadcrumbs). I'm also using a structure for the main menu because it needs to be set up somewhat different than the static pages (and I need extra fields). This was all chosen based on the needs of my client's site. So just think about your client's needs. Will they be editing it? Is how you have it set up now easy for them to understand how to edit?


Is it possible to return data/models from controller to template via setRouteVariables?

I believe you are overwriting the log variable you are sending back to the template when you set log equal to the response of getPost.

From what I can see of your code, when you return variables to your template via setRouteVariables, you should be providing the variables you define in that array to your template, without having to take a second step and retrieve them.  So, when your controller returns:

craft()->urlManager->setRouteVariables(array(
   'log' => $log
));

You should then be able to access that variable in your template if it exists:

{% if log is defined %}
    {{ dump(log) }}
{% endif %}

setRouteVariables adds your variables to Twig's context, which you can see in your template by dumping _context:

{{ dump(_context) }}

Or, a handy way to just see the variables available in the context and not the full models is using the keys filter:

{{ dump(_context|keys) }}

In your case, I believe when your page reloads, your log variable is available, but then you set it to null when you try to retrieve it.

Your current code:

{# Sets log to null, because no post variable exists named `log` #}
{% set log = craft.request.getPost('log') %}

{% if log is defined %}
    {{ dump(log) }} {# outputs null #}
{% endif %}

Try outputting the log variable before setting your getPost value:

{# Outputs log if it exists in Twig's context #}
{% if log is defined %}
    {{ dump(log) }} {# will probably output your value #}
{% endif %}

{# Delete this. It just overwrites your existing log variable #}
{% set log = craft.request.getPost('log') %}


WARNING: heuristic fragment matching going on! when querying matrix fields or any query with multiple fragment types with Graph QL using Nuxt Apollo

I struggled with this for ages, but after @mylesthe.dev (who responded to one of the posts i mention above) spoke to me directly to provide fantastic support and some examples, I figured it out. So for anyone else still struggling like I was, here's the code (thanks to his work) which finally got things working for me:
First of all, in your nuxt.config.js set up your apollo configs:
// Apollo config and endpoint for graph ql
  apollo: {
    includeNodeModules: true,
    clientConfigs: {
      default: '@/apollo/client-configs/default.js' // This is where you'll set up the client and import the possible fragment types
    }
  },

Now we create the apollo client set up with the fragment schema file (which we'll create) in apollo/client-configs/default.js
import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import schema from './schema.json';
const fragmentMatcher = new IntrospectionFragmentMatcher({
    introspectionQueryResultData: schema
  })

export default ({req, app}) => {
    const token = process.env.GRAPHQL_TOKEN
    return {
        httpEndpoint: process.env.API_ENDPOINT,
        getAuth: () => `Bearer ${token}`, // remove if you're using the public schema
        cache: new InMemoryCache({ fragmentMatcher }),
    }
}

Now save an empty schema.json file in apollo/client-configs/.
Next we need to set up the script to query and generate this schema on nuxtServerInit.  You'll need fs to write your schema file. You can install it with NPM: npm install --save fs.
Once installed, go back to your nuxt.config and add fs to the build:
  build: {
    extend (config, ctx) {
      config.node = {
        fs: 'empty'
      }
    }
  }

Then in your store/index.js:
import Vuex from 'vuex';
import fetch from 'node-fetch';
import fs from 'fs';

const createStore = () => {
  return new Vuex.Store({
    actions: {
        async nuxtServerInit({commit}, {app}) {

            // only update fragements locally
            if (process.env.NODE_ENV == 'local') {

                // LOAD FRAGMENT TYPES AND STORE IN FILE
                // APOLLO READS THIS FILE LATER
                fetch(process.env.API_ENDPOINT, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json', authorization: 'Bearer ' + process.env.GRAPHQL_TOKEN, },
                    body: JSON.stringify({
                        variables: {},
                        query: `
                            {
                                __schema {
                                    types {
                                        kind
                                        name
                                        possibleTypes {
                                            name
                                        }
                                    }
                                }
                            }
                        `,
                    }),
                })
                .then(result => result.json())
                .then(result => {
                    // here we're filtering out any type information unrelated to unions or interfaces
                    const filteredData = result.data.__schema.types.filter(
                    type => type.possibleTypes !== null,
                    );
                    result.data.__schema.types = filteredData;
                    fs.writeFile('./apollo/client-configs/schema.json', JSON.stringify(result.data), err => {
                        if (err) {
                            console.error('Error writing fragmentTypes file', err);
                        }
                    });
                });

            }

        },
    }
  });
};

export default createStore

Your schema should now be generated locally to the schema file and that file will be stored in the apollo cache.


How can I configure multi-site base URLs where the subdomains are static but the domain name is dynamic?

You could achieve this using Aliases.
In your .env, you could set DEFAULT_DOMAIN="yourdomain.com" then in your config/general.php you would do:
'aliases' => [
    'siteAbc' => 'http://abc.' . getenv('DEFAULT_DOMAIN'),
    'siteXyz' => 'http://xyz.' . getenv('DEFAULT_DOMAIN')
],

With this in place, you will be able to use @siteAbc and @siteXyz to set your site URL as well as @siteAbc/images for your assets Base URL for example...
Note that all naming convention is up to you, of course...


Is it possible to change a user's password in the front-end?

It is! To do so, they will have to be logged in and input their old password. They need the old password to change their email or update a password.

Here's an example:

{% macro errorList(errors) %}
    {% if errors %}
        {% for error in errors %}

{{ error }}

        {% endfor %}
    {% endif %}
{% endmacro %}
{% from _self import errorList %}

<form method="post" action="" id="action-form" accept-charset="UTF-8" enctype="multipart/form-data">
    {{ getCsrfInput() }} {# Remove this if you aren't using CSRF #}
    <input type="hidden" name="action" value="users/saveUser"> {# "users/save-user" if you're on Craft 3 #}
    <input type="hidden" name="redirect" value="{{ entry.url }}">
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

    Current Password
    <input type="text" class="form-control" id="currentPassword" name="password" />
    {% if account is defined %}
        {{ errorList(account.getErrors('currentPassword')) }}
    {% endif %}

    Email
    <input id="email" type="text" name="email" class="text" />
    {% if account is defined %}
        {{ errorList(account.getErrors('email')) }}
    {% endif %}

    New Password
    <input type="text" class="form-control" id="newPassword" name="newPassword" />
    {% if account is defined %}
        {{ errorList(account.getErrors('newPassword')) }}
    {% endif %}
</form>

This is code that would be inserted into a new custom front end template.


You'll be able to get better/quicker help through the plugin page and submitting an issue - https://github.com/engram-design/FeedMe/issues. I'd be happy to help and see what might be the issue.

But if you could, please follow the Support steps as outlined here - https://github.com/engram-design/FeedMe#support.


The controller you're posting to is responsible for the validation. In the case of the entries/saveEntry controller for example there's an Entry model populated and then run through the validation. Each model attribute and all the fields (content) have to give their ok for the complete model to validate correctly.

For the fields it's the field type's attribute type and an optional validate method that are responsible. Have a look at this plugin by Marion Newlevant, it provides a simple field type with configurable validation and is probably a good example for what you're trying to achieve.

https://github.com/marionnewlevant/craft-mn_matchinput


Display a list of categories excluding the current one

With a little help I got there:

{% set categories = craft.categories.group('developmentType').id('not ' ~ category.id) %}

{% for category in categories %}

{{ category }} Opportunities

{% endfor %}


BE formatted dates not imported correctly (or not at all)

After being in contact with the developer both issues are solved. If you have a similar issue use the latest codebase on the master branch (not the 2.0.7 as that version doesn't have the fixes yet)

for the first issue (date format problem) there is an additional functionality available that allows you to predefine what the layout is of the date field you're trying to import

second issue (the date offset problem) was a bug and has been fixed

The most recent codebase can be found here: https://github.com/engram-design/FeedMe/archive/master.zip

A big thanks to Josh Crawford for helping out that fast!


How to require form submission before template display?

Not terribly familiar with Sprout Forms, but it looks like you could gate the download with a query string parameter, like in Sprout Forms' Thank you Page example

Example:

Add this to your form:

<input type="hidden" name="redirect" value="/DOWNLOAD_PAGE?submitted=true">

and then in your download link template:

{% if craft.request.getParam('submitted') == 'true' %}
    DOWNLOAD_LINK
{% else %}
    Please submit the form here LINK_TO_YOUR_FORM to access this whitepaper.
{% endif %}


“Access Plugin” doesn't appear in Permissions list

If your plugin has a CP section (specifically, the main Plugin class declares a $hasCpSection property, and it’s set to true), you should get an “Access My Plugin Name” option near the top of the permissions list—this might be enough to grant access to your plugin's controllers. See how this is enforced, here.

If you want to use more granular permissions, you'll have to check that box, plus anything you register via the UserPermissions::EVENT_REGISTER_PERMISSIONS event. Here's an example of that being done in a stripped-down main plugin class:

<?php

use Craft;

use craft\base\Plugin as BasePlugin;
use craft\events\RegisterUserPermissionsEvent;
use craft\services\UserPermissions;

use yii\base\Event;

class MyPlugin extends BasePlugin {
    // ...

    public function init()
    {
        Event::on(
            UserPermissions::class,
            UserPermissions::EVENT_REGISTER_PERMISSIONS,
            function (RegisterUserPermissionsEvent $event) {
                // Each "group" is just a key in the Permissions array, and you can have
                $event->permissions[Craft::t('my-plugin', 'My Plugin Features')] = [
                    // You might have discrete feature permissions, or different ones for `access` vs `modify`:
                    'my-plugin-access-first-feature' => [
                        'label' => Craft::t('my-plugin', 'Can Access Feature A')
                        // You can also use the `nested` key here to group permissions!
                    ],
                    'my-plugin-access-second-feature' => [
                        'label' => Craft::t('my-plugin', 'Can Access Feature B')
                    ]
                ];
            });
    }

    // ...
}

In a controller action, you can call $this->requirePermission('my-plugin-access-first-feature'); to lock down access.

  Also worth noting: Some plugins (like Commerce) use a few abstract controller definitions (i.e. BaseController, BaseCpController, BaseAdminController) to lock down entire bundles of functionality. If you're using this paradigm, you won't be able to easily relax permissions—only tighten—enforced by the parent Controller.


From reading your question it seems like the fields haven't been added to your entry type for the section you are trying to add entries to.

The first thing I'd recommend doing is to go to Settings > Sections then find the section in the list you are trying to add entries to.
You should see an Entry Types column at the right; click on the Edit entry type option for the section.

This part of Craft allows you to add the fields you would like available in your entry. You can create your own tabs to categorise your fields as you see fit.

All you will need to do is drag the fields from the bottom of the screen into your field layout.

Go back to the entry and hopefully the fields you added will be showing!


From that code snippet, it looks like you're needing nested arrays. Try setting your $email->cc property like this.

$email->cc = array(
    array('name' => 'Your Name', 'email' => 'name@example.com')
);

The code snippet is iterating over $email->cc as $cc as the first array, then going into cc['name'] and cc['email'] as a nested array.


Is it possible to use the MySQL LIKE directive in an ElementCriteriaModel?

The * wildcard character should do the trick.

c.f. https://craftcms.com/docs/templating/elementcriteriamodel#parameter-value-syntax

$assets = craft()->elements->getCriteria(ElementType::Asset, array(
    'filename' => $prefix.'*',
    'limit' => null,
))->find();


What is the best approach for multi categories filtering

You could leave the Category URI Format blank in your settings and set an advanced route in config/routes.php like so:

'projects/<type:{slug}>/<state:{slug}>/<location:{slug}>' => ['template' => 'projects/index'],

Which would make {{ type }}, {{ state }} and {{ location }} available as variables in your template.


Prevent Craft URLs containing # from redirecting

The setup you have there is creating routes within the system not overriding the URL property of your entry. If you just want to generate anchors you should uncheck "Entries in this section have their own URLs"

Then within your template for your top-level structure item run a loop and output the content with ids and then the anchors as links.

{% set entries = craft.entries.section('myStructure') %}

{% for entry in entries %}

{{ entry.title }}

{% endfor %}

{% for entry in entries %}

        {{ entry.content }}

{% endfor %}


I run Craft on IIS/Win 10 on my main development box and don't have issues with it.  Don't recall having to jump through hoops to get it working, either.

I suspect it's more of the "shared server" that's the issue, but you can start by enabling devMode in Craft and check the timestamped profiling output (code and database) in the browser's console and craft/storage/runtime/logs to try and narrow down where the time is going.


Do Freeform Events Fire From Control Panel?

"Submissions" is referring to the submission  of a front end form. Not the Control Panel.


Matrix within Matrix isn't possible... yet. Brandon has stated a few times that it's part of the long-term plan, and it's really more of the UI which is a stumbling block, rather than any major technical challenge.

  ... Matrix within Matrix is still something we intend to get working at some point.

  … Matrix within Matrix will be coming eventually. The UI is tough, but the code is all in place.

In the meantime, you may want to try using the LJ Dynamic Fields plugin. It may not be exactly what you're dreaming of, but it can certainly help keep things a little DRY-er.


Eager loading relations in Plugins Element Type

Ok, so i managed to solve my problem without actually fetching any extra records, but instead using mysql group_concat function for the fields i need to display. Posting this here for anyone else that might need it.

In OrderElementType:

public function modifyElementsQuery(DbCommand $query, ElementCriteriaModel $criteria){

    $query
      ->addSelect('group_concat(items.productName separator \';\') as productnames')
      ->join('orders orders', 'orders.id = elements.id')
      ->leftJoin('items items', 'orders.id = items.orderId'
      ->group('elements.id');
}

public function populateElementModel($row){
  $model = OrderModel::populateModel($row);
  $products = explode(';', $row['productnames']);
  foreach($products as $product){
    $item = new ItemModel();
    $item->productName = $product;
    if(!$model->items){
      $model->setAttribute('items', array());
    }
    $model->setAttribute('items', array_merge($model->items, array($item)));

  }
  return $model;
}


If other image formats are working fine, then maybe check that you have Imagick installed and enabled on the server.

Eg.

sudo apt-get install imagemagick php5-imagick
sudo service apache2 reload

If you're on a shared host then either consult their knowledge base or contact support to check for Imagick availability.

Some servers/hosts only have the GD library installed by default, which isn't so good with PNG files.


I like where you're going with this, but what you're trying to do isn't possible (yet).
As it currently stands, you need to use an Asset as the kmlFile parameter...
https://plugins.doublesecretagency.com/smart-map/kml-files/
It's on the roadmap to allow a string URL to be passed in directly.

UPDATE:
I've just added the ability to specify a KML by its absolute URL string. The new feature will be included in the next release of Smart Map. :)


Dependency Conflict Updating to Craft 3.5

Not a true fix, but on the off chance this helps someone, here are the steps I took:

Create a local clone of the live Craft install with a dummy database, but the same composer.json and project.yaml files.
Delete the storage and vendor folders, and the composer.lock file.
Run composer update.
Install a plugin from the live admin panel.
Delete the vendor folder and composer.lock file on the server.
Upload the new local vendor folder to the server.
Uninstall the plugin again, causing composer to run.

Then when I went back to the updates panel and reran it, Craft upgraded without any issues.


with is just another query param, like limit or whatever parameters you’re defining in entryParams.

The {% paginate %} tag requires that you pass in an ElementCriteriaModel, but as soon as you call find() you’re actually dealing with an array of the matched entries.

So the key to getting eager-loading working with pagination is to assign the with param like any other param, rather than passing it into the find() function.

{% set queryParams = {
    // ...
    with: [
        'gridMatrixBlock1:rowItem1',
        ['gridMatrixBlock1:rowItem1.gridimageFile', {
            kind: 'image',
            withTransforms: projectThumb
        }],
        ...
    ]
} %}

and then you can create your ElementCriteriaModel just like you were doing before:

{% set allProjects = craft.entries(queryParams).limit(itemsPerPage) %}


Import JSON feed data automatically without FeedMe

The answer is Routing.
Define a wildcard route
e.g. URL/path/*
Then tell it to use a particular template if that route is used.

The key thing to do (which I didn't do first time around) is:
Don't duplicate the same route in a section.
If you do, Craft follows the section path not the routing path and expect entries to be in the CMS.


Where is this spam message sent using the Contact Form plugin?

Currently not possible without forking the Contact Form plugin and changing the logic to do what you're looking for.

There are other form builder/contact form plugins that might have more options when dealing with SPAM you might want to look at as well: https://plugins.craftcms.com/search?q=contact%20form


Yes it's possible.

You're kind of making more work for yourself by keeping the blog on one platform and the store on another but there is no reason you can't do it that way.

You will need to run the blog and the store on separate domains i.e. www.yoursite.com and shop.yoursite.com or else move the blog over to Craft (or run your store on Wordpress).

There will be extra challenges involved if you want to share data between the 2 sites - because they will effectively be 2 separate websites. But again, totally possible with the right planning.

Commerce will cope fine with 5000 products.


How to do "restricted page/asset"->login->register->"restricted page/asset"?

You should be able to get the return url from craft. I just did a quick test and it seemed to carry over to a registration page from a log in page that happened due to a restricted page, so maybe try something like this in your registration template:

{% set redirectUrl = (craft.session.getReturnUrl() ?: '/') %}

<input type="hidden" name="redirect" value="{{ redirectUrl }}">

That way after they register they will be redirected to the restricted page, asked to log in and then craft should redirect them to the restricted page automatically.

Hope that helps!


Using Craft with CloudFront, and handling invalidation

One way would be to manually clear it with Cloudfront Invalidation.


Conditional to see if an Entries field in a user profile contains a certain entry ID

My initial though was that you do not need to not put the "entry.id" in quotes because it's a variable reference, but the contains() method appear to not work as expected here even when this was corrected.

The booksField returns an ElementCriteriaModel, so you should be able to fetch the list of IDs as a plain array and then use Twig's in "containment operator" to search it:

{{ entry.title }}

{% if entry.id in currentUser.booksField.ids() %}
  I have read this book
{% else %}
  I haven't read this book
{% endif %}


Categories not displaying as nested in control panel

So, there's no mention of this in the v3 docs that I could see.

I went back to an older project where I'd used categories to find that I set the Category URI format field to {% if object.level == 1 %}read/category/{slug}{% else %}{parent.uri}/{slug}{% endif %}

This was obviously documented at some point for me to implement it on what would have been an original Craft install.

There's no mention of this being needed to enabled nested categories on https://docs.craftcms.com/v3/categories.html#category-groups so it should get added.


Output first matching matrix block model if condition is true

Can't something like this help you?

{% for block in entry.myMatrixField.type('fruits').ligthswitchField(params) %}


Craft 3 - Save new Entry with Relations (Categories/Assets)

This should be as simple as setting the relation field (category, asset, etc.) value on the entry as an array of related element IDs before saving.
$entry->setFieldValue('categoryFieldHandle', [$categoryId1, $categoryId2]);

Craft::$app->elements->saveElement($entry);

This will work for all relation fields:
$entry->setFieldValue('assetFieldHandle', [$assetId1, $assetId2]);

Craft::$app->elements->saveElement($entry);


Can you batch-change all authors in the CP?

There's currently no way to do so natively in the CP, but there is a round-about way to do it using a CSV file with a pair of indispensable plugins from Bob Olde Hampsink:

Import
Export

Do the export/import 2-step

Use the Export plugin to spit out just the Title and Author from the section you want. Open up the resulting CSV file in whatever editor you want, you don't necessary have to use Excel or OpenOffice in this case since it's just text.

Do a find/replace on the author with the new author. Save the file.

Open up in the Import plugin, and again, tell it what section you want and to replace the data. On the next screen, confirm Title and Author are already selected for you. Title should be checked as how to match up the data. Run the import.

You're basically telling the plugin to leave everything alone except to replace the Author and use the Title (which we exported before) as the source.
Rinse and repeat with as many sections you have.


How to set index page as parent of a structure

If I understand your question, you want to combine a Single and a Structure into the same family of URL's, something like this:

/services - (Single)

/services/service-01 - (Structure Entry)

/services/services-01/example-sub-service-01 - (Structure Entry)

/services/services-01/example-sub-service-02 - (Structure Entry)

/services/service-02 - (Structure Entry)

/services/service-03 - (Structure Entry)

As you rightly said, you would create a Single for your Services homepage and set the URI to services.

You would then create a Structure called "Servcies", and set the URI to:

{parent.uri ? parent.uri: '/services'}/{slug}

This nice bit of Twig checks if parent.uri is defined, and outputs it if it is. Otherwise (if the entry is top level in the structure, it just outputs /services/{slug}


Any native solution is likely to be slow - I would recommend using the Preparse field plugin.

It lets you use Twig to dynamically generate a field at the time an entry is saved — you could have Preparse count up the number of related users on save, and then sort by that custom field.


Pass Craft Instance to A Vendor PHP File

You don't need to pass anything in there.

The function craft() is just a public function that returns the static app. It does not matter if you call it inside a plugin or somewhere else.

namespace Craft; //<----- added namespace
class Wally {
   function __construct() {
      $criteria = craft()->elements->getCriteria(ElementType::Entry);
   }
}

If you don't want to be in the same namespace you can do

class Wally {
   function __construct() {
      $criteria = \Craft\craft()->elements->getCriteria(\Craft\ElementType::Entry);
   }
}

If you really want to save the app in an extra variable for whatever reasons you would do

new Wally(craft());


Trigger sent before user is added in user group so no email is sent

You can programmatically trigger a notification email using the Sprout Email service layer. Notification Emails are sent via the SproutEmail_DefaultMailerService using the sendNotification() method:

craft()->sproutEmail_defaultMailer->sendNotification($campaign, $object);

$campaign needs to be a SproutEmail_CampaignModel
$object, in your case, would be the Craft UserModel (and more generally is any object that you want to make available to your email templates


To expand on my comment you could do this:

In templates/_pages/index.twig you would do:

{% include '_pages/_types/_' ~ entry.type %}

Then create a folder in /templates/_pages/ called _types in it use, an example _standard.twig in which "standard" coincides to your Entry Type slug.

I hope that helps. I couldn't find the original SE post but I know that this method has been mentioned and preferred by many Crafters!


Path and Entry Template problems when developing locally

Your image/CSS/JS URLs should be either absolute, protocol-relative, or root-relative:

<link rel="stylesheet" href="http://example.com/assets/css/nav.css">

<link rel="stylesheet" href="//example.com/assets/css/nav.css">

<link rel="stylesheet" href="/assets/css/nav.css">

Relative URLs (which start with either ./, ../, or no slash at all) are generally a bad idea, since the URL will need to vary depending on the number of segments in your URI.

For example if you were to access http://example.com/, the relative path to your nav.css would be assets/css/nav.css, but if you were to access http://example.com/about/ (with a trailing slash), then the proper relative URL would be ../assets/css/nav.css.

That’s not to say that relative URLs are impossible. The main issue with your URLs is not that they’re relative, it’s that you’re treating them as relative from the physical template file location. Keep in mind that these front-end resource URLs are resolved by the browser, not by the server, and browsers have no idea how the resulting HTML gets generated, let alone that it came from a template that happened to live a couple directories up from your web root, and in a craft/templates/... subfolder. So they need to be relative based an the apparent location of the webpage, as defined by its URI (e.g. “/news/some-slug”).


Redirecting after login based on user group

To set the setting dynamically, you’ll need to create a new plugin, which just has an init() method with this:

public function init()
{
    // Is this a login request?
    if (
        craft()->request->getActionSegments() === array('users', 'login') &&
        ($loginName = craft()->request->getPost('loginName')) !== null &&
        ($user = craft()->users->getUserByUsernameOrEmail($loginName)) !== null
    )
    {
        if ($user->isInGroup('userGroupA'))
        {
            craft()->config->set('postLoginRedirect', 'path/a');
        }
        else if ($user->isInGroup('userGroupB'))
        {
            craft()->config->set('postLoginRedirect', 'path/b');
        }
    }
}

If none of the conditions match, then Craft will stick with whatever’s in your craft/config/general.php file.


Troubleshooting Slow Craft Website - New Relic

I don't know where the first set of data you posted is coming from, but in the attached stack trace autoloading is only .54% of the total request.

Whatever template(s) you're rendering account for 65% of the request (for a total of 8 seconds), so I'd start inspecting there.

Loading all of the plugins you have installed is about 10% (which accounts for about 1.3 seconds of the request), so I'd investigate those as well.


Setting system email address and sender name in multi config

The testToEmailAddress config setting which

  Configures Craft to send all system emails to a single email address (or multiple email addresses), for testing purposes.

sounds like the one you are looking for.


Where do I begin troubleshooting a Form in Craft that is redirecting to /login on iPad and iPhone?

Just an idea, but are you Allowing Anonymous Access to Actions? Maybe you are logged in on your Desktop, but not on your iPhone.

Example:

protected $allowAnonymous = true;


Getting all the values out of a field as array of values

$element->getFieldValue('handle') or it's Twig equivalent element.handle contains an Object of type MultiOptionsFieldData you can get all possible values via itsgetOptions()` function

Twig

{{ dump(entry.fieldHandle.getOptions()) }}

PHP

$options = $element->getFieldValue('handle')->getOptions();


How to print all possible options of a dropdown field inside of a Matrix field?

This can be done like so...

{% set matrix = craft.app.fields.getFieldByHandle('myMatrixField') %}
{% for field in matrix.blockTypeFields if field.handle=='myDropdownField'  %}
    <select>
    {% for option in field.options %}
        <option value="{{ option.value }}">{{ option.label }}</option>
    {% endfor %}
    </select>
{% endfor %}


activateAccountSuccessPath doesn't work as expected

If the user account that is registering has access to the control panel, either directly or via a user group, then they'll get redirected to the control panel login page after clicking the activation link in the email.

If they don't have access to the control panel, then they'll get redirected to the 'activateAccountSuccessPath' config setting.


Image transforms getting applied even when image is smaller than the transform's width

I think you're confusing the "Width" setting to mean "Max Width", which it doesn’t. The image will get sized to match your transform's Width setting, regardless of whether it's bigger or smaller than that width beforehand.

If you want to conditionally apply the transform, only if it's larger than the transform's width, you can do this:

{% if asset.width > asset.getWidth('detail') %}
    {% do asset.setTransform('detail') %}
{% endif %}

<img src="{{ asset.url }}" alt="{{ asset.title }}" class="{% if block.position in ['left'] %}pull-left{% endif %}">


Getting Twig_Error_Runtime when trying to open the website

siteName is automatically global... you don't need to include the global. prefix.

<title>{{ siteName }}</title>


Cart Items Total to include qty of variants

You can get the total quantity of items with:

cart.totalQty

Docs: https://craftcommerce.com/docs/order-model#totalqty


Impossible to invoke a method on a null variable

Well, the first method only tries to get an asset model. But if there's no asset added to the field it simply returns null. So calling a method like getUrl, or accessing a property like url or title can't work, as they do not exist for null.

{% set image = entry.geschaeftsbereichHeadImage.first() %}

{% if image %}

{% endif %}

Or if you'd like to display a fallback image consider somthing like this:

{% set image = entry.geschaeftsbereichHeadImage.first() %}
{% set imageUrl = image ? image.url(headBanner) : 'path/to/fallback.jpg' %}


We have multiple clients, and so using craft.dev for our development is not really feasible.

How about client1.craft.dev, client2.craft.dev etc?


If you're looking for a more robust and easy-to-use solution, have a look at the CPNav plugin, which allows you to re-order, rename and hide menu items.


Not sure if this is a good idea, but it does work. You simply got the syntax wrong, it should be:

{{ url('a-url-slug'|t) }}


How can I skip a required field if is not in the form?

If they're required, then they're required... it doesn't matter if the form is being submitted on the front-end or back-end.

The easiest solution to this would be to simply provide that data as hidden inputs...

<input type="hidden" name="fields[myRequiredField]" value="default value">


You need access to the server your Craft site is installed on to install the plugin code in the craft/plugins folder.

In addition to that, you will need administrator access to the Craft Control Panel to access Settings->Plugins in order to install any plugins.

Most likely, you'll need to contact the administrator of your site or whomever developed/still maintains it to progress.


This was an email template problem. While the template loaded fine in a browser, it was failing when being sent by Craft Commerce on a status update. The only clue was when manually updating a status in the control panel and receiving a Javascript alert saying 'Undefined'. Nothing in any logs. I feel quite fortunate to have happened to have stumbled across the solution with only a day's work.


Template extraction of namespace node values from RSS using Feedme plugin

As the example actually shows, you'd reference these sort of nodes using the array notation.

{{ node['dc:creator'] }}


If you set the elementType to User, then the transformer will have a UserModel object passed in like so:

<?php
namespace Craft;

return [
    'endpoints' => [
        'players.json' => [
            'elementType' => 'User',
            'criteria' => ['group' => 'player'],
            'transformer' => function(\Craft\UserModel $user) {
                return [
                    'username' => $user->username,
                    'jsonUrl' => UrlHelper::getUrl("player/{$user->id}.json")
                ];
            },
        ]
    ]
];


I missed this in the .env file, I'll leave this here in case anyone else is as bad a space case as myself. :)

# The environment Craft is currently running in ('dev', 'staging', 'production', etc.)
ENVIRONMENT="dev"


It seems that before and after() don't work with the year as an int, if instead of '2018', you use '2018-01-01', your code works again. Check this.

Basically, use a DateTime object
:)


How to store value of checkboxes without predefining them in the SproutForm plugin

I don't feel I fully understand how you will be using the data on the back end, but here are some ideas.

It sounds like the best way to solve this problem would be to build a custom field-type plugin that stored checkbox data in the way that you need it to be stored on the back end.

A simpler workaround may be to use a multi-line Plain Text field as your "checkbox" field.  You could display things however you want to the users on the front-end, and submit the checkbox data behind the scenes in a way that stores the data in that field in a readable way.  While the data may not behave like a checklist, you would get a snapshot of the checklist items for each submission and the length of items could vary.

To capture the User ID and To-do List ID, you might be able to use the Sprout Hidden Field or Sprout Invisible Field which would just store those IDs in a plain text field.

If you wish to store the ID as relational data, you'll need to create the appropriate relational field (such as a Users Relations field) and submit the ID as an array:

<input type="hidden" name="fields[usersFieldHandle][]" value="{{ currentUser.id }}">

Additional examples of inputs to submit data from the front-end can be found in the Craft Field Guide


Conflict with assets folder and section URL

You should be able to rename the directory on the server and then update the Asset Source settings changing the URL and system path. It should take care of it as Asset folders are stored relative to the top folder.


Syntax for permissions in comments.php config file (comments plugin by Verbb)

I've just updated the docs, but because it uses the UID of element "groups" it might be annoying in practice to use the config file to set this up, as it requires a bit of manual looking-up of these values.
As the plugin settings are stored in Project Config, you'll probably get the same value setting it through the control panel.
'permissions' => [
    'craft\elements\Asset' => [
        // Volume UIDs
        '33974e79-b3b6-47ec-af91-4519fe4985be',
        'c194716f-aa74-40b6-8426-c835599cbe93',
    ],

    'craft\elements\Category' => [
        // Category Group UIDs
        'a27827c8-4810-433c-acb9-261b53d46281',
        '346194f0-6da8-4f46-a20b-795631ee9a5f',
    ],

    'craft\elements\Entry' => [
        // Section UIDs
        'a8d4bdf1-164e-4ddc-aaad-640026b8d3bf',
    ],

    'craft\elements\User' => [
        // User Group UIDs
        'c23a4d8d-47f0-4e71-927c-d5897ec9c9f8',
    ],
],


Updating Craft to 3.3.19 gives 503 error only for logged-out users

I've found this question through search.

I did not perform any update which broke my controllers, but I was unable to access them publicly.

My solution was adding $allowAnonymous = true; to my controller:

class MyController extends \craft\web\Controller
{
    public $allowAnonymous = true;
}


How do I create an external transformer class when using the ElementApi plugin?

You're getting a whitescreen because you've got some PHP syntax errors in both files. Craft isn't reporting them because those config files get loaded before Craft has had a chance to bootstrap.  The underlying errors should be recorded in your web server's error logs depending on your default server configuration.

Try these:

elementapi.php

<?php
namespace Craft;

require_once craft()->path->getConfigPath().'transformers/EntryInfoTransformer.php';

return [
    'endpoints' => [
        'api/articles' => function() {
            return [
                'criteria'        => [
                    'section' => 'blog',
                    'order'   => 'postDate desc',
                ],
                'elementsPerPage' => 5,
                'elementType'     => 'Entry',
                'transformer'     => new EntryInfoTransformer(),
            ];
        },
    ]
];

EntryInfoTransformer.php

<?php
namespace Craft;

require craft()->path->getPluginsPath().'elementapi/vendor/autoload.php';

use League\Fractal\TransformerAbstract;

class EntryInfoTransformer extends TransformerAbstract
{
    public function transform(EntryModel $entry){
        return [
            'id' => $entry->id,
        ];
    }
}


Is it possible to display another column in Entries type field?

Nope, not out of the box – but being able to display fields in addition to the entry title for selected entries being displayed in an Entries field, in an easy-to-use interface like the Customizable Element Index, sounds like a killer feature request.

For now, your best (albeit not super easy, I suspect) bet would be to create a custom plugin that adds a custom FieldType extending the EntriesFieldType class.

By overriding the BaseElementFieldType's $inputTemplate property (i.e. by adding an $inputTemplate property to your custom FieldType's class, pointing to a different template) you might be able to display entries in a different manner compared to the vanilla Entries field.


How are parent and child categories related in Craft database?

As of Craft 2 all information about Parent - Child relations are stored in the craft_structureelements table. But it's not like a hierarchy (child has the parent id) so it can be quite confusing at the first moment.
When you take a look into the ElementService you'll see the following how the getChildren() parameter from your ElementCriteriaModel is converted into a Query

if ($criteria->descendantOf)
{
    $query->andWhere(
        array('and',
            'structureelements.lft > :descendantOf_lft',
            'structureelements.rgt < :descendantOf_rgt',
            'structureelements.root = :descendantOf_root'
        ),
        array(
            ':descendantOf_lft'  => $criteria->descendantOf->lft,
            ':descendantOf_rgt'  => $criteria->descendantOf->rgt,
            ':descendantOf_root' => $criteria->descendantOf->root
        )
    );

    if ($criteria->descendantDist)
    {
        $query->andWhere('structureelements.level <= :descendantOf_level',
            array(':descendantOf_level' => $criteria->descendantOf->level + $criteria->descendantDist)
        );
    }
}

The ancestorDist is the level of the child. If you only want to have direct children you can ignore that part. $criteria->descendantOf is actually the BaseElementModel of your current element -> $element->getChildren . $criteria->descendantOf->rgt is the value in craft_structureelements for the certain Id. Imagine element is your current element - your where could be like

WHERE [....] AND (structureelements.lft < element.lft AND structureelements.rgt > element.rgt AND structureelements.root = element.root)

And the getParent() function will be treated with

if ($criteria->ancestorOf)
{
    $query->andWhere(
        array('and',
            'structureelements.lft < :ancestorOf_lft',
            'structureelements.rgt > :ancestorOf_rgt',
            'structureelements.root = :ancestorOf_root'
        ),
        array(
            ':ancestorOf_lft'  => $criteria->ancestorOf->lft,
            ':ancestorOf_rgt'  => $criteria->ancestorOf->rgt,
            ':ancestorOf_root' => $criteria->ancestorOf->root
        )
    );

    if ($criteria->ancestorDist)
    {
        $query->andWhere('structureelements.level >= :ancestorOf_level',
            array(':ancestorOf_level' => $criteria->ancestorOf->level - $criteria->ancestorDist)
        );
    }
}