Dates Expiring By Custom Field date_modify

You could write a fairly simple plugin to automatically set the expiration based off of another field value or calculation.

In your plugin's main file:

public function init() {

    parent::init();

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

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

        if ($entry->section == 'Events') {

            if (empty($entry->expiryDate)) {
                $date = new DateTime($entry->dateTime);
                $modifiedDate = date_modify($date, 'tomorrow 5am');
                $entry->expiryDate = $modifiedDate;
                craft()->entries->saveEntry($entry);
            }

        }

    });

}

Updated Code fixed syntax errors and added a check to see if expiration date is already set, otherwise created an endless loop (and may overwrite a manual setting).


How to Properly Use Controller and Service in Custom Plugin

It's actually quite simple.
First you need a form:

<form method="post" id="myForm">
    <!-- insert your route as an action parameter in camelCase -->
    <!-- pluginName/controllerName/methodName -->
    <input type="hidden" name="action" value="craftMailchimped/submittal/receiveEmail">
    <input type="text" name="email">
    <input type="button" id="submit" value="Submit">
</form>

Then you have your javascript (I'll use jQuery ajax for that)

$("#submit").click(function(e){
    e.preventDefault();
    $.ajax({
        type: "post",
        url: '', //<- leave the url blank.. always...
        data: $("#myForm").serialize(),
        success: function(data){
            console.log(data);
            if(data.success === true){
                alert(data.message);
            }else{
                //display your data.errors here
            }
        },
        error: function (XMLHttpRequest, textStatus) {
            console.log("Status: " + textStatus);
        }
    });
});

And your controller and this model

public function actionReceiveEmail() {
    $response = [
        'success'   => false,
        'message'   => Craft::t('something went wrong')
    ];

    $emailModel = new CraftMailchimped_EmailModel();
    $emailModel->email = craft()->request->getParam('email');

    if(craft()->yourServiceName->subscribe($emailModel)){
        $response['success'] = true;
        $response['message'] = Craft::t('wuhu great :D');
    }else{
        $response['errors'] = $emailModel->getErrors();
    }

    $this->returnJson($response);
}

Your service could contain this method

public function subscribe(CraftMailchimped_EmailModel $emailModel){
    if($success = $emailModel->validate()){
        //make your API calls
        $response = ......;
        if($response['error'] === 444){
            $emailModel->addError('email', Craft::t('Email is already taken'));
            $success = false;
        }
    }

    return $success;
}

So you are totally right with your points. In case you want to see how to manage records in your database take a look at this plugin Click I created it for learning purposes for someone else in this thread. Maybe you'll find it useful to learn some stuff like fetching objects from the database and inserting.

Edit
to resume

You should always leave the url blank, define an action parameter for your route. The request type does not matter, it's the same for ajax and normal requests
Your Route is always pluginHandle/controllerName/functionName in camelCase
Your messages and responses should always be defined in your Controllers, your Services are just for logic that return true or false (or some objects like craft()->entries->getEntryById()), you can create models with validations for error messages you can use them like that: (validators will provide the translated messages)

// in your controller
$mailChimpModel;
if(craft()->mailchimp->subscribe($mailChimpModel)){
    $response['success'] = true;
}else{
    $response['errors'] = $mailChimpModel->getErrors();
}

$response['errors'] is an array with all field handles and the corresponding translated error messages like 'email' => ['This Mail is already in the list']
Crafts RequestService has all the methods you need to access the request variables. Those values are all safely escaped and secure, so you can be sure there won't be security measures. You can access parameters with craft()->request->getParam('key', default value);


Craft itself is caching this data. Once you've removed those lines from your composer.json file, you'll also need to remove them from the cached plugins.php file in Craft.

Open this file...

  /vendor/craftcms/plugins.php

Then find your plugin. Remove the relevant lines from there, and save the file.

For this reason I actually recommend declaring hasCpSettings and hasCpSection the "old fashioned way"... within your plugin's main PHP file.

Yes, it's possible to declare those values via PHP as well. And if you declare them via PHP, they won't get cached in Craft's plugins.php file.

  https://docs.craftcms.com/api/v3/craft-base-plugintrait.html#property-hascpsection
  https://docs.craftcms.com/api/v3/craft-base-plugintrait.html#property-hascpsettings


How to use required fields on localised entries?

I don't know if you re-use the fields you're using in that channel in other sections and if you do, my suggestion might not work for you, but here's what you could do:

Set all fields to be "not translatable" and if content is entered in one locale it will get synced to all locales. Thereby all required fields will always be filled out and disabling individual "dummy versions" is no problem any more.


Multiple forms on same page.. Solspace Freeform

Thanks for reporting this issue. We'll have a fix available for this in the next release of Freeform. :)

In the meantime, affected customers can contact us for a patched copy.


net::ERR_CONTENT_LENGTH_MISMATCH for CP after enabling compression

I think we've just found a workaround for this in the upcoming 2.3 release. :)


When using Settings -> Routes in the CMS with wildcard, routes.php does not work

I don't know if it's great practice to do this but if you want a "wildcard", especially as your first segment, you should a) put it in your routes.php manually b) make it the last route (always) otherwise it will take precedence just as you said and the other routes won't work. Also, using regex in your named parameters is good practice, if you are sure that teamid> is always and only a number, you could do this <teamid:\d+> so that someone visiting contact-us/peanuts would get a 404.

As far as setting this catch all route you want, just use a named parameter again:

'<anything>/<teamid:\d+>'         => ['template' => 'pages/index'],

This would have your catch all effect and will allow you to fetch the first segment if you need to.

If you expect a certain format for this first segment, in your template by calling {{ anything }} you could do some sort of validation. Also you could use regular expression to narrow the possibilities down a bit... With this as is, 500shoes/54896 would return your index page...

Hope that helps :)


postDate keeps jumping ahead when editing an entry

Adding as an official answer since we've had a handful of reports about this.  Best we can tell it's a bug in Firefox that happens when you live in a non-UTC timezone.  There are several Date related bugs in Mozilla's bug tracker, but this one looks to be the most relevant: https://bugzilla.mozilla.org/show_bug.cgi?id=1227499


Randomly getting the "Integrity constraint violation" sql error on saving entry

It's not a Craft bug.

The error means that the data in your craft_relations table is out of sync with the data in the your craft_elements table.  i.e. an ID exists in craft_relations.targetId that doesn't exist in craft_elements.id or visa-versa.

How it got that way is hard to say, but here are some common causes:

Someone manually edits database data without realizing the implications.
A database was imported into a MySQL box that only supported the MyISAM storage engine, which doesn't support foreign keys, so all of the foreign keys that Craft relies on to keep data consistent between tables are silently dropped.  If this is the case, you can use https://github.com/pixelandtonic/craft-fixfks to try and restore Craft's foreign keys.
A botched import/export script.
A plugin behaving poorly.

In the context of these two tables, if you want to find all rows that have a value in craft_relations.targetId that doesn't exist in craft_elements.id, the SQL would be similar to:

SELECT * FROM craft_relations r
LEFT OUTER JOIN craft_elements e
ON r.targetId = e.id
WHERE e.id IS NULL


For better practice, you should never use ".htaccess" file. Especially your problem can be easily solved by modify Apache configure file.

You should be able to find an Apache configure file somewhere in your /etc folder.
On my server its /etc/httpd/conf/httpd.conf.

Then just find the code

<VirtualHost *:80>
   ... your server setting
   ServerName your-server-address.com
   # add the following line
   Redirect permanent / https://your-server-address.com/
</VirtualHost>

Don't forget to restart your server after you done the change.
This will redirect any traffic trying to visit your site with none ssl to ssl, regardless your folder structure.


Creating / manage content - how is everybody doing it?

This is a simplified example, but this is how I'd approach user-manageable page content, using a content builder. Each content type gets its own block in a matrix field:

Which allows authors to add whichever page content blocks they require, in whatever order they like:

Simply add whatever blocks your design requires.


How to set a dynamic title in plugin on entry save?

To get more code into the template field that generates the title I tried importing a macro, but this didn't work. So squeezing it into the 255 chars is probably our only chance here. So it would be in fact better to do it with plugin.

To get your plugin code working you should use entries.onBeforeSaveEntry instead of entries.onSaveEntry.

Because when this event is triggered, it's already too late to update $event->params['entry'] properties for your save.

Another thing to change is setContentFromPost(). Change the ContentModel directly
$entry->getContent()->title = $fullTitle;


The usual method for debugging a Craft site is to pull down a copy of the production database content, import it into your local development database and run a local copy of the site's code on your computer. You can run the site using Craft's Nitro development environment, or use other local development environment frameworks like Valet or MAMP.
Once you have this local development site running, you can make changes to the templates to help debug issues or view the properties of objects, just by modifying the Twig templates. The Twig dump function is useful for viewing the contents of an object to see which properties you have available:
{% for tweet in craft.ssTwitterFeed.displayPost( '4' ) %}
    {{ dump(tweet) }}
{% endfor %}

If you're running the site with devMode enabled, the dd tag (Dump-and-die) is also helpful. This will dump out the variable and nothing else, i.e. your page won't render but instead you will get a formatted dump of the variable you're inspecting:
{% dd(craft.ssTwitterFeed.displayPost('4')) %}


Redirect user to language site of choice

The answer here was to redirect to another url using a different template rather than hitting the index template again, which was what was causing the loop.


Using Global Variable as Price for Variant

Removed the var_dump() from setting the variable as follows, and it works perfectly:

