Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't Create New Field Programmatically in Script #2999

Closed
RitterKnightCreative opened this issue Jun 15, 2018 · 4 comments
Closed

Can't Create New Field Programmatically in Script #2999

RitterKnightCreative opened this issue Jun 15, 2018 · 4 comments

Comments

@RitterKnightCreative
Copy link

RitterKnightCreative commented Jun 15, 2018

Description

Trying to add a few (plain text) fields in a basic one-off script... can't even get one to save.

<?php
use craft\base\Field;
use craft\base\FieldInterface;
use craft\fields\MissingField;
use craft\fields\PlainText;
use craft\helpers\ArrayHelper;
use craft\helpers\UrlHelper;
use craft\models\FieldGroup;
use craft\web\Controller;
use craft\services\fields;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use yii\web\ServerErrorHttpException;


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


// Load Composer's autoloader
require_once CRAFT_VENDOR_PATH.'/autoload.php';
// Load dotenv?
if (file_exists(CRAFT_BASE_PATH.'/.env')) {
    (new Dotenv\Dotenv(CRAFT_BASE_PATH))->load();
}
// Load and run Craft
define('CRAFT_ENVIRONMENT', getenv('ENVIRONMENT') ?: 'production');
$craft = require CRAFT_VENDOR_PATH.'/craftcms/cms/bootstrap/web.php';

		
     $fieldsService = Craft::$app->getFields();
       
      $field = $fieldsService->createField([
            'type' => 'craft\fields\PlainText',
            'groupId' => 1,
            'name' => 'My Test',
            'handle' => 'myrandomStringHandleGoesHere',
            'instructions' => '',
            'translationMethod' => 'none',
            'translationKeyFormat' => NULL,
            'settings' => [
                'placeholder' => 'Type here',
                'charLimit' => '',
                'multiline' => '',
                'initialRows' => '4',
                'columnType' => 'text',
            ],
        ]);

       
                           
        if (!$fieldsService->saveField($field)) {
            echo "Something went wrong...";

	    } else {
		   echo "Saved";
	    }

The field allegedly saves correctly but when I then try to access another page (say the CP), the very next thing I get is a "Setting unknown property: craft\behaviors\ContentBehavior::" and then the field handle error.

The row appears to be inserted in the fields table and fieldService isn't throwing an error but apparently something else isn't being saved.

Not sure it's my script or a Craft bug? (Basically boilerplate code from this gist.)

Stack Trace:

yii\base\UnknownPropertyException: Setting unknown property: craft\behaviors\ContentBehavior::theTestField in /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/yiisoft/yii2/base/BaseObject.php:163
Stack trace:
#0 /Volumes/ProBeast/Users/dave/Sites/Walbec/storage/runtime/compiled_classes/ContentBehavior.php(508): yii\base\BaseObject->__set('theTestField', NULL)
#1 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/base/Element.php(1589): craft\behaviors\ContentBehavior->__set('theTestField', NULL)
#2 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/base/Element.php(1568): craft\base\Element->setFieldValue('theTestField', NULL)
#3 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/elements/db/ElementQuery.php(2111): craft\base\Element->setFieldValues(Array)
#4 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/elements/db/ElementQuery.php(1085): craft\elements\db\ElementQuery->_createElement(Array)
#5 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/services/Elements.php(196): craft\elements\db\ElementQuery->one()
#6 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/services/Elements.php(239): craft\services\Elements->getElementById(318, 'craft\\elements\\...', 1)
#7 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/web/UrlManager.php(332): craft\services\Elements->getElementByUri('__home__', 1, true)
#8 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/web/UrlManager.php(301): craft\web\UrlManager->_getMatchedElementRoute('')
#9 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/web/UrlManager.php(110): craft\web\UrlManager->_getRequestRoute(Object(craft\web\Request))
#10 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/web/Request.php(919): craft\web\UrlManager->parseRequest(Object(craft\web\Request))
#11 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/yiisoft/yii2/web/Application.php(82): craft\web\Request->resolve()
#12 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/craftcms/cms/src/web/Application.php(262): yii\web\Application->handleRequest(Object(craft\web\Request))
#13 /Volumes/ProBeast/Users/dave/Sites/Walbec/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#14 /Volumes/ProBeast/Users/dave/Sites/Walbec/public_html/index.php(21): yii\base\Application->run()
#15 {main}

Additional info

  • Craft version: 3.0.11
  • PHP version: 7.1.12
  • Database driver & version: 5.6
@brandonkelly
Copy link
Member

Looks like you’re doing this in a custom entry script? You probably just need to add this to the bottom:

$craft->end();

To fix your current install, just delete your storage/runtime/compiled_classes/ folder.

@RitterKnightCreative
Copy link
Author

@brandonkelly Awesome, thanks for the help.

I did put in $craft->end(); at the end as well, but same result.

Is there a reason those classes in compiled_classes aren't being regenerated automatically after the field gets added?

@brandonkelly
Copy link
Member

Those dynamically-generated ContentBehavior and ElementQueryBehavior classes are only regenerated when the info.fieldVersion value changes in the database. The Fields service is supposed to update that value each time a custom field is saved or deleted. But to avoid updating the version multiple times in a single request, it was just registering an end-request event listener, and updating the value from there.

I’m not sure why $craft->end() didn’t work for you – maybe that line isn’t being reached by PHP, or maybe since you're echoing out values before then, it’s getting ignored. But this issue has bit me in the past too, and I’m sure will bite others in the future, so I just changed the logic so the field version value is updated immediately rather than waiting for request end (with a safeguard to make sure it only does it the first time it was called). So this should be fixed for you in the next release.

@RitterKnightCreative
Copy link
Author

You guys rock, thanks Brandon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants