PHP 7.0 and 7.1 PDF error with Craft Commerce orders

I came across the same issue yesterday. After a bit of reading and trial and error I found the most elegant way for now is to remove the white space between these elements.

Personally I achieved this by adding comments  between to remove the white space

I piked this up from this thread initially.
https://github.com/barryvdh/laravel-dompdf/issues/389

I think that the proper solution might be to enable the html5 parser, but I think this might be a config setting within the DomPDF? Would this fall ino the Craft Commerce files?

"enable_html5_parser" => true,


Can I set shipping rates based on order value?

Within Commerce Settings -> Shipping Methods you can set within the rules of that method, the 'Minimum Order Total Price' and the 'Maximum Order Total Price' and an associated shipping cost, so yes, it is possible to recreate your clients existing setup.


Dragging images inside of rich text editor

Just looked into this and it’s a Craft bug. If you add an image manually using the “Insert URL” option, the image can be dragged around, but not if you use the “Choose image” option, which opens Craft’s image selection modal.

Saving the entry and coming back to it (or just typing Command + S) will also make the image draggable, regardless of how you added it.

We’ll get this fixed.


I've had that happen before and it was just a matter of refreshing the page a few times to clear it up. If that doesn't work try clearing the control panel resources cache (or just deleting the cpresources folder from your webroot).


Send e-mail notificacion ( including attached files ) after user send information with Guest Entries

Instead of using the Postmaster plugin, which appears abandoned and hasn't been updated since 2016, you could write a simple plugin that listened to the afterSaveEntry event.

That plugin could grab any info from the submitted Entry model, including uploads/attachments, and manually compose and send an email out.

You can see an example of how to do that in code in the Contact Form plugin.


Hadn't thought about using simple if logic here in the template

{% if entry.postDate <= now|date_modify('-90 days') %}
    {% redirect 'jobs/expired' %}
{% endif %}


Sounds like your options simply need to be JSON decoded. Unfortunately, Twig doesn't ship with a json_decode filter, so you'll need a plugin – there are several that fit the bill over at StraightUpCraft.

Using the JSON Decode Filter plugin, here's how your code would look:

{% set options = entry.optionsAndAccessoiries|json_decode %}
...


Do I use Twig filters 'include' and 'extends' for localized site correctly?

From the localization guide - When Craft is looking for a template, it first sees if a template with that path exists inside a directory named after the current locale, then for the actual path provided.

So in your case, when you're in the de locale, it would look for the following templates:

templates/de/_layouts/base.twig
templates/_layouts/base.twig

and

templates/de/_includes/header.twig
templates/_includes/header.twig

etc, using the first one that exists.

If there's little or no difference between how the site behaves in different locales (other than the translated strings,) then it might not be necessary to override whole templates like that, but it's great when you need it.


How can count and then order by the # of entries assigned to a category; and then limit to only the top 3?

Ideally you'd do this from a custom plugin so you could write some queries directly against the database.

If you're looking to do this from a template, this should work, albeit it's not very efficient.

{% set entryArr = {} %}

