valet share, ngrok giving 404, CORS errors I have a Craft instance running via Valet, per the instructions here.

Running the project via valet link works great, and valet share works, except when I try to access the admin side. I'm using valet share to try to access the site over a local network for a demo.

In Chrome from http://ad3f5068.ngrok.io/admin/login when I try to log in, I get:

OPTIONS http://craftycoffee.test:60/index.php?p=admin/actions/users/login 404 (Not Found)
Access to XMLHttpRequest at 'http://craftycoffee.test:60/index.php?p=admin/actions/users/login' from origin 'http://ad3f5068.ngrok.io' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

If I use HTTPS, I get net::ERR_SSL_PROTOCOL_ERROR across a bunch of requests.

What am I missing to get this to share over a local host?

I'm not 100% sure this is the answer to your issue; but this might be the solution:

Helge has written an article here about using ngrok with Craft CMS (which I'd recommend looking over if you haven't already). In particular, he mentions he has the following lines in his Craft config particularly for logging into the CP over ngrok:

// Logging in to the CP will fail unless you turn off CSRF protection.
'enableCsrfProtection' => false,

Try that config option and see if that fixes the issue for you...


How do I get past this MySQL error installing Craft 3 using CLI I am using https://box.scotch.io/ (vagrant).

I'm trying to install Craft 3 with the cli, but can't get past these errors:

Connection refused
No such file or directory

One or the other error shows up depending on what I use for the host name.

I have tried the answer here.
I can connect fine with Sequel Pro using the same credentials.

(Note: I did intentionally change the db name and password from the defaults that came with Scotchbox, and have successfully connected with those new details using Sequel Pro).

See log:

Which database driver are you using? [mysql,pgsql,?]: mysql
Database server name or IP address: [192.168.33.10]
Database port: [3306]
Database username: [root]
Database password:
Database name: [craft]
Database table prefix:
Testing database credentials... failed: SQLSTATE[HY000] [2002] Connection refused
Which database driver are you using? [mysql,pgsql,?]: mysql
Database server name or IP address: [192.168.33.10] localhost
Database port: [3306]
Database username: [root]
Database password:
Database name: [craft]
Database table prefix:
Testing database credentials... failed: SQLSTATE[HY000] [2002] No such file or directory
Which database driver are you using? [mysql,pgsql,?]: mysql
Database server name or IP address: [localhost] 127.0.0.1
Database port: [3306]
Database username: [root]
Database password:
Database name: [craft]
Database table prefix:
Testing database credentials... failed: SQLSTATE[HY000] [2002] Connection refused

This is all very specific to the box you're using, and how it's configured. I realize Scotch Box is a historically popular setup; you might also consider Homestead as it is geared specifically for PHP development.

Anyway, according to the Scotch Box docs the setup should be:

Database Host: localhost
Database User: root
Database Password: root

Which I assume you're doing in the second example? You are also running all of this from inside of the box, yes?


Using Composer to Manage Site-Level Dependencies I would like to use Composer to manage dependencies for my site, like Twitter's Bootstrap.

Is there a recommended way to integrate Composer with Craft to support managing this type of Global dependency (as opposed to managing dependencies for an individual plugin)?

Or should I make a plugin that somehow sets up Bootstrap as the theme for my site?

I think what you really want is something like Bower:

http://bower.io

It has Bootstrap in its manifest, amongst many others.


Display an entry page if entry is disabled I am trying to view an entry, even if it disabled on the front end but having no luck.

On the _entry.html (which works perfectly for entries that are live), I have tried the following.  Am I missing something?

{% set entry = craft.entries.slug(entry.slug).status(null).first %}

Thanks

Out of the box, Craft won't even load your _entry.html file for a disabled entry – it'll just throw a 404.

To work around that, you can create a dynamic route which matches the entry type URL format 1:1, and point that route to the same template (i.e. _entry.html).

For instance, if your entry type's URL format is news/{postDate.year}/{slug}, you'd create a dynamic route using the "year" and "slug" tokens (i.e. news/(year)/(slug)). Then, Craft will automatically match your dynamic route whenever an entry URL doesn't (e.g. when the entry is disabled).

You're not home free yet, though – as you're probably aware, Craft automatically populates a template with an entry variable whenever the current URL request matches an entry type's URL format, and an enabled entry is found at that URL. This won't be the case for any entries matched by your dynamic route, so put this at the top of your template (replacing the line in your question!):

{% set entry = entry ?? slug ? craft.entries.section('yourSectionHandle').slug(slug).status(null).first() %}
{% if not entry %}
    {% exit 404 %}
{% endif %}

What the above does, is to test for the entry variable Craft would set if the entry was enabled. If that evaluates to false, then it checks to see if there's a slug variable set – which there will be if the URL was matched by the dynamic route. If there is a slug, it'll then attempt to pull the entry using craft.entries, similar to your initial code. Finally, if an entry is not found, it'll throw a 404 error, as it should.

In your template, you can easily test for the entry's status:

{% if not entry.enabled %}

Danger danger! I am disabled!

{% endif %}


content and fields won't show up on new single I just installed Craft, linked it to my database (localhost) and then created a new single "about" page. But when I go to edit the single, there are no fields. I haven't changed anything else! When I go to the slug it shows the right template, but there's no content to pull in, since I can't add it in with the dashboard. I've enabled Dev Mode and there are no error logging. Any ideas?

I fixed it... I hadn't assigned a field to the section.


How to check how many characters there are in my string? Lets say I have a simple string:

{% set string = "Simple String" %}

How to get number of characters of my string?

Twig has a length filter that can help you with that:

{% set stringLength = "Simple String" | length %}

Note that this also works on arrays to give you the number of items in the array.


Display Backend User Entries on Front end I have the user submitting to a function that adds entries to a field called completed. It basically adds entries to each user showing the admin who has completed what.

I'm trying to figure out how to display a message on the front end that states if the user has completed the article. I need the message to stay on the front end for each entry that's been completed.

Assuming completed is an Entries field, and you want to test if a particular entry has been added to the currently logged in user's completed field, something like this'd work:

{% set isEntryCompleted = currentUser and entry.id in currentUser.completed.ids() %}

{% if isEntryCompleted %}
    ...
{% endif %}

The idea here is to first check if currentUser is set (it'll be null if the current user isn't logged in), and then pull an array of all selected entries' IDs with currentUser.completed.ids(). Finally you can use the in operator to check if a particular entry's ID is in that array.


Retrieving an entry based on the request URI in a plugin controller I'm working a plugin and part of the task is to grab the entry based on the current URI using craft()->request->getRequestUri().

Is there a way to grab the entry based on the URI from the request?

You can grab the current entry using the $uri = craft()->request->getRequestUri() which will return the URI in a format like so:

/path/to/uri

To grab the entry, its easiest to grab the element first, based on the URI, using craft()->elements->getElementByUri($uri). However, this will not work because of the beginning slash that is returned by getRequestUri. So you must remove the slash using ltrim like so:

$uri = ltrim(craft()->request->getRequestUri(), '/')

Once you have the URI, minus the beginning slash (path/to/uri), you can use $element = craft()->elements->getElementByUri($uri) to return the element and then grab the entry using $entry = craft()->entries->getEntryById($element->id).

If you were going to need this often, you can place it in a helper method on the controller.

private function getEntryByRequestUri()
{
    // remove the first trailing slash
    $uri = ltrim(craft()->request->getRequestUri(), '/');
    $element = craft()->elements->getElementByUri($uri);
    $entry = craft()->entries->getEntryById($element->id);
    if ($entry == null) {
        // log something and do something
    }
    return $entry;
}


Using a custom Commerce 2 Adjuster in a Craft Plugin I wrote a little commerce 2 price adjuster that works fine if i place it in
/vendor/craftcms/commerce/src/adjusters/FriendsDiscountAdjuster.php and register it manually in /vendor/craftcms/commerce/src/services/OrderAdjustments.php

However, i wanted to port it to a plugin, but i do fail registering the adjuster to commerce.

I placed the adjuster in my vendor/pluginName/src/adjusters/ folder
and added it to my plugin.

It fails with:
Cannot declare class craft\commerce\adjusters\FriendsDiscountAdjuster, because the name is already in use

this is my main plugin file Friendsdiscount.php:

<?php
namespace hendrikeng\friendsdiscount;

use Craft;
use craft\base\Plugin;
use craft\services\Plugins;
use craft\events\PluginEvent;
use craft\commerce\services\OrderAdjustments;
use craft\events\RegisterComponentTypesEvent;
use hendrikeng\friendsdiscount\adjusters\FriendsDiscountAdjuster;

use yii\base\Event;

class Friendsdiscount extends Plugin
{
    public static $plugin;

    public $schemaVersion = '1.0.0';

    public function init()
    {
        parent::init();
        self::$plugin = $this;

        Event::on(
            OrderAdjustments::class,
            OrderAdjustments::EVENT_REGISTER_ORDER_ADJUSTERS,
            function(RegisterComponentTypesEvent $event) {
                $event->types[] = FriendsDiscountAdjuster::class;
            }
        );
    }
}

the src/adjusters/FriendDiscountAdjuster.php:

<?php

namespace craft\commerce\adjusters;

use Craft;
use craft\commerce\base\AdjusterInterface;
use craft\commerce\elements\Order;
use craft\commerce\models\OrderAdjustment;
use craft\commerce\Plugin;

class FriendsDiscountAdjuster implements AdjusterInterface
{
  // ...Adjust something
}

the adjuster had the wrong namespace, changing it to:

namespace hendrikeng\friendsdiscount\adjusters

fixed the issue


Cannot select subcategory field in entity I have a Structure section fruit with a single entry type fruit.

I also have a Category fruitType with 2 levels:

Citrus

Orange
Lemon
Lime

Melons

Watermelon
Honeydew

The entry type fruit has a Category field for fruitType.

If I select a level 2 category for the fruitType field, say Orange:

Craft CMS dismisses the category selection pop-up and the parent category is shown instead, in this case Citrus.

From the browser's network inspector, I noticed that a POST request to /admin/actions/elements/getCategoriesInputHtml with the following form data:

categoryIds[]:893
locale:en_us
id:fields-fruitCategory
name:fields[fruitCategory]
limit:1
selectionLabel:Category

However, the response from the server is:

