What is the correct way to use UserIdentity?

The basic user identity relies on login and password, so you will have to create your own class to represent an identity based on something else, like a token for example:

<?php

namespace Craft;

class TokenIdentity extends UserIdentity
{
    private $_id;
    public $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public function authenticate()
    {
        $socialUser = craft()->social->getUserByEncodedToken($this->token);

        if($socialUser) {
            $this->_id = $socialUser->user->id;
            $this->username = $socialUser->user->username;
            $this->errorCode = static::ERROR_NONE;

            return true;
        } else {
            return false;
        }
    }

    public function getId()
    {
        return $this->_id;
    }
}

Then you'll need to create your own user session service to be able to authenticate the user (with a token for example):

<?php

namespace Craft;

class Social_UserSessionService extends UserSessionService {

    private $_identity;
    public $allowAutoLogin = true;

    public function init()
    {
        $this->setStateKeyPrefix(md5('Yii.Craft\UserSessionService.'.craft()->getId()));

        parent::init();
    }

    public function login(Oauth_TokenModel $token)
    {
        $rememberMe = true;

        $this->_identity = new TokenIdentity($token->encodedToken);
        $this->_identity->authenticate();

        // Was the login successful?
        if ($this->_identity->errorCode == TokenIdentity::ERROR_NONE)
        {
            // Get how long this session is supposed to last.

            $this->authTimeout = craft()->config->getUserSessionDuration($rememberMe);

            $id = $this->_identity->getId();

            $user = craft()->users->getUserById($id);

            $states = $this->_identity->getPersistentStates();

            // Run any before login logic.
            if ($this->beforeLogin($id, $states, false))
            {
                // Fire an 'onBeforeLogin' event
                $this->onBeforeLogin(new Event($this, array(
                    'username'      => $user->username,
                )));

                $this->changeIdentity($id, $this->_identity->getName(), $states);

                // Fire an 'onLogin' event
                $this->onLogin(new Event($this, array(
                    'username'      => $user->username,
                )));

                if ($this->authTimeout)
                {
                    if ($this->allowAutoLogin)
                    {
                        if ($user)
                        {
                            // Save the necessary info to the identity cookie.
                            $sessionToken = StringHelper::UUID();
                            $hashedToken = craft()->security->hashData(base64_encode(serialize($sessionToken)));
                            $uid = craft()->users->handleSuccessfulLogin($user, $hashedToken);

                            $data = array(
                                $this->getName(),
                                $sessionToken,
                                $uid,
                                ($rememberMe ? 1 : 0),
                                craft()->request->getUserAgent(),
                                $this->saveIdentityStates(),
                            );

                            $this->saveCookie('', $data, $this->authTimeout);
                        }
                        else
                        {
                            throw new Exception(Craft::t('Could not find a user with Id of {userId}.', array('{userId}' => $this->getId())));
                        }
                    }
                    else
                    {
                        throw new Exception(Craft::t('{class}.allowAutoLogin must be set true in order to use cookie-based authentication.', array('{class}' => get_class($this))));
                    }
                }

                $this->afterLogin(false);
            }

            return !$this->getIsGuest();
        }

        Craft::log('Tried to log in unsuccessfully.', LogLevel::Warning);
        return false;
    }
}

This code comes from a plugin which is still under development so don't take for granted it's all secure or the best way to achieve this, but hopefully it will help you get started !


How to output first segment title/channel name of entry?

Unless I'm misunderstanding, it should be as simple as:

{{ entry.section.name }}


Yes. It's not documented, but by instantiating the Event class (which is just a thin wrapper for Yii's CEvent) you can create and raise your own events. Obviously you could extend the Event class as well, if need be.

See Aaron Berkowitz' excellent answer to a similar question for details -> https://craftcms.stackexchange.com/a/6941/1098

Also, check out the following resource for more on events in Yii: http://www.yiiframework.com/wiki/327/events-explained


How do I set up event listing & detail pages with entry post dates that are in the future?

STEP ONE:
Create an "Events" section in Craft and uncheck "Entries in this section have their own URLS".

STEP TWO:
Create your listing page and use ".status('pending')" to have CRAFT return only future dated entries. Also use ".order('postDate')" to have Craft order entries so that the next future dated entry is the first in the list:

{% set entries = craft.entries.section("events").order('postDate').status('pending') %}

STEP THREE:
In the listing template, you need to manually build the URL to the event's detail page:

{{ entry.title }}

STEP FOUR:
Set up a custom Route to tell Craft which template to load for the URL pattern you're using in STEP THREE.

STEP FIVE:
Code your event's detail page template to grab the entry's slug from the URL and query the DB to get the right entry.

{% set slug = craft.request.getSegment(2) %}
{% set entry = craft.entries.section("events").slug(slug).status('live', 'pending', 'expired').find()%}
{% for entry in entry %}

{{ entry.title }}

{% endfor %}

NOTE: I've set the code sample in STEP FIVE to use .status('live', 'pending', 'expired') to show return these types of entries on my event detail page. You can use .status(null) to return ANY/ALL entries on the event detail page... or you can use .status('pending') if you only want future dated events to show and all others to return a 404. This is 100% up to you and based on your project requirements.


Not sure if there is more to your code or not but looks like you need to set the title as well as other required fields. In addition the entries field is expecting an array of entryIds.

Here is a link to the saveEntry method in the EntriesService, which shows the required fields:
https://craftcms.com/classreference/services/EntriesService#saveEntry-detail

This answer is somewhat similar in that they are relating an entry, but you can see that the entryField is being set with an array.

How do I relate a user to a channel entry from a form?


Craft will only look in the immediate pluginHandle/services folder when auto-loading and registering a plugin's service files.

If you wanted to support services in subfolders (i.e. pluginhandle/services/subfolder1, etc.), you'd have to manually autoload and register those classes yourself from your plugin's init() method.


You could use Regex (Regular Expression), /^[a-zA-Z]{3,}$/ would for instance allow a minimum of 3 characters behind the comma would be the max value.

As for numbers it would be something like this /^[0-9]{3,}$/

http://regexr.com/ to test your regex en examples

And I would do this before the user is saved with the users.onBeforeSaveUser Event in a plugin.


Assuming what you're trying to attach is on the local filesystem, you can see an example of this here: https://github.com/pixelandtonic/craftnet/blob/master/src/orders/OrderBehavior.php#L160-L182

Essentially, you'd just use attachContent, but there is also an attach method:

->attachContent($pdf, [
    'fileName' => $filename,
    'contentType' => 'application/pdf',
])


How to display payment gateway error message only

When submitting a payment form to the commerce/payments/pay controller action there are three potential sources of error messages.

If you are submitting via a normal form submission (not ajax) you will be able to get access to the errors in the following manner from your template.

General Errors

{% set flashError = craft.app.session.getFlash('error') %} For general errors e.g. requireBillingAddressAtCheckout is set to true and there is no billing address on the order.

Order Save Errors

{% set orderErrors = order.getErrors() %} The order is recalculated and saved during the pay process to make sure something has not changed elsewhere. The order is validated and therefore errors will be returned if there are validation issues.

Payment Form Errors

{% set paymentFormErrors = paymentForm.getErrors() %} The payment form errors will contain any errors related to the payment form and, dependant on gateway, may also return payment gateway errors.


Blank screen for /admin and public site with Craft 3

What you'll want to do is change the CRAFT_BASE_PATH in your index.php file.

Look for line 7, and change this:

define('CRAFT_BASE_PATH', dirname("__DIR__"));

to this:

define('CRAFT_BASE_PATH', dirname('./'));

I had this issue as well, being used to doing the same thing with Craft 2, changing the $craftPath variable.


Switching plugin license from Craft 2 to Craft 3

That's a question for the plugin developer. If the plugin isn't purchased through the plugin store, then each developer is responsible for generating Craft 3 licenses on their own.

It's probably safe to say that your Craft 2 license number is not going to match your Craft 3 license number. Contact the plugin's developer for more information.


You'll have to query all matrixes in that field with that type first. With these results, you should then be able to query the entries that are relatedTo these results.
You'll end up with
{% set matrixes = craft.matrixBlocks()
    .field('matrixField')
    .type('video')
    .all() %}

{% set entries = craft.entries()
    .section(['events', 'sessions'])
    .orderBy('datum desc')
    .matrixField(':notempty:')
    .relatedTo(matrixes)
    .limit(30)
    .all() %}

Documentation about relations can be found here


Oli’s comment is mostly right, but I think the solution is event simpler—the method you discovered is specifically for saving the GlobalSet settings/definition (like its name, handle, and the fields it uses), but what you're looking for is a more generic method for saving the Element that contains the actual content (as though you were updating it from the main Globals menu in the CP):

// Generic save method for any Element type, including Globals:
Craft::$app->getElements()->saveElement($giveaways);

✌


Trying to set a default asset folder using Craft tags

I had a stupid typo in my path, where instead of the date filter, I'd typed dateCreated:

/our-journal/{ entry.dateCreated|date('Y-m') ?: now|dateCreated('Y-m') }/{ slug }

Should be:

/our-journal/{ entry.dateCreated|date('Y-m') ?: now|date('Y-m') }/{ slug }

Which, with what I learnt about fallbacks (see below), can be shortened to:

/our-journal/{ entry.dateCreated|date('Y-m') }/{ slug }

And if you're doing this within a matrix field, the entry is referred to by owner - so you'd need:

/our-journal/{ owner.dateCreated|date('Y-m') }/{ owner.slug }/

Fallbacks

I also found that I didn't need to provide fallbacks for entry tags - I'd thought that I'd need to provide a fallback for when a new entry hasn't yet been saved (to stop it falling over on e.g. dateCreated).

It appears that Craft is clever enough to hold the image in some temporary store, then move it into the intended folder when the article is first saved.


You can use this to help debug why tasks sometimes get "stuck": https://craftcms.com/help/stuck-tasks


Pass field handle from to render tag using Freeform field

Is this what you are looking for?

{{ entry.myFreeformfieldname.render() }}


I went and looked at the MatrixBlockModel; there's an attribute named sortOrder (If you output {{sortOrder}} inside the for loop, it will display the index of that block).

You can use that attribute to sort by, in reverse:

{% for cta in entry.ctas.order('sortOrder desc') %}


How to render template instead of throwing an error?

You can see common patterns for this in Craft's own controllers.