craft()->on('commerce_lineItems.onPopulateLineItem', function($event)
{
    $lineItem = $event->params['lineItem'];
    $globalPrices = craft()->globals->getSetByHandle('defaultPrices');
    $itemPrice = $globalPrices->fontStylePrice;
    $lineItem->price = $itemPrice;


Getting HTTP 500 error at end of update process when going from Craft 2 to Craft 3 with MAMP

Try switching MAMP out of Fast CGI mode. Go to the PHP Tab and select "Identical PHP Version for all hosts (Module mode)". Restart the servers and then. Then run the update.

You can normally switch back to Fast CGI mode at this point and it will continue to work OK. But if you do run into this, or a file upload problem, it's worth changing to Module mode temporarily as it often fixes whatever is causing the issue.


Is there a 2-factor authentication plugin for Craft?

I've heard of one in private testing, but I'm not aware if they plan to release it publicly or not.

Until the official Craft plugin store becomes a thing, the most comprehensive list of Craft plugins available I know of is over on the awesome Straight Up Craft.

  I want to build a system that someone on a dynamic IP could access, so static IP's are a bit harder.

O.K. What's the reasoning there, if you don't mind me asking?

  I was also thinking if there was a way to add another field to the login page, which was a decryption key, then use one the twig decryption method. If you don't have it, you'd see the data, but it would be all garbled up.

Not currently, but we've discussed giving plugins the ability to control the HTML of the login page.  Probably worth making an official feature request for that.

It is worth mentioning that there is an onBeforeLogin event a plugin can already listen to and apply their own custom password business logic (i.e. must be 200 characters long, have 40 emojis, 20 Egyptian hieroglyphs, be purple and only work on Tuesday).


Can I run one Craft install on multiple domains and/or subdomains?

Update for Craft 3

Craft 3 includes native support for multi-site installation. Here's a link to the official docs and here's a link to another question with more resources.

Old answer for Craft 1 & 2

Credit to @LukeHolder for the original answer, but here's a bit more detailed and technical answer. Note, this might not be possible on all hosts.

Place the craft folder above both domains, add Craft's index.php file to both domain web roots and set the $craftPath variables in them to point to the same craft folder.

To make a template (say for a blog) only load on its own subdomain instead of whenever any of its slugs are requested on any domains you can run this quick check:

{% set domain = craft.request.getServerName() %}

{% if not domain starts with 'blog' %}
    {% redirect '404' %}
{% endif %}

This will make "blog.example.com/some-blog-post" load, but "example.com/some-blog-post" will redirect to the 404 page.

Links to posts can formatted like this to add the subdomain to the URL:

http://blog.example.com/{{ entry.uri }}

While this isn't an end all solution, it is a functional workaround, especially if it's only for page or two. Use Craft 3 if you can.


400 Bad Request on account or admin login

Add this to your nginx server block:

server {
  ...
  large_client_header_buffers 4 16k;
  ...
}

and restart nginx. The default is 8k. If you have a lot of headers, beefing that value up should resolve it otherwise you may want to play with client_header_buffer_size as well.


If you're looking to reuse existing fields, you may want to take a look at the Neo plugin: https://github.com/spicywebau/craft-neo


Craft CMS on LEMP Stack (mcrypt not detected)

RitterKnights solution worked! I hadnt restarted php5-fpm.


302 redirect when updating the cart via Ajax using Craft Commerce 2

The function contains this

if ($request->getAcceptsJson()) {

Thus you'll need to set the dataType in your ajax request to json or text/json in order to not get redirected. If you didn't set it correctly Craft will treat it as a normal post request instead of an ajax request


If I'm understanding you correctly, this is possible using the standard Craft Pro "locale" stuff. In addition to making text translatable, you can make Assets translatable - in which case you can upload a different image for each translated region. The appropriate asset will be used. This assumes you target each region by having a dedicated URL prefix for each (mysite.com/thailand, mysite.com/japan etc)

https://craftcms.com/docs/localization-guide


Verbb Navigation Plugin Assistance needed

One way would be to use the positionedBefore query. Let's say Node 2 has the ID of 1000. Then you would write it like this

{% set nodes = craft.navigation.nodes('main')
    .positionedBefore(1000)
    .all() %}

The output would be all nodes before the node with the ID of 1000. In your case just Business Environment.

With descendantOf you would get all items within your specified node for example. Just check the documentation an all available node queries.

To get the ID of the node just use the inspector in the control panel, go to your navigation and look for the data-id="XXXX" of the node element.


How to use license in different environments

A few pre-requisites:

A Craft purchase/edition is tied to the craft/config/license.key file that is in place at the time the purchase is made and wherever that file goes, the purchase/edition will follow.
A craft/config/license.key file can only be tied to one "public" domain at a time.
Craft license validation doesn't run on "non-public" domains and you're able to trial the different editions of Craft for as long as you want on non-public domains.

https://craftcms.com/support/license-enforcement#how-do-we-determine-craft-is-running-on-a-public-domain

Craft will treat app-client.local.mycompany.com.br as a "non-public" domain, because it has one of the keywords we're looking for in its own segment in the subdomain.  You can see a list of those keywords here in number 4 of the previous link.

The rest of those domains Craft treats as "public" because they don't match any of the rules in that link, so license validation will run on them.

You don't say exactly what you're issue is, but if you purchased Craft on the development domain and you're using that same license.key file on the three other public domains, you're probably getting a warning in the Control Panel saying that license is already in use on another domain.

Since they are all for the same "site", you can either tell everyone that has access to the Control Panel to ignore the message and to not transfer the license away from the production domain, or you can change your qa and hom domains so Craft treats them as "non-public" and license validation won't run.

More related reading: https://craftcms.com/support/license-key-info


How do you use a for loop to output to JS?

It'd probably be easier to assemble the items the way you need them in Twig, and then JSON encode them. Try something like this:

{% set nations = craft.categories.group('country') %}
{% set countries = [] %}
{% for country in nations %}
    {% set thisCountry = {
        'country-id' : country.countryCode,
        'url' : country.url
    } %}
    {% set countries = countries|merge([thisCountry]) %}
{% endfor %}

{% set countryJs %}
var countries = {{ countries|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}
{% endset %}

{% includeJs countryJs %}


Creating environment variable from JSON file

You could write some PHP at the top of your general.php file that reads the JSON manifest in your public root directory, and add its keys/values to the config array. I wouldn't use environment variables here, personally – just add the manifest to the returned array in general.php:

// In general.php:

$assetsManifest = @json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'].'/assets/assets.json')) ?: [];

return array(
    '*' => array(
        ...
        'assets' => (array)$assetsManifest,
    ),
);

...and in your template:

<script src="{{ craft.config.assets['main.js'] ?? 'main.js' }}"></script>

Be advised that the null-coalescing operator (??) was just added in Craft 2.6 – if you haven't updated yet, you can use the default filter instead:

<script src="{{ craft.config.assets['main.js']|default('main.js') }}"></script>

Another approach for getting revved asset filenames in templates, is to use a plugin which adds either a custom template variable method or Twig filter/function to Craft. For an example of the latter, see Viget Labs' Gulp Rev Craft plugin, which is bundled with their awesome Gulp Starter repo. Here's how revving works using this particular plugin:

<script src="{{ 'main.js'|gulp_rev }}"></script>

For me, individual asset filenames in the config feels a bit off and the custom filter option seems a lot cleaner, so I'm personally going with that approach.


This Authorize.Net Accept.js gateway for Craft Commerce might be a good place to start: https://github.com/marionnewlevant/craft-acceptjs


Is it safe to have PHP files in the public directory of a craft cms website?

As long as the PHP files themselves don't introduce any security holes, having them in your web root is perfectly fine. That's not uncommon at all. How they were written makes all the difference, of course. If you aren't sure whether the developer followed best practices for the security of the mailer scripts, that might be of some concern.


Is it possible to grant admin permissions via plugins through userPermissions->saveUserPermissions?

This should do the trick...

$user->admin = true;

That data is part of the UserModel, so be sure to add it before the saveUser call.

Being a full-blown admin not technically part of setting permissions. If the user is an admin, that supersedes all other permissions settings.


Here's an example of accessing an entry's version history that Nathaniel Hammond recently shared on Twitter:

{#
Options for getVersionsByEntryId
* @param int $entryId The entry ID to search for.
* @param int|null $siteId The site ID to search for.
* @param int|null $1 limit The limit on the number of versions to retrieve.
* @param bool $includeCurrent Whether to include the current "top" version of the entry.
* @param bool $withContent Whether the field content should be included on the versions.
* @return EntryVersion[]
#}
{% set entryId = 7 %}
{% set siteld = null %}
{% set limit = null %}
{% set includeCurrent = true %}
{% set withContent = false %}
{% set versions = craft.app.entryRevisions.getVersionsByEntryId(entryId, siteId, limit, includeCurrent, withContent) ?? null %}

{% if versions|length %}

    {% for version in versions if version.getCreator() %}

{{ version.getCreator().username }}

    {% endfor %}

{% endif %}

In this example he's accessing the version's creator and displaying that, but you could easily swap that out for whatever you need to do, such as grabbing the version creation date etc.


Whitespace created when using if statements

You can also the hyphen/dash '-' modifier for shorter syntax and in place of the spaceless tags. Plus you get a bit more granular control where you want it, like trimming only leading or trailing space.

Example 1 taken from Twig Docs: Whitespace Control, this would remove whitespace around the if's and output of value.

{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# output 'no spaces' #}

Example 2 is a possible real world scenario for retentive space people:

{%- set metaDescription = 'Page description.' -%}
{%- set metaKeywords = 'word1 word2 word3' -%}
{%- set pageTitle = 'A Title' %}

{% if metaKeywords is defined -%}
    <meta name="keywords" content="{{ metaKeywords }}" />
{%- endif %}

{% if metaDescription is defined -%}
    <meta name="description" content="{{ metaDescription }}" />
{%- endif %}

{% if pageTitle is defined -%}
    <title>{{ pageTitle }}</title>
{%- endif %}

Rendered output:

<meta name="keywords" content="word1 word2 word3" />
<meta name="description" content="Page description." />
<title>A Title</title>


Is it possible to use the field layout designer in settings screen?

There are two ways to retrieve field layouts: by ID (FieldsService::getLayoutById()) and by element type (FieldsService::getLayoutByType()). The former is useful for element types that manage multiple field layouts and have their own way of storing those field layout IDs (e.g. sections, asset sources, etc.), and the latter is useful for element types that only need to manage a single field layout (e.g. users, or in your case, inquires.)

So, here’s what your plugin’s getSettingsHtml() method should look like:

public function getSettingsHtml()
{
    $fieldLayout = craft()->fields->getLayoutByType('Inquiry');

    return craft()->templates->render('inquires/_settings', array(
        'settings' => $this->getSettings(),
        'fieldLayout' => $fieldLayout
    ));
}

That “inquiries/_settings” template would map to craft/plugins/inquiries/templates/_settings.html, and that should include this:

{% include "_includes/fieldlayoutdesigner" with {
    fieldLayout: fieldLayout
} only %}

And your plugin’s prepSettings() method should look something like this:

public function prepSettings($settings)
{
    // Delete the old field layout
    craft()->fields->deleteLayoutsByType('Foo');

    // Extract the field layout data from the settings
    $postedFieldLayout = isset($settings['fieldLayout']) ? $settings['fieldLayout'] : array();
    $requiredFields = isset($settings['requiredFields']) ? $settings['requiredFields'] : array();

    // Save the field layout
    $fieldLayout = craft()->fields->assembleLayout($postedFieldLayout, $requiredFields, true);
    $fieldLayout->type = 'Foo';
    craft()->fields->saveLayout($fieldLayout);

    // Return the settings without the field layout data
    unset($settings['fieldLayout'], $settings['requiredFields']);
    return $settings;
}

Finally, whatever model your element type’s populateElementModel() method returns should have a getFieldLayout() method that looks like this:

public function getFieldLayout()
{
    return craft()->fields->getLayoutByType('Inquiry');
}

Note: The Field Layout Designer will only work within the plugin settings in Craft 2.2.2596 or later.


Search, by just one user field - fullName?

There's a nice list in the Craft docs with lot of examples for supported search syntaxes. Here's two that probably do what you are after:

  body:salty → where the ‘body’ field contains “salty”.
  body::"salty dog" → where the ‘body’ field is set to “salty dog” and nothing more.

Combine it with your variable like so:

craft.users.search('fullName::"' ~ getauth ~ '"')


Craft 3 Cache Busting for Pending Entries

That code would still work in Craft 3 and achieve the same thing it did in Craft 2.


Craft “Embedded Assets” Plug-in didn't save Embed in selected Asset Volume in CP

Have you seen this: https://github.com/spicywebau/craft-embedded-assets/issues/95

Might be related and a fix is expected in Monday.


TwigExtension added to Craft don’t work in emails

All you should need to do is remove this condition check:

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

You are only registering the twig extension for front end (site) requests, but emails can be triggered both on a cart complete front end (site) requests AND a back-end (CP) order status changes.


Different setPasswordSuccessPath for different user groups

A bit heavy handed, but the only way I can think of do pull this off, would be to write a custom plugin with it's own controller action that you change the link in the email to point to instead of Craft's UsersController->actionSetPassword().

That method would be nearly identical to Craft's except at the end, you'd redirect based on the user groups (if any) the $userToProcess is a member of, instead of just the setPasswordSuccessPath config setting.


Using the example in your comments, a simple solution would be to create a "Potential Jobs" Entry field and assign it to the Users field layout.

Whoever is doing the manually checking to find a match between tradesmen and clients would assign entries to that field that match the requirements.

The front-end user's dashboard would check that field to see if it has any entries in it and display them to the user.

You could probably get more elaborate with a Category field (that had Entry fields in it) if you want to group by more fine-grained details.


How to use an asset as featured image in different entries

You can assign an image to as many entries as you like; what's happening is for some reason, Craft appears to be unable to generate the appropriate image transform. It's very likely some kind of local dev environment setup issue.

For whatever reason, it's unable to access the AssetsController to generate the transformed image on the frontend, as seen in that 404 url.


The problem you're running into is that FeedMe doesn't know how to import into custom element types; I think a special hook would need to be written.

If you use my SEOmatic plugin it has a FieldType that lets you choose what fields to pull things like the title, description, etc. from which solves this problem.

Check out the section of the wiki docs on SEO Entry Meta to see how that all works.


Adjusters: Conditionally include tax in price

Answer is yes, you could use an adjuster to try and make the price "even" while in the cart.


Adding entry type using setContentFromPost

Relationships are always added as arrays of IDs, even if you are only relating a single element:

$user->setContentFromPost(array(
    'companyName' => $admin->companyName,
    'companyId' => $admin->companyId,
    'partnerManager' => array($admin->partnerManager[0]->id)
));


Not sure there is a definitive answer here. :) For the use-case you're concerned about, Craft uses the security key to encrypt/decrypt data in the database. In a stock Craft installation, that's for sensitive email settings.
Even then, with the advent of Project Config, that's not likely an issue anymore. Those settings will get stored in Project Config files, which hopefully are using environment variables to hide their values.
I'd guess that 99% of plugins aren't encrypting/decrypting sensitive info and the ones that are, are probably storing that info in Project Config, so it still wouldn't be a concern.


I'd just put whatever you want to share into an include. Also you shouldn't need the .html either as craft should find the file


Carbon 1 is deprecated - migrate to Carbon 2

To find the culprit, you could run a composer show --tree to see which plugin is using the dependency.

So far, I found two plugins using it :

rias/craft-contact-form-extensions (1.1.6)
solspace/craft3-calendar (2.0.20)

If you're using Solspace calendar, you should consider to upgrade to v3.
If you're using Rias Contact form extension, you can try to add the updated dependency to your composer.json file by running a composer require nesbot/carbon. It will fix the warning until the plugin is updated.


In the example code above, the query is retrieving a list of Entries and setting it to the variable entries.  Then, you are trying to loop through those Entries and treat them like they are a list of Assets.

As noted in the comments, this was complicating the situation.

It appears that, on the entry.html page, the entry variable was already available, as Craft makes that entry variable to all individual entry pages in Sections that have URLs.

This makes accessing the Assets field on that page as simple as accessing a field, rather than needing to create a separate query to find the data.  From the comments above, the solution was to just access the appropriate Assets field on the Entry Page template and loop through them:

{% for asset in entry.entryFieldHandle %}
    <img src="{{ asset.url }}">
{% endfor %}


See this issue: https://github.com/craftcms/cms/issues/4355#issuecomment-498829513

reproduced here for completeness:

  A yii variable 'isWindows' is apparently the way to correct this issue, but I haven't been able to find any documentation describing where/how to set this.

From your Craft config/app.php file, you can use this to set the isWindows property of the FileMutex class to true.

return [
    'components' => [
        'mutex' => function() {
            $config = craft\helpers\App::mutexConfig();
            $config['isWindows'] = true;
            return Craft::createObject($config);
        },
    ],
];


Something like this might work (obviously, replace the matrixField, assetsField and imageTransform handles with real values):

{# Basic query parameters for your sibling entries #}
{% set siblingCriteria = craft.entries.section(entry.section.handle) %}

{# Creates an array with the next and previous entries, based on the basic query parameters #}
{% set siblingEntries = [entry.getPrev(siblingCriteria), entry.getNext(siblingCriteria)] %}

{# Loop through the next and previous entries
{% for siblingEntry in siblingEntries %}

    {% if siblingEntry %}{# This might be null, if there isn't a next or previous entry #}

        {# Get the first `gallery` block for the entry's Matrix field #}
        {% set galleryBlock = siblingEntry.matrixField.type('gallery').first() %}

        {# Get the first asset in the gallery block's Assets field #}
        {% set galleryImage = galleryBlock ? galleryBlock.assetsField.first() : null %}

        {# Render the image #}
        {% if galleryImage %}

        {% endif %}

    {% endif %}

{% endfor %}


Cannot call service: "'MyPlugin' not found" error

I found the issue. The author of the tutorial I copied my first code from made the unfortunate choice to not use a proper plugin class:

class Plugin extends \craft\base\Plugin { ... }

To fix the problem, I replaced this line with

use Craft;
use craft\base\Plugin;
class Yutulic extends Plugin { ... }

and had to add a reference to the class to my controller and service modules:

use ns\yutulic\Yutulic;


You will need to use your Matrix field handle (which you didn't show in your question) and replace yourMatrixFieldHandle:

{% for client in clients %}
    {{ client.title }}

    {# Get all blocks related to the client entry #}
    {% for block in client.yourMatrixFieldHandle.all() %}

        {% switch block.type %}

            {% case "clientImage" %}

                {% for image in block.clientImage.all() %}
                    <img src="{{ image.getUrl() }}" alt="{{ image.title }}">
                {% endfor %}

            {% case "clientDescription" %}

                {{ block.clientDescription }}

        {% endswitch %}

    {% endfor %}

{% endfor %}

Read more about working with Matrix fields here


How to get an entry url from EVENT_AFTER_SAVE_ELEMENT callback?

Check out the definition of the ElementEvent that you're passed:

class ElementEvent extends Event
{
    // Properties
    // =========================================================================

    /**
     * @var ElementInterface|null The element model associated with the event.
     */
    public $element;

    /**
     * @var bool Whether the element is brand new
     */
    public $isNew = false;
}

So you can access the element (in your case, presumably an Entry) via:

$event->element

Make sure to check for null, and depending on how you set up the event listener, that the element is of the type of you're looking for.

For instance, if you want only listen to all elements that are saved, you'd do:

    Event::on(
        Elements::class,
        Elements::EVENT_AFTER_SAVE_ELEMENT,
        function (ElementEvent $event) {
            Craft::debug(
                'Elements::EVENT_AFTER_SAVE_ELEMENT',
                __METHOD__
            );
        }
    );

...but if you only care about Entry elements, you'd do:

    Event::on(
        Entry::class,
        Entry::EVENT_AFTER_SAVE,
        function (ModelEvent $event) {
            Craft::debug(
                'Entry::EVENT_AFTER_SAVE',
                __METHOD__
            );
        }
    );


Editing a tag not reflecting on all records.. kindof

That's because your search indexes still contain the wrong word. Please go to your utilities section in your CP and rebuild the search indexes

Making changes in the DB directly is sometimes not a good idea if you don't know the consequences it might have. You should have changed the title via CP rather than via DB


How to check if a DateTime attribute is set?

You shouldn't be returning a record instance to your templates directly. That can lead to all sorts of badness like templates being able to update the database themselves.

Have your plugin's service populate a Mailer_LogModel with just the attributes you want to expose to your template and return that.  Pretty sure after you do that, a simple:

{% if log.dateFinished %}

will work.


I'd rather:

{% if entry.uri == "__home__" %}

{% endif %}


You need to add .first() when setting the category. As far as I can tell, if you don't have .first() only {{ category.slug }} will work.

First get the slug:

{% set catSlug = craft.request.getSegment(3) %}

This will give you the CategoryModel object for catSlug:

{% set category = craft.categories.slug(catSlug).first() %}

You can now access whatever you want from the category, like the title:

{{ category.title }}


If you're hitting /api/news.json in the browser, you'd want to define the endpoint as 'api/news.json' as well.  i.e.

<?php
namespace Craft;

return [
    'endpoints' => [
        'api/news.json' => [
            'elementType' => 'Entry',
            'criteria' => ['section' => 'news'],
        ]
    ]
];


How can I retrieve a global value in a different locale?

Yes, that's how you would do it.

{{ craft.globals.getSetByHandle('localeModal').locale('es').getFieldValue('headline') }}

Or in shorter syntax:

{{ localeModal.locale('es').headline }}


Is it possible to limit the level at which entries can be selected from within an entries field?

There's already a popular feature request for this:
"Entry Type" setting for Entries fields

But yes, it's currently also possible to do this by extending the default entries field type
and adding your custom criteria with getInputSelectionCriteria().

class BusinessLogic_CustomEntriesFieldType extends EntriesFieldType
{
    public function getName()
    {
        return Craft::t('Entries (custom)');
    }

    protected function getInputSelectionCriteria()
    {
        return array(
            'level' => 2
        );
    }
}


A few options to consider:

Use one big Matrix Block and a plugin such as Pimp My Matrix to get added control over which blocks display in which channels and various other details.
If you find yourself reusing the same Matrix Patterns from site to site, consider a plugin that can help you manage reusable schema such as Sprout Import or The Architect, both plugins let you define your schema in a JSON format that you can tweak and import multiple times.
I'll add this here as a third option as I think it's relevant for consideration but it probably doesn't address your question about reusing blocks: Consider using a plugin like Neo which takes a Matrix-style approach but let's your blocks use global fields which you can reuse as well as several other features.


Using the Charge plugin for membership subscriptions

Developer of Charge here.

Setup for installs up to (and including) 2.0.x  :

The simplest setup would be to use the onBeforeCharge event.

This fires at the very start of the charge request, after validation but before anything has actually happened.

You'd use that to jump in, and create your user, entry, or anything else you might want to do. As part of that same event you can modify the actual ChargeModel which will be used in the payment request too.

The onBeforeCharge event fires before we pull out the user for the request, so as long as you're creating the user at that point, you won't need to do anything else to have all the subsequent steps properly associated to that user either.

Of course be aware that a payment can fail for any number of reasons, so check in that onBeforeCharge event if you actually do need to create the user before blindly going ahead.

Additionally, you can use the onCharge event to later perform any clean up you might need once the payment has actually succeeded.

Setup for installs from 2.1+

2.1 (not yet released as of 25/04/16) is bringing inline user registration to the payment forms, so in that case you'd just pass a new flag on the request to registerUser = true, and let Charge do the rest.

Charge will only attempt to register a new user if required, and will use the customerEmail as the default base, but that can be overridden with other parameters and inputs on the form.


Change the URL of nav child entry conditionally

Instead of using {% ifchildren %} use {% if entry.hasDescendants %}. It allows for more flexibility in your nav templating.


The Craft website has a great article on this, you can simply use migrations following this document:

https://craftcms.com/docs/plugins/migrations

  If your schema changes over the life of your plugin, you can write a migration to keep existing installations updated with the latest schema. Craft automatically checks for new migrations whenever a plugin’s version number changes.

In summary, you can create the Record and define all the attributes, then create a migration that would create the new table with those attributes. This would be done in the safeUp() method that utilizes Craft create command:

craft()->db->createCommand()->createTable('new_table_record_name', $attributesArray, null, true);

When the plugin is updated, it will run the migrations and create the table.


Add entry with the select-entry-modal-field

There isn't, as far as I'm aware of, but have a look at the Craft Plugin Library. If you write your own, you might have a look at the following to see an example of a modal that craft does use:

var modal = Craft.createElementSelectorModal('Entry');

Try typing that into your console on any page in the CP.

Categories use a different kind of model when double clicking a category item that actually saves data, so might have a look at that as well.

Also, the amcommand plugin provides a nice modal command palette with a command to create entries that also might be worth checking out.


Poor performance on midsized site / Queries without index?

I can tell you that both of those are the semi-dynamic element queries that Craft uses to grab elements from the database.

The 2nd one is likely the result of someone calling a .total() or .count() on ElementCriteriaModel.

I see you ran EXPLAIN, but don't see the results from it.  You can use that as a starting point to see what index MySQL chose to execute that query and if it's not ideal.  Craft can't add an index to every content column (for obvious reasons), so if something in your templates is generating a SQL query frequently that causes MySQL to chose an index that isn't ideal and adding an index to content column would solve that for you, then that's something you can certainly do.

  I understand that the i18n tables are where the locales data is stored. Is there a way to disable a locale without losing any data?

No. It either exists or it doesn't.


Image fields are an array, because you can have multiple images within that field. Usually you would loop through the array to output your images:

{% if Logo.logo | length %}
    {% for image in Logo.logo %}
        {{ image.url }}
    {% endfor %}
{% endif %}

Or, if you only have a single image in the array, you can just do this:

{% set image = Logo.logo.first() %}

{% if image %}
    {{ image.url }}
{% endif %}

More info on Asset templating here


How can I check a user has completed a field in their profile after log in?

If you have a front end form for user registration then you should mark the fields as required in the CMS, you can then make use of Crafts form validation.

I had a project where we imported user data that didn't contain all required fields so needed to redirect users, after they signed in for the first time, to their profile page if data was missing.

I achieved this using a Plugin that contains a service that set a "status" for the current user. The service checked for several different fields and their values and also checked that the user had entered all required fields.

public function setUserStatus( $user ){
    // Get whether user has agreed to current years terms
    $userAgreedToTerms = ( $user->getContent()->agreedCurrentYearsRules == 1 );

    // Use craft validate() function to find ask if user has completed all required fields in profile
    $userHasCompletedProfile = $user->validate() && craft()->content->validateContent( $user );

    if ( $userAgreeToTerms ){
      $userStatus = 'AgreedToTerms';
    }
}

I then used the results of these checks to set a cookie with the "status" of the user.

// Sets a cookie which is used to determine where the user should be re-directed to
$cookie = new HttpCookie( 'userStatus', $userStatus, [ 'expire' => time() + 10 ] );
craft()->request->getCookies()->add( $cookie->name, $cookie );

The function was run from the template using:

{{ craft.pluginName.setUserStatus( currentUser ) }}

And the result of the check was used to redirect the user to the template I needed.

{% set userStatus = craft.request.getCookie( 'userStatus' ) %}

{% if ( userStatus == 'needsToPay' ) and ( site_area != 'payment' ) %}
  {% redirect 'payment' %}
{% endif %}

Hopefully this provides you with enough to create something that works for your case.


How to create an entry from plugin controller?

As Damon mentions, I'd highly recommend checking out the Guest Entries plugin.

Specifically the private _populateEntryModel() method which creates the EntryModel class and gives a good example of the properties that are necessary to set to before calling EntriesService->saveEntry().


Within the CP, how can I filter the listed Entries based on a Lightswitch field value?

Lightswitch fields are a bit of an edge-case in searching because it can only be true/false (in the real boolean sense of true/false) so Craft doesn't explicitly index it in the searchindex table.
That's a bit awkward because even through there is a field setting "use this field's value for the search index" it's the one field where it doesn't apply.
Regardless, this should all be rectified for the upcoming Craft 4 release where we plan to make this possible.


Just saw this resolved issue on GitHub: https://github.com/craftcms/cms/issues/5930
So Lightswitch querying should be fixed in the upcoming release CraftCMS 3.5

Edit: there is a workaround until 3.5 is released. see comment by @harrymee123 and my example query at https://github.com/craftcms/cms/issues/5930#issuecomment-657417173


How to load entries data in the General Configuration file?

When you take a look at the Docs you'll see

  See craft\helpers\ConfigHelper::localizedValue() for a list of supported value types.

And that contains

  $value (mixed) – The config setting value. This can be specified in one of the following forms:
  A scalar value or null: represents the desired value directly, and will be returned verbatim.
  An associative array: represents the desired values across all sites, indexed by site handles. If a matching site handle isn’t listed, the first value will be returned.
  A PHP callable: either an anonymous function or an array representing a class method ([$class or $object, $method]). The callable will be passed the site handle if known, and should return the desired config value.
  $siteHandle (string, null) – The site handle the value should be defined for. Defaults to the current site.
  Returns

The interesting thing is a function

'activateAccountSuccessPath' => function(){
    return Entry::find()->section('myAccount')..... // do your thing
}


Setting selected elements in a BaseElementSelectorModal (or BaseElementIndex)

After much exploring in craft.js, I've concluded that this can't be done in a clean way.

However, I found a workaround which seems to do the trick.

First, here's (a simplified version of) the code that creates the modal (which is stored in the variable modal):

var modal = new Craft.BaseElementSelectorModal('Entry', {
    criteria: criteria,
    onSelect: onElementSelect
});

After creating the modal, I use setInterval to look up the modal.elementIndex property. The reason I use a poller is that this property is actually null until the internal AJAX call to actions/elementIndex/getElements is completed. Anyway, I poll the elementIndex property every 10ms, until the property is found (or after 5 seconds have passed, when its safe to assume something has gone awry).

Finally, the element index' method selectElementAfterUpdate is used to select the entries. The method only takes a single entry ID, so I have to call it once for every entry ID in the entryIds array.

var pollCount = 0;
var pollInterval = 10;

var poller = setInterval(function () {
    pollCount++;
    if (pollInterval * pollCount >= 5000) clearInterval(poller);
    if (modal.elementIndex)
    {
        clearInterval(poller);
        $.map(entryIds, function (entryId) {
            modal.elementIndex.selectElementAfterUpdate(entryId);
        });
    }
}, pollInterval);

Not very smooth! But it works.


Let me start with a minor side note... You'll want to change the first line to this:

{% if craft.smartMap.visitor.ip %}

It's better to test against a "falsey" IP address, instead of explicitly testing for an empty string. I believe the IP address would resolve to false if nothing was found. Either way, a general "falsey" check will work as expected here.

It's not currently possible to convert a raw set of coordinates into a more complex object.

That being said, you could fairly easily do it using the built-in smartMap JavaScript object...

{# Get visitor's coordinates #}
{% if craft.smartMap.visitor.ip %}
    {% set coords = craft.smartMap.visitor.coords %}
    {% set jsCoords = 'smartMap.coords(' ~ coords[0] ~ ', ' ~ coords[1] ~ ')' %}
{% else %}
    {% set coords = craft.smartMap.lookupCoords(90210) %}
    {% set jsCoords = 'smartMap.coords(' ~ coords['lat'] ~ ', ' ~ coords['lng'] ~ ')' %}
{% endif %}

{# Blank map #}
{{ craft.smartMap.map([], options) }}

{# Add visitor marker #}
{% js %}
    smartMap.createMarker('visitor-marker', {
        position: {{ jsCoords }},
        map: smartMap.map['smartmap-mapcanvas-1'],
    });
{% endjs %}

UPDATE: I fixed a bug in v3.0.5 which makes this even easier.


How do I add next/prev controls to a blog?

Take a look at: How do I build a pagination nav?


Why can't we log items regardless of dev mode?

If you want a log item to appear regardless of whether devMode is enabled, you can pass true as the third argument to the log() method.
Is this accurate?

Yes. Logs will only get flushed to disk is a proper craft()->end() occurs, firing the onEndRequest event.  So if you're doing something in your plugin like calling PHP's exit() directly or there is some other logic that inadvertently kills the request, then they won't get written to the log file.
I'd suspect that's what you're running into.


Don't be alarmed if this post gets flagged for being off-topic. Typically questions regarding whether "craft is appropriate for x" are considered too broad and opinion based. But I'll try and give you some suggestions anyway, which may give you a head start.

The short answer is yes, craft can do all those things. The only point to maybe consider is when you say "purchase", unless you are just linking to amazon or something. As I'm sure you're aware, E-commerce is not something to take lightly and I would make sure you research your options here, and have a plan. E-commerce solutions for craft are limited at the moment, but keep an eye on the plugin page.

You will likely want to have Craft Pro, so that you can have multiple user accounts.

Here is one approach to the basic CMS design, without really knowing anything about your requirements.

Create a single for your homepage.
Create a 'structure' (call it "pages" for example, or whatever you like) to contain all of your static pages and index/landing pages. This would include for example pages like "About us", "Company", "Services", "Authors" index page, "Books" index page, and anything else that you would consider as part of your main nav. 'Entries' within this structure would be defined with unique 'Entry Types' for each unique page layout that you need. Within each 'Entry Type' fields can be defined independently from other 'Entry Types'. In the 'pages/_entry.html' template you can determine which template code to display by checking the entry.type property. The advantage of using a structure here (as apposed to channels and singles) is that you can use it to generate dynamic navigation. See example below.
Create a channel for Authors (called 'authors' or whatever). You can also create users for this if you ever want to allow clients to log-in for whatever reason. (Note: I would use a channel regardless because it allows for multiple tabs in the edit page, and link it to users via a users field. But that's just me). Another tip: Might also check out a plugin called Introvert to display reverse related books from the books channel.
Create a channel for Books (called 'books' or 'products' or whatever), with a 'related users' or 'related entries' field for 'authors' (depending on how you dealt with authors above).
Create a category group for your books subject taxonomies (I'm just guessing at this point), but you get the idea.
Add salt and pepper to taste and serve.

Now for some code examples (and useful concepts regardless of your design).

In your '_layout.html' master template, to generate nav (copied from the docs):

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

    {% nav entry in entries %}

            {{ entry.title }}
            {% ifchildren %}

                    {% children %}

            {% endifchildren %}

    {% endnav %}

In your 'pages/_entry.html' template, to determine the entry type and retrieve related entries:

{% switch entry.type %}
    {% case 'about' %}
        {{ entry.title }}
        ...
    {% case 'authors' %}
        {{ entry.title }}
        ...

            {% set authors = craft.entries.section('authors') %}
            {% for author in authors %}

{{ author.firstName }} {{ author.lastName }}

            {% endfor %}

    {% case 'books' %}
        {# repeat code above but for books, likely with some category break-down based on the categories field #}
    {% case default %}
        {# display default template #}
{% endswitch %}

Note: You can also use 'includes' in the switch statement, for better template organization, or use this technique to eliminate the need for the 'switch' statement altogether.

In your 'authors/_entry.html' template, to get related books.

{{ entry.title }}

   {{ entry.bio }}
   ...

Books

    {% set books = craft.entries.section('books').relatedTo(entry) %}
    {% for book in books %}

            {{ book.title }}

    {% endfor %}

In your 'books/_entry.html' template, to get authors from the 'authors' entries field.

{{ entry.title }}

....

Authors

    {% for author in entry.authors %}

{{ author.title }}

    {% endfor %}


I believe the way to do this would be to have your plugin listen for the onBeforeLogin event.

From inside there, you'd check to see if the there is an existing session craft()->userSession->isLoggedIn() and the current user is an admin craft()->userSession->isAdmin().

If both of those are true, I believe its going to be a pretty safe assumption that an admin just clicked the "Login as User" button.


background-image CSS property: how to do it right with Craft?

There is a function called alias that returns a defined alias. A default alias is @web and it represents your base url,

background-image: {{ alias('@web') }}/path/to/image.jpg;

Would display the file image.jpg in web/path/to/


Charge Pro not sending Subscription Emails

I've actually answered the question in the question. Not sure why it's not showing as is, but the solution is updating the plugin file as mentioned above.


How to get Category URL from field in Matrix

{{ block.linkTo.first().url() }} looks basically right, but a couple of things could be going wrong here:

Does the Galleries category have a url assigned? (make sure the "Categories in this group have their own URLs" box is checked)
Is there a category? You should always check, even if it is a required field. You can do {% if block.linkTo.first() %}...{% endif %} or {{ block.linkTo.first().url() ?? '' }} and use the A null coalescing operator.


Possible memory leak - GeneratePendingTransforms/ImageMagick

I had this same issue with an image-heavy site hosted on WebFaction w/ PHP5.6, using latest Craft 2.6.x version.

I added the fix Brad mentions + another config line:

// From http://stackoverflow.com/a/12835966
// Pixel cache max size
$this->setResourceLimit(\Imagick::RESOURCETYPE_MEMORY, 256);
// Maximum amount of memory map to allocate for the pixel cache
$this->setResourceLimit(\Imagick::RESOURCETYPE_MAP, 256);

in craft/app/vendor/pixelandtonic/imagine/lib/Imagine/Imagick/Imagick.php at line 33, at top of smartResize() function.

This was before adding the 'generateTransformsBeforePageLoad' => true, line to our config, I haven't tested removing this setting after adding that to our config.

When still in heavy development, we'd clear image asset caches and the transform queue would grow like crazy, and PHP processes would grow past 1.5gb until our host killed all of our processes. I haven't seen this issue since adding those Imagick settings.


How to save Entries to an entry? (non-plugin)

All related fields need to be passed as an array even if it is limited to 1.

so for example change your eventBooking and userBooking hidden fields to be the following (also you may need to specify the user id when relating to a user):

<input type="hidden" name="fields[userBooking][]" value="{{user.id}}">
<input type="hidden" name="fields[eventBooking][]" value="{{eventID}}">

This should get you want you need.


How to access a previous matrix field value

As it turns out, you must use bracketed and not dotted syntax for matrix fields.

{% for contentBlock in entry.contentBlocks %}
    {% if contentBlock.prev %}
        {% if contentBlock.prev[matrixField] is defined %}
            {{ contentBlock.prev[matrixField] }}
        {% endif %}
    {% endif
    ....
{% endfor %}

fixed this issue for me :)


I hope I am not completely missing the point, but I guess like that:

Initial 5:

{% for block in block.eventList.eventDate('>=' ~ (now|atom)).orderBy('eventDate asc').limit(5).all() %}
     {{ block.eventTitle }}
{% endfor %}

rest:

{% for block in block.eventList.eventDate('>=' ~ (now|atom)).orderBy('eventDate asc').offset(5).all() %}
          {{ block.eventTitle }}
{% endfor %}

past events:

{% for block in block.eventList.eventDate('<' ~ (now|atom)).orderBy('eventDate desc').all() %}
     {{ block.eventTitle }}
{% endfor %}

you will probably need to change the date('Y-m-d') format


Plugin settings per site / locale (Craft 3)

There is no native support for this, you can follow my approach and create a custom table for it to store the settings for each site

Another way is to return a different array depending on the current site in your config file

if(Craft::$app->getSites()->getCurrentSite()->handle === X){
    return ['flagName' => 'Tricolore'];
} else {
    return ['flagName' => 'Bundesflagge'];
}

or

$array = [
    'de' => [
        'flagName' => 'Bundesflagge'
    ],
    'fr' => [
        'flagName' => 'Tricolore'
    ]
];

return $array[Craft::$app->getSites()->getCurrentSite()->handle];


Enforce password change every 90 days (3 months)

$date90DaysAgo = (new \DateTime())->modify('90 days ago')->format('Y-m-d H:i:s');
foreach(\craft\elements\User::find()->lastPasswordChangeDate('<='.$date90DaysAgo)->all() as $user){
    Craft::$app->getUsers()->sendPasswordResetEmail($user);
    $user->newPassword = // generate some temp password, so the user can't login with his/her anymore
    $user->setScenario(User::SCENARIO_PASSWORD);
    Craft::$app->getElements()->saveElement($user);
}

get the date 90 days ago, find all users where lastPasswordChangeDate is smaller than this date, send them a new password reset email and change their password to something else, so they can't login anymore.


How to filter relational field types on their related content's status?

My assumption that the query was not getting all the related entries from withing the Matrix was wrong. The filtering that happens is applied at output level, and not the query level.

The solution is to tell craft that you don't care about the status of any linked anEntryField entry as part of the if...

{% if
    user.myMatrixField | length
    and
    user.myMatrixField.first().anEntryField.status(null).first() | length
%}
...
{% endif %}

In this example the result will be the first myMatrixField block with a status of 'enabled' (that's the default filter), and fetching from that first Matrix result the first related Entry on the anEntryField regardless of the status of that related entry.

That's what I was after.


How do I make display a specific post based on what the day of the week it is?

To get the current date and time in Twig use the string "now" and filter it with the date() filter to return it in the format you need (see the list for supported parameters).

Then do the if / elseif conditionals similar to how you'd do it in PHP. Another option would be to use the Craft specific switch tag.

{% switch "now" | date("l") %}

    {% case "Monday" %}
        {# Do Monday stuff #}

    {% case "Tuesday" %}
        {# Do Tuesday stuff #}

    {% case "Wednesday" %}
        {# Do Wednesday stuff #}

    {# etc. #}

{% endswitch %}


Asset Uploading via Assets Field Broken, please help

Checking the logs is of course recommended:

craft/storage/runtime/logs

However, I have personally found that failed uploads are related to "write" issues where either the directory permissions are invalid or the actual upload path doesn't exist (aka invalid).

One simple way to potentially obtain more information is to look at the actual HTTP response for the "upload file" AJAX request. I often do this via Chrome's Developer Tools' Network tab.

Open Chrome Developer Tools
Click the "Network" tab.
Perform the file upload.
Click on the "uploadFile" request that was generated
Click the "Response" tab to view the completed response (which will appear once the response is returned).


Prevent Activation Email on creation - Wait for Admin Approval

Thanks to @BradBell - I just needed to use the Admin setting.

  Seems like you just want to uncheck "Verify Email Addresses?" under >Settings->Users->Settings


How to stop rendering errors being output in production

DB connection errors are the only case where Craft will output the full error even if Dev Mode is disabled, because 99.99% of the time those only occur when Craft is not yet installed, and it’s an extremely common issue people run into when installing Craft.

If you really want to prevent those errors from showing up on the front end, you can edit your index.php file so that it catches them, and displays something different:

<?php

// Path to your craft/ folder
$craftPath = '../craft';

// Do not edit below this line
$path = rtrim($craftPath, '/').'/app/index.php';

if (!is_file($path))
{
    exit('Could not find your craft/ folder. Please ensure that $craftPath is set correctly in '.__FILE__);
}

try
{
    require_once $path;
}
catch (Craft\DbConnectException $e)
{
    exit('An error occurred.');
}


Because your content is cached it "downloads" your website so it loads quick.
This can be fixed by disabling cache to users that are logged in or maybe even certain users. This way you "bypass" the cache so you see the changes as soon as your page is loaded.

unless #

Prevents the {% cache %} tag from activating if a certain condition is met.

{# Don't cache if someone is logged in #}
{% cache unless currentUser %}

You can find the cache options in the docs.

Source: https://craftcms.com/docs/templating/cache


Best way to find a deprecation error with no location hint?

If you look in the list of file paths in the stack trace there will be one or more files in the storage/runtime/compiled_templates directory. In this particular case there is storage/runtime/compiled_templates/1a/1a584296a...ccfb9.php under number 33 in the stack trace. (If you're using PhpStorm you can press shift twice and paste in the filename to find it quickly.)

This file contains a PHP class that Twig compiles when the template is first accessed, so that it doesn't need to parse through all the twig code converting it into PHP every time the template is accessed.

At the top of this file is a comment that contains the path of the actual twig template. If needed, you might be able to work out a bit more context by looking at code at the line number in the stack trace (it's the :43 for this one). There will be another comment above this line that will tell you the line number in the twig template.

There may also be some clues in the stack trace itself. For example, here (again number 33 in the stack trace) you have the line:

twig_array_merge([], craft\elements\db\CategoryQuery)

This suggests to me that you're using the |merge filter, on a craft.categories query without calling .all() on it first, which also makes sense given the deprecation notice.


Can notes on line items be updated on checkout?

I use ajax autosave to achieve this, and ajax update the cart in the background (for notes, but also pretty much everything else).

I essentially use the recipe from:
from https://github.com/geniuscarrier/autoSave/

In the callback function that is called after the autosave event, I post the to the update cart controller.  The JSON object that comes back from an ajax request is quite complete and let's your update your cart page / totals etc from there.

Personally I hate non dynamic carts with update buttons, so I have ajaxed all cart operations, including qty changes, removals, line item and order notes etc.


Image transforms return cpresources URL and doesn't apply crop

I did find the solution i checked the basepath with the server hosting my project and it turned out that the relative path dosen't work like the absolute path, so i serached for the root in the server and i inserted the full path, it work !! thanks for letting me know this by myself :)


Using embedded assets plugin to display youtube or vimeo embed urls on a template

You need to define your assets, if the asset field is named videoEmbed in your matrix matrixFieldHandle you would loop through the matrix and grab the first asset with:

{% for block in entry.matrixFieldHandle %}

  {% set asset = block.videoEmbed.first() %}

  {% set embed = craft.embeddedAssets.fromAsset(asset) %}

  {% if embed %}
    {{ embed.safeHtml|raw }}
  {% endif %}

{% endfor %}

You can find additional information about matrix-fields and templating here: https://craftcms.com/docs/matrix-fields#templating


I made a Craft plugin that simply wraps PHP DatePeriod: "Date Period plugin for Craft". The plugin provides a datePeriod Twig function. It works really simple, your give it a start date, an end date and an interval to create a DatePeriod object.

datePeriod( startDate, endDate, interval )

This DatePeriod object you can now iterate over to get the dates, recurring at the set interval, over the period spanning your start and end date. By default the interval is set to 1 day, but you can modify that with the (optional) parameter.

{% set datePeriod = datePeriod(startDate, endDate, '1 month') %}

{% for month in datePeriod %}
    {{ month|date('F') }}
{% endfor %}

To also list the days in between, you would add Craft's group filter like so:

{% set datePeriod = datePeriod(startDate, endDate) %}

{% for month, daysInMonth in datePeriod|group('{ object|date("F") }') %}
    {{ month }}
    {% for day in daysInMonth %}
        {{ day|date('d') }}
    {% endfor %}
{% endfor %}


Examples of magazine/newspaper publication websites using Craft?

Check out the Straighupcraft gallery. Maybe you'll find something there.


How do I prevent a runPendingTask script being included in returned HTML via ajax?

The next (post 2.5.2767 release) will no longer inject that code on AJAX requests.


You can use the request service. craft()->request->isCpRequest() or craft()->request ->isSiteRequest()

https://craftcms.com/classreference/services/HttpRequestService#isCpRequest-detail


Database documentation / tips / resources

It's difficult to answer this without specifics on what you're looking for and what your plugin is trying to do, but I'd recommend following the plugin development docs, which includes working with databases.

I'd also recommend using somethign like https://pluginfactory.io to generate the plugin boilerplate code for the plugin components you might need.


The proper conditional statement in this case would be to test for the length property of your Asset field, i.e. cover:

{% if cover | length %}

The reason this works, is that calling slide.coverImage will – as long as the attribute "coverImage" exists for the "slide" model – never return a falsey value, even if there are no files. It will in fact always return an instance of the ElementCriteriaModel class, i.e. an object representing your Asset field.

What the conditional {% if cover | length %} does is to read the length property of the ElementCriteriaModel object. The length property will represent the number of images in the Asset field – if it contains 0 images, the conditional will evaluate to "false" – as the number 0 within a conditional is interpreted as a falsey value. If you prefer, you can also write the statement like this:

{% if cover | length > 0 %}


On entry save/update, centered text returns to left in rich text field

When you create a Rich Text field, there is an option for Clean up HTML which is checked by default. The description underneath the setting reads:

  Removes spans, empty tags, and most style attributes on save.

When aligning text in Redactor, inline styling is added, which would be stripped away on save if the Clean up HTML option is checked.

You'll just need to uncheck this option in your field settings if you want inline styles to be saved.


Craft constantly logging out from admin area

My solution is to add:

'overridePhpSessionLocation' => false

Into craft/config/general.php

This tells Craft to use the default location to write sessions, instead of craft/storage/runtime/sessions

For whatever reason, even though  craft/storage/runtime/sessions has CHMOD 777, PHP was saving the session file with 644. When it tried to write to the same file again, it got and error and logged me out.

I also (unsuccessfully) tried giving PHP ownership of the folder, which should in theory fix the problem too.

 sudo chown -R www-data:www-data sessions
 chown: www-data: illegal group name

I am assuming it's a Vagrant/OSX thing.


Migrate WordPress Site into Craft CMS. How deal with 404's?

David,

I like using Reroute. It's a Craft plugin that lets you create 301s and 302s to any of your entry pages within Craft.


Register custom REST routes while building a plugin for Craft 3

Your code is almost there, Craft allows registering routes for the Control Panel and the front-end of the site. You need to change EVENT_REGISTER_CP_URL_RULES to EVENT_REGISTER_SITE_URL_RULES.

You are listening for an event on EVENT_REGISTER_CP_URL_RULES which will only register routes inside the control panel. This is useful for plugins that want to add controllers for settings and custom logic.

  The event that is triggered when registering URL rules for the control panel.

https://docs.craftcms.com/api/v3/craft-web-urlmanager.html#events

However, in the scenario where access is needed outside of the control panel, Craft triggers the EVENT_REGISTER_SITE_URL_RULES. This allows access for users that do not have control panel access (e.g. site guests and regular users).

  The event that is triggered when registering URL rules for the front-end site.


Can you use a different html template for each system message email?

Alternatively can you determine which system email is being sent from within the template that you can set in the Craft email settings?

Not currently, but in the next (post 2.3.2644) release, there will be an emailKey variable available to the template so you can see which email is being sent.


OK, no one answered....I have to take another way to do which is to put a piece of code like this into user-profile page

{% if not currentUser %}
  {% redirect '/' %}
{% endif %}

and take out loginPath setting in config file.


Can't resize image in Rich Text field since 2.5 update

It's not Craft that's broken it, but the new version of Redactor that's "superior in every way" acording to them:
https://imperavi.com/blog/redactor-superior-in-every-way/


Can I use getCriteria to only return entries with a specified lightswitch field set to on?

This should do it:

$criteria = craft()->elements->getCriteria(ElementType::Entry);
$criteria->section = 'mySection';
$criteria->myLightswitchField = 1;
$entries = $criteria->find();


How do I talk to Smart Map in JavaScript?

I'd recommend loading your JS file after the smartmap.js file has been loaded. The smartMap JS object needs to exist before your code gets run.

Try loading your JS using the includeJsFile tag... I believe that should place it in the correct position.

{% includeJsFile "/assets/js/app.min.js" %}

If that doesn't work, then you may need to wrap your code in something that would prevent it from running until the page is fully loaded...

$(function () {
    // Your code goes here
});

^ That example uses jQuery. The same can be achieved without jQuery, if you're not using it.


If you're running Craft Personal or Client, you'll need to go to the craft_locales table in your database and change the locale to one of the support Craft control panel translations (http://buildwithcraft.com/help/cp-languages).

If you're running Craft Pro, you can go to Settings->Locales and add (and re-order) new locales to your site.  Then you can go to your user account settings and set your preferred locale from list of existing site locales and the CP will display in that.  Again assuming it's one of the locales that the control panel has already been translated into.


A checkboxes field returns an array of models, that you can inspect using {{ dump(sourceCountry) }} in your loop.

The model has a __toString method that outputs the checkbox value when you output the model using {{ sourceCountry }}. This magic method doesn’t do its thing when you use the model in a comparison operator, so you are currently comparing a model to a string.

Access the value property directly and your conditional should work.

{% if sourceCountry.value == 'GB' %}
    {% set visibility = true %}
{% endif %}


You can pass values from other Craft elements or from URL segments, etc to your Freeform forms. Specifically when using with the Element fieldtype, when wanting to override the return URL, you can do something like this:

{{ form.renderTag({
  returnUrl: entry.thankyouUrl
}) }}

When wanting to override Freeform field data values or options, you can do something like this:

{{ form.renderTag({
   overrideValues: {
      hiddenFieldHandle: entry.id,
      stateSelect: "AZ",
      availability: ["tue", "thu"],
   }
}) }}


The {% header %} tag probably isn't what you want then - they must be rendered first, as they affect what the webserver is returning to the browser in the page headers. Because you're setting the location header to the file url, it is telling the browser to redirect to that instead of rendering the rest of the page (which would still technically be rendered by the server, just never seen by the browser).

It sounds like the better option would be to trigger the redirect to the file location via javascript after the page loads, similar to this approach.


No assets found when searching in different locale

This is a known bug on Craft 2 that has been resolved in the upcoming Craft 3 release.  Here's the original Github issue: https://github.com/craftcms/cms/issues/17


What is the benefit of using a calendar event plugin or building your own?

Depending on your sites' actual event handling needs, building your own plugin similar to Solspace Calendar or Venti to handle this (specifically features like recurrences - the CP UI as well as rendering in front end) could easily take you hundreds of hours to build properly. Unless you need something very different or custom from what either of these plugins offer out of the box, I would imagine the $99 or $49 would pay off real fast if you calculated the time it'd take you, even if you were the most seasoned of developers. :-)

Both Solspace Calendar and Venti offer 30 day satisfaction guarantees, so it might be worth it to consider buying one or both and trying them out to see if they fit your needs. If not, you can always ask for a refund within 30 days, or consider modifying the plugin (rather than completely rebuilding the functionality).


Craft 3 Plugin Controller - returnJson() replacement?

I wasn't rtfm'ing hard enough. In the docs for \yii\web\Controller, which is what the \craft\web\Controller class extends (which is what your plugin controllers extend) there is a method asJson().

return $this->asJson($response);


Yes simple use

{{variant.price}}

Or

{{variant.salePrice}}


Does Craft have a way to handle this without needing to manually adjust my database?

Swap to PostgreSQL? :)

This is more of a MySQL limitation/configuration issue than a Craft/PHP one.

You can alter the charset/collation of the column the plain text field is being saved to utf8_mb4 and utf8mb4_general_ci and that should solve it.


If the UserModel contains a user ID, then the existing user will be updated.

If the UserModel does not contain a user ID, then a new user will be created.

Either way, the UserModel will contain an ID after being saved. Since models in PHP are passed by reference, the ID will get set automatically for new users.


Are values in Asset fields held globally for a particular Asset?

The fields attached to an asset source will be connected to the asset, and will follow the asset no matter where it's used. So yes, this is the intended behavior.

If you need to specify on an entry basis what size an image should have, you need to add a field for selecting size on the entry type. Say you have a field "Main image" in your entry type, you'd add a "Main image size" field to the same entry type.

If you're making a gallery or something, instead of having one assets field where you select all images, you could create a matrix field that has one column for (one) asset and one column for size instead, and add each image as it's own row.


It depends on what you mean by "get" the hash anchor, but I'm assuming you're trying to get it in either PHP, Twig, or JavaScript.

It is physically impossible to get the #anchor part via PHP, since PHP never has access to that information. This SO thread describes the issue.

If you're trying to access the #anchor in Twig, you're probably out of luck there too. Twig is just a PHP parser, so you've essentially got the same problem.

All you can do is access it via JavaScript. In which case, there is nothing Craft-specific about it (see linked SO thread).


Can a plugin force download an asset from third-party source like Amazon S3?

I have found a solution.

public function actionDownloadAsset()
{
  $this->requirePostRequest();
  $id = craft()->request->getRequiredPost("id");
  $attributes = array('id' => $id);
  $element = craft()->elements->getCriteria(ElementType::Asset)->first($attributes);

  $file = $entry->url;
  $name = $entry->filename;

  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; filename='.basename($name));
  header('Content-Transfer-Encoding: binary');
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');

  readfile($file);
}

To get access to the file url I had to array_shift the $element returned from getCriteria.  Then I had to exclude the file size header. This was ultimately causing the "this webpage is not available". Not sure the reason.

header('Content-Length: ' . filesize($entry->size))


How to UNION Craft blog articles array with Social Media plugin (non craft table)

More of general guidance than an answer, but I'd look into creating a custom ElementType and overriding the modifyElementsQuery in your ElementType to latch onto the main query Craft uses to grab elements.  From there you'd be able to join in whatever other data you need.


Are categories the best way to organize Commerce product filters?

Hard to say if they're the 'best' tool, but I don't see anything here you can't do with Craft categories and they seem the logical and built in way to go about it.  In essence you simply look at your url segments and use these as category filters when retrieving the products
I think so.  It keeps the two separate data concerns nicely separated - but do be aware from a UI point of view, separate category groups are very separate things - you can't use one field to select from both groups (quite a surprise to me the first time I implemented this!)
I think you really only need one template here that simply inspects the url segments and builds the products query from whatever is there.  This part of the question reads a little as if you're confusing the presentation concerns and the data holding concerns (which is not criticism - it's very easy to do!) - your products will live as products over in Commerce, but your actual url routing and display of those at the category level (i.e. the product listing level) - can probably be handled by just one display template.  .  You don't need a 'channel' for these pages as such (they're not pages, rather filtered views).  So probably just a route that points, say, /catalogue/* -> to your one product listing template.  (The actual individual product pages (if they have significantly different displays) - can use multiple templates if need be (or again, conditional logic within the one template)).
There's really no reason that you could not use a route to point say  /products/new to the same template and again inspect the url to build your products query, showing only the newer products.  There's no need per se for a single here unless you want other content on the page or something.

While you described this on slack as a 'noob' question it's not, and it's good to think it through - in some ways this stuff is the hardest part to get your head around with Craft/Commerce.  Once you actually get to implementing it you'll find this bit was actually a lot harder than making it work (well, I did!).

The fact you're using separate urls for everything probably makes it a lot easier than some approaches I think, so nothing in your message really strikes me as unachievable.  The point to understand is that you don't need a channel or section to hold all of these pages - they aren't really pages as such, really they are all views on the same data (all, or some subsets thereof) - you simply have route(s) which point to a single template with logic that inspects the url and filters the products based on that.

More than happy to chat this through more on Slack if that would help.


Sounds quite do-able. I will first admit I don't know how postmaster works at all, so I could be way off in my suggestion. Regardless, you're looking at two plugins working together; a contact form & postmaster.

I would start with the contact form plugin, but modify it a bit so that it captures the users's information. Depending on your needs, I would either have a checkbox so the user could select which section they wanted notifications for, or have a hidden field that is pre-populated with the current section - then just pass that through.

If you want to have a visual representation of these records, you'll either want to look at creating entries for them, or just capture them within the plugin. I have an example of both to help get you rolling. DM me on the slack channel and I can send you my examples.

Here is where I'm not sure how to help. Once you have the information, somehow you'll need to tell postmaster where those records are, loop through and send an email. I'm guessing at this point creating entires that represent subscribers would be easier for postmaster to understand?


Questions prior using Craft for the first time

While I've got no expierence with ProcessWire, I'm a fairly new Craft user myself, and I have to say, it's been a breeze to work with.

With regards to your questions:

All your separate, custom code goes into a plugin, which has to have a certain structure (can be generated for you at this site). There you can hook into events, make your own controllers for custom actions, ...
Creating an entry from code can be done by working with it's Model/Record classes and saving it.
There's quite some things already in Craft by default, but to handle forms, you'll either have to write your own controller action to capture it, or use a plugin, same goes for using PayPal or creating PDF's. You can also use composer packages with Craft.

While there is a slight learning curve, mainly for plugin development (as you need to know more about Craft's internals than when just creating templates etc...), I found the community around Craft to be one of the best I ever encountered. When stuck, feel free to pose your questions here or on slack :)


Styling Subsequent Pages in Craft Pagination

For those who might stumble upon this with a similar issue, the answer ended up being quite simple...

I made sure that my css.main was located in a public directory, in my case /web/css/main.css, and all of the pagination and styling works perfectly.


How do I display the index of the asset in assets loop?

This will do it:

{% for key, image in block.images %}
    {{ key }} - <img src="{{ image.url }}" data-index="{{ key }}">
{% endfor %}

Keep in mind that's a 0 based array, so the first image will output 0, the 2nd 1, etc.


Entry form with field translated accross multiple sites

Craft has no default process to handle such things, you need to do that on your own. Here is a form and a controller example how it could be achieved.

{# just to show you.. you can edit existing one as well #}
{% set entry1 = craft.entries.id(11).siteId(1).one() %}
{% set entry2 = craft.entries.id(11).siteId(2).one() %}

<form method="post">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="my-module/save">

    {# if you have an ID use it #}
    {% if entry1 is defined and entry1 is not null %}
        <input type="hidden" name="id" value="{{ entry1.id }}">
    {% endif %}

    {# the site ids you want to store, you can as well use the handle or whatever you want #}
    <input type="hidden" name="siteId[]" value="1">
    <input type="hidden" name="siteId[]" value="2">

    {# title #}

Title Site 1

    <input type="text" name="title[1]" value="{{ entry1.title?? '' }}">

Title Site 2

    <input type="text" name="title[2]" value="{{ entry2.title?? '' }}">

    {# a field #}

Headline site 1

    <input type="text" name="fields[1][headline]" value="{{ entry1.headline?? '' }}">

Headline site 2

    <input type="text" name="fields[2][headline]" value="{{ entry2.headline?? '' }}">

    {# slug #}

Slug site 1

    <input type="text" name="slug[1]" value="{{ entry1.slug?? '' }}">

Slug site 2

    <input type="text" name="slug[2]" value="{{ entry2.slug?? '' }}">

    <input type="submit">
</form>

And then in your Controller

/**
 * actionIndex
 *
 *
 * @throws \Throwable
 * @throws \craft\errors\ElementNotFoundException
 * @throws \yii\base\Exception
 * @throws \yii\web\BadRequestHttpException
 * @return \yii\web\Response
 */
public function actionIndex(): \yii\web\Response
{
    // grab all the sites you want to store
    $request = Craft::$app->getRequest();
    $sites = $request->getRequiredBodyParam('siteId');

    $elements = Craft::$app->getElements();
    // change the handle of course
    $section = Craft::$app->getSections()->getSectionByHandle('news');
    // only applies to me, you need to figure out the type on your own
    // note: don't just grab things by id if you use the project config
    // please check if those variables are not null
    $type = $section->getEntryTypes()[0];

    $elementId = null;
    $element = null;
    foreach ($sites as $siteId) {
        // TODO check if the site exists
        $elementId = (int)$request->getBodyParam('id', $elementId);
        if ($elementId !== 0) {
            $element = $elements->getElementById($elementId, Entry::class, (int) $siteId);
        }

        if ($element === null) {
            $element = new Entry(
                [
                    'sectionId' => $section->id,
                    'typeId'    => $type->id
                ]
            );
        }

        $this->populateModel($element, $siteId);
        if($elements->saveElement($element) === false){
            // handle errors somehow
            echo "
";
            var_dump($element->getErrors());
            echo "
";
            die();
        }

        $elementId = $element->id;
    }

    return $this->asJson(['success' => true]);
}

/**
 * populateModel
 *
 * @param \craft\base\ElementInterface $element
 * @param                              $siteId
 */
public function populateModel(ElementInterface $element, $siteId)
{
    /** @var Entry $element */
    $request = Craft::$app->getRequest();
    $element->title = $request->getBodyParam('title.' . $siteId, $element->title);
    $element->slug = $request->getBodyParam('slug.' . $siteId, $element->slug);
    $element->enabled = $request->getBodyParam('enabled.' . $siteId, $element->enabled);
    // and so on.. continue with the rest you want to post + the author..

    $fieldsLocation = 'fields.' . $siteId;
    $element->setFieldValuesFromRequest($fieldsLocation);
}


Extra spaces appearing in Rich Text fields after 2.5 update

The fix is in!

Running Redactor “I” in Craft 2.5

Just used this on one of my problem upgrades and it worked seamlessly - now they get to be in on the 2.5 party too :)


[** Updated Dec 2016]

I think at this stage the best approach will be plugin based.

Create a business logic plugin if you haven't already.

Two good ways of doing that are : Business Logic Plugin or via https://pluginfactory.io

If you listen to:
https://craftcommerce.com/docs/events-reference#commerce_lineitems.onpopulatelineitem

...then you can do (basically any) logic on the price as it is created as a lineItem in the cart (i.e. added to the cart).

Here's some sketch code to get you started:

craft()->on('commerce_lineItems.onPopulateLineItem', function($event){

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

  if(isset($lineItem->options['giftWrapped']) && $lineItem->options['giftWrapped'] == 'yes')){
      $lineItem->price = $lineItem->price + 1;
  }

});


Attempting to create a complicated grid layout with batch

I think I got it. Here's what I did:

{% for entry in items|batch(10) %}

    {% for batch in entry[0:3] %}
        {% if loop.index == 1 %}

{{batch}}

        {% elseif loop.index == 2 %}

{{batch}}

        {% elseif loop.index == 3 %}

{{batch}}

        {% endif %}
    {% endfor %}

    {% for batch in entry[3:2] %}
      {% if loop.index == 1 %}

{{batch}}

      {% elseif loop.index == 2 %}

{{batch}}

      {% endif %}
    {% endfor %}

    {% for batch in entry[5:3] %}
      {% if loop.index == 1 %}

{{batch}}

      {% elseif loop.index == 2 %}

{{batch}}

      {% elseif loop.index == 3 %}

{{batch}}

      {% endif %}
    {% endfor %}

    {% for batch in entry[8:2] %}
      {% if loop.index == 1 %}

{{batch}}

      {% elseif loop.index == 2 %}

{{batch}}

      {% endif %}
    {% endfor %}

{% endfor %}


I had not seen this before, but it's the solution to my problem as I was dealing with grouping.  See link below.

Group entries by section


Can I apply an image transformation to an arbitrary image (non-Assets field)?

While transforms are an asset-only feature, you can get at all of the underlying image manipulation features pretty easily using the ImagesService.

$image = craft()->images->loadImage($imageSource);
$image->setQuality($quality);
$image->resize($transform->width, $transform->height);
$image->saveAs($targetFile);


No need for a plugin, just don't check this option


No obvious solution sticks out to me using only native Twig functions/filters.

It'd be pretty trivial to write a custom filter using parse_url(), though...


Searching on whole title returns no results

I don’t think it’s a bug, that’s what the docs describe, although I would tend to make the same assumption that you’ve made about how it should work.
Either way you can search for a contains, or an exact match at the same time:
.search(search_query "OR \"" ~ search_query ~ "\"")


Local install does not start, PDO Exception

You are using multi-environment configs improperly.

You must have an environment with the * key. This is how Craft knows that you are using a multi-environment config. Even if the value is simply an empty array, it must exist.

  The '*' array is required to enable Craft’s multi-environment config support, even if you don’t need it. Craft specifically checks for it when deciding whether to enable multi-environment config support or not.

And this is a bit of speculation... but I'd highly recommend having your * environment as the first item in the array. I'm not sure if it makes a difference to Craft, but it's at least a bit of a standard.


Saving matrix field of a duplicate of an entry not working

This sounds suspiciously like a bug that was fixed in today's Craft 3.6.10 release.

Fixed a bug where entries could return the wrong Matrix/Neo/Super Table blocks if the blocks were queried immediately after the entry was created via craft\services\Elements::duplicateElement().

My guess is if you update to that release, it'll behave like you expect now.


Can I use Twig in a FreeForm html field?

Thanks Kelsey: "Sorry, unfortunately you cannot, as these fields are pre-rendered beforehand. Kelsey Martens"


Looks like this was a ModSecurity tripping up the contents of the particular Redactor field in the POST request.

The nuclear option for a fix is to disable ModSecurity.  The more nuanced fix is to find the particular rule that is tripping up the request and either disable it or to modify it so it allows that content through.


How to immediately redirect to an entry after creating the new entry from a frontend form?

I think the answer is as simple as providing the new Entry's URI to the redirectInput function:
<form method="POST">
  {{ actionInput('entries/save-entry') }}
  {{ redirectInput('{uri}') }}

  <input type="text" name="title">
  <button>Save!</button>
</form>

Craft looks at the string you pass in, and evaluates it as an "object template," wherein you can use the short-hand syntax here ({uri}) to access properties of the saved Entry.

Keep in mind! The behavior here differs based on what Controller you're using—sometimes it'll be a different kind of Element, which may or may not have a useful/predictable uri (i.e. if you're updating an Asset).

The "template" you pass in can be as complex as you want. For example, if the form was part of your dashboard, you might want to prepend with a path of some kind:
{{ redirectInput('my-account/orders/{id}') }}

Similarly, you can use regular Twig syntax here—Craft just does some of these easy substitutions for you:
{{ redirectInput('my-account/orders/{{ object.id }}') }}

Note that the "template" won't get rendered in the actual request, so you'll see exactly what you typed here (well, plus a hash of the string, so users can't manipulate it)—it's only evaluated when submitted.

For more info, check out the redirectToPostedUrl($object) method!


Preserving  tags inside a  tag in a Redactor rich text field

Would you consider an alternative Matrix based approach where one rich text field was used for article-copy and another separate rich text field, used for the blockquote?

So: Matrix field: "Article blocks"

Block 1: "Article"
Block 2: "Quote"

e.g. (screen shot from a current project...)

That way you could leverage Matrix functionality and allow more layout control as well - such as alignment etc - to the blockqoutes, and maintain your paragraphs as well.


Find matching asset (image) for category

I would add the brand category field to the assets field set. This way you can add brands to images and use .relatedTo to find them.

  {% for category in craft.categories.group( 'brands' ) %}
    // This will give you the first image that relates to the category, you could use .find() to get all images and then loop through them.
    {% set image = craft.assets.relatedTo( category ).first() %}

        {% if image|length %}

        {% else %}

        {% endif %}

  {% endfor %}


Conditional to detect mobile devices with getUserAgent?

Unlike in PHP, it's not actually possible to break a for loop in Twig.

To work around that fact, you can use the for loop to set a flag, and then put the conditional outside the loop:

{% set isUserOnMobile = false %}

{% for item in browserValues %}
    {% set isUserOnMobile = not isUserOnMobile ? item.agent in userAgent : isUserOnMobile %}
{% endfor %}

{% if isUserOnMobile %}
    You're on mobile
{% else %}
    You're not on mobile
{% endif %}

Another option: I actually wrote a plugin called Detect for device detection (the plugin wraps the excellent Mobile_Detect library, which is sponsored by BrowserStack). Might be you'll be be able to use that, instead of hard coding lots of user agent strings. Here's how you can use Detect in a template:

{% set isUserMobile = craft.detect.isMobile %}
{% set isUserTablet = craft.detect.isTablet %}
{% set isUserPhone = craft.detect.isPhone %}
{% set isUserIphone = craft.detect.is('iphone') %}
{% set userAgent = craft.detect.getUserAgent %}


Technically, that's up to each individual plugin developer. But realistically, the vast majority of commercial plugins are only valid for a single site.

If it's a paid plugin, you'll probably need to pay for it on each site independently.

  "I may power more than one site for free under the terms of the Solo license."

It's important to realize that you're actually working with multiple licenses in this case... they just all happen to be Solo (aka free). Each site has its own license, you are not sharing a Solo license across multiple sites.


Is there any way to replace the asset programatically?

You need to set the scenario SCENARIO_REPLACE or SCENARIO_CREATE depending what you like to do

$asset = new \craft\elements\Asset();
$asset->tempFilePath = $tmpFilePath;

$asset->setScenario(\craft\elements\Asset::SCENARIO_REPLACE);