I am planning to use ubercart for selling digital products. So there won't be any dimensions or weight of products. As suggested in #1301032: Remove SKU, dimensions prices from user view of product. form fields can be hidden from the user view. So I created a new content type, configured it as product and set the dimensions field to invisible. Now if I try to create a new content of that type I get a white page telling me something went wrong. The errorlog lists:

mod_fcgid: stderr: Uncaught PHP Exception Drupal\\Core\\Entity\\EntityStorageException: "SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'length' cannot be null: INSERT INTO {uc_products} (vid, nid, model, cost, price, weight, weight_units, length, width, height, length_units, pkg_qty, default_qty, shippable) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11, :db_insert_placeholder_12, :db_insert_placeholder_13); Array

So I guess as the field is defined as required I cannot hide it from the user view? The often proposed https://www.drupal.org/project/uc_product_power_tools aren't ready for Drupal 8. Maybe I can somehow prepopulate unnecessary fields with random data and hide them, but I'd be interested in a nicer solution. :-)

Comments

pheraph created an issue.

djdevin’s picture

Yes please, this breaks programmatic creation of nodes that aren't aware that a SKU is required.

$n = Drupal\node\Entity\Node::create(['title' => 'test', 'type' => 'product']);
$n->save();

Column 'model' cannot be null

Temporary solution:

function mymodule_node_presave(\Drupal\node\Entity\Node $node) {
  $node->set('model', 'placeholder');
}
TR’s picture

Because D8 has many more features than D7, a lot of uc_product_power_tools isn't needed anymore. For example, you can control which fields are shown at /admin/structure/types/manage/product/form-display and /admin/structure/types/manage/product/display. That should address most cases raised by the original issue. All of the required product base fields have default values defined, so the specific case raised with 'length' should not happen in the -dev version of Ubercart. A field like SKU however must have a value filled in because it is used as an identifier throughout the code. In principle it should unique, but historically that was never enforced. uc_product_power_tools does have a way to automatically generate SKUs if you need that to be done for you - I don't know if that feature works properly, but the place to discuss that is in the issue queue for that module. If you want to look into that and you find out it needs work, just post a patch in that module's queue and I will be happy to provide the permissions so you can fix that yourself.

The use case in #2 really doesn't hold up - ALL entities have some required fields, so when you're programmatically creating ANY entity you need to query the entity to determine the required fields then ensure they get set. This is what other modules like Rules do when they need to create entities of an unknown type. This works for every entity type I've ever encountered (except the core User entity, which marks the email field as NOT required but then adds a constraint that it MUST have contents - a contradiction which cannot be dealt with programmatically because you can't query constraints programmatically). But if you know ahead of time what type of entity you're creating, then it should be no issue to provide all the necessary fields.

In the case of products, Ubercart properly defines those fields as required base fields so that you CAN tell programmatically which fields need to be filled in.

djdevin’s picture

What was odd to me is that it's marked as required in uc_product_entity_bundle_field_info() but also has a default value of '' (empty string) which seems to have no effect. I'd think that would still give it a value since an empty string is not NULL but it seems to be converted to NULL before it goes to insert it in the DB. Doesn't matter if you pass in ['model' => ''] either. Things like cost and price are also required but they default to 0.00 and that doesn't throw errors if omitted. So '' is null but 0 and 0.00 are not null. Doesn't seem like it's Ubercart's issue anyway.

Scenario I discussed is really an edge case so I don't think it warrants any change since we can just generate a placeholder. This is for creating a draft product that won't be assigned an SKU until edited later.