{# Store the slug as the key in an array and the total number as the value #}
{% for categoryName in craft.categories.group('markets') %}
    {% set entryArr = entryArr|merge({(categoryName.slug): craft.entries.section('posts').relatedTo(categoryName).total()}) %}
{% endfor %}

{# Sort the array by the descending value maintaining the keys #}
{% set entryArr = entryArr|sort|reverse %}

{# Grab the first 3 values from the array #}
{% set entryArr = entryArr|slice(0, 3) %}

{# print them off #}
{% for slug, number in entryArr %}
    {% set categoryName = craft.categories.slug(slug).one() %}
    {{ categoryName.title }} - ({{number}})
{% endfor %}


Getting Price and Add to Cart Button. Any thoughts on what I am doing wrong

I am a little confused with your twig code assigning so many variables.

Put simply, only a purchasableId can be used to add something to the cart.

If you know the product ID then it is as simple as:

{% set product = craft.commerce.products.id(6901}.first() %}

{% if product %}
    <form method="POST">
        <input type="hidden" name="action" value="commerce/cart/updateCart">
        <input type="hidden" name="redirect" value="commerce/cart">
        <input type="hidden" name="qty" value="1">
        <input type="hidden" name="purchasableId" value="{{ product.defaultVariant.purchasableId }}">

        <button type="submit">BUY NOW {{ product.defaultPrice|commerceCurrency }}</button>
    </form>
{% endif %}


Error trapping on discount codes based on Cart contents

So this is for coupons?

If a coupon can't be applied during an updateCart, you'll get back the rather unhelpful response in JSON of {"error":"Cart not completely updated."}

We intercept this, and because we know it's a coupon operation just replace the text of that to 'Could not apply coupon'.

But it does not give you a reason or anything, unfortunately.


Should I just have a single Volume called "uploads" and then create the subfolders within the craft dashboard via Assets?

I think that's typically how people would set it up.  You might run into some edge-case synchronization issues with nested Volumes.


Commerce - Ajax returning obj.success even when failed

This sounds like a bug and I would raise it with support@craftcommerce.com

The stock part of Craft Commerce is still pretty basic at this point.


Contact form on form submission redirects to index.twig

I inspected your form, and the redirect value is 45e4c422dc3ef7c10d24f04e10a42c07affd1f5456fb253747b332aed6481678thanks.

Perhaps try being more explicit with your redirect, something like: {{ redirectInput(siteUrl ~ 'thanks') }}


Over ride auto-generated alt tag on image added via Rich Text field

The Retcon plugin works great for DOM manipulation. You can override the attribute with a default value or remove it completely.

{{ entry.body|retconAttr('img', {'alt': entry.title}) }}

{{ entry.body|retconAttr('img', {'alt': false}) }}


Query for multiple date ranges on a date field

You can use two queries, each for each range, and then merge them like this:
{% set firstRange = craft.entries({fieldHandle: ['and', '>= '~date1FirstDay, '< '~ date1LastDay]}) %}
{% set secondRange = craft.entries({fieldHandle: ['and', '>= '~date2FirstDay, '< '~ date2LastDay]}) %}

{% set entries = firstRange |merge(secondRange) %}

This is the way to do it. Also you should query for the ids, and then merge those, and then query by id.
I hope this will help.


Inserting Multiple Block Types in one div row

It wasn't a CSS issue. Lack of twig knowledge. Here is the final fix.

    {% case 'pageRelatedContent' %}
{% set relatedContentBlocks = entry.memberCommunicationsPageContent.type('pageRelatedContent') %}
{% if entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 1 %}
    {% set colSize = 12 %}
{% elseif entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 2 %}
    {% set colSize = 6 %}
{% elseif entry.memberCommunicationsPageContent.type('pageRelatedContent')|length == 3 %}
    {% set colSize = 4 %}
{% endif %}
    {% set isFirst = not block.getPrev() or block.getPrev().type != 'pageRelatedContent' %}
        {% if isFirst %}

        {% endif %}
        {% set relatedBlockInfo = relatedContentBlocks|batch(colSize) %}
        {% for blocks in relatedBlockInfo %}

                     {{ block.relatedContentTitle }}

                                {% for row in block.relatedLinkInformation %}

{{ row.linkTitle }}

                                {% endfor %}

        {% endfor %}
    {% set isLast = not block.getNext() or block.getNext().type !='pageRelatedContent' %}
        {% if isLast %}

        {% endif %}


How do I check for the presence of an asset before accessing an empty asset field?

You could just check the length of the whole asset array first, to make sure there are two images. Something like this:

{% if (entry.igBanner | length) > 1 %}
    {% set asset = entry.igBanner[1] %}
    <img src={{ asset.url }} class="img-responsive" alt={{entry.title}}>
{% endif %}


Currently not... after all, the task has to be triggered by something (either a cron job or a PHP request to kick it off).

We've discussed the possibility of adding quasi-cron support natively in the future.  It wouldn't be 100% accurate, though, since it would still require a PHP request to trigger it. At most you'd be able to say something like "Start this task at 8PM tomorrow", but it wouldn't actually start until the first PHP request that occurs after 8PM tomorrow.


You can’t change or add fields to the General Settings page, but for site wide available content Craft has this concept of Globals.

See the documentation on it:
https://craftcms.com/docs/globals

It’s also very easy to manage user permissions for Globals, so you can allow certain user groups (besides admins) to change the meta data, somthing that (currently) isn’t possible for everything in Settings.


Password Update form accepting any data for currentPassword

If the user already has an elevated session then they do not need to enter their current password. You can see the relevant code for this check here:
https://github.com/craftcms/cms/blob/bd3820f19a0680c635a89c7f16805299964d97f2/src/controllers/UsersController.php#L1713-L1721
That is the only explanation I can come up with for the difference in what you are seeing locally and in production.


Perform inclusive relatedTo query with multiple categories in Craft 2.5+

Some of the unexpected behavior here ended up being due to a bug in the new 2.5 relatedTo syntax. It was fixed in Craft 2.5.2724 Beta.


How to show to profile related data inside Users page in admin dasboard, also showing some addtional filters

I might be misunderstanding your question, but you can choose which columns are shown on all of Craft's element index pages using the little cog at the bottom of the sub-nav sidebar. You can also add additional headings to the sidebar and rearrange them from here.
For non-superadmins, you need to grant permission for them to access this functionality by enabling the Customize element sources permission under Settings > Users > [User Group] > General.


How to move entries from one channel to another

Currently there isn't any core functionality in Craft for duplicating/moving entries between sections. I think this has been brought up a few times before, but I'd recommend heading over to Craft Feedback and posting up about it there!

Anyways, back to your question. I did post something similar to this at the end of last year. I haven't used this particular code in a long time, and I'm afraid I can't currently test it for you right now, but it might be worth giving a try.

It's also worth noting to take database backups before trying this in-case things start getting scary!


The syntax to set a custom field parameter on a Matrix Block element criteria model is like so:

{% set blocks = entry.myMatrixField.mySmartMapField(params) %}


Using the nav tag repeat the parent once in the children

I'm an idiot, i can just do:

   {% nav page in blah %}

         {% if page.level == 1 %}
            {{ page.title }}
                {% else %}
                    {{ page.getLink() }}
         {% endif %}

         {% ifchildren %}

{{ page }}
 -- this is dodgy
                {% children %}

         {% endifchildren %}

    {% endnav %}


Is there a way to add a url(not to the file itself) to assets?

You can add any number of fields to your asset sources (just like you can for 'user groups', 'category groups', 'tag groups', or 'entry types'). Under 'settings > assets > sources', click a source (or create new); then click the 'field layout' tab and add your field (field needs to be created first); and save. For a url you would likely just use a textfield.

In your template you would access it with something like this:

{{ entry.myAssetsFieldHandle.first().myLinkUrlFieldHandle }}


Shipping Adjustment not being added to Total Price

Turns out it was another plugin interfering with the order total.


I think it's because you're trying to cram too much into your entry variable.  For one, .slug() is going to return an entry with that slug, so I think that's a bit of a full stop.  For two, .descendantOf() accepts an EntryModal object, but you're feeding it a uri/slug (ie. name-of-artist).

Try something like this:

{% set artistEntry = craft.entries.slug(artistParent).first %}
{% set projectEntry = craft.entries.descendantOf(artistEntry).first %}

Keep in mind that .descendantOf() only works with structures (not channels), so I'm assuming that's what you're working with. Also, you may need to specify how far down the lineage to go with .descendantDist().


This sounds like a bug, and I think I know why. Can you try changing the {% set entryCount ... line to this?

{% set entryCount = craft.entries.relatedTo(category.id).total() %}


In Craft 3 how do I find the title of the previous and next entry when looping through a channel?

This did the trick - I'm assuming a news channel here with datestamped entries.

{% set query = craft.entries
    .section('nieuws')
    .id('not ' ~ entry.id)
    .limit(1) %}

{% set prevEntry = clone(query)
    .postDate('<= ' ~ entry.postDate.timestamp)
    .order('postDate desc')
    .one() %}

{% set nextEntry = clone(query)
    .postDate('>= ' ~ entry.postDate.timestamp)
    .order('postDate asc')
    .one() %}

{% if prevEntry %}

< {{ prevEntry.title }}

{% endif %}

{% if nextEntry %}

{{ nextEntry.title }} >

{% endif %}

Hat tip to How to get the previous or next two entries


Fixed.  Had to delete the plugin entry from the database plugins table.


Automatic cache clearing when reordering custom element type

So i found an answer, was a little more manual but it works.

I added a call back to the onMoveElement to automatically more manually clear the cache.  This was added to my plugins init() function

craft()->structures->onMoveElement = function(Event $event) {
      $element = $event->params['element'];
      craft()->templateCache->deleteCachesByElementId($element['id']);
};

Was interesting to me that i only had to do this for reordering sturctures while adding/deleting elements automatically cleared the cache with no event code.

Not sure if this was a bug or by design?


How to create a simple shopping list (but not ecommerce)

Never used it before, but it sounds like maybe the Shortlist plugin might do what you're looking for.

Outside of that, sounds like it'd be a fairly simple plugin to custom develop.


Get entries that aren't related to current user

Try this:
{% set entries = craft.entries.section('movementCoursesEntries').level(1).relatedTo({
   targetElement: currentUser,
   field: 'permittedUsers'
}).ids() | join(', not ') %}

{% set unrelated = craft.entries.section('movementCoursesEntries').level(1).id('and, not '~entries).all() %}

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


Actually, everything was working fine with the migration.  The issue was that I had code inside of a Twig extension and inside of a rendering hook that was being executed before the migration tried to take place.

I wrapped it in if (!craft()->request->isCpRequest()) to only do its thing when it's a non-CP request (which is how it probably should have been anyway), and all is well.


If I understand correctly, it looks like you really only have 2 branches to your tree (products and services). Everything else applies to all products or all services respectively and is one-to-one (except for budget). Instead of using categories, I would probably opt for using Entry Type to determine whether it's a product or service, and dropdown and/or checkbox fields to determine the product/service attributes, which you can then use to search for products/services directly using an ElementCriteriaModel.

Channel => productsServices
    Entry Type => product
        Field => testingType (dropdown)
        Field => surfaceType (dropdown)
    Entry Type => service
        Field => reportingLevel (dropdown)
        Field => isoCertification (checkbox)
        Field => price

In your template, you can use javascript to display the correct form questions (based on the answer to the first question) using .on('change', function(event){..}). Select field options can be set dynamically from the field options. Budget options can perhaps be stored in a separate field in a global set ('budgetOptions') for example.

Who will test your self-cleaning surface?
<select name="productServiceType">
    <option value="product">I'll test it myself</option>
    <option value="service">I want the experts</option>
</select>

    What is the reason for your testing?
    <select name="testingType">...</select>
    What surface type will you be testing?
    <select name="surfaceType">...</select>

    What level of reporting do you require?
    <select name="reportingLevel">...</select>
    Do you require ISO certification?
    <select name="isoCertification">...</select>
    What is your budget?
    <select name="budget">...</select>

You can then submit the form to your productServices template, retrieve the attributes and find the associated products/services.

{# set default params #}
{% set params = {
    section: 'productsServices',
    limit: null
} %}

{# determine productService Type #}
{% set type = craft.request.getParam('productServiceType') %}

{# set product params #}
{% if type == "product" %}
    {% set testingTypeParam = craft.request.getParam('testingType') %}
    {% set surfaceTypeParam = craft.request.getParam('surfaceType') %}
    {% set params = params|merge([
        testingType: testingTypeParam,
        surfaceType: surfaceTypeParam
    ]) %}
{% endif %}

{# set service params #}
{% if type == "service" %}
    {% set reportingLevelParam = craft.request.getParam('reportingLevel') %}
    {% set isoCertificationParam = craft.request.getParam('isoCertification') %}
    {% set budgetParam = craft.request.getParam('budget') %}
    {% set params = params|merge( [
        reportingLevel: reportingLevelParam,
        isoCertification: isoCertificationParam
        price: '>= ' ~ budgetParam
    ]) %}
{% endif %}

{# retrieve entries #}
{% set entries = craft.entries(params) %}
{% for entry in entries %}
    {{ title }}
    ...
{% endfor %}

Not tested, but should be close.


You can't.

The composer.json file (and the composer.lock file so you can't even reverse engineer composer.json) isn't shipped with the official release on purpose.

Craft 3 is still in development preview status (not even alpha release), but the next release will include updated Composer dependencies.


Freeform: How do I detect if a form was submitted?

One way you could do this is on the backend via a module and the FreeForm events:

Run composer require ramsey/uuid in the root directory of your project
Add the following lines to the top of modules/Module.php right after the line that says use Craft;

use yii\base\Event;

use GuzzleHttp\Client;
use Ramsey\Uuid\Uuid;
use Solspace\Freeform\Services\FormsService;
use Solspace\Freeform\Events\Forms\AfterSubmitEvent;

Add the following in the Module's init() method, right after the line that says // Custom initialization code goes here...:

Event::on(
    FormsService::class,
    FormsService::EVENT_AFTER_SUBMIT,
    static function(AfterSubmitEvent $event) {
        $form = $event->getForm();
        $submission = $event->getSubmission();

        $uuid4 = Uuid::uuid4();

        $client = new Client();
        $client->post('https://www.google-analytics.com/collect', [
            'headers' => [
                'User-Agent' => Craft::$app->request->getUserAgent(),
            ],
            'query' => [
                'v' => 1,
                'tid' => 'REPLACE-THIS',      // Tracking ID from GA
                'cid' => $uuid4->toString(),
                't'   => 'event',
                'ec'  => 'REPLACE-THIS',      // Event Category
                'ea'  => 'REPLACE-THIS',      // Event Action
                'el'  => 'REPLACE-THIS',      // Event Label
            ]
        ]);
    }
);

Replace the REPLACE-THIS strings with your own Tracking ID and Event options
Uncomment the following line in config/app.php:

//'bootstrap' => ['my-module'],

Tip: You have the form and the submission available to you as $form and $submission respectively in case you want to use any of their values to populate your Event options (i.e. use the form name as the Event Label or something).

Hopefully that helps! (Disclaimer: I just threw this together so it's not really "tested"  - if you do run into issues ping me on Discord and I'll help you get it working.)


Custom field type that has multiple fields to extend the default field types

I would say you can do this yeah, it just take a little figuring out is all.

Your input template could look something like:

<input type="text" name="{{ name }}[title]" value="{{ value.title is defined ? value.title }}">
<input type="text" name="{{ name }}[description]" value="{{ value.description is defined ? value.description }}">
<input type="text" name="{{ name }}[caption]" value="{{ value.caption is defined ? value.caption }}">
<input type="text" name="{{ name }}[thumb]" value="{{ value.thumb is defined ? value.thumb }}">

Then in your fieldtypes main class, something like:

public function getInputHtml($name, $value)
{

    // If value is null, we set it to an array to prevent template errors
    if(!$value)
    {
      $value = array();
    }

    return craft()->templates->render('bosh/input', array(
        'name'  => $name,
        'value' => $value
    ));
}

public function prepValueFromPost($value)
{
    return json_encode($value);
}

public function prepValue($value)
{
    return json_decode($value, TRUE);
}

So basically you are settings the fieldtype value to an array of pluginHandle[field] which then you json_encode so it can all go into database without any issues.

Then when you retrieve the value from the DB, its a string, so you json_decode it into an array. The TRUE part states you want an associative array, rather than a stdClass object.

Thats pretty much it at a basic level :)


So you can't just change the type of the mainEntityOfPage because there's a unique PHP class for each schema.org type.
What I would typically recommend here is that you set up the mappings via Content SEO (which lets you set up a different mainEntityOfPage per entry type) or you use the SEO Settings field to allow for per-entry changing of the mainEntityOfPage.
But if you really want to do it dynamically via Twig, you can. You just need to create a new object.
{% do seomatic.jsonLd.create({
    'key': 'mainEntityOfPage',
    'type': 'Whatever',
{# fill in other properties here #}
}) %}


Padding on .redactor-editor hides "structure" setting display

Redactor puts a "redactor-structure" class in the markup, so to override, I'm putting:

body .redactor-box:not(.redactor-box-fullscreen) .redactor-editor.redactor-structure {
   padding-left: 32px;
}

Might be nice to have that in the core.


How can I get an S3 asset's remote path minus the bucket name from within my plugin?

I'd just use the replace filter to chop it off...

  https://craftcms.com/docs/templating/filters#replace

Even if you didn't know the bucket name exactly, replace supports regex.


Since you are building a custom URL, you shouldn't be using url() here, since it automatically appends your values to the siteUrl. Try one of these instead:

-or-


If you are faced with such a task, then I think it's better to use user IDs, getting from the method a ids from the field in which users are stored, and check the received array using the in method. Another option is a plugin https://plugins.craftcms.com/user-group-field.
 {% set usersIds = entry.usersField.ids %}

    {% if currentUser.id in usersIds %}
        Show the page
    {% else %}
        Permission Denied
    {% endif %}


How do I target the 3rd entry and only that entry?

As soon as you apply .all(), the variable you're working with becomes an array. Which means that the .offset(2) needs to be applied before you convert it into an array.

UPDATE

As @andrew.welch points out in the comments, it's as easy as grabbing the third item in your array...

items[2]

Ultimately, it looks like you want something like this...

{% set cardC = items[2] %}

{% if cardC %}

    {# ... the rest of your code #}

{% endif %}

ORIGINAL ANSWER

Once it's an array, you'll need to use the Twig syntax instead...

items[2:1]

Which translates to: "get third item (0-based index), limit of one".


Nearest entry using related entry Smart Map field

Being that the smartMapField attribute belongs to entries in the Property section, and not the entries in the Unit section, your current element criteria is a bit off (it basically assumes that the smartMapField property is found on the Unit entry models).

Basically, you'll need two element criterias to accomplish what you want.

The first criteria will pull Property entries based on their smartMapField value and the params object. The second one will pull Unit properties, by relation to the Property entries in the first criteria.

Finally, we'll need to use the group filter to output the unit entries in the correct order (i.e. those related to the nearest property entry first).

Important: It isn't 100% clear from your question, but I'm assuming that the relation between Units and Properties originates from a relatedPropertyField in the Units entries, rather than the other way around.

I haven't been able to test this, but I believe something like this should do the trick:

{% set nearest = craft.entries.section('units').relatedTo({
    targetElement : craft.entries.section('properties').smartMapField(params).order('distance').limit(null),
    field : 'relatedPropertyField'
}).limit(null).order('targets1.sortOrder')|group('relatedPropertyField.first().id') %}

Note the group filter applied to the nearest variable. This is needed to group the returned entries by their common Property relation. The group filter turns nearest into an array of grouped elements, which means that when you output the entries, you'll need a nested for loop:

{% for units in nearest %}
    {% for unit in units %}
        ...
    {% endfor %}
{% endfor %}


Element API: How to get entries up to a certain page?

This tweet shows a way to adjust the elements per page dynamically with a query string param -> https://twitter.com/JakeDohm/status/1157305040278839296?s=20 so you could just request 6 or 9 items to get the same result.


How do you page through child entries in a structure?

getPrev, getNext, getPrevSibling, getNextSibling all specify an entry relative to the current one. prevChild and nextChild if they existed would somehow specify an entry relative to a child of the current entry. They don't exist.

What you can do is paginate through the children. Here I use .limit(1) to page through them one at a time, but you could fetch more.

{% set prePaginatedEntries = entry.getChildren().limit(1) %}
{% paginate prePaginatedEntries as entries %}
  {% for oneChild in entries %}
    {# do whatever with oneChild #}
  {% endfor %}
  {# pagination links #}
  {% if paginate.prevUrl %}
    Previous Page
  {% endif %}

  {% if paginate.nextUrl %}
    Next Page
  {% endif %}
{% endpaginate %}


How do you install a plugin through the command line?

Will these two commands also install the plugin migrations

There will be no migrations to run since it is a brand new installation.

  enable the plugin, and update the project.yaml file, just as if I had installed the plugin through the control panel?

Yes to both.

  Is it also necessary to run ./craft migrate/all? Or ./craft clear-caches/all?

Nope.

  Also, is it possible to install a specific plugin edition (e.g. Lite or Pro) through the command line?

Not natively. If a plugin has multiple editions, it will default to whatever is listed in their getEditions() method, which is typically going to be "Lite" first.


Unable to load the "Craft\xyz" runtime after Craft update

Fixed by changing:

class xyz extends \Twig_Extension
{
    //...
    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('kex_cache_breaker', array(__CLASS__, 'cacheBreaker'))
        );
    }
    //...
}

To:

class xyz extends \Twig_Extension
{
    //...
    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('kex_cache_breaker', array($this, 'cacheBreaker'))
        );
    }
    //...
}


Swapping Hogan for other JavaScript template engine in the SearchPlus plugin

Hi, Developer of Search Plus here.

Swapping out the js template engine isn't a simple thing. It certainly can be done, but it'd involve a reasonable amount of reworking to change.

If you're less experienced with js I wouldn't recommend it off hand.

Instead of swapping out the javascript templating engine, I'd recommend using the alterBasicMapping (that's exactly what it's designed for) hook to change the actual content to the format you need before it's passed to algolia for indexing

If you did want to dig in and give it a try, the first step would be to create your own clone of the bundled searchplus.js, found in the /plugins/searchplus/resources/js/ folder.

Within that there are a few key parts, from line 48 you'd see the various Hogan.compile markers which would need changing, and then each of the separate renderHits(), renderFacets(), renderPagination() etc.. would need updating.

Most of those methods are dedicated to handling the logic, with the last lines of them finally passing the data down to Hogan, which looks like : $hits.html(hitsTemplate.render(content)).

Your swig version would replace that hitsTemplate.render() part.

Again - not something I'd directly recommend unless you're comfortable with the javascript side of things.


Element API: return a related entry's asset data with entry data

Sounds like you need to do some eager loading of your assets.

Here are some examples of how to do that in the Element API plugin:

ElementAPI handling CategoryModel and returning a heirachical object

Getting categories in elementAPI performance issues and help required


Use postDate in section title format field

The entry will be passed to this template as a variable named object. When you want to reference its properties you have two options:

{postDate} (single braces)
{{object.postDate}} (regular Twig syntax)

The first one is just a shortcut for the second one. When Craft is getting ready to pass your Title Format template off to Twig, the first thing it will do is find any of those shortcut tags and swap ten with the full Twig syntax.

So in your case here's what you should do:

New Arrivals for {% if object.postDate %}{postDate|date('M j, Y')}{% else %}{{ now|date('M j, Y') }}{% endif %}


Possible to reflect changes to a plugin's composer.json without uninstall/reinstall?

You can uninstall the plugin via CLI but I guess that's not really what you are after. The only other way is to change the auto generated config file in vendor/craftcms/plugins.php and change the parameter for your plugin there. But you can't ever change this attribute for others that downloaded your plugin remotely without doing things you should not do.


Invalid Configuration Error in Craft CMS 3 using Nitro 2

This path is on your host machine but this isn't how docker sees things. To Nitro, the location of the folder is /app/web/cpresources.
Without going into too much details, I'd recommend going with an alias instead of hard-setting your webroot the way you are currently doing it. Doing so will make your scaffolding just work without having to change this path every time.
In your config/general.php define your webroot alias like this:
'aliases' => [
    'webroot' => dirname(__DIR__) . '/web'
],

You can then remove 'resourceBasePath' => App::env('WEB_ROOT_PATH').'cpresources', altogether since its default value is already correct.
This alias will also be handy for setting things like File System Path on your volumes.


Eager Loading a Structure and descendants

Craft 2.6.2789 added this feature, which is seems you've reverse engineered. :)

  It is now possible to eager-load Structure entries' and categories' descendants using the 'descendants' handle.


How to only show entries older than 12 months

You were close, you can set a postDate param on your craft.entries criteria model. And the Twig filter date_modify helps you to get the DateTime from 12 months ago.

{% set timeAgo = now|date_modify('5:00 -12 months') %}
{% set postDateParam = '< ' ~ timeAgo|date('U') %}

{% set entries = craft.entries.section('news').postDate(postDateParam) %}


Show shipping rate on Cart screen in Craft Commerce

I've not tried this so early in the checkout process, but how about adding the following to your Add To Cart forms? Replace the # with the correct value obviously.

<input type="hidden" name="shippingAddress[countryId]" value="#">
<input type="hidden" name="shippingMethod" value="#">

That way, as soon as people arrive on the Cart page a country has been added already as a shipping address, which, I think, should be enough for shipping to be calculated.


How can I return specific matrix rows based on criteria?

As far as I know, the only criteria to filter Matrix blocks is the type property or to pick a block by it's position with first, last or the new nth filter.

Yes, it would totally make sense to have more options to grab select Matrix blocks and I am rather confident that this is s.th. that is already on "The List".

Update:

Craft 2.3 change things! Besides using the type property or to pick a block by it's position with first, last or the nth filter it is now possible to query for Matrix blocks using all sorts of custom field parameters.

{% set entry = craft.entries.slug('myMatrixEntry').first() %}

{# Query Matrix blocks using custom field parameters #}
{% set blocks = entry.myMatrixField.type('text').myLightswitchField('1').myDateField('> 2014-12-02') %}

{% for block in blocks %}
...
{% endfor %}


Passing variable from block within including template

Anything that is defined in index.twig outside of a block will be available in skeleton.twig, and so also in template.twig. This should work:

skeleton.twig

{% include '_includes/template' %}

index.twig

{% extends "skeleton" %}

{# Set parameter #}
{% set param = {
    section: ['handle1', 'handle2']
} %}


Commerce makes no assumptions about, but also provides not real support for, the front end of your store (other than some simple example templates).

It's up to you to build the UI you're looking for - be it a table of variants, or some sort of multi/select type system.  You simply retrieve the product & variants (checking availability as you do) - and then in your twig code build the UI you want.  And if you want dynamic updates of pictures etc, without page reloads, you'll use JS to achieve this.

Super flexible, and quite deliberately built this way to allow complete freedom in content presentation, like Craft itself, but definitely a little less 'for free out of the box' than with some systems.


After research with lots of trail & error I found the solution. I just had to add [] to my hidden field to establish the relation:

<input type="hidden" name="fields[assetId][]" value="1478" id="hidden-assetID">

The leading hint was here: Setting User field type from a front end form


Save as a new entry doesn't seem to copy all locales

This is a known Craft 2 issue that has been fixed in the upcoming Craft 3 release.

It likely won't be back-ported to Craft 2 since it takes advantage of much larger refactorings.


Connect to an external database from a Craft 2.x plugin

If only the service will be connecting to it and only one method, then your example works fine.

If only the service will be connecting to, but you use it across multiple methods, then you might want to move the bootstrapping part to the service init() method and save the database connection as a private instance variable in the service so everything in the service can access it.

  Do I need to manually "close" this connection

I wouldn't worry about it.


For that particular file, the answer is no... not without hacking the core Commerce plugin file, which we don't recommend.

If you think there's a bug in the file, send an email to support@craftcommerce.com.  If you'd like to create a feature request to open up that file so it is configurable, you can do that here.


Nginx: index.php URLs still being served alongside pretty URLs

I fixed it by adding rewrite ^/index.php/(.*) /$1 permanent; to my server block. This will redirect all urls containing index.php and something after it to the contents after index.php.

E.g. /index.php/about will be permanently redirected to /about. Google knows that if something is permanently redirected its the same content and will only index the redirect.

There's one drawback though, because index.php is an actual file you can still access that. So you need to keep Disallow: /index.php into your robots.txt as well.


Using a back reference inside a regex search string within replace filter

Backreferences within the regex are normally defined as \1, \2, etc. In the |replace filter you need to escape all backslashes, so it’ll be \\1, \\2, etc.


How can I get the locales that are actually enabled for a given entry?

Actually, entry.getLocales() (or just entry.locales) will return an array of the locales enabled for the entry's section, not all locales in the system.

Unfortunately, there's no easy way to determine which locales a single entry is enabled for. One way to do it, is to use a craft.entries query per locale, and add the locale ids to an array whenever you get an element back from the query:

{% set localesEnabledForEntry = [entry.locale] %}
{% for locale in entry.locales|keys %}
    {% set localeEntry = locale not in localesEnabledForEntry ? craft.entries.id(entry.id).locale(locale).first() : null %}
    {% if localeEntry %}
        {% set localesEnabledForEntry = localesEnabledForEntry|merge([locale]) %}
    {% endif %}
{% endfor %}

Of course, if you're looping through a lot of entries (and/or you have a lot of locales enabled for the entries' section(s)), this will quickly become a performance issue (you're basically doing 1 additional database query per entry per locale, except for the current locale being viewed).


AJAX Update Entry (500 Internal Server Error)

Try changing the url from "/actions/entries/saveEntry" to "/actions/entries/save-entry"


I already found a solution. I just created a simple query:

SELECT content.elementId entryId, title, uri
FROM `craft_content` content
JOIN craft_elements elements ON elements.id = content.elementId
JOIN `craft_entries` entries ON entries.`id` = content.`elementId`
JOIN `craft_elements_i18n` `elements_i18n` ON elements_i18n.elementId =
elements.id


favicon.ico throwing 404 TemplateLoader exception

I don't think you can open a .ico file with the browser directly, that's why the request 404s.

There's two ways to make it do its thing:

simply place it in the web root, e.g. public/favicon.ico
use this link tag in your document head: <link rel="icon" href="{{ url('dist/img/favicon.ico') }}" type="image/x-icon">


If you're using GD, try swapping to Imagick.  Also, make sure you're using a recent version of the library as well as the PHP wrapper extension.


Visitor-facing pages work; admin login doesn't--I can't login in to admin

The contents of the "web" folder should be inside public_html, not public_html/web. The craft folder (or it's contents) can then go into private_html (or whatever you have as a private folder, if any). Just remember to point index.php to the right folder for it to load.

It should in practice work if you set the right flags in .htaccess or nginx config, but there might be some inherent bug or hardcoded paths/routes in Craft. Not sure what might be causing it other than cpresources not being in /public_html/


"Single" Entry page gives 404, even though it's enabled

This was occurring because I didn't have a template file for the page in question. I added it under /craft/templates/. All I had to do was copy another template used for news articles and adapt it to my specific page requirements. Then the page showed up flawlessly, as did the Live Preview button.


Before saving Guest Entries, redirect to an entry review page?

You can listen for the beforeSave event, but by redirecting or rendering another template, you're essentially hijacking the request and cancelling the initial save.

You could fork the plugin and add some custom logic using a flag you can tell whether it's an initial save and to redirect, or it's a subsequent save and to continue processing as normal.


Getting unknown property: craft\feedme\events\FieldEvent::fieldValue

It should be $event->parsedValue - see here - https://github.com/craftcms/feed-me/blob/develop/src/services/Fields.php#L225


The 3rd parameter passed into getFeedItems is for an offset, not caching.  The caching parameter is in the 4th place and accepts any valid PHP time format.


Actually, image resizing and alignment is still available in Redactor II
(at least it is by now, might have been different a year ago)

It seems that in Reactor II both of those have to be enabled explicitly in the config. See Redactor docs

In Craft CMS you can modify the config in craft/config/redactor. Or create a new file and select it in the Control Panel. More details

My Standard.json looks something like this:

{
    "buttons": [...],
    "plugins": [...],
    "imageResizable": true,
    "imagePosition": true
}


How could I create a button to loop through entries and re-save them?

If all you want to do is re-save all of the entries without making any modifications to them, you're best bet is to use the completely undocumented TaskService and trigger the ResaveElements task.

There is an example of how to do it from your plugin here.


Alright. Guess the conclusion to my question is that with Craft 3 it isn't realisticly possible to use the plugin store without composer.

Luckily I finally found the problem composer had in connecting to packagist via ssl. Just in case other people have problems with composer too and are running ESET, this might help: unable-to-get-composer-running-to-install-craftcms


Your craft/config/memcache.php config file has the same multi-environment config support as any other of Craft's config files.

You can see all the default memcache config options Craft ships with in craft/config/etc/config/defaults/memcache.php.


Advice on entry form file uploads and S3

This is a great learning resource. Worth the investment, IMO, if you're building a lot of sites with Craft CMS.
https://craftquest.io/lessons/switching-from-craft-local-assets-volume-to-s3


Get entries based on multiple fields in controller

I haven't tested it but it should give you a pretty good idea on how to set this up.

public function actionTest() {
    $entryQuery = Entry::find()->section('mySection');

    // All the element relations. For example tags and categories.
    // These have to be Element objects. For example craft\elements\Tag.
    $myArrayWithTags = [/* ... */];
    $myArrayWithCategories = [/* ... */];
    $allRelations = array_merge($myArrayWithTags, $myArrayWithCategories);

    // Filter by relations
    $this->_applyRelationFilter($entryQuery, $allRelations);

    // Filter by custom fields
    $this->_applyFieldFilter($entryQuery, 'myRadioField', 'value2');
    $this->_applyFieldFilter($entryQuery, 'myNumberField', 3);
    $this->_applyFieldFilter($entryQuery, 'myCheckboxField', ['option1', 'option2']);

    // Build response string
    $content = "Entries:
";
    $content .= "
" . json_encode($entryQuery->all()) . "
";

    // Respond
    $response = Craft::$app->getResponse();
    $response->content = $content;
    return $response;
}

private function _applyRelationFilter(ElementQuery $query, array $elements) : array {
    $relatedTo = [];

    // Build the list of relations in the correct format
    foreach($elements as $element) {
        array_push($relatedTo, [
            "targetElement" => $element
        ]);
    }

    // Create an array with and as the first value so
    // the result only contains elements that have all the set relations
    $relatedTo = array_merge(['and'], $relatedTo);

    // Set query relatedTo
    return $query->relatedTo($relatedTo);
}

private function _applyFieldFilter(ElementQuery $query, string $handle, $value) {
    $query->andWhere([
        ('content.field_' . $handle) => $value
    ]);
}

You need to have the following imports:

use Craft;
use craft\elements\Entry;
use craft\elements\db\ElementQuery;

Info about querying by custom field:
https://craftcms.stackexchange.com/a/22995/9754


I'm not 100% following your question, but it's likely a variable re-use issue.

Basically, you're setting the variable once, and if it exists, do blah....

Then, you're attempting to re-set that variable below.  Something goes wrong with that, but entry still exists at that point, so it passes the seconds test but in that second block  entry is still pointing to the data it retrieved in the first use.

(You might find it useful to check out:
https://straightupcraft.com/articles/testing-if-something-exists-is-defined-length-is-not-null-is-not-empty

...which has a whole lot of stuff about testing variables too)


"Eager loading" of relations like Yii's "with" function

This feature has now made it into Craft core as of version 2.6.

See this link for documentation on the subject:
https://craftcms.com/docs/templating/eager-loading-elements


Forcing destruction of httpSession variables on logout

Currently when you manually click the logout button in Craft, it will destroy your authenticated session information (to be logged into the control panel), but keep your existing PHP session (represented by the CraftSessionId cookie) so anything stored in PHP's session will remain.

If that's not the behavior you're looking for, you can make a feature request to expose this behavior via a config setting and/or write a simple plugin that listens for the userSession.onLogout event and manually destroy PHP session.


Need clarification on the need for a Single section being created

There are probably other points that can be added to this, but here are a few...

If you deleted the Single, and there was no change when the template is viewed, then you probably didn't need the Single. Were there any fields assigned to the Single, and were those fields referenced in the template? If the answer is "no", then the Single was definitely extraneous.
You can make a template hidden by prefixing the template name with an underscore: /rec/_list.html. This makes the template invisible on the front-end, unless it's being called up through a Single/Channel/Structure. Without the underscore, any template can be viewed directly. (Worth noting that the underscore can also be applied to the folder name, hiding all templates inside that folder.)

In summary, the value of a Single is to be able to manage your content via the Control Panel. Whatever dynamic data is stored in your Single will be pulled into your template. If you have no dynamic data, then the Single is unnecessary.


Preview PDF doesn't work in Safari but works in other browser

I think this question does not really belong here but I'll answer it anyway. Sarafi changed the way it displays PDF documents. You can see instructions from Adobe how to enable the browser view. Besides that you have not really a chance to force other Safari users to open PDFs in their browsers. You can as well see other multiple other discussions about it the Apple Forum


How to return entries based on Checkboxes field criteria?

The default Checkboxes field type stores its value to the database as a serialized PHP array. So for an entry with checkboxes "7", "12" and "32" checked, the value in the field_interests column is ["7","12","32"].

This is not query friendly at all, so the best solution would be to use a different field type.

But if you really want to use the checkboxes field, here's how you can query for your elements. Convert your criteria model to a DbCommand object and add a new WHERE clause with a LIKE condition to perform pattern matching. Include the quotes enclosing each ID in the pattern, this should make the query robust.

$user_criteria = craft()->elements->getCriteria(ElementType::User);

$query = craft()->elements->buildElementsQuery($user_criteria);
$params = array(
    ':interestId' => '%"'.$interestId.'"%',
);
$query->andWhere('field_interests LIKE :interestId', $params);
$results = $query->queryAll();

$users = EntryModel::populateModels($results);


2 options to avoid duplicate content:

add a canonical tag to your HTML
redirect non-www to www or vice versa


How to integrate Craft Commerce with Salesforce?

Is there a Craft API to talk to?

Yes, but it depends on what sort of API you're talking about and you'll need a Craft plugin no matter what.

At the PHP level, Craft has a service layer API that plugins can utilize.

If you're looking for a web service API where you can configure what gets exposed so that 3rd party apps can consume Craft data, there is the Element API plugin that works with any Craft elements (including plugin elements, like Orders, Products and Variants like in Commerce).  Note that this is read-only and is not a REST API.

There currently isn't a native REST API in Craft, but feel free to add your comments to this feature request.  It's also possible for a plugin to implement its own REST API using its own controller endpoints and authentication/authorization methods.

As far as consuming 3rd party web endpoints, Craft ships with Guzzle that a plugin can utilize, or it can use any other library it desires (or straight up cURL).


This is not hard to implement in Commerce if you're ok with all the content going in one email (which I think is a better approach from the customer's point of view - we used to do this as separate emails years ago but customers got irritated that one order results in a whole bunch of emails). If you do want to trigger multiple separate emails, that's a tiny bit harder - but would not be difficult to implement in a plugin.

(Sketch of that approach - listen to onOrderComplete and loop through cart items.  For any that match your desired triggers, parse a template and then email it off with Craft's email functions - simple stuff as far as plugins go - let me know if you want me to expand on this).

But back to the one email approach - your order emails (receipts or any triggered by any other status) - are full twig templates - that means you can use conditionals, includes etc, to achieve what you want.

Basically, in your email template, you can loop through the products in the order and set content into some 'storage' variables (with the content being directly written in that template, or stored in fields on your products, or stored in entries in a section, or using include of other templates - anything really!).... and then output that content later in the email.

We do this to produce a 'Super Receipt' - basically a receipt that includes a whole lot of additional 'How To Get The Best From Your XXX' type content.  This content comes, in our case, from 3 levels - the product category for stuff that applies to e.g. all monitors, the brand, for brand specific stuff (how to get support from NEC, for example), and finally from product specific content.  This allows for very quickly building up libraries of this content, and a nice hierarchy of concerns.  Categories, Brands and Products each have a field autoResponder that holds this content.

Clients love it.

Here's the code.

    {# Store items we've seen already so we don't get duplicate AR content #}
    {% set seenItems = [] %}
    {% set seenProductCategories = [] %}
    {% set seenProductBrands = [] %}

    {# And store the actual content we need to print out at the end in groups #}
    {% set arProductContent = {} %}
    {% set arBrandContent = {} %}
    {% set arCatgeoryContent = {} %}

    {% for lineItem in order.lineItems %}

        {# No need to look at the same products twice... #}
        {% if lineItem.purchasable.product.id not in seenItems %}

            {% set seenItems = seenItems|merge([lineItem.purchasable.product.id]) %}

                {# Category AR content #}
                {% if lineItem.purchasable.product.id not in suppressedIds %}
                    {% for category in lineItem.purchasable.product.categories %}
                        {% if category.autoResponder|length %}
                            {% set arCatgeoryContent = arCatgeoryContent|merge({(category.title):category.autoResponder})  %}
                        {% endif %}
                    {% endfor %}
                {% endif %}

                {# Brand AR Content #}
                {% set brand = lineItem.purchasable.product.brand.first() %}
                {% if brand|length %}
                    {% if brand.id not in seenProductBrands %}
                        {% if brand.autoResponder|length %}
                            {% set seenProductBrands = seenProductBrands|merge([brand.id]) %}
                            {% set arBrandContent = arBrandContent|merge({(brand.title):brand.autoResponder})  %}
                        {% endif %}
                    {% endif %}
                {% endif %}

                {# Product AR Content  #}
                {% set product = lineItem.purchasable.product %}
                {% if product.autoResponder|length and product.type != "service" %}
                    {% set preamble = 'See also: ' ~ product.title ~ ' wiki' %}
                    {% set arProductContent = arProductContent|merge({(product.title): preamble|raw ~ product.autoResponder})  %}
                {% endif %}

         {% endif %}

    {% endfor %}

    {# Now, print it all out, most general & needed to most specific #}

    {% for key, content in arCatgeoryContent %}
        {{ emailLib.paraWithHeader ( key, content|raw )}}
    {% endfor %}

    {% for key, content in arBrandContent %}
        {{ emailLib.paraWithHeader ( key, content|raw )}}
    {% endfor %}

    {% for key, content in arProductContent %}
        {{ emailLib.paraWithHeader ( key, content|raw )}}
    {% endfor %}


You would need query for these entries using the first and the last method.

{% set criteria = craft.entries.section('blog').order('title asc') %}

{% set prevEntry = entry.getPrev(criteria) ?: criteria.last() %}
{% set nextEntry = entry.getNext(criteria) ?: criteria.first() %}

{{ prevEntry.title }}
{{ nextEntry.title }}


How to add assets field to control panel plugin template

Something like this...

{{ forms.elementSelect({
    id: 'invoicePdf',
    name: 'fields[invoicePdf]',
    elementType: craft.elements.getElementType("Asset"),
    elements: invoice.invoicePdf | default,
    criteria: {"kind":[],"localeEnabled":null,"locale":"en_gb"},
    jsClass: 'Craft.AssetSelectInput',
    addButtonLabel: 'Upload invoice',
    limit: 1,
    sources: ['folder:1']
}) }}


Why isn't my Twig replace filter working with craft.request.getUrl()?

Try:

{{ pages|replace({('data-url="' ~ craft.request.getUrl() ~ '"'): 'class="active"'})|raw }}

You were double nesting Twig tags {{ {{ }} }}, which is never necessary.  You'll want to use string concatenation instead. Also for dynamic keys in twig you need parentheses.


I'd suggest reading through the Yii QueryBuilder docs, which is what the code you've written is using.

->from('{{ assetfiles }}')

should be:

->from('assetfiles')

And if you want multiple rows returns as a a result, you need to add a:

->queryAll();

to the end of the statement.

From there, you can do a foreach loop to access the results of your query:

foreach ($query as $row)
{
    $id = $result['id'];
}


Using { slug } to create subfolders won't work

Got the problem solved, I had wanted to have the option of selecting photos from another folder so in the field settings I had Default Upload Location with the {slug} in there. When I switched it to "restrict to single folder" and set the {slug} then it is all functioning as expected. I don't think it would make sense selecting a photo from another folder in this field as the asset wouldn't be able to move when entry is saved. Hope this makes sense. I just have the same issue as the other post now where I don't see the caption field until the entry is saved.


I assume you've seen https://www.linode.com/docs/websites/apache/apache-web-server-on-ubuntu-14-04?

Craft really isn't any different than any other PHP application in the way it needs to be setup to execute.  The only extra thing that other apps might not require (because most PHP apps don't auto-update) is that Craft needs to be able to recursively write to its craft/app folder in order for that to work.

There's a handy script here: https://github.com/nystudio107/craft-scripts that can help automate the necessary permissions for your box, but you'll need still need to know what user:group Apache is running as for it to set things up properly.


How to setup a multi-lingual site on IIS

Looks like it was only because I was missing the clear tag in my rules in the subfolders.  Everything works like a charm now.


HTML Email Template setting not working for reset password email

I've had issues in the past where Twig template errors would cause the HTML email template to fallback to using the default plain text system email template. It's definitely worth checking your web.log file for any errors when the sendPasswordResetEmail method is invoked, if you haven't already.


How to use `{% cache %}` and `{% paginate %}` together?

Yes, the database query you'd want to cache is this:

{% paginate craft.entries.section('employment').endDate('>= ' ~ now).limit(10) as pageInfo, pageEntries %}

So to get the benefits of caching, it needs to be within the cache tag.


Is there a way to make Disqus notify an entry author when a new comment is posted?

Disqus has a callback function that you can use to fire an email off to the author. Within that callback, you could make an AJAX request to another template which sends an email.


Multiple sources on category field type - possible?

You cannot allow selection from multiple category sources in a category field.

I would keep the 4 category fields but set each field to limit to one (1) category selection.

Then, when you add the field to the field layout, make the field required to ensure they select a category for each field.


I did a little more research on Ajax and found a solution. I updated my Ajax such that the data line looks like:

$.ajax({
    method: 'get',
    url: 'actions/websiteListing/checkStatus',
    data: {filter: data},
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

Then in my controller, I was able to pass that data by adding $filter to the first line and including that for my 3rd $criteria line:

public function actionCheckStatus($filter)
{
    $criteria = craft()->elements->getCriteria(ElementType::Entry);
    $criteria->section = ('live');
    $criteria->hostSite = $filter;
    $criteria->limit = null;

    $entries = $criteria->find();

    foreach ($criteria as $entry) {
        echo $entry->title . '<br>';
    }
    die();
}


Contact form plugin only sending the content of the textarea?

When using multiple fields, you'll need to use message[body] for the main message field's name attribute. Passing just message as the name for your main text field will clobber your other custom fields that precede it, as will custom fields, if they appear after it.

I think the only fix you'll need in this case is to the “Comments” textarea:

<textarea name="message[body]">Your initial text</textarea>


There is an issue open over on their Github, asking about this and the last answer says it's something they are going to add at a later date.

Ajax Sending Issue

So, in short I guess not for the time being.

Edit: I guess if you have the time and fancy the challenge, you could always add it yourself and do a Pull Request?


Update record definition after plugin is already installed

If you want to change database schema after a plugin has already been installed, the way to do it is through migrations.

You can see many examples of this in Craft in the craft/app/migrations folder.


Short answer, it can't be done. I'm not sure why, but it's some sort of conflict with how nav, children, and ifchildren operates.

The workaround is ugly (but it works). Just use two separate, but identical if statements... one before the ifchildren, and one after.

{% if comment.isFlagged() == false %}
    ...
{% endif %}
{% ifchildren %}
    ...
{% endifchildren %}
{% if comment.isFlagged() == false %}
    ...
{% endif %}

EDIT:

If this solution doesn't work for you, I recommend looping over the comments array and removing all flagged comments before you run it through the nav loop.


Getting all entries posted on any given weekday

Can't think of a way how to query posts from a certain day, but you can certainly group entries by day they were posted on:

{% set allEntries = craft.entries.section('blog').limit(null) %}
{% for day, entries in allEntries | group("postDate|date('l')") %}

{{ day }}

        {% for entry in entries %}

{{ entry.getLink() }}

        {% endfor %}

{% endfor %}


If merging two sections from different locales how do I then sort them by a shared criteria?

With that last {% set news = craft.entries.id(ids) %} criteria model you're querying in one locale only
and there's no way to change that, Craft doesn't have a feature to set up a criteria model to query in multiple locales.

You'd have to merge the entry models themselves and use something like the Super Sort plugin to bring them in order.

{% set entriesA = craft.entries.section('news' ~ Section).relatedTo(active).ids() %}
{% set entriesB = craft.entries.section('newsAlumni').status(null).locale('prior_alum').search('shareNewsAlumni:1').localeEnabled(false).ids() %}
{% set entries = entriesA|merge(entriesB) %}

{% set entries = entries|supersort('sortAs', '{postDate}')|reverse %}
{% set entries = entries|supersort('sortAs', '{stickyNews}') %}


Set Up Route to Template - then variable Entry is undefined

Variables like entry are only auto-injected for routes that match the Section's Site Settings routes:

If you're using custom routes, they won't match, and you'll need to set entry (or whatever) yourself manually. SEOmatic uses the same Craft mechanism for recognizing injected entrys (or whatever), so the same applies there. Vide: Rendering Metadata From Another Route


Selecting a subset of entries, based on a relatedTo call

Second relatedTo call overrides first one. Calling it again won't add more parameters to the query.

If you don't want to repeat yourself you can always do this:

{% set creatorRelated = { targetElement: creatorEntry, field: 'creator' } %}

{% set caseEntries = craft.entries.section('case').relatedTo(creatorRelated) %}

{% set caseEntries = caseEntries.relatedTo('and', creatorRelated, { targetElement: categoryEntry, field: 'caseCategories' }) %}


How can I use categories to filter entries?

The relatedTo parameter requires one of the following as an argument:
- AssetFileModel
- CategoryModel
- EntryModel
- UserModel
- TagModel
- An element’s ID
- An array of element objects and/or IDs

Passing in a string from the URL will not work. If you are not on a template that is the result of a category route, you need to fetch the category first.

{% set thisCategory = craft.categories.handle(lastSeg).first() %}

You can then use thisCategory as your argument in the relatedTo parameter.

{% set meubels = craft.entries.section(‘meubels’).relatedTo(thisCategory) %}


Incorrect content/mime-type on S3 SVG upload

Your SVG file is probably missing the the XML declaration at the top (<?xml version="1.0" encoding="UTF-8"?>). PHP's FileInfo detects XML files (which SVG is) without that declaration as text/html files.

Lots of SVG editors/exporters will (annoyingly) omit that.


It looks like you are not targeting the action URL. When accessing a Craft controller, you'll need to use the actionTrigger in your URL:

Your current URL:

http://talkbox.es:8888/index.php/tags/createTag

Should be updated to:

http://talkbox.es:8888/index.php/actions/tags/createTag

The actionTrigger is configurable so if you plan to reuse your code on multiple sites, you won't want to hard code that value. In twig, you can output that value using the craft.config variable:

{{ craft.config.actionTrigger }}


How can I get Craft Commerce talk to the API of a CRM?

You will need to write a plugin to perform the integration. If you make it generic enough, you could share it with the community.

Your plugin would use Craft Commerce events to run PHP code at specific points in the code, which would communicate with the third-party systems.

Docs on event:
https://craftcommerce.com/docs/events-reference

The event you would probably be most interested in is the onOrderComplete event:

https://craftcommerce.com/docs/events-reference#commerce_orders.onordercomplete


Excessive resource usage / virtual memory size

It appears those emails are being generated by something called Config Server Firewall running on your server.  I don't know if your host gives you access to configure settings in it, but it looks like they have allocated you 512M of memory and you're exceeding that.

You can hit that easy enough with image transforms and spikes/surges in traffic can amplify that effect.


Is there a guide for using Craft Commerce headless?

After looking at the Commerce docs further, I see I can use the GraphQL API to get information from Commerce. That is, at least for products. Craft 3.5 will allow GraphQL mutations so perhaps that’ll encompass some sort of write API to commerce. If not, I’ll have to create custom endpoints in the Craft app to do the following:

Create customer account
Edit customer account
Edit subscription info
Edit cart
Checkout


Counter for entries to show most read Articles

Updated: There is an Entry Count plugin that is designed to do exactly this, written by Ben Croker. Thanks Ben!


Migrating Content from ExpressionEngine that used Matrix Image haystack Technique

You have two main options with a challenge like this.

1) Do it manually - While this option doesn't always sound like the most glamourous option, it's often a fairly reasonable step to consider during migrations. Writing and debugging advanced code that is only going to be used once can be costly, and there are plenty of people who specialize in data entry who are capable of helping out if you prepare a good workflow and take the time to train them on the task.

2) Do it programatically - If you take this approach, you'll probably be using an Extract, transform, load Process (also referred to as an ETL Process). In your case this would roughly equate to:

Extract the data from your ExpressionEngine database
Transform that data – processing the body and EE matrix haystack fields and updating the data into the format which you wish to import it into Craft
Load your new data into Craft (using a script or import plugin like Brad mentioned in the above comments)

My firm runs a database migration service, The Great Migration, and I can confirm that it is possible to migrate ExpressionEngine sites using a "matrix image haystack" technique to Craft CMS. We have used both programmatic and manual steps in doing so for images, videos, and quotes using this technique. Your final solution will largely depend on the format and integrity of your source data and the desired format of your target data.


How do I filter by multiple Smart Map addresses?

You would need to setup two criteria models, one for each Smart Map field, and query for the element IDs. Merge these IDs and have a 3rd criteria model where you pass in the IDs to the id parameter.

See this question for example code:

  Complex logic on a ElementCriteriaModel parameter?

Here's a blog post describing the technique in details:

  Manipulating Craft's ElementCriteriaModel objects with Twig

If you need better performance, have a look at the custom Yii query builder code I posted here:

  How can I query for entries that have one of two Lightswitch fields enabled?


Why is my Super Table field returning the ID for existing blocks?

I think the key thing here is that its a static Super Table field, which is treated differently to a repeatable one. Instead of looping through each block, there's only one. Fortunately, you have all the required information, as this is in fact the blocktype variable.

{% set fieldHandle = 'mySuperTableField' %}
{% set field = craft.fields.getFieldByHandle(fieldHandle) %}
{% set blocktype = craft.superTable.getSuperTableBlocks(field.id)[0] %}

<form method="post" accept-charset="UTF-8">
    {{ getCsrfInput() }}
    <input type="hidden" name="action" value="users/saveUser">
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

    {# Start with the top-level Super Table field #}
    <input type="hidden" name="fields[{{ fieldHandle }}]" value="">

    {# Ensure any existing rows in your Super Table field are saved #}
    <input type="hidden" name="fields[{{ fieldHandle }}][{{ blocktype }}][type]" value="{{ blocktype }}">
    <input type="hidden" name="fields[{{ fieldHandle }}][{{ blocktype }}][enabled]" value="1">

    <input type="text" name="fields[{{ fieldHandle }}][{{ blocktype }}][fields][customField1]" value="Value 1">
    <input type="text" name="fields[{{ fieldHandle }}][{{ blocktype }}][fields][customField2]" value="Value 2">
    <input type="text" name="fields[{{ fieldHandle }}][{{ blocktype }}][fields][customField3]" value="Value 3">

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


Can you get the baseUrl for site by handle or id?

{% set site = craft.app.getSites().getSiteById(1) %}
{% set site = craft.app.getSites().getSiteByHandle('handle') %}
{{ site.baseUrl }}

But I would rather suggest you to grab the entries URL for a certain site in your language switcher

{% set entryInOtherSite = craft.entries.id(entry.id).siteId(2).one() %}
{{ entry.getUrl() }}

I'm not sure why you even ask this question since everything is well documented here since you "answered" that question


I can't answer it clearly, but I did a workaround for something similar.

I've loaded the same template for my structure but gave my structure 2 entry-types(overviewPage, detailPage).

Both entry types loaded the same template but got handled differently. So my template for the structure looked something like this:

{% if entry.type == 'overviewPage' %}
  {% include 'snippets/content_overviewPage.html' %}
{% elseif entry.type == 'detailPage' %}
  {% include 'snippets/content_detailPage.html' %}
{% endif %}

I hope to see on this thread how other people handle this.


Is it possible to order entries by Entry type title/slug

I don't think it's possible to order by the name or handle of Entry Types. To order by the ID of your Entry Types use 'typeId' as the value:

{% set entries = craft.entries.section('more-info').order('typeId') %}

Now you only have to create your Entry Types alphabetically ;)


When a user is deleted from the system via the Craft control panel, they are presented with a model offering them the choice of what they want to do with that user's content.

The options are to 1) transfer it to a different user (which you can select) or 2) delete it entirely.

So the behavior you're describing certainly sounds like someone went through the UI to delete a user and transfer their content.

You might want to consider installing something like the Audit Log plugin to catch the borderline criminal.

The only other time we've seen a user and their content get deleted is from a more convoluted process where a Craft install has users in a "pending" state and they've never authenticated their accounts and they start assigning content to that account (via a custom plugin or some such).  They also have the purgePendingUserDuration config setting set to something other than false (say 1 month), then once the user account has been "pending" for a month, they get deleted along with all of their content.

But it doesn't sound like that's what is happening for you.


Show Category Title only where an entry has been included in an Entries field

You just need to check if it's related to the current entry. entry is the entry you're displaying.

{% for category in craft.categories().group('someGroup').relatedTo(entry).all() %}
    {{ category.title }}
{% endfor %}


In a previous project when I was in dev mode, the website was very slow. But when I shut this down it was fast again. Could this be a solution?


I wrote a plugin called Retcon HTML which will solve this nicely using PHP's DOMDocument class.

You'll want to use the attr filter, which is documented here:

{{ entry.richTextField | retconAttr( 'img', { 'class' : 'image fit' }) }}


How do I pull categories from another category group for members of another category?

I forgot about the related entries.  So, I actually want to pull the related countries from the **entries** related to the market.

Here is the solution.  The key was the answer to this related question about related tags.

{% set entries = craft.entries.relatedTo(category).find() %}
{% set nation = craft.categories.group('country').relatedTo(entries).find()%}


Convert checkbox values from an array to a string

If you need to do this in a twig template, the join filter will do the job.

Use {{ yourCheckboxesValues|join(', ') }} to print something like that : value1, value2, value3.


Entries from all categories in a category group via URL?

Create a URL structure like this:

yourwebsite.com/categories/groupName

Then in your template:

{% set group = craft.request.getSegment(2) %}

{% set categories = craft.categories.group(segment) %}

Once you have the categories you can loop over them and fetch entries related to each. It may however, be more beneficial to do this via a plug-in where you can construct a more complex query based on the categories and therefore be more efficient.

{% for category in categories %}

    {% set entries = craft.entries.relatedTo(category) %}

    {% for entry in entries %}
        // template stuff
    {% endfor %}

{% endfor %}


Trouble with "restricted" upload folders

Whenever you're not using the shortcut syntax with single braces you need to acces the element via object.

So add that var before owner etc. and you should be good.

One thing I noticed is that you can't use ternary syntax for conditionals within short syntax either but with Twig code you can:

{{ object.owner.author ? object.owner.author.friendlyName }}


When setting siteUrl in config.php, it overrides the "Site URL" setting in CP → Settings → General. It doesn't show the settings in that field.

  This is being overridden by the siteUrl config setting.


Amazon S3 endpoint is wrong when accessing Asset info

The problem ended up being that I had completely missed the location setting in the database column of the Asset source.


Update search index after assets.onSaveAsset Event

You could try and listen to onBeforeSaveAsset events instead of onSaveAsset. With onBeforeSaveAsset you can modify the asset model before being saved, so you don't have to do that manually.


How to save Asset field of an Entry programmatically in Craft 3

That's because you have to insert an array of ids rather than a single id

$craftCategoryIds

is an array.

$featureImageId

is an integer. Even if you have just a single element you need to insert an array

'featuredImage' => [$featureImageId]

will work


How can I add in new Locales to the locale list?

There are several locales that Yii comes with but Craft doesn't, simply to keep Craft's filesize down a bit (they add a lot of weight). You can see the master list of Yii locales here: https://github.com/yiisoft/yii/tree/master/framework/i18n/data   - If you see a locale in there you want that Craft doesn't come with, just view the raw version of the file on GitHub and then save it to your craft/app/framework/i18n/data/ folder. Then Craft will start supporting it.

If you need a locale that Yii doesn’t offer, find the closest locale Yii/Craft does come with, and copy it with a new name (e.g. en_us.php => en_mx.php).


Has someone figured out Craft 3 content migrations?

This is a plugin I'm working on to do exactly what you are after.

https://m.youtube.com/watch?v=n6ko2PKUqAo&feature=youtu.be

The syntax to figure out how to create sections, elements etc is determined by reading through the craft service and model classes.


Craft 2 - Adding custom CSS classes to Sprout Form fields on a global basis

You are correct. This is quite easy now in Sprout Forms for Craft 3 but is more of a challenge in Craft 2 because we can't easily give you access to the input html.

Your options in Craft 2 include:

Use Sprout Forms to override the field wrapper in the field.html file and then update your CSS to target input fields within the parent tag (i.e. div.my-class input instead of input.my-class. This will be the most maintainable option.
Target each individual field you wish to add a custom class to using rendering options. As you mentioned, the limitation here is that it's not very maintainable for multiple forms.
While I can't recommend it, if you are planning to upgrade to Craft 3 and choose to hack the core while you remain on Craft 2, the easiest place to do so may be right in the template files (instead of in the PHP classes). You can find the Sprout Forms input field template files in sproutforms/templates/_components/fields/*. You would need to update each individual template file with the classes you want. This option would be maintainable with the caveat that you'd need to remember that each time you update Sprout Forms you may overwrite your changes. If you go this route, it's probably best to manage your project in a git repository so you can recover any changes you might overwrite during an update.
If you did want to do this as your own plugin, you would not be able to modify the existing fields. You would need to create a new custom field to replace each existing custom field, and you would see both your custom fields and the default custom fields in the dropdown. This is maintainable in a general sense, but creates a lot of overhead for creating the duplicate fields with slightly different classes and will make the user interface feel like it has twice as many fields in the UI.
I expect you've considered this option, but updating to Craft 3 will have many benefits on top of greater control in Sprout Forms.


Limit category choice in entry to 1 and select child category

You could use a structure for Genre rather than categories. This would let you select Thrillers as a single entry.


Does the request requires login?
If it doesn't, you need to add the exception on the controller
protected $allowAnonymous = array('actionSubscribe');

Also, did you try adding admin to your URL?
<input type="hidden" name="action" value="/admin/actions/paypalSubscription/subscription/subscribe">

I was trying to post to an action once through the front-end and it only worked after adding /admin


Plugin eager loading not loading relations

What strikes me as interesting here is your dump contains a Model instance.

For example you said:

  When I dump the response from the service method i'm getting back is:
  Craft\Placid_ResourceModel Object

When I query findAll through a CActiveRecord derived class I get an array of Records. In order to populate this into models, the populateModel(s) methods are typically used.

If you have a relation at the ActiveRecord level, it is a pseudo-attribute and will only be carried through to the model if the attribute is defined as defined attributes can only be mass assigned. Yii also supports rules definitions to mark attributes as safe, but this is almost entirely optional.

The question is really why you have a model being output.

E.g. for me the following code:

$records = SomePlugin_ProductRecord::model()->with('pricing')->findAll($criteria);
var_dump($records[0]);

Results in:

object(Craft\SomePlugin_ProductRecord)#179 (14) {

Do you have any code which is auto inflating into a model? or are you calling populateModel(s)?

If so, then you have made the correct call of creating the attribute in your model if you want to access it from there, as far as I've experienced.


Is there a hook or event we can use to intercept a search request?

We are looking to log searches so we can report on them. Are there any
  hooks or events we can use to get this data?

No, there aren't any hooks or events related to searching, currently (Craft 2.4). Like Brad says, you can add a feature request.

  [...] how can a custom plugin log the initial search parameters, call the
  underlying core Craft search, and finally log the results?

Something like this should work:

class MyPluginVariable
{

    public function search($query = '', ElementType $elementType = null)
    {

        MyPluginPlugin::log($query);

        $criteria = craft()->elements->getCriteria($elementType ?: ElementType::Entry);
        $criteria->search = $query;

        MyPluginPlugin::log(count($criteria));

        return $criteria;

    }

}

...and in the template:

{% set entries = craft.myPlugin.search('body:foo -body:bar') %}


How does the allowAutoUpdates setting differentiate?

Craft's version numbers follow this pattern:

major.minor.build

So your update was a minor update and you could have blocked it with the settings build-only or false.


It sounds like this is something that could be done using a module. You could use the sites field type to select the sites you want to enable the entry for, and then listen to the beforeSave event to enable the selected sites (and disable all others).

You would listen for, and act on, this event in your module's init method.

The beforeSave event gets called for every site the entry gets saved for, so it could be something like (untested):

Event::on(Entry::class, Entry::EVENT_BEFORE_SAVE, function (ModelEvent $event) {
    // Get the entry from the event
    $entry = $event->sender;

    if (
        $entry->type->id == 1 // <-- Section type ID for entry
        && !in_array(
            $entry->siteId,
            $entry->getFieldValue('visibleOnSites')
        )
    ) {
        $entry->enabledForSite = false;
    }
}

This assumes that entries are enabled for every site by default, and that propagation for this section is active.


{% for entry in craft.entries.section('sponsors').showOnHome('1') %}

The .showOnHome('1') restricts your query to ones with the lightswitch on.

If you wanted only the ones with the lightswitch off, you would use .showOnHome('not 1')


Grouping by Date (Day) Not Working Correctly

Figured it out. I actually asked for all entries for the group, rather than just the entries (events) that matched the date.

{% set passEvents = craft.entries.section("event").eventForwardPass("Yes").status('live','pending').order('eventStartDate').find() %}
{% for date, events in passEvents|group('eventStartDate') %}

{{date}}

    {% for entry in events %}

               {% if entry.eventLinkOverride == 1 %}

{{ entry.title }}

                {% else %}

{{ entry.title }}

                {% endif %}

        {% endfor %}
    {% endfor %}


Is it possible to add white background to transformed images?

Unless one of the devs say otherwise, Craft's image processing is resizing only. They do not add anything to the image.


passing the search query into html title tag

You should be able to use:

{% set title = "Search results for: " ~ query %}


Seems totally doable with a plugin.

The protected page where they enter their email address would post to a controller action in your plugin.

Your controller checks the domain of the submitted email, verifies it's from acme.com then generates a token (maybe using StringHelper::UUID() or craft()->security->generateRandomString() if it should be cryptographically secure).  I'm assuming you'll save that token into the database for later verification.

You can use craft()->email->sendEmail() to send an email with the link they need to click.

When they click the link, you'd also have it point to another controller action that gets the token from the URL, verifies it's valid, then logs the user in similar to how Craft does it in UsersController->actionLogin(), but minus all of the username/password logic.

Keep in mind, if you invalidate the token after one use (which you probably should), then the user will have to go through this whole process every time they want to log in.


Find entries from related section after certain date

You’d first get all the relevant entries of your “trainings” section, or better get just their IDs as that’s way better on performance.
Then on another element query you set the relatedTo parameter to only get entries related to these entry IDs.

{% set trainingsEntriesIds = craft.entries({
    section: 'trainings',
    postDate: '>= ' ~ 'now'|date('c'),
}).ids() %}

{% set entries = craft.entries({
    section: 'locations',
    relatedTo: {
        targetElement: trainingsEntriesIds,
        field: 'entriesFieldHandle'
    },
}).all() %}


DRY variable setting across templates (macro for variable?)

As you noted in your comment, the Twig Perversion plugin will do exactly what you need. It allows you to return a value from a macro, which isn't typically something that Twig permits.
Personally, I'd consider it to be fairly safe to rely on this plugin for a few reasons. Marion is a long-standing and trusted developer in the community, the plugin is relatively simple, and could easily be replaced with a small custom module if it ever went defunct. It also doesn't touch your data, so removing it in the future won't cause any problems.


PHP warning with composer on MacOS High Sierra: Failed to open stream

It sounds like you're running into this recent Composer autoloading bug: https://github.com/composer/composer/issues/6977

Chances are if you composer self-update, the issue will go away.


Doesn't look like Dukt Analytics has any tables it creates in the database, but it does require Dukt OAuth, which creates a craft_oauth_providers table and a craft_oauth_tokens table you could move over.

Both of the plugin save their plugin settings in the craft_plugins table, so you might want to move their rows over as well.


Good way to handle multisite fallback templates

You can create localized template files by placing them in a subfolder of templates/ named after the site handle.

See https://docs.craftcms.com/v3/dev/#template-localization for a full explanation.


Neo plugin - Displaying an image from a Matrix field

It's tough to see the full context, just based on what you have here. From what I can tell, it seems like you might need to change  to .

Since the asset field can hold many assets, you have to declare .first() to grab the first one -- even if there's only one image. Then you have to grab the url property from the image, in order to get the correct src value.


Recommended approach for integrating a CDN with a Craft site

It's extremely easy if you're using a pull CDN like MaxCDN or KeyCDN. You just point your CDN at your server, and then point your Asset Sources at your CDN.


Open pop on click of custom action and get filled data

I'm not sure what your Question is exactly and what your expected outcome is but to create a Modal you can use this HTML

My Awesome Modal

and via JavaScript you can show it

//create it
var modal = new Garnish.Modal($('#my-awesome-modal'));
modal.show();


Access Image Transforms for S3 images via Element API

Yep, you can access transforms the same way you would in a template - via the asset’s getUrl() method.

That $transform argument can either be a string, set to the handle of one of your transforms in Settings → Assets → Transforms, or in can be an array that defines the transform settings at runtime. (Or it can be null if you just want the source image URL.)

Keep in mind that if the transform hasn’t been created yet, the default behavior of getUrl() will be to return a temporary URL that actually triggers the transform generation process, and responds with a redirect pointing to the new image once it has actually been created. But in this case you’d probably prefer for the transform to be created in the actual Element API request, so the actual URL can be returned right off the bat. You can do that by enabling the generateTransformsBeforePageLoad config setting at runtime.

So your transformer function would look something like this:

'transformer' => function(EntryModel $entry) {
    // Generate new image transforms right away
    craft()->config->set('generateTransformsBeforePageLoad', true);

    $blockData = [];

    foreach ($entry->myMatrixField as $block) {
        $image = $block->myAssetsField->first();

        if ($image) {
            $imageUrl = $image->getUrl('myTransform');
        } else {
            $imageUrl = null;
        }

        $blockData[] = [
            'image' => $imageUrl,
            // ...
        ];
    }

    return [
        'blocks' => $blockData,
        // ...
    ];
},


Search return wrong result with special character like æ ø å in Craft 3

Not possible natively.  Craft runs each search keyword through a "normalization" process before saving in its search index and part of that is converting characters like å to their ASCII counterparts a.  You can see the whole process here:

https://github.com/craftcms/cms/blob/develop/src/helpers/Search.php#L41

If this were solely in the context of the searching on the front-end of the site, you could use/write a plugin that integrated with a 3rd party search service like Algolia that offered more flexible options, but that wouldn't affect Control Panel searching until this was implemented: https://github.com/craftcms/cms/issues/833


Many versions of the same structure of entries?

I don't know about searching by version ID natively — I don't think Craft has that capability out-of-the-box... but I can envision setting up such a user guide using a Matrix, where each Matrix block represents a revision of content: Each block would have a field denoting which version the content was written for, along with the content itself. By default, you'd display each entry's most recent content by sorting the blocks by version-update number, and selecting the single most recent block from the sorted set. However, you could also display the docs for a 'legacy' version by filtering out blocks where the version-update number is greater than the version of interest.


Is it possible to stop Craft from logging so much?

As someone who theoretically might inherit your site one day... and also as future-you trying to diagnose a problem... please don't try to limit what Craft logs. If you want a quicker way to look for critical problems, check out the Yii2 Debug Toolbar as discussed here Profiling your Website with Craft CMS 3’s Debug Toolbar
You can use it to very quickly and easily see only errors, or only warnings, and so on. And then if the additional data that Craft logs is needed to help you diagnose a problem, it'll still be there.
To learn how to parse the Craft CMS log files quickly, check out the Zen and the Art of Craft CMS Log File Reading
If you do end up wanting to make your own logger, check out the Creating a Custom Logger for Craft CMS article
I echo Brad's comments, though, unless for some reason devMode is on, it shouldn't be logging every query, except for performance profiling.


Craft install via composer: install to public_html?

You can just rename web/ to public_html/, or move all the files inside web/ into public_html/. (Don’t forget to move the .htaccess and .env files, if the latter.)

As long as the location of the public_html/ folder is in the same place as the web/ folder was, you don’t need to change anything else.

my-project.test/
├── config/
├── ...
└── public_html/
    ├── index.php
    └── ...

If you need to change the location to something like this:

my-project.test/
├── craft/
│   ├── config/
│   └── ...
└── public_html/
    ├── index.php
    └── ...

Then just make sure that your CRAFT_BASE_PATH constant points to the right base path (craft/).

// old:
define('CRAFT_BASE_PATH', dirname(__DIR__));

// new:
define('CRAFT_BASE_PATH', dirname(__DIR__) . '/craft');


If I am reading you right you are wanting to update the shipping address on the order rather than create a new one.

You should be able to do that right now:

{% set cart = craft.commerce.carts.cart %}

{% set flashNotice = craft.app.session.getFlash('notice') %}

{% if flashNotice %}

            {{ flashNotice }}

{% endif %}

{% set flashError = craft.app.session.getFlash('error') %}

{% if flashError %}

    {{ flashError }}

{% endif %}

//meat and potatoes:

{{ cart.number }}

Shipping Address ID: {{ cart.shippingAddressId }}

<form method="post">
  <input type="hidden" name="action" value="commerce/cart/update-cart"/>
  <input type="hidden" name="cartUpdatedNotice" value="The address was updated.">
  {{ redirectInput('shop/address') }}
  {{ csrfInput() }}

  {% if cart.shippingAddress.id %}
  <input type="hidden" name="shippingAddress[id]" value="{{cart.shippingAddress.id}}"/>
  {% endif %}

  First Name:
  <input name="shippingAddress[firstName]" value="{{cart.shippingAddress.firstName ?? ''}}"/>

  <button type="submit">Update</button>
</form>

As demonstrated above, using an input with name="shippingAddress[id]" with the address ID set as the value will update the address with that ID on the commerce/cart/update-cart controller action just fine.

You would only use name="shippingAddressId" if you wanted to let the user select an existing one.


SQL Error - cannot add foreign key constraints

Based on that description, my guess is you're running into #2 here (https://stackoverflow.com/a/16969176/684) and you've got some inconsistent data in one of the three foreign key constraints that the SQL is trying to add.


How can I retrieve number of times an entry has been updated since postDate

Update: This came up in another question and I think that I may have found a simple way to do this without the use of a plugin.

{% set versions = craft.entryRevisions.getVersionsByEntryId(entry.id, entry.locale) %}
{{ versions|length }}


Is this Garnish message bad? "Element was added to more than one selector"

That message comes from from Garnish.Select, when the same DOM element is associated with two separate Garnish.Select instances. The JS will log that message right before destroying the first Garnish.Select instance.

It’s not necessarily a bad thing, but could be an indication of something in your JS that could be improved. (Craft’s own JS causes several of those messages, so don’t worry too much about it if everything seems to be working correctly.)


Let a client log in to the site when the system is off

Turns out there was a bug in Craft that prevented a scenario like the one you're trying to achieve from happening.

It has been fixed for the next (post 2.4.2702) release, though!


The 3rd parameter for the hash cost you can control via the blowfishHashCost config setting.

The 2nd parameter (for the algorithm) is a bit more difficult because it's not exposed via a config setting. I assume you want to use PASSWORD_ARGON2I since that and PASSWORD_BCRYPT
 (the default) are the only two options: https://secure.php.net/manual/en/function.password-hash.php

You'd need to create a custom Application Config component that overrode Craft's security component with your own Security class.  Your own class could extend Craft's an overwrite just the hashPassword method, or any others that you might need to.


How to limit Expanded Search (plugin) query results for pagination?

This was solved in my latest release: https://github.com/mustasj/expanded-search/releases

So if you want to use it with pagination, you can now add limit and offset to the settings param.

So in your case the top of your template would look something like this:

{% set limit = 10 %}
{% set entries = craft.entries()
    .search(searchQuery)
    .orderBy('score')
    .limit(limit) %}

{# Paginate the entries #}
{% paginate entries as pageInfo, pageEntries %}
{% set expandedResults = craft.expandedSearch.search(searchQuery, {
    length: 155,
    offset: (pageInfo.currentPage - 1) * limit,
    limit: limit
}) %}


How to save multiple related entries on the frontend with 1 checkbox?

You can't solve that with one input alone but you can make use of hidden fields (like craft does)
Your solution would be 1 visible dummy checkbox and multiple hidden "real" inputs.. So your visible dummy checkbox triggers a javascript event, that sets the values of your hidden.
Here is the syntax

<input type="checkbox" id="user-type-select-{{ userType|kebab }}" />

You have to add a javascript/jquery onchange event that sets the values of your hidden fields

<input type="hidden" id="someId1" name="fields[hasUserTypes][]" value="someIntegerValue1" />
<input type="hidden" id="someId2" name="fields[hasUserTypes][]" value="someIntegerValue2" />
<input type="hidden" id="someId3" name="fields[hasUserTypes][]" value="someIntegerValue3" />

in your php part your $_POST variable would be looking like

array(
    ....
    'fields' => array(
        'hasUserTypes' => array(
            someIntegerValue1, someIntegerValue2, someIntegerValue3
        ),
    ),
    ....
);

If you have (let us say) 3 visible checkboxes and each of it contains 2-3 relation presets you would like to store you have to change the values of your 2-3 hidden fields depending on what the user has selected. If you right click on craft cp pages and inspect the code you'll see craft does exactly the same, for every relation you select one <input type="hidden"> is created with the value of the id from the related entry


I migrated a Blogger site by writing a Craft plugin to parse Blogger's XML and save images, posts, and categories into the Craft setup established with the client. The challenge with Craft is that last part: you're the one deciding how things will work, the CMS doesn't come with opinions about how your blog posts will be constructed or organized.

You can use the Feed Me or Sprout Import plugins to migrate your Blogger data, but you'll still need to set up your blog in Craft and decide how to map the Blogger data to your Craft install.

Comments are another animal. It may be easiest to move them to Disqus. I've not used this comment plugin, but expect it would be solid.