For example in https://github.com/craftcms/cms/blob/master/src/controllers/EntriesController.php#L499-L507, if there's a problem, you can catch the error, set it on a route variable and return null so the original template can display it.

Craft::$app->getSession()->setError(Craft::t('app', 'Couldn’t duplicate entry.'));

// Send the original entry back to the template, with any validation errors on the clone
$entry->addErrors($clone->getErrors());
Craft::$app->getUrlManager()->setRouteParams([
    'entry' => $entry
]);

return null;

If you don't want to let the original template handle the error, then you should be able to do something like this from your controller:

return $this->renderTemplate('error', ['error' => 'Test']);


Select dropdown linking to Matrix blocks

Two options:

Physically output all the floorplans in the markup {% for block in entry.matrixHandle%} then hide them using CSS, and only display the one from the dropdown using JavaScript. Something like $('#dropdown-id).on('change', function(){});
Change the field from a Matrix so that each floorplan is a separate Entry and you visit each one with an href="{{ entry.url }}.


Issues accessing Control Panel with iPad on iOS 7

As @RitterKnight points out, it does seem to be an issue with Garnish. I've managed to narrow it down to garnish-0.1.js:1020, which is to do with resize detection as adapted from http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/

As one of the comments points out, changing the following line fixes the issue:

var obj = elem.__resizeTrigger__ = document.createElement('object');
to
var obj = elem.__resizeTrigger__ = document.createElement('iframe');

I'm not sure if this has any adverse effects on anything else, so would be keen to see if this is something already tested by the P&T team.

EDIT: This has now been fixed in Craft 2.4.2691.


Multi-user blog "repost entry" functionality

I think it's going to be a lot easier if you go the custom plugin route with your own front-end forms for everything.  Not hacky at all!


To achieve an empty state for my group (When there's no entries existing within that group). I re-assembled the array and outputted them in a certain order - allowing for an if to come alive when there actually wasn't any status available.

{% set proposals = craft.entries.section('proposals').authorId(currentUser.id) %}
{% set proposalsByGroup = proposals|group('proposalStatus') %}

{% for status in ['pending','accepted','delivered'] %}

  {% if proposalsByGroup[status] is defined %}
    {% set entriesInStatus = proposalsByGroup[status] %}
          {{ status }}
          {% for proposal in entriesInStatus %}
             Hello.
          {% endfor %}
  {% else %}
          {{ status }}
          Nothing here, but still gives a status that you've set above.
  {% endif %}
{% endfor %}


Smart Map - Outputting locations from a Matrix field for all entries within a single section

Great question! While seemingly tricky, the solution to this should be relatively simple...
Per the documentation, the locations parameter can come in a variety of different forms. But the one we're looking for here is this one...

As an array of elements

Collecting Matrix blocks from across different entries can be complicated, but I think you have (fortunately) described a fairly straightforward use-case. We'll need to do the following:

Loop through relevant entries.
Build an array of Matrix blocks.
Use that array to render a map.

{# Initialize locations array #}
{% set locationsArray = [] %}

{# Loop through all relevant entries #}
{% for entry in craft.entries.section('buildings').find() %}

    {# Get all relevant Matrix blocks #}
    {% set matrixBlocks = entry.buildingContent.type('howToGetThere').find() %}

    {# Append blocks to locations array #}
    {% set locationsArray = locationsArray|merge(matrixBlocks) %}

{% endfor %}

{# Render map #}
{{ craft.smartMap.map(locationsArray, options) }}


yii\web\ServerErrorHttpException Craft 3 install

The info table is missing its row...

The craft_info table in the database should only ever have one row in it.  In a fresh Craft installation, then installer should populate the row with the relevant information.

If you're getting that error message, then that table is missing its one row, which would indicate that some other error happened during installation.

If it's a Craft generated error, then that underlying message would be in your craft/storage/logs files.  If it's a web server generated error, that error would be in your web server's error logs.


Simply put, a Categories field is an array containing category ids, and your form needs to send it that way:

<input type="hidden" name="fields[fieldHandle][]" value="100">

Adding brackets to your field-handle submits the value as an array, and 100 is the id of the category.


If you actually have products selected in that entry's matrix products field, then

{% for block in entry.MatrixHandle %}
  {% if block.type.handle == "matrixProductsBlockTypeHandle"%}
    {% for product in block.productsFieldHandle %}
        {{ product.title }}
    {% endfor%}
  {% endif %}
{% endfor %}

That is the simplest approach really.  So if that doesn't work, triple confirm the entry vairable is the one you think it s and that you do indeed have chosen products in that field.  If still nothing, check the craft.log I guess!


Redactor clips plugin removes DIV tags from inserted HTML?

Edit:

There's other problems / bugs with the Redactor API going on that lead to unexpected behavior on formatting the inserted HTML. The solution provided below does allow to insert HTML with DIV tags only if inserted in a new paragraph, otherwise it strips the tags. Another issue I came across is that I get empty SPAN tags added and I don't know where these come from?!

--

The plugin uses Redactor API's insert.html function. Which by default cleans the HTML before inserting it. But there's a parameter to prevent it from doing so.

You can hack / fork the plugin and set the parameter in redactorclips/resources/clips.js (line 63):

this.insert.html(html, false);

I will create a Github issue for this, because it definitely makes sense to have HTML cleaning disabled by default or at least have a setting for it. (Edit: makes no sense as long as there's all the other issues with the API!)


Based on the docs and this guide, looks like you'll want to set selectedSubnavItem in your Twig template(s) to whatever the key of your selected subnav item is (moderateentries, notificationmessages, etc).

Alternatively, you could do somthing similar to what Andrew Welch does in his SEOmatic plugin; he sets the selectedSubnavItem variable as a keyed item in a variables array and then right after that renders his plugin template (including that variables array in the render method).


One approach would be to create a comments channel with an entries fieldtype (with sources checked for any channels that you want to allow commenting; limit set to 1) called 'relatedEntry' (or whatever you like). On your article template, include a for loop to display existing comments relateTo the entry. Check to see if there is a current user, and if yes, include a comments form. In the comments form place a hidden field with the id for the current entry. Something like this:

  {{ entry.title }}
  {{ entry.body }}

{% for comment in craft.entries.section('comments').relatedTo(entry) %}

{{ comment.author.fullName }}
{{ comment.body }}

{% endfor %}

{% if currentuser %}
<form method="post" action="" accept-charset="UTF-8">
    <input type="hidden" name="action" value="entries/saveEntry">
    <input type="hidden" name="sectionId" value="2">
    <input type="hidden" name="redirect" value="{{ entry.url }}">
    <input type="hidden" name="fields[relatedEntry][]" value="{{ entry.id }}">

    Comment

    <input type="text" name="comment">
</form>
{% endif %}

name="fields[relatedEntry][] is formated this way because related fields expect an array even if it's only a single related entry.

You could also create threaded comments by creating another related entries fieldtype called parentComment (or whatever you like) and including that as a hidden field in the form as well (you might need ajax or javascript here to help set the hidden field value from the 'comment' link).

To make it a little nicer you could also load the comments form via ajax or reveal it with javascript.

Untested, but hopefully this will point you in the right direction.


(Commerce) Multiple line items with the same purchasable ID?

Commerce will by default combine line items that have the same hash value for the options (that is, the values of the items chosen options are run through md5 to get a hash - if the hash matches, the lineItems quantity is increased as the item is seen as the same item.

If you want line items with the same options to remain as separate line items, then you can simply add another unique option to the product as you add it to the cart (you don't need to display this of course).

<input type="hidden" name="options['whatevs']" value="somethingRandom">

Twig isn't actually ideal at generating random things I believe, I'd personally create a template variable in my Business Logic plugin that returns a random value, e.g. something like:

public function random(){
    srand(time());
    return rand(1,time());
}

You can e.g. call the current timestamp in twig but there's always a chance that might not end up as random I suppose?

<input type="hidden" name="options['time']" value="{{ date().timestamp }}">

(Calling twigs own random (https://twig.sensiolabs.org/doc/2.x/functions/random.html) - doesn't seem ideal as that's inclusive so you might see the edge values returned more than you'd like).


Use Entries fieldtype functionality in plugin populated by REST api data

You are speaking of the Element Selector Modal. It is javascript and available to use by third-party devs, but the code is specific to Craft Elements (Entries, Assets, Users, etc.). I don't think you'll get it to work with information polled from a third-party API.

There's a post about it in the Craft Dev Google+ group (invite only), but I'm not sure if the info exists anywhere else.


Database issue on upgrade to 2.5 on shared hosting

Have you checked craft/storage/runtime/logs to see if there's an error in there related to the update?

In case it is the database: you can disable the database backup during the update by changing https://craftcms.com/docs/config-settings#backupDbOnUpdate to false in general.php

Remember to make a database backup every time you run an update when you change that setting!


Strange issue with logging out user on frontend

Turned out to be a browser issue specific to one mac. And we also noticed that when using chromes device mode it seemed to kill the session!


SQL error when trying to use sortOrder on Matrix related block (Craft 2)

So this was me being a bit of a numpty here. I was calling the field the wrong way. Doing the following obeys the sort order from the field:

{% for entry in block.hostingPackage %}


It does in fact need to be loaded on every request, because otherwise your EVENT_REGISTER_FIELD_TYPES event listener wouldn’t get registered, which is responsible for telling Craft that the field type exists.


What are the most common template performance gotchas to avoid?

Avoiding unnecessary DB queries is definitely the main thing to watch out for. Here’s an example that came up recently in support: Someone wanted to display the first 6 Matrix blocks in an entry, outputting them 2 at a time. Initially the template code looked something like this:

{% for block in entry.matrixField.limit(2) %}
    <!-- Get the 1st two items -->
{% endfor %}

{% for block in entry.matrixField.offset(2).limit(2) %}
    <!-- Get the next two items -->
{% endfor %}

{% for block in entry.matrixField.offset(4).limit(2) %}
    <!-- Get whatever's left, not more than 2 -->
{% endfor %}

Rather than doing that, we suggested that all 6 blocks be grabbed up front, and output 2 at a time using Twig’s slice filter:

{% set blocks = entry.matrixField.limit(6) %}

{% for block in blocks|slice(0, 2) %}
    <!-- Get the 1st two items -->
{% endfor %}

{% for block in blocks|slice(2, 2) %}
    <!-- Get the next two items -->
{% endfor %}

{% for block in blocks|slice(4, 2) %}
    <!-- Get whatever's left, not more than 2 -->
{% endfor %}

Remember that you can always see what DB queries are happening in a given request by enabling Dev Mode and checking your browser’s Javascript console, where all DB queries for the current request will be logged, ordered by how long they took. It will also show if the exact same query was run multiple times.


For those wondering, here is the link to Craft 3 reserved words:

https://github.com/craftcms/cms/blob/ae64588a4963b06a093636be6686345bd3a9bca8/src/base/Field.php#L190


Method to grab URL hash in Twig or craft.request?

This isn't possible because the #hash-part isn't even send to the server. See this question on StackOverflow: Can PHP read the hash portion of the URL?

But if you use ?hash=something instead, these functions will help you: getParam() and getQuery()


How to update the lineItemStatus of an order on the front end with twig?

You can use the same technique to set the line item data like this:
{% set order = craft.orders.id(123).one() %}

{% for lineItem in order.lineItems %}
    {% do lineItem.setAttributes({lineItemStatusId: 2}, false) %}
{% endfor %}

{% do order.setAttributes({
    orderStatusId: 4,
    lineItems: order.lineItems
}, false) %}

{% do craft.app.getElements().saveElement(order) %}

^ That would set all line items in an order to the same status... I imagine you have some kind of interface where you can either update a single line item at a time or mark several at once and press a submit button, so in that scenario you'll probably want to add some conditionals inside the loop to check that the line item id you're on matches say, the line item id passed in through the URL or through POST data or whatever so that just the right one(s) get updated


How can I output ALL strings from a lang file?

You could include the translations file into your controller:

$translationsFile = craft()->path->getPluginsPath().'myplugin/translations/de.php';
$translationsArray = include $translationsFile;

$this->returnJson(array_keys($translationsArray));


The file does not appear to be an image. Bug?

That error will occur if the fileinfo extension or imagick (ImageMagick) extension are not configured with a comprehensive list of file MIME types (the "magic file", as they refer to it, I think), or the images you're uploading aren't really images despite their extensions.

Regarding GIFs - you must use ImageMagick if you want to upload animated GIFs, as it's not possible for Craft to reconstruct an animated gif using the GD library.


The second example won't work since .find() should be at the end of the ElementCriteriaModel. But since you treat the CriteriaModel like an array, you don't need to add it at all.

Your first code looks correct, but you should check if the loop found an entry:

{% for item in craft.entries.section('images').slug('home') %}
    ....
{% else %}
    No entry found
{% endfor %}

Also your current code is only outputting the title of the AssetFileModel:

  Outputting an AssetFileModel object without attaching a property or
  method will return the asset’s Title

That's why you should add the "url" property, and also check whether the field contains an asset:

{% for item in craft.entries.section('images').slug('home') %}
    {% set asset = item.image.first() %}

    {% if asset %}
       {{ asset.url }}
    {% else %}
        No asset added to the field
    {% endif %}
{% else %}
    No entry found
{% endfor %}


Using FeedMe 2.x with a custom authentication mechanism

So, here's what I've found after after some research. It is certainly possible to create your own datatypes. Support for it, looks to have been added since around 2.0.1. Previously, the feed type field wasn't able to have custom types as it was a fixed list, but with hooks it is now possible. There is a great plugin that shows how to add custom data types here:

https://github.com/surprisehighway/craft-feedmehelper

You do need a Pro license to use custom data types however.

Unfortunately, the documentation for data types is currently TBA on Verbb's website: https://verbb.io/craft-plugins/feed-me/docs/developers/data-types, so this is going off looking through the code of both the helper plugin and FeedMe itself. Hopefully that will be added at some point.

The way to add your own data/feed type is to call the registerFeedMeDataTypes() function in a plugin, register the datatype:

public function registerFeedMeDataTypes()
{
    return array(
        new MyCustomFeedMeDataType(),
    );
}

You'd import the MyCustomFeedMeDataType class, with Craft::import in the plugin init() function

Then in your datatype class:

<?php
namespace Craft;

class MyCustomFeedMeDataType extends BaseFeedMeDataType
{
   // Custom data type stuff here
}

The datatype should then appear in the feed type dropdown within the FeedMe feeds section in Craft for selection. By default it will use part of the class name for the field label/value, you can also set a specific name, according to this pull request:

https://github.com/verbb/feed-me/pull/172

Quick and reasonably simple in the end, but certainly provides better custom integration options for my project now!

Hope this helps other Craft CMS folk!


Target second (or nth) element in a for loop

It's not working because you're using loop.index in the context of the inner loop.

Based on your comment, there will only ever be one images selected, so loop.index will never be 2.

If you don't want to move the loop.index check to the outer loop, then a simple counter will work:

{% set counter = 0 %}

{% for relatedImage in entry.relatedImages %}
    {% set counter = counter + 1 %}

    {% for images in relatedImage.image %}

             {% if counter == 2 %}

Welcome!

{% endif %}

    {% endfor %}

{% endfor %}


Programatically setting dropdown options in a matrix

I figured it out! Field-specific options need to go inside 'typesettings'.
'typesettings' => [
    'options' => [
        ['label' => 'H1', 'value' => 'h1', 'default' => 1],
        ['label' => 'H2', 'value' => 'h2', 'default' => ''],
        ['label' => 'H3', 'value' => 'h3', 'default' => '']
    ]
]


I'm not exactly sure what you are trying to achieve, but here is a way to have unlimited locales with only a single subfolder in your public root directory.

Put all of your locale subfolders into a single folder, called locales for example. So your directory structure would be:

public/locales/de/
public/locales/es/
public/locales/fr/

Make sure you update the craft path in each locale's index.php file accordingly:

$craftPath = '../../../craft';

Then you just need the following code in your root .htaccess file to redirect to the appropriate subfolder:

# Redirect locales
RewriteCond %{REQUEST_URI} ^/(de|es|fr)/ [NC]
RewriteRule (.+) /locales/$1 [QSA,L]


Why would one environment use "+" instead of "%20" for spaces when using url_encode filter?

It looks like the twig url_encode filter uses the php function http_build_query if parameters are passed to it as an array. i.e. {'key':'value', 'key':'value'}|url_encode. Otherwise it uses rawurlencode.

http_build_query was modified in php 5.4 to include a new property enc_type, that allowed you to specify that it use PHP_QUERY_RFC3986encoding (which is also what rawurlencode uses).

The url_encode filter is defined in craft/app/vendor/twig/twig/lib/Twig/Extension/Core.php on line 596, and contains a clause to make it backwards compatible with php 5.3, but you obviously will loose the encoding type.

Options are: upgrade php to 5.4+; do not pass params as an array to the url_encode filter; or do a string replace on the encoded string.


Assetconflict after changing general.php

If it were related to basePath, then you'd most likely be getting other errors as well.

This one sounds like Craft simply can't autoload the file it's looking for.  I'd re-upload your craft/app folder to make sure all of the files got transferred up properly and aren't corrupted.


Craft update process affecting Element API cache

Got to the bottom of it. It was a CORS thing - permission with the domain htaccess and elementAPI. A shift from non-www, to www redirection seemed to be the cause so now solved


Pasting tables from Microsoft Word into Rich Text fields

This is not possible at the moment. Craft 2.5 uses the updated Redactor II WYSIWYG editor, which dropped this from it's features. All pasted text is stripped to plain text.

Perhaps someone can suggest an alternative method that we can set up to make this easy for content editors.


Craft Commerce carts containing out-of-stock products

The next time the cart 're-calculates' - so really any process on the cart such as updating it etc, the out of stock product will be detected and removed from the cart.

If somehow they get straight to the attempt order completion stage, then I am pretty sure an error is raised (& returned in flash) and the order won't complete.


Create Craft 3 Plugin - Call to a member function getVersion() on null

Shame on me, but maybe still interesting to others who have this problem: I'm using vagrant and the path of my extension was NOT mounted to the vagrant box. That's all. So it simply could not find the files. Maybe a warning by craft would be nice, that it can not load the plugin files

Though I do not understand, why it found the composer.json to read the basic information, which showed up in the Plugins section of Craft...


List the categories an entry is part of?

This will list all the categories that are assigned to the entry regardless of level.

    {% for category in entry.categoriesFieldHandle %}

category.title

    {% endfor %}

If you only want to list the subcategories, (regardless of whether a main category is also assigned) then you can add a test for the category level.

    {% for category in entry.categoriesFieldHandle %}
        {% if category.level > 1 %}

category.title

        {% endif %}
    {% endfor %}


Error with Twig templates.

In case anyone is interested, I was using extends in a template that was include by a index template. Generating a sort of bad recursion that emptied memory ( PHP Error ).


How can I output the territories array with craft.i18n?

Looks like Yii doesn't expose a way to grab all of the territories for a given locale by default.

I've just added it to Craft 2.2, though.  So when that comes out, you'll be able to do this:

$localeData = craft()->i18n->getLocaleData('en_us');
$allTerritories = $localeData->getAllTerritories();


import store items from Magento to Craft Commerce

I don't think there's a plugin that does this. However, I would like to point you to a talk by James Greig that happened last Friday, in which he explains a number of possible ways to migrate content from X to Craft. He too uses FeedMe to do the import part, but has a few approaches to exporting the content on the other side:

https://www.greig.cc/dotall2018


Re-populate additional fields on Contact Form on failure of form validation

From the changelog:

  1.7.0

  Added the ability to access individual message fields values via message.messageFields when a validation error occurred. For example, the value of the input message[Phone] can now be accessed via message.messageFields['Phone'].

So I think you should be using message.messageFields[Course] rather than message.message[Course]


How can I best extend TagModel to add a `count` property?

Before worrying about how templating should work, let’s just get one thing out of the way: Computing this data every time it’s requested is horribly inefficient, and could easily take a site down. You’ll absolutely need to find a way to store the tag counts in a more permanent location, and calculate it when entries are saved rather than when the template requests it. (Even if you wrap the template in a {% cache %} tag, you’re still forcing a couple people to experience slow page load times for no good reason.)

You have multiple options on how to store the data, but giving it its own table is probably the most obvious/reliable. I’d call it something like tagcounts, and give it tagId and count columns. tagId should be a FK to the tags table, set to cascade delete.

Then you’d want to listen to the entries.onSaveEntry event. When it fires, loop through all the entry’s Tags fields, and each of their selected tags. For each one, get the total count of rows in the relations table where the targetId column is set to the tag’s ID. Use DbCommand::insertOrUpdate() to save the value in your table.

craft()->db->createCommand()->insertOrUpdate('tagcounts', array(
    'tagId' => $tag->id
), array(
    'count' => $count
));

You’ll also need to loop through all existing tags and populate this table when the plugin is first installed.

With the tag count data in place, next up is templating. Unfortunately I don’t have a good answer for you there. It’s a complicated problem.

I think what I would do is, create a Variable class which accepts an ElementCriteriaModel, passes that off to craft()->elements->buildElementsQuery() which will take most of the parameters into account, then make some additional modifications to the query – join in the tagcounts table and set the ORDER BY.

Next up you would basically have to copy a ton of code from ElementsService::findElements(), which is totally lame. I’m going to see what I can do to make it much easier on you going forward. Ideally at this point you would be able to just do something like:

return craft()->elements->findElementsUsingQuery($query);


Is it possible to view 'Expired' entrys on the front end?

I don't think you can enable the default Entry Routing for expired entries. So you need to add a custom route.

To keep your current URLs, try to rebuild the default Entry Route with a custom one:

news/{slug}  →  news/_entry

Expired entries shouldn't return 404 now any more and load your entry template. You now have to get the Entry Model manually though:

{% set entry = craft.entries.section('news').slug(slug).status('live, expired').first() %}


How do I force www in URL along with the Patrol plugin to force https

This is how our default .htaccess with https redirect and forced www. for all our projects looks like. So if you have the url example.com you'll get redirected to https://www.example.com.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
    RewriteRule (.+) index.php?p=$1 [QSA,L]
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
    RewriteCond %{HTTPS} !=on
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</IfModule>
Action application/x-httpd-php70 /cgi-sys/php70-fcgi-starter.fcgi
AddType application/x-httpd-php70 .php .php70


If you category is related to your entry there is no need to fetch the category via url segment. This method is slower and will need more resources since you'll do the work twice for no reason.

entry.relationFieldHandle

will contain an ElementCriteriaModel with a ready to use query to fetch the related elements. So entry.relationFieldHandle.first() will return the category.

If you want to get all entries, that are related to the category of your current entry you should do

{% set categoryIds = entry.fieldHandle.ids() %}
{% set relatedEntries = craft.entries.relatedTo(categoryIds).find() %}

Your code could be

{% set category = entry.fieldHandle.first() %}
{% set relatedEntries = craft.entries.section('propertiesSection').relatedTo(category).find() %}

That's basically it. Note: you don't need to fetch the category to get the related entries, you only need the id. That's why I used .ids() in the first example instead of .first() or .find()


Getting fatal error when installing new plugin by hitting memory_limit

This is more of a Composer than a Craft issue. Depending on your project dependencies, Composer could easily need 1GB of memory.

I assume you got the 410M from the 4039 bytes in the error. That's only what Composer can't allocate for what it's doing, you might need more later in the process.

I would start by upping my memory_limit to 512M and see where it gets you.


{% set entries = craft.entries({
  section:        'blog',
  order:          'postDate',
  limit:          5,
  id:             'not ' ~ entry.id
}) %}

or

{% set entries = craft.entries({
  section:        'blog',
  order:          'postDate',
  limit:          5,
}).id('not ' ~ entry.id) %}


It depends more on how you are going to create and display them. I had to import 20k elements this weekend and I had to be careful to store them step by step.

Depending on your server/hardware - you can't just insert 10k elements in one request. There is a function App::maxPowerCaptain() to disable the timeout but I still faced overflow errors.

And of course you can't display so many users in one single page without using a pagination or Ajax

Besides that - Craft is able to handle such an amount of elements if you can do it in your code as well


Including customer details in Stripe emails

Probably best to use Craft Commerce emails, then you can put whatever information you want into the emails to your accounts departments. Like: {{ order.billingAddress.fullName }}

If the billing address information is not being sent to Stripe, you might need to modify your checkout.js or stripe.js payment screen implementation to ensure it sends the billing address information through along with the card info: https://stripe.com/docs/stripe.js#stripe-create-token

Unlike other gateways, Stripe is building the card request within javascript to make the token, when our server sends the payment request, it only uses that token - no billing address is sent again.


list entries by category, including uncategorized entries

You could do something like this:

{# Fetch all entries in postDate and category/structure order #}
{%  set entries = craft.entries().section('companies').order('dateCreated DESC').all() | multisort(e => e.yourCategoryField.one().lft ?? 1000) %}

{# Group entries by categories and set a group name for non-categorised one #}
{% set allEntriesByCat = entries|group(e => e.yourCategoryField[0] ?? 'The non categorised one') %}

    {% for groupName, entries in allEntriesByCat  %}

{{ groupName }}

        {% for entry in entries %}
            {{ entry.title }}

        {% endfor %}
    {% endfor %}

{% endblock %}

Change yourCategoryField to your own field handle, of course. The Order of your sponsorship levels ({{ groupName }}) is the one you will define by drag/dropping in your Control Panel → Categories.

Note that this won't show an empty sponsorship level if there is no company attached to it.


Twig isn't very well equipped to deal with more than basic logic and comparisons, but you can accomplish some of these tests with a bit of extra juggling:

{% set constraintMet = false %}

{% for value in [0, 30, 50, 10, 9, 200] %}
  {# Here’s where you get to set up your advanced comparison criteria: #}
  {% if not constraintMet and value < 10 %}
    {% set constraintMet = true %}
  {% endif %}
{% endfor %}

Constraint {{ constraintMet ? "was" : "wasn't" }} met.

Alternatively, you can build the conditional into your for loop…

{% set constraintMet = false %}

{% for value in [0, 30, 50, 10, 9, 200] if not constraintMet and value < 10 %}
  {% set constraintMet = true %}
{% endfor %}

Constraint {{ constraintMet ? "was" : "wasn't" }} met.

…but this is a little more difficult to read, in my opinion, as it obscures the critical test. One improvement this offers, though, is that it prevents the loop from running after the constraint is met, unlike the first option, which runs/renders the body of the if block for every element in the array—even if it finds a match early on.

Whenever possible, I'd recommend stashing this kind of logic in a custom Twig extension. If you haven't built a plugin or module before, Pluginfactory can set you down the right path!

  Heads up! map, filter, and reduce functions have come to Twig (and Craft, as of 3.2), which make this possible to collapse this into a one-line statement: {% set hasMatchingValue = [0, 30, 50, 10, 9, 200] | filter(v => v < 10) | length > 0 %}. This just iterates over the array, and filters out anything that is 10 or greater with the implicitly returned value from the “arrow function,” then checks if the new array includes “more than zero” values.


The picture you posted is from Craft 2 when Dev Mode is enabled.  In that case, it would output the debugging and profiling information to the browser's console.

In Craft 3, that has been replaced by the Debug Toolbar.  There is a good article here on what it is and how to use it:  https://nystudio107.com/blog/profiling-your-website-with-craft-cms-3s-debug-toolbar


{% paginate %} Tag issue, no prevUrl / nextUrl Data

You need to set a limit on your element query, so Craft knows how many entries you want per page:

{% paginate craft.entries.section('newsBlog').limit(1) as pageInfo, pageEntries %}

If you don't set a limit, {% paginate %} will return a single page with all entries, because the default value for limit in Craft 3 is null (in Craft 2, the default was 100).


It's probably just a drop down that sets the crop position setting in the image transform parameter string.

See this: https://craftcms.com/docs/image-transforms#defining-transforms-in-your-templates


Simple way to create a slideshow with Twig and a for loop?

This isn't really a Craft question. Craft is simply responsible for outputting the requested data into your template, and you can use whatever you'd like on the front end to display it.
What you want in this case is a JavaScript carousel or slider. You can build your own, or use a simple library. I like Flickity and use it often, but if you just do a Google search for "javascript carousel" you'll find tons of options to choose from. If you're using a specific library or framework for your site, you might want to include that like "javascript carousel bootstrap" or "javascript carousel react" to find something that leverages libraries you're already loading.


So this seems like a bug to me. I found the issue, and it was caused by another tag group having the same tag name. Here is an example

We have three tag groups.

Default
Industry Tags
Services Tags

Logos was a tag in Default, and also Services Tag group. Once I removed or renamed the tag named Logos from the Default Tag Group. I was then able to find entries using the tag named Logos from a section where entries used the Services Tag Group. This section has a tag field called Services which the source is Services Tags.

I just found another tag called Brand that does not work in the Services Tag Group because Industry Tag Group has the same Brand tag. If I rename the tag named Brand from Industry, then the entries are found in the section that uses the Services Tag Group for the tag named Brand.

Is this normal behavior as it doesn't seem like it to me. Easy solution would be to just not use tag groups but that would be a lot of refactoring tags for all entries.


How to return data to an ajax succes callback

As Robin mentions, your controller needs to return an object of type Response, and in your case you probably want to return it with the format set to json. There's a helper method in Craft's Controller class, asJson, which is handy for this. Example:

public function actionMyControllerAction()
{
    $result = ['my' => 'data'];
    return $this->asJson($result);
}

This should give you back an object for data with a key of my with value data.


Is there a way to force Assets to redo transforms?

I can't actually reproduce your problem but here's a couple of things to check and try:

Clear your browsers cache!
Did you re-upload through Assets with the same filename and click replace?
Purge all the caches via the Clear Caches button on the settings page
Update Asset Indexes on that same page
Failing those, manually delete the contents of the /craft/storage/runtime/assets and /craft/storage/runtime/cache folders
You can also try deleting the generated images manually in web/assets/..
If you're still weeping into your coffee try emptying the craft_assettransformindex table in the database

Of course, back everything up before you try all this...


filter matrix blocks by multiple light switch value, and then merge them

Keep in mind objects in PHP are always called by reference not by value thus your anchors query will always return blocks from the type subhead with the field value anchor =1 while your matrix query anchorLinks will return blocks of type copy with the field value anchor = 1 and anchorLink = 1

I'm not sure why you don't fetch the results in one single query as it would be faster and easier in my opinion but you want to create 2 queries you need to either reset the previously set property to null or use the clone  function

{% set anchors2 = clone(entry.pageBuilder).type('copy').anchorLink('1').all() %}
{% set anchors1 = clone(entry.pageBuilder).type('subhead').anchor('1').all() %}


ImageOptimze - Will removing image Variant Ratio delete image files?

So Image Optimize just uses regular old Craft Transforms to do its thing. So whatever would happen to transformed images that you deleted the transform for would happen here as well.

I don't know the answer specifically, but if I had to guess, it'd be that Craft will not "clean up" its image transforms, and delete the ones that are no longer used. But you can do that manually, have it rebuild your Asset Indexes.


Multi language site not working on sub domain

Ok after several weeks of head scratching. I worked out the solution. So hopefully this will help someone else.

Each locale has it's own folder on the root. So to enable you to view the pages on a subdomain you need to edit the .htaccess file within the locale folder and add a RewriteBase /fr or whatever the folder name of the locale you are targeting is.

This will then resolve the problem.

Hope this helps someone else.


How can i apply "current" class for category nav?

You can get the current Category Model via the pre-populated category variable on all of your category pages. (→ see Routing type no. 4)

As you probably know, entry pages come with entry pre-populated. To get all the Category Models that are related to an entry page with a Categories Field make a craft.categories call using relatedTo(entry) as a parameter.

Save the Category Model / -Models to a var outside your nav loop, so you don't have to make those requests multiple times. And make sure to save the one Category Model on category pages as an array [myCategoryModel], so you always end up with your variable being of the same type.

Within you nav loop you can now check, if the Category Model of your current loop iteration is within your saved array using the in containment operator.

{# Is this an entry page with a category field? #}
{% if entry is defined %}
    {% set currentCategoryIds = craft.categories.relatedTo(entry).ids() %}
{# Is this a category page? #}
{% elseif category is defined %}
    {% set currentCategoryIds = [category.id] %}
{# None of both? Set an empty array. #}
{% else %}
    {% set currentCategoryIds = [] %}
{% endif %}

{% nav cat in craft.categories.group('artCats') %}

    {% set class = cat.id in currentCategoryIds ? 'current' : '' %}
    {% set entryCount = craft.entries.relatedTo(cat).total() %}

{{ cat.title }} ({{ entryCount }})

{% endnav %}


How to check if matrix block type is empty or not

You can fetch the number of entries for the first type, check if you receive an empty array if so fetch matrix blocks of type B

{% set blocksTypeOne = entry.matrixFieldHandle.type('blockTypeHandle1').find() %}
{% if blocksTypeOne|length %}
     // blocks with type A exists
{% else %}
    {% set blocksWithTwo = entry.matrixFieldHandle.type('blockTypeHandle2').find()
    // do something with them
{% endif %}


What, if any, are the dangers to modifying users directly in the database?

Manually modifying anything in the database inherently comes with risks.  The biggest is that you risk corrupting data by getting it in an inconsistent state across tables, which can cause foreign key constraint violation errors later on.

In the case of suspending/un-suspending a user, that risk is pretty low since it's limited to just the craft_users table, but in the case of changing user groups, it's higher because now you're talking about craft_users, craft_usergroups, craft_usergroups_users.

In both cases, you also need to take into account any plugins that might be using that data as well.


getPath() does not return subfolder for S3 asset source

Seems to be working as expected for me.  I've got an Asset Source setup with an S3 bucket.

At the root of the bucket, there is a test1 folder and in it is a test2 folder... i.e. root/test1/test2/.  From there, I put a test.jpg file inside of test2.

When I do this from a template (where ID is the Asset ID for test.jpg:

{% set image = craft.assets.id(13).first() %}

{{ image.getPath() }}

I get the expected:

test1/test2/test.jpg


You could go for a lightweight content-builder. That would mean that you could and would create a matrix blocktype for each of your content elements i.e. one blocktype for image with all the metadata you could chew on as fields, another for say body with some props too and so forth.

That would also give your users some neat control over the document flow.

Then you would saw it seamlessly together on the template layer. Your Content-Editors will not feel a thing.


How do I load composer dependencies for a Yii module that's in my site repo?

With a little nudge from Brad, here's the answer:

In order to get the module's composer dependencies taken into account in the parent site's composer dependencies, you need to add the module in the parent's composer.json, both as a require and as a repository with the path type, like so:

{
  ... a bunch of stuff from the default composer.json goes here ...
  "require": {
    "php": ">=7.0.0",
    "craftcms/cms": "3.0.0-RC5",
    "vlucas/phpdotenv": "^2.4.0",
    "roave/security-advisories": "dev-master",
    "modules/modulename": "dev-master" <-- add your module here (package name)
  },
  ... more stuff goes here ...
  "repositories": [
    {
      "type": "path",
      "url": "modules/modulename" <--- and add it here (package path)
    }
  ]
}


Bulk resave entries to trigger onSaveEntry event

If you re-save the section(s) that your entries are in, it should re-trigger a save of all of the entries.

Hope that helps!


Sort entries by a related entry (lastName) and then paginate

If I understand correctly, then it may be better to loop through the books rather than the authors, then group by author. I'm not 100% on this syntax but may send you down a good path...

Set the query

{% set query = craft.entries.section('books').order('author.lastName').all()|group('author.lastName') %}

Loop and divide

{% paginate query as pageInfo, pageEntries %}

{% for author, books in pageEntries %}

{{ author.lastName }}

        {% for book in books %}

{{ book.title }}

        {% endfor %}

{% endfor %}

{% if pageInfo.prevUrl %}Previous Page{% endif %}
{% if pageInfo.nextUrl %}Next Page{% endif %}


order and limit the occurrences of related categories

As is mentioned in multiple places, Twig is for viewing, not manipulating data. However, this should work.

We create an empty array, then loop through each entry's categories and if they aren't in the array, add them. Then finish up with a sort by title

{% set categories = [] %}
{% for entry in entries %}
  {% set entryCategories = craft.categories.group...all() %}
   {# notice the IF to combat duplicates #}
   {% for category in entryCategories if category not in categories %}
     {% set categories = categories|merge([category]) %}
   {% endif %}
{% endfor %}
{% nav category in categories|sort((a,b) => { a.title <=> b.title } %} {# reverse to b.title <=> a.title to change sort #}
...
{% endnav %}


Yes, sort of. As soon as the rendering template hits a {% cache %} tag, Craft grabs the outputted content from the cache table in the database and ignores all other template logic until the {% endcache %} tag.

So, the results of the PHP-based query will be cached with the rest of whatever is between the tags only for use in that instance as HTML.

If your hook is called anywhere else, Craft will make the PHP query again, as the query itself is not cached independently. In order to accomplish that (if you want), you will need to implement some plugin-level cacheing using the Cache Service.

For cache invalidation, here is what Brandon has to say:

Any time ElementCriteriaModel::find() et al. is called within {% cache %} tags, it will be recorded, however you will have to manually register any elements that should be associated with the cache, using this code:

// Don't initialize the CacheService if we don't have to
$cacheService = craft()->getComponent('templateCache', false);

if ($cacheService)
{
    $cacheService->includeElementInTemplateCaches($elementId);
}


How do you show which Sale a product has applied in Commerce?

The real answer is:
{% for sale in variant.sales %}

    {% sale.description %}

{% endfor %}


As noted in the comments above, eager-loading is not yet compatible with Live Preview. A clean workaround is to disable eager-loading in the template when the page is being viewed in Live Preview:

{% if craft.request.isLivePreview %}
    {% set images = entry.gallery %}
{% else %}
    {% set images = craft.assets({
        relatedTo: {sourceElement: entry.id, field: 'gallery'}
    }) %}
{% endif %}

{% for image in images %}
    {{ image.url }}<br />
{% endfor %}


How can I replace a newline (in a plain text field) with a comma?

I figured out that the best way to do this was to replace the newline character \n.
Final code:
{{ plainText|replace({ "\n" : ", "}) }}


Whats the best way to save a new entry in my plugin?

You can use the FrontEnd Entry Form for this. If you want to allow guests (non-registered users) to submit the form, you need to use the Guest Entries plugin.

Both methods will set "publishing date, id, etc" automatically, you just need to specify the title in the form.

If you want to hard-code some field values and prevent the user from changing it, you'd need to create a plugin which checks for entries.onBeforeSaveEntry or guestEntries.beforeSave (if you use Guest Entries plugin).

Edit:

The Entry Form is just an example. You can just as well use an ajax-request to send your data. Just make sure the POST values are set correctly.

If you want to save an entry from within your plugin, use the EntriesService API


Getting a "500 Internal Server Error" when uploading an image asset

ok i solved the problem by following the answer to this question here:

FastCGI error when accessing a local development site using MAMP Pro

even though the ajax call didn't generate an apache error at the moment it was called, it must have been something to do with fastcgi in general, cos the answer to that question worked for me!

i have never had this problem before, and i have heaps of other local sites which also do file/image uploading. so strange. and uploading of other file types (eg pdf) into the assets area worked no problem! doesn't make sense. but as a developer, sometimes you just accept the mystery of it all...

UPDATE

the problem started rearing it's ugly head again, even though i hadn't touched the httpd.conf edit i did to fix it. so i just deactivated the fastcgi module on the MAMP Pro dashboard. et voila, we're back in business....


How to read form response URL variables in template?

I'd go with the built in craft functions.

craft.request.getQuery('login')

craft.request documentation here


How do I loop through entries for a specific entry type?

{% set entries = craft.entries.section('pages').type('blogPost') %}

{% for entry in entries %}
   {{ entry.title }}
{% endfor %}

Is what I have cobbled together... any pointers on improvements would be welcome.


What's the best way to paginate through entries from an entries field type?

To do this, you would need to use getPrev() and getNext() on the related entries’ template.

The trick is telling getPrev() and getNext() to use the order you defined in the source entry’s Entries field.

So first, you will need to get that source entry. If you only have a single entry in your structure section that has one of these Entries fields, that could be as simple as this:

{# Get the entry in the structure section that relates to `entry` %}
{% set sourceEntry = craft.entries.section('myStructureSection').relatedTo({
    targetElement: entry,
    field: 'myEntriesField'
}) %}

Once you have that, you can just pass its Entries field into getPrev() and getNext():

{% set prevEntry = entry.getPrev(sourceEntry.myEntriesField) %}
{% set nextEntry = entry.getNext(sourceEntry.myEntriesField) %}

{% if prevEntry %}
    Previous: {{ prevEntry.title }}
{% endif %}

{% if nextEntry %}
    Next: {{ nextEntry.title }}
{% endif %}


It's probably a validation error.  Use this to check if there are any.

$userModel->getContent()->setAttributes(array(
    'mycustomfield' => 'my field value'
));

if (!craft()->users->saveUser($userModel))
{
    $errors = $userModel->getErrors();
}


how can I filter to get only root categories in elementapi.php

To get all root categories you can use: 'criteria' => ['level' => 1]


Creating a multi-dimensional Photo Gallery on Craft CMS

Ah yes, gallery2. Used that quite extensively a few years ago. Have a client with an old gallery2 project as well, we might be doing something with it, so we're probably in the same boat.

I can tell you the last time I looked into the gallery project, they were shutting it down. I have no idea where the project stands now, the original authors wanted someone to take it over if possible. The website is still active but when a project is in limbo, it's never a good sign.

Integrating it with Craft is going to be an exercise in futility and it's going to be just as easy to get the original photos working inside Craft "natively". Craft can really do everything Gallery can do... and better because now you can do things  like relate photos back to actual content entries and more.

I took a quick glance at a lot of the site's galleries and it looks like they're not really doing anything special, hardly using any of the gallery features (like tags, etc).

Gallery stores all of its photos in a folder called g2_data. You could grab that folder,  throw it up in a Craft asset source, have Craft index that folder, and everything will be neatly organized by folder ready to roll. Make some Entries that correspond to albums and sub albums and then go to town adding them to each entry/album. Telling Craft about which photos live in which album is going to be the most time consuming but since Gallery 2 stores them hierarchically, at least you have a visual reference vs something simply stored in a flat database structure.

As far as maintainability, Craft is the easiest CMS I've ever had the privilege of using. A lot of my clients figure out most of the control panel before we even have the training session. I remember Gallery2 being very finicky about clearing caches, generating thumbnails, etc. All of this will be handled mostly automatically by Craft.


User Registration Form error message customisation

You can do this using Craft's static translation support.

For example, if your site is using en_us for its primary locale, then add a craft/translations/en_us.php file that has this in it:

<?php

return array(
    '{attribute} "{value}" has already been taken.' => '{attribute} "{value}" has already been taken. Login here instead.',
);


Matrix Field - variable entry does not exist

Thank you @Robin :) but I managed to do it myself.
It works nicely :)

{% set entries = craft.entries.section("galeria").all() %}

{% for entry in entries %}
    {% for block in entry.galeriaMatrix.all() %}
        {% switch block.type %}
            {% case "itemsGaleria" %}
                {% for image in block.fotografia %}
                    <img src="{{image.url}}" alt="{{image.title}}" />
                {% endfor %}

                {{ block.titulo }}
                {{ block.texto }}
            {% default %}
        {% endswitch %}
    {% endfor %}
{% endfor %}


You'll have to build a list of the data and then display it.

{% set arr = [] %}

{% for coupon in craft.entries.section('coupons').status('live').order('postDate asc') %}
    {% for content in coupon.contentBuilder %}
        {% set arr = arr|merge([content.myUniqueFieldName: content]) %}
    {% endfor %}
{% endfor %}

{% for item in arr %}
    {{ item.title }}
{% endfor %}


GeneratePendingTransforms stuck every time

I think to solve your issue we're going to need a bit more of information. A couple of things you can try:

set a higher max execution time. I think normally the max execution time is 120 sec. and this sometimes blocks other transforms
try using the craft task manager plugin to remove any tasks that get stuck.
try reindexing the images, remove all the cached items, check your folder permissions

That being said, I stopped using the image transforms Craft provides out of the box and started using Imager. Imager provides a handy way to do transforms in your template. Works like a charm and lots of handy options.


Unable to update Craft: 'requires yiisoft/yii2-queue 2.1.0'

How about changing the yii2-queue version number in composer.json and then running a composer update?


How to auto enable a plugin after install?

It's because the plugin is doing this in the init():
https://github.com/poptins/craftcms-poptin-app/blob/master/src/Poptin.php#L69-L74
That's basically overwriting Craft's default Project Config settings for a plugin (which is to be enabled).
https://github.com/craftcms/cms/blob/develop/src/services/Plugins.php#L536-L545
If you keep it there, then you'll have to explicitly set it to enabled in Project Config as well, but ideally, you'll want to move that logic out of init() and into something like an EVENT_AFTER_INSTALL_PLUGIN event.


Found the answer in the database. Apparently Sprout Forms uses the date field named "dateCreated". Also getting it in order by date (newest first) needs 'dateCreated desc'

{% for formEntry in craft.sproutForms.entries.formHandle('contact').order('dateCreated desc') %}
   {{ formEntry.dateCreated|date('d F Y') }}
{% endfor %}


How do I order by _entry type_ when looping through entries in a template?

You could use Craft's group filter for this, but you'll lose the ability to
use the paginate tag to paginate your entries by doing so.

{% set entries = craft.entries.section('mySection').order('title') %}
{% set entriesByType = entries|group('type') %}

{% for type, entriesInType in entriesByType %}

{{ type }}

    {% for entry in entriesInType %}

{{ entry.title }}

    {% endfor %}
{% endfor %}


You'd need to do this from a plugin that has a controller that calls UserGroupsService->assignUserToGroups().


How to install Craft on live server parallel to existing CMS?

Is the existing CMS live?
Often depends on your whole development process.
Quick thoughts would be to use a subdomain of live site.,e eg 'staging.mysite.com'

For managing redirects the answer is it depends.
Typically htaccess 301 redirects
Redirect 301 /my old url  https://www.mynewurl.com/my old url

You can replace the latter domain name with subdomain name eg as above 'staging' and then switch to real domain when live.

Depending upon Craft version you could use Retour for Craft2 or check the plugin directory for redirect management solutions.

Or if the original url structure is solid then you can always make craft match in section  settings :)


For the Live Preview button to show up, two criteria must be met:

Your section’s “Entries in this section have their own URLs” setting must be checked
Your section’s “Entry Template” setting must be set to a valid template path
For Craft 3.2+ pro version, a preview target must be specified. This happens automatically, but might be missing due to a bug. Add a preview target with Primary entry page => {url} to fix this.

Make sure both of those are set correctly, and the Live Preview button will show up.


Refreshing meta data when using AJAX page transitions

You'll need to send the new pageview to Google Analytics manually on your ajax success. You'll want to read the Google documentation page, but it can be as simple as added the following line where ga_page is the new url:

ga( 'send', 'pageview', ga_page );


Is there a way to apply project.yaml changes on deployment?

You can create a script to use the craft executable to sync your project config file

./craft project-config/sync


Live Preview failing in Safari and Firefox only

CORS (or Cross-Origin Resource Sharing) issues usually occur when you are attempting to load a resource such as a font, a stylesheet, or a script from a remote location that does not give your domain explicit permission to access it. Thinking the resource is unsafe, your browser will block it.

Are these pages attempting to load any resources from remote locations such as a CDN or web storage like an S3 bucket? If so, you may need to edit your CORS policy for those services to mark your resources as "safe" for your domain.


In pure MySQL land, this will depend on the underlying character set and collation of the underlying database and tables that Craft is searching against.  You can read more on the MySQL 5.1 rules regarding that here and see an example of how to utilize it here.

In Craft, however, we will do some normalization and additionally swap any known diacritics with their ASCII counterparts (ü => u) among other things before saving to the craft_searchindex table in the database.


I haven't tested this, but I think .sum() will execute your query, so put it at the end:
{% set reimbursementAmount = craft.matrixBlocks()
  .relatedTo(cat)
  .fieldId(9)
  .specialCase(':empty:')
  .sum('field_item_reimbursementAmount')
%}


How can I get a full stack trace in my custom plugin log?

By default a full stack trace will only be assembled and logged if an exception is thrown (which is what you're looking at in your 2nd example) mainly for performance reasons - cycling through the backtrace and assembling all of that info is a relatively expensive operation.

Standard calls to MyPlugin::log or Craft::log will get a partial backtrace added to each message.  The depth of that is controlled by the YII_TRACE_LEVEL PHP constant, which Craft sets to 3 by default.

If you want to have them log deeper into the trace, set that to a higher number in your public index.php file, just be aware of the performance implications.

There is some discussions of that constant here in the Yii docs: http://www.yiiframework.com/doc/guide/1.1/en/topics.logging#logging-context-information


Okay - this was a problem at our end.
We had a plugin which provided a twig extension that modified Craft's own hash method which was causing issues with the migration update.

Consider solved!


Welcome to Craft! Seeing as you are new I will try and explain the error, and offer some advice on how I would architect what you are trying to achieve:

Variable "siteLogo" does not exist.

This error is coming from the code sample you provided, more specifically it is referring to this part:

{% for asset in siteLogo.

Craft is looking for something called siteLogo. It's not looking for a field called siteLogo, rather a place where that field might exist.

I would assume your asset field exists inside a Global? That's how I would do it, but you just need to double check what the handle of your Global is, as that's what you use to access it in the templates. Also double check what the handle of your asset field is, as again, that's what you use in the templates to reference that field and get the asset in it.

So taking that, here is what I would do:

Firstly, I would use a Global, but I wouldn't call this "Site Logo". That is too specific. Maybe call it "Branding", as this opens up the possibility of adding more fields (Colour Scheme etc).

When you create a Global, Craft automatically generates the handle from the name you provide. A Global with a name of "Branding" would have a handle of branding.

Next I would create an Asset field, and call this "Site Logo". This handle would automatically generate to siteLogo (what you have already). You would also want to restrict this Asset field to 1 asset.

Now for the template.

As you only have 1 logo you do not need to do a forloop. Instead you can just output the 1 asset like so:

{% set logo = branding.siteLogo.one %}
{% if logo|length %}
    <img src="{{ logo.url }}">
{% endif %}

I hope that helps!


Displaying errors on frontend user forms

I just tested this with the user registration for in your link and got the expected behavior when you try to register with a username that already exists.

A few things to check.

Make sure you have public registration enabled in the Control Panel under Settings->Users->Settings.
When you're testing registering a user in your front-end form, make sure you're logged out of your current user account.


Issue with Matrix `type` property and Live Preview?

Live preview have gone through a major refactoring for Craft 3.2, which addresses this issue. For Craft 3.1 and below see solutions below.

This is happening because Matrix will only show the non-live blocks so long as you don’t set any Matrix parameters in your template. As soon as you tell it to only show blocks of a certain type, it no longer feels confident that the blocks it was going to output are the right ones, so it will dump them and run a new DB query.

One possible way around this would be to do this:

Craft 2:

{% if craft.request.isLivePreview %}
    {% set firstCopyBlock = null %}
    {% for block in entry.matrixField %}
        {% if firstCopyBlock == null and block.type.handle == 'copy' %}
            {% set firstCopyBlock = block %}
        {% endif %}
    {% endfor %}
{% else %}
    {% set firstCopyBlock = entry.matrixField.type('copy').first() %}
{% endif %}

{% if firstCopyBlock %}
    {{ firstCopyBlock.plainText }}
{% endif %}

Craft 3:

{% if craft.app.request.isLivePreview %}
    {% set firstCopyBlock = null %}
    {% for block in entry.matrixField.all() %}
        {% if firstCopyBlock == null and block.type.handle == 'copy' %}
            {% set firstCopyBlock = block %}
        {% endif %}
    {% endfor %}
{% else %}
    {% set firstCopyBlock = entry.matrixField.type('copy').one() %}
{% endif %}

{% if firstCopyBlock %}
    {{ firstCopyBlock.plainText }}
{% endif %}


Craft Commerce: Geo Location, and option select dropdown to switch between currencies

The Cart's currency {{cart.currency}} is always the default base currency. You can't change or switch this currency.

This means all prices/discounts/taxes are all stored and entered in that currency.

In the example templates, the price of items is shown in that currency using the currency filter and passing in the cart.currency like so:

Sale Price Subtotal: {{ item.subtotal|commerceCurrency(cart.currency) }}

When the user goes to pay for the order, we allow them to pay in a different currency called the paymentCurrency this is accessible with {{cart.paymentCurrency}}. You can also change the cart's current payment current with the controller action commerce/cart/updateCart and passing a valid currency ISO. The ISO you pass must be a valid one set up in your settings, along with a conversion ratio.

We don't recommend converting the price of all items with the payment currency using the currency filter, as the total will not match the order amount. We recommend only converting the actual payment due or order total.

In addition to changing the payment currency with controller action here are the other ways you can change the payment currency: https://craftcommerce.com/docs/payment-currencies#switching-currencies

By default the payment currency is the default currency of the system.

As for taxes, these are always based on the shipping address. So the only way to switch the tax rate would be by the customer changing their shipping address on the cart. FYI there is an option to base the tax calcs on the billing address:

https://craftcommerce.com/docs/configuration#usebillingaddressfortax

Hope that helps.


Front-End Entry (Guest) saving correct values on error

Digging into a past solution for checkboxes thanks to @bradbell, here's the answer!

 <select name="fields[honorific]">
     {% for honortitle in entry.honorific.options %}
         {% set chosen = false %}

         {% if honortitle.selected %}
             {% set chosen = true %}
         {% endif %}

         <option value="{{ honortitle.value }}"{% if chosen %} selected{% endif %}>{{ honortitle.label }}</option>
    {% endfor %}
 </select>


getAllSections but not these specific sections

Here's how I've gone about that in the past.

Loop through all sections, and only if section.type is structure and doesn't have the handle 'pages' (skip that section, essentially);

{% for section in craft.sections.getAllSections() if section.type == 'structure' and section.handle != 'pages' %}
  What you want to do here... Print the content or whatnot.
{% endfor %}

And if you only want to get channels;

{% for section in craft.sections.getAllSections() if section.type == 'channel' %}
  What you want to do with the channels here...
{% endfor %}


You're close! The relatedContent field is an ElementCriteriaModel, so you need to loop over it (or otherwise treat it somewhat like an array) to get to the entries.

The matrix field is also an array like thing, and you need to loop over it to get at the blocks. See here

Here is what I would do (assuming the matrix field handle is genericContent:

{% for oneRelatedContent in entry.relatedContent %}
  {% for block in oneRelatedContent.genericContent %}

        {{ oneRelatedContent.sectionTag.first }}

{{ oneRelatedContent.title }}

        {{ copy }}

  {% endfor %}
{% endfor %}

You want to use loop.index to tell you which matrix block this is.
If you need to count the entries in relatedContent, you will need loop.parent.loop.index Loop variable


ADLDAP plugin in Craft 2.6 - New User Required In Craft Table?

In order to navigate as a user in craft the user needs a record in the users table. So what the plugin does is the following

Starting an authentication by active directory
If the login credentials are correct it searches if a craft user exists
If there is no craft user connected to the active directory user it creates a new user with the same name/password like he/she has in active directory
If there is a craft user instead of checking the password with the craft user - in case you changed it in active directory - it just overwrites the current craft user password every single time a user tries to login. The password will be crypted only for craft. There are no changes to your active directory

In summary: you don't need to be afraid, there are no changes in active directory but every time a user tries to login his password will be stored into the db again and again.

The Code is not optional, you have to store the active directory user as a craft user in order to change their permissions otherwise they won't be able to login to the backend or make any changes unless you implement your own logic/controllers to manage the content.

Edit
just some more thoughts: If your users won't be able to login to the backend and should be able to make changes only via frontend requests, there is no need to store them as craft users, so you could eventually(!) - depends on the rest of the plugin - remove that block but you won't be able to use crafts build-in functions like detecting which user made certain changes.

You would have to create a custom logic to give them permissions (if needed) and you would have to log user activities by yourself (if needed). So if you want to see who did something you have to include a custom username field for every entry.

Furthermore you can't use the craft->userSession service to get current user information and you have to implement logic that the user is actually logged in by yourself (store some values in the $_SESSION) You can't use crafts currentUser global in twig as well -> you need a custom twig extension or a custom function.

All controller actions must be allowed for everyone so they can't access all the craft default controllers since most of them don't allow anonymous requests.


Craft cacheMethod setting is being overridden

The craft/config/memcache.php file has nothing to do with where PHP sessions are stored.  It is for Craft's general purpose data caching.

If you want to save PHP session in memcache, you'll need to set the php.ini save_handler and save_path similar to: https://www.digitalocean.com/community/tutorials/how-to-store-php-sessions-in-memcached-on-a-centos-vps

At this point, I'd suggest not using the overridePhpSessionLocation config setting.  Everything it does can be done through php.ini and it's been removed from the upcoming Craft 3 release anyway.


Restict admin user permissions to only editing users he/she has created.

I believe what you're looking for is 'isInGroup'

{% if currentUser.isInGroup('groupHandle') %}

It will also accept an actual group object or a group ID as well.

There is also getGroups:

{{ entry.author.getGroups() }}

So you have several options:

If all users only have one group (so they can not be in two) you can check if the current user is in the same group like the first group of entry.author. But this has the disadvantage if someone wants to change his/her group the entry will become invisible for the previous group
You could attach the group handle to an entry. So you field create a plainTextField and insert the group handle of the author to this entry -> if the author changes his/her group the entry will still be available for the author as well as everyone who was able to see the entry before.

If you choose the second option you would be able to include the search condition in a ElementCriteriaModel very smooth. And search only entry that is connected by the current group of the currentUser. If someone should be able to see entries but he/she is not allowed to edit them you would just include the isInGroup condition to check if she/he may proceed.

For example your user list could look like that

{% set users = craft.users.find() %}
{% for user in users %}
    <!-- everyone can see the firstName of each user -->
    {{ user.firstName }}
    {% if currentUser %}
        <!-- but only logged in users can see the last name -->
        {{ user.lastName }}
        {% set groupsOfUser = user.getGroups() %}
        {% if groupsOfUser|length %}
            {% if currentUser.isInGroup(groupsOfUser[0]) %}
                <!-- only users of the same group can edit/delete or whatever -->
            {% endif %}
        {% endif %}
    {% endif %}
{% endfor %}


Use an entry field's value in body class

You've assigned the string 'work modifierClass' to the bodyClass variable, rather than adding the value of the modifierClass variable to bodyClass.

You can assign the value of modifierClass to bodyClass like this:

{% set bodyClass = 'work ' ~ modifierClass %}

The ~ (tilde) character is Twig's string concatenation operator.

You could even remove the modifierClass variable altogether and just do this:

{% set bodyClass = 'work ' ~ entry.shortName %}


Trouble calling a plugin's controller function from within an event listener function

You really, really shouldn't do this.

I'm not familiar with FormBuilder, but if it is well-built, its controllers will comprise thin methods calling services to do the grunt work; services which you can also call.

If there isn't a service method which does what you want (still assuming everything is well-architected), that means the author chose not to make that functionality part of FormBuilder's API, presumably for a good reason.

If FormBuilder isn't well-built, and instead shoves a load of code in its controllers, well, that's still not a reason for you to do something similarly ill-considered.


Associating multiple FreeForm entries with a single Craft entry

I was thinking about this myself, and I found the following 2 articles which I have been going over. It looks like it is quite possible:
http://craftsnippets.com/articles/using-template-hooks-in-craft-cms
https://docs.solspace.com/craft/freeform/v3/overview/relations.html#overview
The 2nd link has a heading for “Relating more than one element” which looks like it would apply in your situation.


Getting related project of a submitted 'wish' through the entry field.

The way you've set it up now, it won't be possible without doing 2 requests: one to create the wish, and one to alter the project (add the wish relation).

If you'd turn it around, and give the wish section a field 'belongsToProject' (or whatever else you'd like to call it), you'd be able to create this hidden input field in your wish form:

<input type="hidden" name="fields[belongsToProject][]" value="{{ project.id }}" />

Notice the []. Those are needed because a relation field can have multiple related elements, even if you limit it to have only one.
On saving, the field will be populated with the project relation you're looking for.

On viewing your projects and wishes, assuming you have a variable called project with your current project in it, you could simply do:

{% set wishesForProject = craft.entries.find({
    section: 'wishes',
    relatedTo: {
        targetElement: project,
        field: 'belongsToProject',
    },
}) %}

{% for wish in wishesForProject %}
    {{ wish.title }}
{% endfor %}


Complete working example for adding Craft Commerce items to the cart using AJAX and jQuery?

The question you link to - that is a working example really except you a) might not need the CSRF stuff if you haven't turned on CSRF protection (you should, though) - and of course the ... at the end means you should at least finish off the function and do some error handling.

In any case, in this specific case, you should just in essence need:

$(function() {

    $form = $("#addToCartForm");

    // handle submits via ajax

    $form.on('submit', function(e) {

        //Prevent the default submission
        e.preventDefault();

        //Get the form data
        var form_data = $form.serializeArray();

        // ajax it over to the server
        $.ajax({
            type: 'post',
            url: '/',
            data: form_data,
            success: function(response) {
                if (response.success) {
                    alert(response.cart);
                }
                else {
                    alert("Failure!");
                }
            }
        });
    });

});

..although I am doing this on my phone.  So if you get syntax errors let me know!


Display notification if no entries exist for status criteria and logged in user

Why don't you just grab disabled entries from the author?

{% set entries = craft.entries
    .section('profileEntry')
    .status('disabled')
    .authorId(currentUser.id)
    .all() %}

Then you can loop those

{% for entry in entries %}
    {{ entry.title }}
{% else %}
    no entries found
{% endfor %}


Is it possible to restrict access to a page based on a visitor's country?

Luke Holder has created a plugin that would help you in this situation.

Geo Plugin for Craft CMS


Unable to sort large number of blocks in Matrix field in CP and template

This is because Craft stores the sortOrder values in the database with a MySQL column type of tinyint that happens to be signed, which means it can store a range of -128 to 127.

Aside from the fact that negative sort orders don't make much sense, that means if you have 127 or more Matrix blocks to sort, things will stop working as expected.  Because 127 things to sort ought to be enough for anyone, right?

Regardless, in the next (post 2.5.2765) release, we've changed all sort order column in the database to be unsigned smallints, which means they can store a range of 0 to 65535.


How to add an alpha ordered list option in Redactor?

I ended up making a custom redactor plugin for this. Code at https://github.com/FosterCommerce/redactor-alphalist (repo is currently private but should be published soon).


So I figured out the issue, it is related to Ubuntu and how the mount process works using Upstart. I had a line in fstab to load the network drive but Ubuntu fails. Because of that failure, craft couldn't find the shared path which points to craft/storage/


Little bit confused with your question, if you want to access your settings then you can do craft::$app->plugins->getPlugin('handle')->getSettings()->foo;


Make dump() available when devMode is disabled

Add this to your plugin/controller:

if (!craft()->config->get('devMode'))
{
    craft()->templates->getTwig()->addExtension(new \Twig_Extension_Debug());
}

Thanks to the all-knowing Brandon Kelly, who posted the solution on Slack.


How to pragmatically set registered user status to pending and then manually send activation email

So, for the part preventing the activation, don't use:

if (Craft::$app->request->getIsSiteRequest())

Just do:

Event::on(
    Users::class,
    Users::EVENT_BEFORE_ACTIVATE_USER,
    function(Event $event){
        $formName = Craft::$app->getRequest()->post('group');
        if ($formName==='ypo' || $formName==="yp") {
           $event->isValid = false;
        }
    }
);

For the other part:

Event::on(
Elements::class,
Elements::EVENT_AFTER_SAVE_ELEMENT,
    function(Event $event){
        // Check it's a front end request
        if (Craft::$app->request->getIsSiteRequest()) {
            if($event->element instanceof \craft\elements\User) {
                $user = $event->element;
                if($event->isNew) {
                    $user->unverifiedEmail = $user->email;
                    Craft::$app->getElements()->saveElement($user, false);
                    $formName = Craft::$app->getRequest()->post('group');

                    if($formName==='ypo') {
                        Craft::$app->getUsers()->assignUserToGroups($user->id, [1]);
                    }
                    if($formName==='yp') {
                        Craft::$app->getUsers()->assignUserToGroups($user->id, [2]);
                        $emailSent = Craft::$app->getUsers()->sendActivationEmail($user);
                    }
                }
            }
        }
    }
);

Because you don't enforce email verification in control panel/user settings, you are skipping populating the unverifiedEmail field for the new user which is done here and that was part of the issue too :)


You have two different options. You can either use Crafts search so your string would be listingAgent:*searchterm* OR coListingAgent:*searchterm* or listingAgent:searchterm OR coListingAgent:searchterm if it should be an exact search

{% set results = craft.entries()
    .search({
        query: 'listingAgent:*' ~ getAgent ~ '* OR  coListingAgent:*' ~ getAgent  ~ '*',
        subLeft: true,
        subRight: true
    })
    .all()
%}

or you query correctly for the field values but I would prefer to do that in PHP instead of Twig


How to support chained Element queries with Twig tags

You need to return the instance in every single set call. As you noticed correctly the last line in every function that changes properties of your query is return $this which allows you to chain another function after the call. Simple as that.

Always return the query until you execute it with all() or another function like that is enough


How to create a new Tag group and save it?

You were on the right track. To save things in Craft, you need to use the according service. In your case you need the tags service:
$tagGroup = new TagGroup();
$tagGroup->name = 'GroupName';
$tagGroup->handle = 'GroupHandle';
$isTagGroupSaved = Craft::$app->getTags()->saveTagGroup($tagGroup);

if(!$isTagGroupSaved) {
    // Inspect validation errors if saving the tag group failed
    var_dump($tagGroup->getErrors());
}


How do I output a file’s URL in a Matrix field?

Assuming the field where your client can select the download is an asset field, you can use the following:

{% elseif block.type == "bladeBrochure" %}
    {% set download = block.download.first() %}
    {% if download %}
        Click me to download
    {% endif %}

Replacing block.download with the name of your field.


You can add custom fields to users the same way as you do for entries, categories, and all other elements in Craft. Create a custom field for middle name, and go to Settings > Users > Fields and add that field to the field layout.

EDIT:
The field will show in the profile tab, and there is no way to properly add fields to the account tab, even with a plugin. But, although a bit hacky, you could do this by just moving the field with javascript.

First, install the Control Panel JS plugin by Lindsey DiLoreto. Read the docs on how to get the plugin to load your custom js-file.

Each custom field in the form has an id with the naming convention fields-myCustomFieldHandle-field. If you name the field middleName and want to put it before the email field on the account tab, you could do something like this:

$(function () {
    if ($('#userform').length>0) { // just to make sure we're in the user edit page
       $('#email-field').before($('#fields-middleName-field'));
    }
});

Getting it to appear between the first and last name fields, or making them 100% width and putting the middlename in the middle, would also be possible, but requires a bit more DOM manipulation. Let me know if this is important for you.


How do I print the last level of a category?

I've not actually done this, but I'm guessing:

{% set category = entry.categoriesFieldHandle.last() %}

(...then .level on that to get the level if that's what you want).  .last() is the opposite of first().

(Make sure you check category|length as it might be that no categories are assigned...)


"Field Limit is too big for your chosen Column Type" error on already existing fields when updating matrix

If you scroll down a little bit from your screenshot, you'll see an "advanced" toggle for the Plain Text field settings.

In there is a "Column Type", which I'm guessing is set to varchar(255B) for you.

Set that to Text and that should solve it for you.


The only possible core solution to query for these entries in Twig is to query for entry IDs first, process them with merge or without and then pass the IDs to the id parameter of a new ElementCriteriaModel.

Other than your solution implementing a conditional in the for loop this works with paginate and getNext tags, you only query for the entry models you're after, but the cost of this is the extra queries you need to get the IDs.

{% set futureEventsIds = craft.entries.eventStartDate('>=' ~ (now.date)).ids() %}
{% set specialEventsIds = craft.entries.genericEventDate(':notempty:').ids() %}
{% set idParam = futureEventsIds|merge(specialEventsIds) %}

{% set allEvents = craft.entries.id(idParam).order('GREATEST(eventStartDate, genericEventDate) desc') %}


Bootstrapping Craft for PHPUnit on command line

I read that you cannot use bootstrap.php in the craft/app folder because you're essentially trying to bootstrap a webapp (and this server isn't a webserver).

Not sure where you read that, but that doesn't sound right.

I'm assuming you've got a multi-environment config setup?  If so, then manually set the CRAFT_ENVIRONMENT PHP constant before you load the Craft bootstrap.php file to the environment you want Craft to load in the config files.

That will get rid of the Undefined index: SERVER_NAME error you're getting as well as should fixed your database connection issue.


Fire event first time future dated entry goes 'live' from 'pending'

I've created a plugin called Published Event does exactly what Brad suggests in his answer. It fires off an event when a entry moves from pending to live.


Craft, CSS Frameworks, Bower & Grunt setup suggestions

In my humble opinion, this is a task for Grunt / Gulp, not for Craft.

Addy Osmani has an excellent article on Environment-specific builds that would be interesting for you and the kind of use case you mention.

In short, gulp-replace or gulp-processhtml and gulp-preprocess will give you what you need to build such functionality in your build scripts. Similar plugins exist for Grunt as well.

As for file organisation, I generally keep my package.json and gulpfile.js files at the root of the repo / website. I find it a lot easier to manage paths.


unsucessful setFieldValues after programatically creating field on a migration

The main issue here ended up being a Craft bug (craftcms/cms#6651), which has been fixed for the next release (3.5.5).
There are a couple ways your code could be improved as well, though:

$fieldGroup is a craft\models\FieldGroup object, not an array, so you should access its ID via $fieldGroup->id, not $fieldGroup['id']. (Or just use the $groupId property.)

Avoid using === for numeric properties like id, unless you know for certain what the type is going to be. IDs should be casted as integers, not strings, and places where they are strings should be considered a minor bug. (It’s due to how MySQL returns the data, but not an issue in PostgreSQL, and we are working toward always ensuring that they are typed as ints correctly even for MySQL.) Safest thing for you to do is replace === with == on this line:
if ($entryType->id === '2') {

Your two continue statements should be break. continue just tells the loop to move onto the next cycle of the loop; break tells it to completely break out of the loop.

$tabsForSaving is never defined. I’m surprised that’s not causing a PHP error for you.


createCommand sql query not working in plugin

Thanks to @carlcs for pointers managed to get this working with the following:

$criteria = craft()->elements->getCriteria(ElementType::User);
$criteria->limit = NULL;

$query = craft()->elements->buildElementsQuery($criteria);
$params = array(
    ':interest' => '%"8948"%',
);
$query->andWhere("field_interests LIKE :interest", $params);
$result = $query->queryAll() ;