Gadgetto Posted February 24, 2019 Share Posted February 24, 2019 Could somebody please tell me why this works ... $templates = $this->wire('templates'); $messageTemplates = array(); $className = 'FieldtypeMessageMeta'; foreach ($templates as $t) { foreach ($t->fields as $f) { if ($f->type instanceof $className) { $messageTemplates[] = $t->name; break; } } } // $messageTemplates array is populated correctly! ... and this doesn't work: $templates = $this->wire('templates'); $messageTemplates = array(); $className = self::FIELDTYPE_GROUPMAILER_MESSAGE_META; // is set to 'FieldtypeMessageMeta' foreach ($templates as $t) { foreach ($t->fields as $f) { if ($f->type instanceof $className) { $messageTemplates[] = $t->name; break; } } } // $messageTemplates array is empty! Link to comment Share on other sites More sharing options...
tpr Posted February 24, 2019 Share Posted February 24, 2019 The self::FIELDTYPE_GROUPMAILER_MESSAGE_META is suspicious, where do you have this code, what class is it in and in what namespace? I put this in ready.php with and it works fine - note that I used \ProcessWire\FieldtypeEmail: <?php namespace ProcessWire; class G { private const CLASS_NAME = '\ProcessWire\FieldtypeEmail'; public function __construct(){ $templates = \ProcessWire\wire('templates'); $messageTeplates = array(); // both of these two below work fine $className = '\ProcessWire\FieldtypeEmail'; // $className = self::CLASS_NAME; foreach ($templates as $t) { foreach ($t->fields as $f) { if ($f->type instanceof $className) { $messageTeplates[] = $t->name; break; } } } echo count($messageTeplates); } } new G(); exit; Btw you have a typo in $messageTeplates". Link to comment Share on other sites More sharing options...
kongondo Posted February 24, 2019 Share Posted February 24, 2019 46 minutes ago, tpr said: private const CLASS_NAME = '\ProcessWire\FieldtypeEmail'; Isn't this (and similar) superfluous? You are already in the ProcessWire namespace. Link to comment Share on other sites More sharing options...
teppo Posted February 24, 2019 Share Posted February 24, 2019 Apparently "instanceof" doesn't allow constants, strings, or expressions, while is_a() happily accepts all of those. This is news to me, and I'm not entirely sure of the behind the scenes logic, but it probably has something to do with instanceof being a language construct (those sometimes behave a little bit unexpectedly) – or it might simply be a performance optimization. After all instanceof is much better in terms of performance than is_a(). Use variables or literal class names instead – or if you really have to, use the workaround provided by @tpr above, i.e. store the constant value to a variable before use ? 3 Link to comment Share on other sites More sharing options...
tpr Posted February 24, 2019 Share Posted February 24, 2019 1 hour ago, kongondo said: Isn't this (and similar) superfluous? You are already in the ProcessWire namespace. Apparently not, my snippet fails when I exclude ProcessWire from it. 1 hour ago, teppo said: Apparently "instanceof" doesn't allow constants, strings, or expressions Are you referring to the #5 example here? To my understanding it's the "variable being tested", and not the class name (after the "instanceof"): http://php.net/manual/en/language.operators.type.php Edit: I see, when using the constant with the instanceof directly it generates an error. 1 hour ago, teppo said: use the workaround provided by @tpr above, i.e. store the constant value to a variable before use He is already doing that ? @Gadgetto Could you post the whole file? Probably we could find what's happening. 1 Link to comment Share on other sites More sharing options...
tpr Posted February 24, 2019 Share Posted February 24, 2019 Just had a look at what PhpStorm offered as abbreviation, and it worked: private const CLASS_NAME = FieldtypeEmail::class; // or $className = FieldtypeEmail::class; (it would add a "use" statement if necessary but in this case it didn't as the namespace was already ProcessWire) Link to comment Share on other sites More sharing options...
adrian Posted February 24, 2019 Share Posted February 24, 2019 47 minutes ago, tpr said: Apparently not, my snippet fails when I exclude ProcessWire from it. Interesting - it works like this here: Link to comment Share on other sites More sharing options...
tpr Posted February 24, 2019 Share Posted February 24, 2019 Same here, but without "\ProcessWire\" the output is 0: $className = '\FieldtypeEmail'; // or $className = 'FieldtypeEmail'; 2 Link to comment Share on other sites More sharing options...
adrian Posted February 24, 2019 Share Posted February 24, 2019 Sorry @tpr - I actually even left the \ProcessWire\ in the version I posted above - d'oh. I did try without and wasn't getting an undefined wire error so assumed it was ok. Link to comment Share on other sites More sharing options...
Gadgetto Posted February 24, 2019 Author Share Posted February 24, 2019 3 hours ago, tpr said: The self::FIELDTYPE_GROUPMAILER_MESSAGE_META is suspicious, where do you have this code, what class is it in and in what namespace? This is correctly defined in class body and the debugger confirms it holds the correct string "FieldtypeMessageMeta" 3 hours ago, tpr said: I put this in ready.php with and it works fine - note that I used \ProcessWire\FieldtypeEmail OK - this is strange: changing the const definition to const FIELDTYPE_GROUPMAILER_MESSAGE_META = '\Processwire\FieldtypeMessageMeta'; ... it works as expected! Why is this? My class file is already namespaced correctly! Link to comment Share on other sites More sharing options...
kongondo Posted February 24, 2019 Share Posted February 24, 2019 1 minute ago, Gadgetto said: it works as expected! Why is this? A PHP oddity, I'm guessing ?. Link to comment Share on other sites More sharing options...
Gadgetto Posted February 24, 2019 Author Share Posted February 24, 2019 Hey, just found out its super easy to copy/paste color-coded code from VSCode! ? Link to comment Share on other sites More sharing options...
Gadgetto Posted February 24, 2019 Author Share Posted February 24, 2019 1 minute ago, kongondo said: A PHP oddity, I'm guessing ?. The question is: should I use this and risk a future problem with newer PHP versions? Link to comment Share on other sites More sharing options...
tpr Posted February 24, 2019 Share Posted February 24, 2019 5 minutes ago, Gadgetto said: My class file is already namespaced correctly! I think it's OK. PHP shouldn't assume that the instance you are checking is in the current namespace, so you should clearly state which one to check against. Link to comment Share on other sites More sharing options...
adrian Posted February 24, 2019 Share Posted February 24, 2019 I know you need to check a constant or variable, but if you enter things directly, you don't need the namespace. I guess it's to do with quoting FieldtypeEmail when assigning to a variable or const that causes the problem. 1 Link to comment Share on other sites More sharing options...
Gadgetto Posted February 24, 2019 Author Share Posted February 24, 2019 (edited) BTW - this works perfectly without \Processwire if I use the class name directly: if ($f->type instanceof FieldtypeMessageMeta) { Edited February 24, 2019 by Gadgetto @adrian: you got me by a few seconds ... :) Link to comment Share on other sites More sharing options...
kongondo Posted February 24, 2019 Share Posted February 24, 2019 5 minutes ago, adrian said: I know you need to check a constant or variable, but if you enter things directly, you don't need the namespace. Yes. This is how I've been doing it in my modules. Typing \ProcessWire\...every time is a pain I want to avoid ?. Link to comment Share on other sites More sharing options...
Gadgetto Posted February 24, 2019 Author Share Posted February 24, 2019 Great help from you guys - as always! I love this community! Link to comment Share on other sites More sharing options...
Gadgetto Posted February 24, 2019 Author Share Posted February 24, 2019 16 minutes ago, adrian said: I know you need to check a constant or variable, but if you enter things directly, you don't need the namespace. I guess it's to do with quoting FieldtypeEmail when assigning to a variable or const that causes the problem. I use the class name many times across this class and in derivates - so using the literal class name directly would be a pain if something changes... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now