{"html":"<input type=\"hidden\" name=\"fields[fruitCategory]\" value=\"\">\n\n
\n\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\t\t

<input type=\"hidden\" name=\"fields[fruitCategory][]\" value=\"887\"><\/a>
<\/span>Citrus<\/span><\/div><\/div><\/div>\n\n\t\t\t\t\t\t\t<\/li>\n\t\t\t<\/ul>\n\n\t
Category<\/div>\n<\/div>\n\n"}

Based on the response and what's rendered in the interface, Citrus is shown and not Orange, despite Orange being selected.

Unlike structured entries, when you relate a category to another element, its ancestors are also included in the relation. Due to the way Craft looks up these ancestors when relating the selected categories, to enforce this behaviour, the ancestors are added to the relation before the one you selected, and it looks like you're limiting that Categories field to 1, so only the parent is being added.

Try setting the limit on that Categories field to 2.


How to save a new entry with custom fields - Craft 3 I'm trying to create a new Entry via PHP, with custom fields (Craft 3). I can save it, however my custom fields don't appear. I've tried using setFieldValue, as well as $entry->excerpt = 'Lorem...';, however neither work.

My code is below, using craft\elements\Entry:

$entry = new Entry();
$entry->sectionId = 4;
$entry->typeId = 4;
$entry->authorId = 1;
$id = uniqid('product_');
$entry->title = $id;
$entry->slug = $id;

$entry->setFieldValue('excerpt', 'Lorem...');

if(Craft::$app->elements->saveElement($entry)) {
    return $entry;
} else {
    throw new \Exception("Couldn't save new bespoke product: " . print_r($entry->getErrors(), true));
}

It turns out the data wasn't being saved as I hadn't set a fieldLayoutId value.

Now that I've figured this out, I've written a helper method to make saving any entry type much easier:

public static function saveNewEntry(string $handle, array $fields) {

    $entryType = EntryType::find()->where(['handle' => $handle])->one();

    $entry = new Entry();
    $entry->sectionId = $entryType->getAttribute('sectionId');
    $entry->typeId = $entryType->getAttribute('id');
    $entry->fieldLayoutId = $entryType->getAttribute('fieldLayoutId');
    $entry->authorId = 1;

    if(isset($fields['title'])) {
        $entry->title = $fields['title'];
        unset($fields['title']);
    }

    if(isset($fields['slug'])) {
        $entry->slug = $fields['slug'];
        unset($fields['slug']);
    }

    $entry->setFieldValues($fields);

    if(Craft::$app->elements->saveElement($entry)) {
        return $entry;
    } else {
        throw new \Exception("Couldn't save new bespoke product: " . print_r($entry->getErrors(), true));
    }
}

This can be used like so:

return self::saveNewEntry('article', [
    'title' => $id,
    'slug' => $id,
    'excerpt' => $excerpt,
    'body' => $body
]);


Is it possible to override the default session notices? I couldn't find anything on here about this. Maybe I'm the only one, but for example when you log in there is a session notice with the message "Logged in.", but I want it to display something like "Good to see you" or something.

I can see the notices are set via Craft::t(), so I would assume they are translatable somehow, so can I do this through configuration files or a plugin init method or something?

If you place a PHP file in craft/translations named after a locale ID and returning an array, those values will be used instead.

craft/translations/en.php

<?php

return array(
    'Logged in.' => 'Good to see you.',
);

Craft's own CP translation files can be found in craft/app/translations.

You can read more about it here: http://buildwithcraft.com/help/static-translations


Getting error: "Matrix do not have a method or closure named..." I just playing first time with Matrix and can't figure whats wrong with this code, here's error code:

Craft\MatrixBlockModel and its behaviors do not have a method or closure named "naglowekPowitanie".

Matrix field config:

{% for block in entry.homepage %}
        {% if block.type == "powitanie" %}

{{ block.naglowekPowitanie }}

{{ block.trescPowitanie }}

        {% elseif block.type == "wstep" %}

{{ block.wstepNaglowek }}

{{ block.wstepTresc }}

{{ block.wstepPrzycisk }}

        {% endif %}
{% endfor %}

On your screenshot of the block type powitanie you see two fields: powitanieNaglowek and powitanieTresc. Yet, in your code you try to use

{{ block.naglowekPowitanie }}

The error simply says: in the block type you are using there is no field called naglowekPowitanie.

Changing that H2 to

{{ block.powitanieNaglowek }}

should do the trick.


Sending email from twig template Does anyone know of a way to send simple php mail from a twig template?

Something we can use like... {% mail 'Message', entry.userEmail %} or similar.

Would be good to not have to pre-define the content in a plugin.

You could create a simple plugin with just a Template Variable that sends the mail: https://craftcms.com/docs/plugins/variables

Not sure if I'd put this kind of logic in templates though.


Create Model relationship with just an ID rather than full Model? Is it possible to just assign the ID to the owning side of a relationship rather than querying the DB, loading the record and assigning it?

Something similar to Doctrines _getReference()

http://www.doctrine-project.org/api/orm/2.1/class-Doctrine.ORM.EntityManager.html#_getReference
https://stackoverflow.com/a/9308576/1982031

I think that's actually the way to do it, assign the id to the owning record:

$record = new Cocktails_CocktailRecord;
$record->authorId = 10;
$record->title = "Gin Tonic";
$record->save();

When getting the record from the db, the record is turned into a model, at this point, records and models are only dealing with authorId, not the whole record. Your model will then have to define a getAuthor() method that will get the author user for you:

public function getAuthor()
{
    if ($this->authorId) {
        return craft()->users->getUserById($this->authorId);
    }
}

This way your model only loads the relationship when you actually use it:

$model->getAuthor();


Use REQUEST variable as dynamic upload location How can I use a request variable used in an upload form like this?

<form method="post" accept-charset="UTF-8" enctype="multipart/form-data">
<input type="hidden" name="action" value="entries/saveEntry">
<input type="hidden" name="sectionId" value="29">
<input type="hidden" name="enabled" value="1">
<input type="file" name="fields[useruploads]">
<input type="text" name="challenge_id">
...

The idea is to use the field "challenge_id" as dynamic upload location.

Is there a way to get this?

That field accepts any valid Twig code, so something like this should work:

challenges/{{ craft.request.getPost('challenge_id') }}/

Fair warning, though... I'd also be wary of accepting untrusted front-end input like this that ends up on the file system.


Best way to implement my own statuses on my custom element type? I'm working on a plugin with its own element type, I'm trying to add custom statuses to the element type. What is the best way to proceed? I have hasStatuses set to true and getStatuses is where I would set them.. But what should the array look like thats returned?

UserElementType returns this:

/**
 * Returns all of the possible statuses that elements of this type may have.
 *
 * @return array|null
 */
public function getStatuses()
{
    return array(
        UserStatus::Active    => Craft::t('Active'),
        UserStatus::Pending   => Craft::t('Pending'),
        UserStatus::Locked    => Craft::t('Locked'),
        UserStatus::Suspended => Craft::t('Suspended'),
        UserStatus::Archived  => Craft::t('Archived')
    );
}

All you need to return from the getStatuses() method is an associative array() where the key represents the status name and the value represents the status label, more or less.
An example might be a set of statuses for a Payment element type:
public function getStatuses()
{
    return array(
        'captured' => Craft::t('Captured'),
        'canceled' => Craft::t('Canceled'),
        'refunded' => Craft::t('Refunded'),
    );
}

Now, since it is likely that you'll be referring to and comparing against those statuses, it makes sense to give yourself a little extra insurance by creating a set of class constants instead of using plain strings.
That is exactly what Craft has done in the UserStatus class and you can achieve the same result in one of two ways.

1. Create your own class and define those constants
// plugin/enums/PluginPaymentStatus.php
namespace Craft;

class PluginPaymentStatus
{
    const CAPTURED = 'captured';
    const CANCELED = 'canceled';
    const REFUNDED = 'refunded';
}

// plugin/elementtypes/PluginElementType.php
public function getStatuses()
{
    return array(
        PluginPaymentStatus::CAPTURED => Craft::t('Captured'),
        PluginPaymentStatus::CANCELED => Craft::t('Canceled'),
        PluginPaymentStatus::REFUNDED => Craft::t('Refunded'),
    );
}

2. Create the status constants in your element type model if you have one

Note that if you go with option 1, you will need to import|include|require your "enum".


Updating large database from Craft 2 > 3 via command line I'm migrating a large Craft + Commerce site up to Craft 3. I've completed all the initial steps and get as far as the "To complete the update, some changes must be made to your database. Finish up" message.

The first time I tried this it timed out, so I used the ./craft migrate/all to perform all the database updates. This worked well - not surprised it timed out over http given the amount it has to do!

Problem is when going back to the Admin URL I still get the database message, if I click Finish up it still times out, I guess it is trying to reapply the migration.

Is there a way to let the Craft install know I have already done this?

Thanks

Turns out the Craft needed to run another set of migrations for Commerce, so I ran the ./craft migrate/all a couple more times to fully update the database.

If anyone is doing this, it's worth backing up the DB after each set of migrations to save running them again if you run into an error.


.first() vs. .one() in craft 3 I'm confused about the new .one() argument in craft 3

If I want to grab all entries I write:

{% for entry in craft.entries.section('thing').all() %}
  {{ entry.title }}
{% endfor %}

Alls is nice and well. 20 something entries are returned.

But I want to fetch only the latest entry so instead of .all() I use .one() (which was formerly .first())

But when I write:

{% for entry in craft.entries.section('thing').one() %}
  {{ entry.title }}
{% endfor %}

It returns the error:

  Impossible to access an attribute ("title") on a string variable
  ("3").

When I write:

{% for entry in craft.entries.section('portfolioEntry').limit(1).all() %}
  {{ entry.title }}
{% endfor %}

Then it works. But that's not the right way, is it?

.all() returns a collection of elements, which you can loop through with a for loop.

.one() returns a single element, so you cannot use a for loop to access it.

In this case you should just store the entry like:

{% set entry = craft.entries.section('thing').one() %} and then access {{ entry.title }} afterwards.

(Also keep in mind that entry is automatically populated for section URLs, so you may want to use another variable name)


Is it possible to restrict assets in multi region/site specific similarly to how you can restrict entries? Is it possible to assign regions to assets similarly to the way that we restrict entries to a region for multi-region/sites?

Ideally I could specify a path for each region/site as well.

Currently Asset Volumes in Craft 3 are defined on a global basis.  If you would like to see differently, you can create a feature request and be sure to include your use-case.

Asset fields have advanced settings where you can relate Assets from a specific site or not in the Control Panel under Assets->Fields->(your Asset field)->Advanced


Whats the best way to save a new entry in my plugin? I have a channel section by the name of order. What I need is that every time a user clicks a button on the front end the data of the form is sent to my plugin which then uses the data to create a new entry of type order and saved in the back end. The data in the form only represents the content of the entry and the only other information we have is that the entry is of type channel and that it belongs to the order channel. What would be the best way to create the entry with the publishing date, title, id, etc all set appropriately? Can I use saveEntry of the entries service in some way?

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

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

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

Edit:

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

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


How can I validate a Redactor rich text field in a front-end form using the VeeValidate Vue.js plugin? Scenario

I'm using the VeeValidate Vue.js plugin to validate a Craft front-end form that contains a Redactor rich text field.

Problem

Validation of the rich text field fails because Redactor adds style="display: none;" to <textarea> elements.

Solution

Add the Redactor Sync callback function to the Vue.js instance to synchronize code/data between Redactor’s visual layer (UI) and the form’s <textarea> element.

As per the Redactor documentation:

  Visual layer contains multiple temporary tags that allow visual editing. Synchronization with textarea inserts clean code to the textarea, removing all temporary tags, styles and attributes.

Solution source: Validate Redactor WYSIWYG Textarea Field #603

Vue.js/VeeValidate Component

// in your component.
export default {
    mounted() {
        var vm = this;
        $('#redactor').redactor({
            callbacks: {
                sync: function () {
                    vm.$validator.validate('fieldName',  this.code.get());
                }
            }
        });
    }
}

Vue.js/VeeValidate CDN

<script>
    Vue.use(VeeValidate);

    new Vue({
        el: '#app',
        delimiters: ['${', '}'],

        mounted: function() {
            var vm = this;
            $('#redactor').redactor({
                callbacks: {
                    sync: function () {
                        vm.$validator.validate('fieldName',  this.code.get());
                    }
                }
            });
        }
    });
</script>


Craft WYSIWYG editor and CKEditor I have a client who requires more advanced formatting options than the current Redactor editor provides, like editing table cells, merging cells, background colors, etc.

My plan is to integrate CKEditor into Craft as a custom field type and a plugin - and basically switch out the current limited editor with CKEditor.

Has no one else needed a more advanced editor than the stock?  Am I heading down the wrong path?

From my experience, I try to strip out as much formatting options as I can from any wysiwyg editor. Otherwise you'll end up with large, purple text with a red background (or some other crazy style the client thinks looks good).

I understand the client wants to construct a table - then alter the table along with the graphics etc.

What if...

Create a matrix field, then within that have a block for the rich text area, then another block that is of type table? I'm not 100% on what capabilities that the table field type has. That should allow them to create the table and work with it.

I would then have some sort of pre-defined css that took over for them, rather than giving the client free reign on the design.


How do you pull entries with a specific category value? Help, I forgot how to do something basic.

How do I pull all the entries in posts for a specific category value (field name = countryName) within the category group called country?

And I am NOT using the template for posts or the category.

I can pull all the entries using

{% for doc in craft.entries.section('posts') %}
--OR--

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

But, I forgot how to now add a second condition to pull up only those entries with the countryName (say) "United Kingdom"?

Thank you.

Is this the best way to do it?

`{% set results = craft.entries.section(posts).search('countryName:"United Kingdom"') %}

It appears to work.


Sprout Reports plugin - How to output a Matrix field into a row I'm not clear on how I would iterate over a Matrix field to be able to include the content in the row.

Wish there was an example in the docs: https://sprout.barrelstrengthdesign.com/docs/reports/custom-twig-template-report.html#template-settings

{% for entry in entries %}

    {% do craft.sproutReports.addRow([
      entry.title,
      entry.myMatrixField
    ]) %}

{% endfor %}

I got it to work with this code:

{% for entry in entries %}

    {% set myArray = [entry.title] %}

    {% for block in entry.myMatrixField %}

        {% set myArray = myArray|merge([block.field1,block.field2,block.field3]) %}

    {% endfor %}

    {% do craft.sproutReports.addRow(myArray) %}

{% endfor %}


Is there a way to force Assets to redo transforms? Client has uploaded a number of severely badly lighted photographs for a 'staff' section of a site and these all have had a 'staffThumb' transform applied to it on the sites pages.

I corrected the lighting on the originals in Photoshop and re-uploaded those -- how do I make assets redo these transforms? Deleting the images in the _staffthumb folder doesn't do it.

Any pointers?

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

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

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


Get all entries with linked entry in entries field I have a channel called 'projects'.
This channel has two entries fields:

relatedThemes
relatedAreas

What I want to do is perform a search query which filters all projects where the relatedThemes field has an entry with a certain id.

I figured out how to search custom fields. Here's an example of a filter with a plain text field with a handle test.

{% set entries = craft.entries({
  section: 'projects'
}).search('test:testValue') %}

This returns all project entries where the test field has the testValue value, as expected.

But I can't seem to make this work with an entries field. I thought I could do something like this

{% set entries = craft.entries({
  section: 'projects'
}).search('entriesfield.id:relatedThemesID') %}

But this does not work.

Another important thing is that I can't actually use template logic, because the query is to be used in the element api (for Craft 2).

I'm not a backend dev, so I test the criteria array in templates first and then convert it to php.

So the correct criteria array for the test text field would be

'criteria' => [
  'section' => 'projects',
  'test' => 'testValue'
],

Have you read the docs about relations?

'criteria' => [
    'section' => 'projects',
    'test' => 'testValue'
    'relatedTo' => id
]

Just replace id with the ID of your element

If you want to filter a specific field you have to include it as an array

'relatedTo' => [
    'sourceElement' => id,
    'field' => 'fieldHandle'
]


Front-end Registration Form just refreshes with no error displayed and user not created I am using the registration form from the docs here - https://craftcms.com/docs/templating/user-registration-form - in the front end of my site. Unfortunately, when I click on "Register" the page just refreshes and no errors are displayed, and the user is not created.

I have checked the following:

"Allow Public Registration?" is checked in the CP.
I made sure that the Snaptcha plugin was disabled (just in case).

Any ideas on what I should look for?

Thanks!

<form method="post" action="" accept-charset="UTF-8">
<input type="hidden" name="action" value="users/saveUser">
<input type="hidden" name="redirect" value="/success/">

{% macro errorList(errors) %}
    {% if errors %}

            {% for error in errors %}

{{ error }}

            {% endfor %}

    {% endif %}
{% endmacro %}

{% from _self import errorList %}

Username
<input id="username" type="text" name="username"
    {%- if account is defined %} value="{{ account.username }}"{% endif -%}>

{% if account is defined %}
    {{ errorList(account.getErrors('username')) }}
{% endif %}

Email
<input id="email" type="text" name="email"
    {%- if account is defined %} value="{{ account.email }}"{% endif %}>

{% if account is defined %}
    {{ errorList(account.getErrors('email')) }}
{% endif %}

Password
<input id="password" type="password" name="password">

{% if account is defined %}
    {{ errorList(account.getErrors('password')) }}
{% endif %}

<input type="submit" value="Register" class="submit">
</form>

Solved the mystery. :) The issue was that even though my user fields were not required, there was a numeric 'year' field which had min and max values set, and this was throwing it off (and I had removed that field during my last round of testing to keep things simple). Removing those required min and max values allowed the form to be submitted. Thanks for the help Brad!


Event onPublishDraft not firing We are still trying to make a custom mail plugin. We have one problem left. When someone makes a draft, and later publishes it, only the onSaveEntry fires but without NewEntry. So we were trying to use the onPublishDraft instead. But we can't get it to fire. I'm using Craft CMS 2.6.3 Pro

this is what we tried so far:

craft()->on('entryRevisions.onPublishDraft', function(Event $event){}
craft()->on('entryRevisions.publishDraft', function(Event $event){}
craft()->on('publishDraft', function(Event $event){}
craft()->entryRevisions->onPublishDraft = function(Event $event) {}
craft()->entryRevisions->publishDraft = function(Event $event) {}

this is the regular on save entry we use, maybe there is another way to catch a draft that is being published;

craft()->on('entries.saveEntry', function(Event $event){
if ($event->params['isNewEntry'] && $entry->status == 'live'){    }});

Hope you guys know how to do that

UPDATE

I did do a test with the exact code Brad gave, but it still didn't do anything... This is how my test starts;

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

    craft()->on('entryRevisions.onPublishDraft', function(Event $event) {
        Craft::log("draft published", LogLevel::Info, true);
    });

    craft()->on('entries.saveEntry', function(Event $event) {
        Craft::log("Entry saved", LogLevel::Info, true);
    });
}

Only the second one gets logged when I change the status of the post, the first never.

*****************************************
2017/12/21 21:29:54 [info] [application] [Forced] Entry saved
*****************************************

Maybe you already solved your issue but I wanted to explain what I did the last time... You can make use of the craft_content table and it's implementation in Craft 2 that fetches and includes all columns no matter of the field layout.

Make use of the light switch field, if you already have one that you are not going to use in your specific entry type you can abuse that, otherwise create a new one. You don't want to include this field into your field layout, you'll only work with it in your php code. Instead of looking if your entry is a new entry you are going to check if that field is set to true or false. You can change the field however you like, it is saved correctly and populated correctly, but your clients won't be able to change it manually (so they can't resend the mail by mistake.

Below is the code I used, my requirement was to send the mail as soon as the entry was activated (they were saved as disabled from a frontend form). Since you asked in a comment how to check when an entry goes from disabled to enabled I thought it might be helpful.

craft()->on('entries.onBeforeSaveEntry', function(Event $event) {
        if(!$event->params['isNewEntry']){
            /* @var $entry EntryModel */
            $entry = $event->params['entry'];
            if($entry->section->handle === "projects"){
                $oldEntry = craft()->entries->getEntryById($entry->id);
                // check if the entry was disabled and is now enabled and if no mail was already send
                if($oldEntry->enabled === false && $entry->enabled === true && $entry->getContent()->getAttribute('mailSended') === 0){
                    $originalPath = craft()->templates->getTemplatesPath();
                    craft()->templates->setTemplatesPath(CRAFT_TEMPLATES_PATH);

                    $html = craft()->templates->render('email/type/activateProject.twig', array(
                        'entry' => $entry,
                        'userFullName'  => $entry->getContent()->getAttribute('firstName') . " " . $entry->getContent()->getAttribute('lastName')
                    ));

                    if($html){
                        craft()->rodach->sendMail($html, Craft::t('email_subject_activate_entry'), $entry->eMail);
                        $entry->getContent()->setAttribute('mailSended', 1);
                    }

                    craft()->templates->setTemplatesPath($originalPath);
                }
            }
        }
    });


How to duplicate an element type model with content? Duplicating models is easy if you do it from the edit view, where you can just omit the ID and pass it along to save().

But how would I go about doing that programmatically without having a POST array to work with?

I tried removing the ID from the model, before I pass it to save(), in the end I had two identical entries in the database, but I could only access the new one when finding records by ID.
The original or any subsequent "original" items I clone from become unavailable even though they're in the database.
My guess is that the Content model just changes its ownership to the newly created entry and that causes this to happen.

I also tried $model->copy() and removing the ID, and that held the same results.

I tried copying the $model->getContent() and removing its ID, then using $model->setContent($clonedContent). This, at least, didn't prevent me from being able to access the original entry, but the content was never copied (all of my custom field data).

So how should go about this?
Any help greatly appreciated!

I'm going to look pretty dumb if somebody drops a one-line answer down the line, but here goes: AFAIK, unfortunately, "cloning" an element (e.g. an EntryModel) isn't that simple.

For one, $model->getContent() will pull the entry's ContentModel, which basically contains all the custom fields that are stored in the craft_content table for your particular entry. Unfortunately, certain fieldtypes (e.g. Matrix, relational fields such as Assets, Categories, Entries etc) don't actually store their content in the craft_content table, so their values in the ContentModel will be null. To get to those values, you'll basically have to loop over your original entry's FieldLayout, and pull each field's actual value. You could then apply those values to your new EntryModel's setContentFromPost() method, but remember that relational fields (such as Assets and Entries) should be set as an array of IDs, not an ElementCriteriaModel (which is what you'll get back when you pull the field using $entry->$someFieldHandle or $entry->getFieldValue('someFieldHandle').

If the entry you want to clone has Matrix fields, that's another can of worms. Matrix blocks are actually elements in themselves, and you'll basically need to follow the same pattern as with cloning the entry itself, in order to properly "clone" the blocks.

Unfortunately, I don't have a full, working example typed out, but here's some non-tested boilerplate code to get you started (I conveniently skipped the Matrix part, but there's a link at the bottom which may be helpful):

$newModel = $model->copy();
$newModel->id = null;

// Loop through the original model's custom field values, and set them to the new model; account for relational fields
$customFieldValues = [];
foreach ($model->getFieldLayout()->getFields() as $fieldLayoutField) {
    $field = $fieldLayoutField->getField();
    $fieldType = $field->type;
    $fieldHandle = $field->handle;
    $fieldValue = null;
    switch ($fieldType) {
        case 'Assets': case 'Entries': case 'Categories': case 'Tags': case 'Users':
            $fieldValue = $model->$fieldHandle->ids();
            break;
        case 'Matrix':
            // Whoa, Nelly
            break;
        default:
            $fieldValue = $model->$fieldHandle;
    }
    if ($fieldValue) {
        $customFieldValues[$fieldHandle] = $fieldValue;
    }
}
$newModel->setContentFromPost($customFieldValues);

// Save the new entry
$success = craft()->entries->saveEntry($newModel);

Note that if you need this to work for all element types, you may get away with calling craft()->elements->saveElement($newModel) at the end, instead of the EntriesService::saveEntry method. Otherwise, you'll need to check the $newModel->elementType property, and call the appropriate service's method for saving the element.

Finally, here are some other SE threads that may be of interest:

Getting all content, including Matrix fields from an EntryModel
How to get all (prepped) field values from an entry, indexed by field handle
Duplicating Matrix fields with content from another locale


Internal Server Error Regarding ElementHelper.php.bak I am getting the following error on my local machine when updating Craft 2.6.

  /craft/app/helpers/ElementHelper.php.bak: failed to open stream: Permission denied

I don't even see that file in the directory.

Any ideas?

At what point of the update process are you getting that error?

During an auto-update, Craft creates a .bak of every file that it's about to update before doing the file swap.  The last step of the update process (the "Cleaning up..." stage), goes through and deletes all of the .bak files that were created.

I'd also make sure that the craft/app folder is recursively writable by PHP as that's required for auto-updating to work correctly.


Access site via local dev IP address => certain image path (xxx.dev) isn't replaced with IP address I'm accessing my site through a local IP address (192.168.1.128:3000 that mirrors xxx.dev)

In my general.php I have these settings which work fine when accessed through IP =>

I then request for 2 image transforms (one non-retina, the other retina):

But when I check the rendered source code in the browser, I notice that only my retina (big format) doesn't have the IP address in it's path, how is this possible?

This isn't that big of an issue on my desktop because it will always find the xxx.dev, but when I try to test the site on my iPhone - through the IP address - it doesn't render the retina image because it can't find the xxx.dev

Any ideas on this one? Thanks in advance!

This issue suddenly fixed itself without any changes that I'm aware of... Thanks anyway!


Force Field Limitation in Drafts - Front End Form I'm not sure if this is a two part question yet. I need to enforce field limitations (specifically, character limits for plain text fields) when working with drafts. In the CP, I discovered that drafts ignore all limitations related to character length and only throw errors when attempting to publish the draft.

I'm assuming that enforcing the draft field limitations in the CP will also apply to front end entries that are saved as drafts as well. If not, this is what I'm doing:

I have a front end form for user created entries. Everything has been working correctly with the exception of field limitations (users submit draft revisions until published by an admin).

Any idea how to force field limitations for a draft?

Custom field validation won't run for disabled entries or for drafts, regardless of whether it's a front-end request or a CP request.

There is an Always Validate plugin that changes that behavior for disabled entries/categories.  It could pretty easily be modified to do that for drafts as well.


Blank entry page in CP I set a matrix block field for a blog's channel and when I try to create a new entry, It is empty

But if I change the matrix field with another field, it works.

Anyone have an idea? Thanks in advance :)

Had the same issue running OS X running native Apache.  It could be PHP config issue.  Increase the max_nesting_level to something like 200.  Add/edit the following line in your php.ini:

xdebug.max_nesting_level = 200


Can I get entries related to one category from a specific site? If I can get entries in a category like this:

{% set entries = craft.entries.section('sectionSlug').relatedTo('categorySlug').all() %}

And a entries from another site like this:

{% set entries = craft.entries.section('sectionSlug').site('siteSlug').all() %}

Is there a way to combine them and get entries from another site in a certain category. The following isn't working for me:

{% set entries = craft.entries.section('sectionSlug').relatedTo('categorySlug').site('siteSlug').all() %}

Relations don't work with a slug. You'll need to insert an ElementQuery an Element or the ID of an Element

{% set entries = craft.entries
    .section('sectionHandle')
    .relatedTo(category)
    .site('siteHandle')
    .all()
%}

However this will only work in certain cases where all category ids are the same for both sites. You'll need to to fetch the category from the other site at first if these are different


Craft Neo – childs Output I have a question. How can I output the Childs from a Neo (Neo Plugin) Block?

With this code, i get the output for all level 1 blocks but i don't get a output for the deeper levels.

And how can I handle different child templates for the Output?

My idea is to have a switch with different case for the level 2 output. Because i've different child block options.

{% for block in entry.MatrixNeo.level(1) %}
    {% switch block.type.handle %}

        {% case 'title' %}

{{ block.mainTitle }}

        {% case 'boxes' %}

{{ block.mainTitle }}

            {% for item in block.children %}
                {% switch block.type.handle %}

                    {% case 'box' %}

{{ block.mainTitle }}

                        {% case 'image' %}

{{ block.mainTitle }}

                {% endswitch %}
            {% endfor %}

    {% endswitch %}
{% endfor %}

Can somebody help me out, please?

=====================

UPDATE

Now my code works fine but i've a new questione:

How can i output a real Matix-Field in a child element (level 2 in Neo).

My Code:

{% nav block in entry.myField.level(1) %}
    {% switch block.type.handle %}
        {% case 'title' %}
            <hgroup>

{{ block.mainTitle }}

{{ block.subTitle }}

            </hgroup>

        {% case 'intro' %}

                {% for item in block.children %}
                    {% include "_includes/elements/" ~ item.type %}
                {% endfor %}

    {% endswitch %}
{% endnav %}

The child Code:

{{ item.mainTitle }}

    {% for button in block.myButton %}
        {% switch button.type %}
            {% case 'buttonIntern' %}
                {{ button.linkText }}

            {% case 'buttonExtern' %}
                {{ button.linkExtern }}

        {% endswitch %}
    {% endfor %}

Your above code is not working because you are using "block" instead of "item" in your children. So...

{% for item in block.children %}
    {% switch item.type.handle %}

You don't necessarily need to do a switch here, you could do a series of includes and make their file names match your block type... so "_includes/neo/box.twig" and "_includes/neo/image.twig"

In the example below I am replacing "item" with "child" to explain it better.

{% for block in entry.MatrixNeo.level(1) %}
      <h2>{{ block.mainTitle }}</h2>
      {% for child in block.children %}
           {% include "_includes/neo/" ~ child.type %}
      {% endfor %}
    {% endfor %}


What is the intended use of categories? Just figuring out the craft interface and finding all sorts of useful features. Just can't figure out what the purpose of "categories" is in the settings.

Would be much appreciated if anyone could please tell me how this function is intended to be used and set-up?

Thanks!!

The Categories Settings let you set up Category Groups, define some behaviors for your Category Groups (for example, if you want them to have URLs and the pattern of those URLs), and assign Custom Fields to those Category Groups (which would allow all categories in that group to have custom fields just like all Entries have the same custom fields in a section).


User-determined price for a product variant? Is there a way in Craft Commerce 2 to have a user-input price as a product variant? In my case, I'm offering several pre-set amounts for a donation product (each is a variant), but I also want to offer a "custom amount" option.

Is there a native way to do this? Or a way I can accomplish this with a plugin action?

Here's how you could accomplish this.

1) Create a product variant called 'custom amount' with a zero price.

2) Get the ID of that variant

3) When submitting/adding/updating the item to the cart make sure to post an 'amount' line item option. For docs on that see: https://docs.craftcms.com/commerce/v2/adding-to-and-updating-the-cart.html#line-item-options-and-notes

3) Create a plugin/module that attaches this listener:

Event::on(LineItems::class, LineItems::EVENT_POPULATE_LINE_ITEM, function(LineItemEvent $event) {
    $lineItem = $event->lineItem;
    $purchasable = $lineItem->getPurchasable();
    if($purchasable && $purchasable->id = ID_OF_VARIANT_HERE)
    {
        $amount = $lineItem->options['amount'] ?? 0;
        if($amount)
        {
            $lineItem->price = $amount;
            $lineItem->salePrice = $amount;
        }
    }
});

This will set the price to the price of the line item option 'amount' that is submitted.


Send sprout email programmatically I'm trying to send a sprout email from my plugin like so:

use barrelstrength\sproutbaseemail\mailers\DefaultMailer;
use barrelstrength\sproutbaseemail\SproutBaseEmail;
use barrelstrength\sproutbaseemail\elements\NotificationEmail;

use Craft;
use craft\base\Plugin;

use yii\base\Event;

class MyPlugin extends Plugin
{
    public function init()
    {
        $mailer = SproutBaseEmail::$app->mailers->getMailerByName(DefaultMailer::class);

        // How do I let it know what email to send?
        $mailer->sendNotificationEmail();
    }
}

It says that sendNotificationEmail expects an instance of NotificationEmail but I can't seem to find any documentation on how to reference the notification email created on the dashboard so it can be sent.

The only similar question I found was this but it's for Craft2.

At the most simple level, if you have a Notification Email configured with the event 'None', you can do the following:

$mailer = SproutBaseEmail::$app->mailers->getMailerByName(DefaultMailer::class);
$notificationEmail = Craft::$app->elements->getElementById(123);
$mailer->sendNotificationEmail($notificationEmail);

If you have an Event selected other than 'None' or want to use any Personalization in your email, you may need to also configure the notification to have the Event Object.

Let's say, your Notification Email body needs to use the person's name:

Hello {firstName}

OR

Hello {{ object.firstName }}

In that case, you can use the setEventObject method to set any variables you need available in your Email Template:

$mailer = SproutBaseEmail::$app->mailers->getMailerByName(DefaultMailer::class);
$notificationEmail = Craft::$app->elements->getElementById(123);
$notificationEmail->setEventObject([
  'firstName' => 'Mr. Smithyyy'
]);
$mailer->sendNotificationEmail($notificationEmail);


Inserting multiple records in a plugin I'm building a plugin and have a form in the plugin's CP page that allows admins to save access codes. The form is a simple textarea where each line is a separate access code.

I'm wondering what the best practice is in terms of inserting these records into the database?

Controller:

// This returns an array of codes to be inserted
$codes = explode("\r\n", craft()->request->getPost('codes'));

foreach($codes as $code) {
    $codeModel = new Portal_CodeModel();
    $codeModel->code = $code;
    $codeModels[] = $codeModel;
}

$success = craft()->portal_code->addCodes($codeModels);

Service:

public function addCodes($codes) {

    foreach($codes as $code) {

      Portal_CodeRecord::model()->insert(array(
          'code'        => $code,
          'code_used'   => 0
      ));

    }

}

Record:

class Portal_CodeRecord extends BaseRecord {

    public function getTableName() {
        return 'portal_codes';
    }

    protected function defineAttributes() {
        return array(
            'code'          => AttributeType::String,
            'code_used'     => AttributeType::Bool
        );
    }
}

Go with #1.  It looks like you've already got a Portal_CodeModel created, you just need to populate them from the controller, perform validation (if any), then pass the array of Portal_CodeModel objects to your service.

You'll want to remove the Portal_CodeModel type hint from your service's addCodes signature (or change it to array) since you're passing in an array of objects, instead of a single one.

Here's an example in your controller with any code validation:

$codeModels = array();
$codes = explode("\r\n", craft()->request->getPost('codes'));

$success = craft()->portal_code->addCodes($codes);

And in your service:

public function addCodes($codes)
{

    foreach($codes as $code)
    {
        $existingCode = Portal_CodeRecord::model()->findByAttributes(array(
            'code' => $code,
        ));

        if ($existingCode)
        {
            $existingCode->code_used = 1;
            $existingCode->save();

            {# or whatever else you want to do when the code already exists in the database #}
        }
        else
        {
            $codeRecord = new Portal_CodeRecord();
            $codeRecord->code = $code;
            $codeRecord->code_used = 0;
            $codeRecord->save();
        }
    }

}


GraphQL mutation or query, how to target specific site? Is there a restriction on graphQL that only allows it to work on the primary site?
My system has for unknown reason switched primary (and I can't change it back due to a bug), and ever since then my graphQL mutation fails claiming there is no such entry (switching primary in my dev env fizes the problem).
I figured that the base URL of the api request controlled which site it was querying, but that doesn't seem to be the case either?
I'm using the mutation save_sectionHandle_entryTypeHandle_Entry(). The ID I send in seems to be the same across different sites, so I need some way to distinguish between them to edit the right entry it seems, or in my case, allowing the call to even find the entry...

Aha, it was merely sending in siteId as well when updating, in addition to id. If siteId is missing, it will default to primary site it seems.


Implementing search with Ajax What is the best way to implement a typeahead search in Craft. I looked at using ElementAPI to do something similar at this example but it doesn't seem to allow me to wildcard search

https://craftcms.com/docs/templating/search-form

Here's an example of the endpoints I have configured:

I have one entry with a title of "test" when I call the API doing

When I call /entries/te its returns 0 results. When I call /entries/test it returns 1 result.

<?php

namespace Craft;
return [
    'endpoints' => [

        'entries/<search:\w+>' => function($search) {
            return [
                'elementType' => 'Entry',
                'criteria' => ['title' => $search]
            ];
        }

    ]
];

If you want to enable fuzzy searching globally (across the entire Craft install - CP, front-end, ElementAPI, etc.), you can use the defaultSearchTerms config setting.

You can also just do it programmatically from the ElementAPI plugin with something like:

Suffix wildcard:

'criteria' => ['title' => $search ~ '*']

Prefix wildcard:

'criteria' => ['title' => '*' ~ $search]

Both sides:

'criteria' => ['title' => '*' ~ $search ~ '*']

Or you can use any of the other search syntaxes listed on the search docs page.


How can my plugin generate a generic modal window in the Control Panel? I'm working on a plugin, and it requires a modal to be displayed when the user interacts with a field of my Field Type. When the user finishes interacting with the modal, they would click "Done".

This is the standard modal that displays when you select Assets...

I basically want a more generic version of this modal, where I can put anything I want into the middle of it.

I would love to have something like this:

What's the best way to pull that off?

Create a div with whatever contents you want in the modal, and with a class "modal". Then create a new Garnish.Modal object with it:

var $div = $('
...
');
var myModal = new Garnish.Modal($div);


loop.last of a certain block type What are I doing wrong here?

I'm setting block types 'stripCustom' and 'stripShowroom' to 'stripBlock'

{% set stripBlock = entry.contentImage.type(['stripCustom', 'stripShowroom']) %}

Then in a loop checking if 'stripBlock' is last and the current block is last but one.

<div class="section {% if loop.last == stripBlock and loop.revindex0 == 1 %}gutter-bottom--double{% endif %}">
....
</div>

To test if the current block is the last in the loop and of a certain type, you could do something like:

{% if loop.last and block.type == "yourBlockType" %}yes{% endif %}

or shorthand

{{ loop.last and block.type == "yourBlockType" ? 'yes' : 'no' }}

In the above example replace 'no' with '' to output nothing. It's  just there if you want to output something in case of false

or even shorter

{{ loop.last and block.type == "yourBlockType" ? 'yes' }}


Display a Matrix field block entry when the block's entry exists I have a videoPost block in a Matrix field. Each videoPost has a imageField. I am trying to display the block’s image if imageField is defined. This is returning images for each block that has imageField defined when I only want to return the specific block’s image.

{% for block in entry.matrixField.type('videoPost') %}
    {% if block.imageField | length %}
        {% for asset in block.imageField %}
            <img src="{{asset.getUrl}}" alt="{{ asset.title }}" />
        {% endfor %}
    {% endif %}
{% endfor %}

Try replacing

{% for asset in block.imageField %}

{% endfor %}

with

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

If you're using Craft 3, replace .first() with .one()


How give parent in navigation-structure the active tag So I have a two-level Navigation in a structure. What I want is to give the parent of my entry (if a parent exists) the active tag.

right now I'm doing that:

{% for nav_item in navigation %}

    {{nav_item.title}}

  {% if nav_item.hasDescendants() %}

      {% for child in nav_item.getChildren() %}

            {{child.title}}

      {% endfor %}

  {% endif %}

{% endfor %}

sadly most children don't share the first segment

How a look at the isAncestorOf() method in the Docs. The given example code probably covers all you need:

{% set expanded = entry is defined and page.isAncestorOf(entry) %}
<li{% if expanded %} class="expanded"{% endif %}>

To only address the direct parent, use isParentOf() instead.


Explanation of how to link to a structure from a structure I've searched these boards and haven't been able to find the answer to my specific question.

I'm working on building my navigation, and I want to build it in a structure. It will be a multi-level navigation, which is why it makes sense for a structure. However, I've already built a separate structure for a sermon catalog that I want to keep separate from the navigation structure.

Basically, I want to be able to link to a separate structure within my navigation structure. Is this possible? Is there a better way to do this that I haven't grasped yet?

Navigation Structure Example

1.Home

2.About

Directions
Staff

3.Watch (I want this to link to my sermon structure)

4.Kids & Students

Highschoolers
Middleschoolers
K-5th

EDIT: I've tried adding in an entry type to navigation and linking to the structure, but it won't let me link to the actual structure. Just entries inside the structure. Which is not what I want. Any thoughts?

I'll assume that 'watch' is a landing page in which you want to list out the various sermons from the sermons structure. In which case you can retrieve and display those in the 'watch' template using a for...in or a nav...in loop. For example:

{% set sermons = craft.entries.section('sermons').limit(null) %}

    {% nav sermon in sermons %}

{{ sermon.title }}

        {% if children %}
            {% children %}
        {% endif %}
    {% end for %}

In your 'sermons' section settings you can then set the top-level uri to be:

watch/{slug}

And the nested uri to:

{parent.uri}/{slug}

In this way, you can set the uri's to match up nicely, with the index page as 'watch' and the sermon entries as 'watch/sermon-parent-slug/sermon-slug'


How can I access a template variable from an include that is loaded via ajax? I am making an ajax request to an entry. It is returning the entry's html - and all is working great.

I have a section called "portfolio" and I loop through each:

portfolio/index.twig

{% set projects = craft.entries.section('portfolio') %}
...
{% for project in projects %}
    ...

    ...
{% endfor %}

When the project is clicked, I am making an ajax request to an entry. It is returning the entry's html - and all is working great.

Now I would like to strip out the static html, and access the parent's entry variable.

For example, here is the html that I am returning.

portfolio/_entry.twig

My Project

            {# image will go here. #}

My Project Description

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eros dolor, efficitur lobortis eros et, dictum hendrerit nulla.

Client: My Client

What I would like to do is:

...

{{ project.title }}

I'm not sure how to do is something like this from within portfolio/_entry.twig

{% set project = ?? %}

So that I can use {{ project.title }}

Thank you for any suggestions!

Since you are only trying to access the existing entry model, you should be able to do something like this:

portfolio/_entry.twig

{% set project = entry %}
...
<h1>{{ project.title }}</h1>


Element API - Markdown in JSON I'm a little bit stuck using the Element API. I managed to get my JSON file going pretty easily which was great but I've reached a point where I want to include some formatted copy as it would be output using markdown in a .twig template, is this possible?

You can convert your Markdown text to HTML using yii\helpers\Markdown, which is what the |md Twig filter hooks into:

'transformer' => function(\craft\elements\Entry $entry) {
    return [
        'body' => \yii\helpers\Markdown::process((string)$entry->yourTextFieldHandle),
    ];
},

If you want the equivalent of |md('text', inlineOnly=true) (where only inline elements are parsed – no <p> tags), call processParagraph() instead of process().

If you want to parse the copy as GitHub Flavored Markdown, pass 'gfm' as a second argument to process():

'transformer' => function(\craft\elements\Entry $entry) {
    return [
        'body' => \yii\helpers\Markdown::process((string)$entry->yourTextFieldHandle, 'gfm'),
    ];
},


is it possible to edit an entry from the front-end when you're not logged in? I'm working on a checkout process for a takeaway restaurant where anonymous visitors can place orders using guest entries.

In this stage the order is saved with a status of "unpaid". Once a visitor saves the order he's taken to a payment provider service where he pays for his order, once the order is payed the visitor is redirected to a page where the order status would be set to "paid" in a hidden form.

In order to accomplish this the aforementioned saved guest entry would have to be edited from the front-end. Is it possible to anonymously edit an entry?

You should be able to edit that entry using craft()->entries->saveEntry($entry) with $entry->authorId set to a registered user with the necessary permissions. To get the ID of the user that created the entry, access the Guest Entries plugin settings in your plugin:

$settings = craft()->plugins->getPlugin('guestentries')->getSettings();
$authorId = $settings->defaultAuthors[$entry->section->handle];


Stop image upload if moderation fails using EVENT_BEFORE_HANDLE_FILE I have a frontend form where images can be uploaded.
I am handling the image moderation within EVENT_BEFORE_HANDLE_FILE on the Asset class. I am setting session errors for any moderation issues detected.
This is all working great, however I need a way of stopping the image uploading if errors are detected, but I want the session errors to continue to show as the page refreshes.
What is the best way to stop the image upload in this event, but for it to still set the session errors?
Thanks

From investigating, the issue could not be resolved at the time of writing this answer. Even though the EVENT_BEFORE_HANDLE_FILE on the Asset class extends the cancelable event, there was not actually a way to cancel.
To answer the question, there is currently no nice way of being able to cancel this event.
I raised a ticket to add this feature, you can follow its progress here https://github.com/craftcms/cms/issues/6875
This would allow you to use $event->isValid = false; in the scenario any tests fail and you didn't want the image to continue being handled by Craft.


A for loop within a for loop that is split Possibly a bad question title...sorry but wasn't sure how to describe it.

Basically I have a for loop that every 4 items I want to pull in a different item from another loop. This is a series of Q&A's in a staff interview, and each 4th item I want to break the side by side and pull in a full width quote.

Here is the breakdown of the code.

{% set pullQuotes =
  [
    'My biggest source of pride to date is my involvement in the Olympic Park Project: that’s part of my personal legacy.',
    'Frosts is a family environment. We’re successful from within. With our recent management acquisition of Frosts Landscapes, we’ve developed a new atmosphere, new business, and a great environment to work in. '
  ] %}

    {% for row in entry.questionsAndAnswers %}
      {#            {% set width = loop.index is divisible by(3) ? 'lg:w-full' : 'lg:w-1/2' %}#}

{{ row.question }}

          {{ row.answer }}

      {% if loop.index % 4 == 0 and not loop.last %}

        {% for entry in pullQuotes %}

              {{ svg('@icons/quote.svg', class="w-20 h-20  text-lime-500 flex-shrink-0 fill-current") }}

              {{ entry }}

        {% endfor %}
      {% endif %}
    {% endfor %}

The problem I have is that the loop of the pullQuotes is being iterated each time after every 4th item. What I want to do is pull the first item from the pull Quotes in position 4 and the second item from pullQuotes in position 8 and so on...

Both of these will be CMS managed and so the number of Q&A's and pullQuotes could vary, so it needs to be flexible.

Anyone able to help me figure this one out?

How about this; you get the pull quote index by dividing the loop index by 4 (will always return an int) and then you modulo that index against the length of your quotes array:

{% if loop.index % 4 == 0 and not loop.last %}
      {% set entry = pullQuotes[(loop.index / 4) % (pullQuotes | length) - 1] %}

          {{ svg('@icons/quote.svg', class="w-20 h-20  text-lime-500 flex-shrink-0 fill-current") }}

          {{ entry }}

{% endif %}


Craft CMS contact form plugin works locally but not in production? Locally in a MAMP environment Craft CMS/Contact Form plugin works great! But for some reason in production on a actual live server on the internet it fails to successfully send any emails.

I'm not sure if this is because of the way email is handled by Craft? In Settings > Email, I set the transport type up to Gmail instead of the default Sendmail. But still no luck.

There's a support article here you can help use to debug email deliver issues: https://craftcms.com/support/troubleshooting-email-errors#dealing-with-email-delivery-issues

The TL/DR is, use a transaction email provider like Postmark, Mailgun, etc. and make sure you've got DKIM/SPF and DMARC all setup properly as well.


Asset Upload via Plugin - S3 gets wrong Content-Type I have a plugin that creates a local JSON file and uploads it to S3 using insertFileByLocalPath. The file is created, saved, and uploaded to s3 successfully. However, S3 detects the content-type to be text/plain and not application/json. Does anyone know of a way to force the content-type when creating an asset?

    $jsonStr = json_encode($arrayToBecomeJson);

    $fileName = $myFileName . '.json';

    $tempPath = AssetsHelper::getTempFilePath('json');

    file_put_contents($tempPath, $jsonStr);

    $assetSaveSuccess = craft()->assets->insertFileByLocalPath(
        $tempPath,
        $fileName,
        $assetFolderId,
        AssetConflictResolution::Replace
    );

While Craft 3 will be smarter about this, this is not currently possible in Craft 2.

What you can do, though, is modify craft/app/helpers/IOHelper.php::getMimeType() function so that it always returns the mime type by extension instead by the content, since the core problem is that FileInfo extension cannot detect JSON by looking at the file contents. I'm a bit doubtful of any future releases for Craft 2 that affect this file, but, for posterity, probably better to write down any changes you make somewhere in case they get reverted.


Activation Email for Pending User Doesn't Work User account is "pending"
verificationCode is created in database, and erases when visiting the hyperlink.
I'm able to successfully produce an activation email using the code below:

Code:

$user = craft()->users->getUserByEmail($emailAddress);

if ($user->getStatus() != "active")
{
    craft()->users->sendActivationEmail($user);

I'm redirected to the page set for activateAccountSuccessPath in config/general.php which an account edit page.
I'm "sort of" half logged in... able to see the email address for my account filled in the edit profile form, but the CMS otherwise does not recognize me as logged in.

Any ideas?

After following the stack trace for activating a user (with the link), I discovered that activation fails at /craft/app/services/UsersService.php:822:

820:   public function verifyEmailForUser(UserModel $user)
821:   {
822:      if ($user->unverifiedEmail)
823:      {

Apparently I needed to set the unverifiedEmail property when creating "Pending" users via a plugin as opposed to only setting the 'pending' property to false.

$user = new UserModel();
$user->email = 'pendinguser@email.com;
// ... set other properties
$user->pending = false;
$user->unverifiedEmail = '';


Craft 3 not running on Ubuntu 18.04 I’ve set up a new Ubuntu 18.04 server, but can not get Craft 3 to run on it - despite it passing the Server test script with flying colours.

I know the server setup is OK as PHPmyAdmin is running on this server (though that has its own issues with PHP7.2, it does at least run).

I don’t want to use Composer as it is not the right choice for our use case; so I’ve downloaded the zip and used that. It won’t install via the browser as whenever I go to /admin/install it claims a 404 error (going to index.php?p=admin redirects to /admin/install).

If I go to the root of the site it claims an Internal Server Error. I can’t see any information in the /storage/logs files, nor in the /var/www/project/logs folder that Apache is configured to dump logs into when hitting the Internal Server Error. There are log entries - and I had issues with - permissions writing to files. Specifically to do with Yii2 file mutex and fopen.

Anyone got any pointers?

Apache is running as the default www-data user and group, the site files are owned by a user belonging to that group, and I’ve 774’d everything recursively.

When I had this problem previously, it was the permissions for the index.php that wasn't set to 644.

Another issue I had once was my database password had some characters that wasn't accepted. Instead of getting errors, I just got a blank page saying Internal Server Error. Once I changed the password to omit weird characters, it worked perfectly. Wasted a ton of hours trying to figure that out.

Good luck!


Clarification on UID creation I have a series of matrix blocks that use a ton of the same fields and was hoping I could simply duplicate them in the database and update the context and id of the fields. It'd be a LOT faster this way however i'm unsure of the UID column, how/when that is created and if i should leave it blank, or if that column existing means i'm going to have to it all manually

As aberkie pointed out, Craft does use them internally, but they should not be left blank or you'll potentially run into some issues now and you'll miss out on some upcoming features.

You can programmatically create one with StringHelper::UUID or use a site like guidgen.com to get a valid one.


How do you reset a cart under Craft Commerce 2? How do you reset or empty the cart, in Commerce 2? There is no mention of this in the documentation.

In Commerce 1, it was possible to issue a request to the commerce/cart/removeAllLineItems action to clear the cart, but this no longer works.

The commerce/cart/remove-all-line-items action (or in Craft 2 terms, commerce/cart/removeAllLineItems) was deprecated (and subsequently removed in Commerce 3), so it's up to you to build a form to explicitly delete all line items:
<form method="post">
    {{ csrfInput() }}
    {{ actionInput('commerce/cart/update-cart') }}

    {% for lineItem in craft.commerce.carts.cart.lineItems %}
        <input type="hidden" name="lineItems[{{ lineItem.id }}][remove]" value="✓">
    {% endfor %}

    <button type="submit">Empty Cart</button>
</form>

This snippet just loops over the current line items, and outputs a hidden input element, which sends the proper POST value to the update-cart action.
It's also possible to give your customer control over which line items are to be removed by changing the input to a check-box (and providing adequate labeling).


Plugin autoload classes im developing a forms plugin and i'm having some trouble getting my plugin model class autoloaded.

To make development easier i'm implementing the Yii way of rendering forms(http://www.yiiframework.com/doc/api/1.1/CActiveForm). The widget basicly takes a model and attribute name to render the form control in HTML. I'm rewriting this for Craft so i can easily hook ajax validation and template macro's to it while still being super flexible and i can easily develop more forms on the same code base later on. This is the setup (as per Craft plugin design);

plugins

forms

models

Forms_BaseModel.php
Forms_ContactModel.php

services

Forms_BaseService.php

FormsPlugin.php

The problem is my model classes aren't getting autoloaded. After snooping around in Craft\PluginsService it seems plugin subclasses are autoloaded per request if their suffix is in the autoloadClasses array found in app\etc\config\common.php on line 661. In this case the suffix is Model so it should get autoloaded.

Since the model class isn't autoloaded nor reachable in the FormsVariable->model() method using Craft::import('path/to/class'), i'm beginning to think this might be a bug or something. I checked for possible typos in the naming but these are all correct.

Does anybody have a clue on what's going on?

Got it working now, namespace issue :s. The autoloaded classes are in the Craft namespace and i didnt prepend this to the dynamicly generated class names. Time to take a break...


Receive all locales with ElementAPI plugin I use Craft to return some JSON data. The content however is available in different languages and I would like to get all those translations in a single API call.

I tried something like

'endpoints' => [
    'products.json' => [
        'elementType' => 'Entry',
        'criteria' => ['section' => 'products', 'order' => ['default' => 'lft asc']],
        'transformer' => function(EntryModel $entry) {
            $translate = [];
            foreach(array_keys($entry->getLocales()) as $locale) {
                //$entry->setLanguage($locale); Doesn't work with EntryModel
                $translate[$locale] = [
                    'title' => $entry->title,
                    'slug' => $entry->slug
                    // ...
                ];
            }
            return $translate;
        },
    ],

Unfortunately, there doesn't seem to be a method call setLanguage() like with fields.
I'm out of ideas.

Here are some other similar questions and answers to this, but the short of it is that you could probably do it with something like using QueryBuilder to query the database directly (and bypassing Craft's APIs) or grabbing all site locales and looping through and re-querying for the entries on a per locale basis.

Both of them are pretty ugly and probably not that efficient in the context of the ElementAPI plugin.


Can't upload GIF files I have the same error in here.

Craft info says i have installed the ImageMagick extension successfully  and even use ‘imageDriver’ => ‘imagick’ in config file. But still cant upload GIF files.

Issue is resolved, as @bradbell said the version for ImageMagick module and library was old and need to be update. You can check the latest relase from here: https://www.imagemagick.org/script/changelog.php

From some servers apt-get update won't really update the package. So you need yo install manually. There is a great how to article regarding this


No installer, but site is there? OK, setting up a production server (not live yet) and I am encountering a strange issue that I have not seen previously.

Issue:
Installed Craft on an Ubuntu 16.10 LAMP server. When all commands for installing were completed, I tested my site with its IP address to make sure everything worked and I got the following:

Then when I got to 192.168.5.254/public/index.php/admin/install -- which has worked on the two test servers I have built previously -- I get this:

An to make sure that I have tried another method of gaining access to the installer, I went here 192.168.5.254/admin which redirected to 192.168.5.254/admin/login, I get this:

Clearly Craft is working as these are not Apache 404's; however I never got the install screen at all. Just the homepage and login screen. Did I miss or mess something up during this specific install?

As usual, if you need additional information, let me know I will post it in here for visual use. Thank you very much for your assistance!

As André pointed out, you only need to run the installer if you need Craft to create all of the necessary tables in a blank database.

If you've dumped your database from dev/staging and imported it into production, there is no need to run the installer, because the tables are already there.

If Craft sees someone try to load the installer on a site that already has a populated database like you have, it will return a 404.


Plugin template's are not available from console commands The if statement on Line 859 of TemplatesService.php prevent the template service from loading templates from a plugin.

Is there a specific reason for this, or is it simply a case that hasn't been needed for the command line interface yet?

I would like to use the template service to render various things like report emails. Is there another way I can do this from the CLI at the moment?

is it simply a case that hasn't been needed for the command line interface yet?

Most likely this one.

Can you send your plugin over to support@buildwithcraft.com and point us to a command that will reproduce it so we can look into it?

Will update the answer here with what we find.


Incorrectly setting module template variable Getting error:

  Calling unknown method:
  craft\web\twig\variables\CraftVariable::markAsReadModule()

Trying to use a template variable that I created in my Craft 3 module, I use this module for other things that work as expected but I am running into an issue with this in the template:

{{ craft.markAsReadModule.read(entry.id) }}

In the init method for craft/modules/markasreadmodule/MarkAsReadModule.php I register the variable:

I am using:

use craft\web\twig\variables\CraftVariable;
use modules\markasreadmodule\variables\MarkAsReadModuleVariable;

Then I have this in the init:

Event::on(
    CraftVariable::class,
    CraftVariable::EVENT_INIT,
    function (Event $event) {
        /** @var CraftVariable $variable */
        $variable = $event->sender;
        $variable->set('markAsReadModule', MarkAsReadModuleVariable::class);
    }
);

In craft/modules/markasreadmodule/variables/MarkAsReadModuleVariable.php

public function read($entryId)
{
    $service = new MarkAsRead(); // initialize the service class
    $read = $service->read($entryId);
}

I suspect I am setting the naming convention where I include it in the template and/or in the init method within craft/modules/markasreadmodule/MarkAsReadModule.php

Was running into the same problem today. I was able to access the controller and the service, but none of the variables. Looks like Brad was able to fix the problem but didn't add a final solution.

I wasn't registering any variables on the init() function. Adding the last line of code registered the variable but did not load it onto every request.

    // Register our variables
    Event::on(
        CraftVariable::class,
        CraftVariable::EVENT_INIT,
        function (Event $event) {
            /** @var CraftVariable $variable */
            $variable = $event->sender;
            $variable->set('formSenderModule', FormSenderModuleVariable::class);
        }
    );

To add it onto every request, I had to add form-sender-module into my bootstrap array in app.php.

'bootstrap' => ['form-sender-module']


upgrade issue Yii Framework from version 2.0.15.1 to 2.0.16.1 I tried installing a site I developed on my work mac (high sierra), pushed to its repo, pulled it down at home on my mac (mojave)and on running composer update get this displayed in my terminal:

Seems you have upgraded Yii Framework from version 2.0.15.1 to 2.0.16.1.

and in the browser get this

PHP Warning – yii\base\ErrorException
Declaration of craft\web\twig\Environment::compileSource(Twig_Source $source) should be compatible with Twig\Environment::compileSource(Twig\Source $source)

I tried deleting the vendor folder and running composer install but get the same, however when I delete all database tables and allow craft to reinstall it's fine (albeit no content!!!) I have no idea how to resolve this, any tips appreciated!

Not sure about the Yii message, though it may be irrelevant. The Twig message refers to an issue where Twig itself was upgraded (to 2.7.2) which broke Craft. The makers of Craft were able to publish an fix within 48 hours.

Update to the latest version of Craft, this has already been fixed.


Dynamic Subfolder Paths - folder does not exist even after updating asset directories in settings I have an asset directory which is set to

{basePath}assets/images/products/

I know my basePath is right as it works on other asset sources.

My entry upload location for products is set to:

{slug}/static/studio

However I get the following error when uploading assets:

upload failed. error uploading the file: The folder "/var/www/html/assets/images/products/carambola-earrings/static/studio/" does not exist

I have tried 'updating asset indexes'. But no luck. I have also double checked that the assets/images/products/ directory exists.

I am also checked the permissions are set to '775' for '/var/www/html'

Any help greatly appreciated :)

Ok, so I have figured out why this wasn't working.
When clicking on reset asset indexes It was always popping up an alert saying that another asset was missing. I already knew this, and it was something I intended on dealing with later. So I clicked OK and as the progress indicator continued to run along with the Tick Icon, I assumed it continued to update everything else, skipping over the error.
But it turns out this isn't the case. The function halts at the error. So once I fixed this other missing asset, everything worked.
It is a little misleading having the progress animation and tick icon still work when in fact nothing is happening.
thanks for all your help. :)


Change system language I have a craft installation (that's up to date), that was installed with english as the system language. Now that Craft has quite a lot of system languages, is there a way to change to another language for the control panel?

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

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


get session data by cookies CraftSessionId Is there a service method I can use to get (any kind of) session data by giving the cookies CraftSessionId as a parameter?

if would look something like this.
craft()->userSession->getSessionBySessionId($craftSessionId)

I don't think I'd use PHP's session for this at all, but recently posted some thoughts on a similar question here https://craftcms.stackexchange.com/a/14188/57 about using custom tokens or authorization headers to perform the authorization.


Display old entry version content through twig? Is it possible to output content from previous revisions of entries in the twig templates?

I need to do a score comparison between say entry 1 and entry 1.1 to see if the value has increased then output an indicator on the front end to indicate the outcome (Up arrow or down arrow most likely) kind of like a music chart style.

Probably something very similar to what Craft does when displaying past entry revisions from a template in the control panel. :)

https://github.com/craftcms/cms/tree/master-v2/src/templates/entries/_revisions.html#L23-L36

{% if section.enableVersioning %}
    {% set versions = craft.entryRevisions.getVersionsByEntryId(entry.id, entry.locale) %}
    {% if versions %}

{{ "Recent Versions"|t }}

            {% for version in versions %}

                    {{ "Version {num}"|t({ num: version.num }) }}
                    {{ version.dateCreated.uiTimestamp() }}, {{ version.creator }}

            {% endfor %}

    {% endif %}
{% endif %}


Allowing CRAFT_TEMPLATE_PATH in index.php from .env variable It appears on Craft 3.1.8 that I can't set the CRAFT_TEMPLATE_PATH from .env without throwing a PHP notice error. This appears to be because the .env is loaded after the defines and I want to access the .ENV for my CRAFTENV_template path.

How can I set CRAFT_TEMPLATE_PATH from my .env without producing an error/warning?

If you add it after you load the dot env stuff in your public index.php file, it should work:

// Load dotenv?
if (file_exists(CRAFT_BASE_PATH.'/.env')) {
    (new Dotenv(CRAFT_BASE_PATH))->load();
}

define('CRAFT_TEMPLATE_PATH', getenv('CRAFT_TEMPLATE_PATH'));


Craft CMS login 500 (Internal Server Error) I transferred a website using Craft CMS and now when I want login to admin the console return me

jquery-2.2.1.min.js?d=1493126871:4 POST http://website.com/index.php/admin/actions/users/login 500 (Internal Server Error)

I put app to debug mode and I have very more error like to

[14:44:38.309][trace][system.CModule] Loading "cache" application component in /home/domains/website.ca/public_html/craft/app/etc/web/WebApp.php (593)

I try put RewriteBase / and ma .htaccess my site is multilang so i put this and the .htaccess of each file /en and /fr

The website is at a hosting company and a not access to ssh . The PHP version is 7 and a have activate all module

remove /craft/storage/runtime and remove all craft_session and database


How can I use a WHERE statement in my template? I am trying query against URL segments. Where I am hung up is how to pass those arguments to a related field.

For example, here is my current query:

twig

{% set profiles = craft.entries({
    section: 'profiles',
    with: ['userAccount']
}) %}

userAccount is a user field that is related back to the user.

I get all entries along with the user account information & all is well.

I would like to query against the userAcount field to only return the appropriate entries in the profile section given url segments.

For example: www.mysite.com/profiles/foo/2017

From the userAccount field:

foo is a checkbox field (name is userOptions. Options are: foo, bar, baz)

`2017 is a plain text field.

This is what I am trying to accomplish (obviously is not correct)

{% set profiles = craft.entries({
    section: 'profiles',
    with: ['userAccount'],
    where: ['userAccount[0].year', '=', craft.request.segment('3')],
    where: ['userAccount[0].userOptions', '=', craft.request.segment('2')],
   limit: null
}) %}

I am getting entries bak when I only query against the year. I haven't checked if they are correct but at least I get something. Where I'm thrown is since userOptions could be any value, how can I check that field if a selected option matches the url segment? Any user could have foo and bar selected. I think I need something like a WHERE IN or something...

Thank you for any suggestions!

You would first need to query for the users that match your criteria and than query for the profile entries which are related to one of these users.

{% set userIds = craft.users({
    year: craft.request.getSegment(3),
    userOptions: craft.request.getSegment(2),
}).ids() %}

{% set profiles = craft.entries({
    section: 'profiles',
    relatedTo: {
        targetElement: userIds,
        field: 'userAccount',
    },
    with: ['userAccount'],
}) %}


Is it possible exclude an entry type from result of craft.entries? I would like to fetch all entries apart from those of a specific type: 'chapter'. How do I achieve this with a standard call to 'craft.entries'?

{% set results = craft.entries({
  'search': query,
  'order': 'score'
}) %}

Going through Craft's docs, I found no easy or official way to do this. Fastest possible way, in my opinion:

{# get all section IDs #}
{% set sections = craft.sections.getAllSections() %}

{# get all entry types for sections #}
{% set entryTypes = [] %}
{% for section in sections %}
    {# exclude the entry type you don't want, add the others to 'entryTypes' variable
       you could, of course, replace handle by ID or whatever you like #}
    {% for entryType in section.getEntryTypes() if entryType.handle != 'handleToExclude' %}
        {% set entryTypes = entryTypes | merge([entryType]) %}
    {% endfor %}
{% endfor %}

{% set entries = craft.entries.section('inhoud').type(entryTypes) %}


How do I use the Element API to search via entry title? I can't seem to find this anywhere. Thanks.

Update:

'api/entry/search.json' => function() {
    return [
        'elementType' => 'Entry',
        'criteria' => [
            'search' => (craft()->request->getParam('search')) ? craft()->request->getParam('search') : ''
        ],
        'first' => true,
        'transformer' => function(EntryModel $entry) {
            return [
                'title' => $entry->title,
                'url' => $entry->url,
            ];
        },
    ];
},

Using the url: api/entry/search.json?search=title:test did not work.

This code works, but the title needs to be exact:

'api/entry/search.json' => function() {
    return [
        'elementType' => 'Entry',
        'criteria' => [
            'title' => craft()->request->getParam('title')
        ],
        'first' => true,
        'transformer' => function(EntryModel $entry) {
            return [
                'title' => $entry->title,
                'url' => $entry->url,
            ];
        },
    ];
},

Using this url: api/entry/search.json?title=Test%20Article, works, but not api/entry/search.json?title=Test

Following is an example of using the search feature in a GET request with parameter 'search'.

return [
    'elementType' => 'Entry',
    'criteria' => ['search' => (craft()->request->getParam('search')) ? 'title:'.craft()->request->getParam('search') : '' ],
    'paginate' => true,
    'elementsPerPage' => 10,
    'pageParam' => 'pg',
    'transformer' => new ListTransformer(),
];`

I assume you can use this instead of the custom transformer class that is being used in the above example:

'transformer' => function(EntryModel $entry) {
    return [
        'title' => $entry->title,
        'url' => $entry->url,
        'summary' => $entry->summary,
        'body' => $entry->body,
    ];
},


ImageOptimze - Will removing image Variant Ratio delete image files? We want to remove an image ratio from out variant options. Will the files with that image size automatically be removed when we do so? If not how do we ensure they are?

We are looking to remove them to increase the storage amount on our s3 instance.

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

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


Error Uploading Assets We're receiving the following error when uploading Assets:

  Upload failed for Michael-Mabry-COO-MOOYAH-executive.png. The error
  message was: “Error uploading the file: The file
  “/nfs/c12/h03/mnt/215595/domains/mooyah.com/html/craft/storage/runtime/temp/assets57c97ea812e213.88692692.png”
  does not appear to be an image.”

I assumed this was a case of the client formatting the images incorrectly, but I tried it myself and they are valid image files.

Anyone come across this before?

I had the same issue on macOS Sierra, running on with the following installed using homebrew:

Craft CMS (2.6.2989)
nginx (1.12.1)
php-fpm 7.1 (7.1.8)
php71-imagick (3.4.3)

After a number of hour of digging around I found the following.

By default (don't ask me why), the configuration file for Imagick has image format configuration commented out....Thanks for that guys.

The Fix

Uncomment file format configurations in /usr/local/etc/ImageMagick-7/magic.xml

<magicmap>
  <magic name="GIF" offset="0" target="GIF8"/>
  <magic name="JPEG" offset="0" target="\377\330\377"/>
  <magic name="PNG" offset="0" target="\211PNG\r\n\032\n"/>
  <magic name="TIFF" offset="0" target="\115\115\000\052"/>
</magicmap>

Then restart php-fpm (on macOS it was for me brew services restart php71)

Don't forget!

Once you've done the above, don't forget to run the Update Assets Indexes in Craft CP. This will generate all of the thumbnails for the images.

Hope this helps someone.


When is Craft 3 ready for commercial use We are  trying out some features of the new Craft update and are wondering how ready for use the current version is and if any of you guys are already using it outside a testing environment.

And if not, is there a clear signal of the development team on when to switch to the newer version?

Thanks in advance.

The full release is only 23 days so I would suggest that it's time to start looking: https://craftcms.com/news/craft-3-launch-faq


Formerly - Checking if e-mail already entered So, I have a form created using formerly and their template.

The form works fine, but I am trying to check for duplicate e-mails and just stop a submission when it notices there is one in the system. The following works and the console spits out true on data.alreadysubmitted but the line below does not stop the post. How should I handle this?

(I know the code needs cleanup. It will be done after functionality is met. I still need to check date of submission after finding an email duplicate to enable a 1 entry per day style form)

$("#form").on('submit', function (e) {
        console.log($("#formtest_email").val());
        $.post('?ok=1', {
            action: 'formerly/submissions/alreadySubmitted',
            formid: $("input[name=formId]").val(),
            email: $("#formtest_email").val()
        },
        function(data, status){
            console.log("already?:" + data.alreadysubmitted + "\nStatus: " + data.ok);
            if (data.alreadysubmitted == true)
            {
                 e.preventDefault();
            }
        });
});

Update: After trying to store data.alreadysubmitted outside of the function, I realize that the function executes after anything below it (outside of the whole .post method). Would it be right to assume that the function is called after the submit is complete, and hence e.preventDefault will not work?

(this is more of a jquery question than Craft, but...:))

The reason this doesn't work is because $.post works asynchronously (that's the A in AJAX). It creates a request, with a success handler (the function), then the submit handler continues execution. The success handler isn't run until the request completes, which is probably a couple of hundreds of milliseconds later.

There are various ways to solve this, but the basic idea would be to cancel the submit event straight away if the check hasn't been done, do the check, and then submit the form again if the email didn't exist, and not run the check the second time.

Here's something a bit ugly that I think'll work, but it can be done much more elegantly, I'm sure:

var emailWasChecked = false;

$("#form").on('submit', function (e) {
    if (!emailWasChecked) {
        e.preventDefault();

        $.post('?ok=1', {
                action: 'formerly/submissions/alreadySubmitted',
                formid: $("input[name=formId]").val(),
                email: $("#formtest_email").val()
            },
            function (data, status) {
                if (data.alreadysubmitted != true) {
                    emailWasChecked = true;
                    $("#form").trigger('submit');
                }
            });
    } else {
        emailWasChecked = false;
    }
});