theoretic Posted November 22, 2023 Share Posted November 22, 2023 Hi friends! And thanks for Processwire ) Maybe I'm missing something, but it appears that PW doesn't have a dedicated selector for text length. Possible selector: $selectedUsers = $users->find("name.length<=5,sort=name.length"); Expected output: Bob Andy Maria ( Steven and Andrea will be skipped because that names are too long ) Of course it's possible to filter the find() results using some custom function, but having a native selector instead could be a better practice. So does that silver bullet really exist? If no, I think it could be useful to many happy PW developers ) Link to comment Share on other sites More sharing options...
Robin S Posted November 22, 2023 Share Posted November 22, 2023 There's an open request for this: https://github.com/processwire/processwire-requests/issues/424 Link to comment Share on other sites More sharing options...
BitPoet Posted November 22, 2023 Share Posted November 22, 2023 A short&quick&dirty module that adds .length (switching back and forth between regular Text fields and "Text with .length Selector" should not cause any troubles): <?php namespace ProcessWire; class FieldtypeTextWithLength extends FieldtypeText { public static function getModuleInfo() { return [ 'title' => __('Text with .length Selector', __FILE__), 'summary' => __('Like FieldtypeText, but with a subfield selector .length for string length comparison', __FILE__), 'version' => '0.0.1' ]; } public function getMatchQuery($query, $table, $subfield, $operator, $value) { $database = $this->wire("database"); if($subfield === 'length') { $table = $database->escapeTable($table); $value = $database->escapeStr($value); $query->where("LENGTH({$table}.data){$operator}$value"); } else { parent::getMatchQuery($query, $table, $subfield, $operator, $value); } return $query; } } 3 2 Link to comment Share on other sites More sharing options...
bernhard Posted November 22, 2023 Share Posted November 22, 2023 Wow @BitPoet that's real bit poetry ? I've taken your example and did some research in the code and found this as an alternative solution: <?php $wire->addHookAfter("PageFinder::getQuery", function (HookEvent $event) { // get the DatabaseQuerySelect object $query = $event->return; // modify the query to only find names with length < 6 $query->where("LENGTH(pages.name)<6"); // remove the hook after first execution $event->removeHook(null); }); // find users with names < 6 chars bd($wire->pages->find("template=user")); It's important to add the hook immediately before the $pages->find() call. And it's important to remove the hook so that it only executes once. 4 Link to comment Share on other sites More sharing options...
BitPoet Posted November 23, 2023 Share Posted November 23, 2023 On 11/22/2023 at 1:30 PM, bernhard said: @BitPoet that's real bit poetry Thanks! Appreciated! ? about it, in times of utf8(mb4) one might want to use CHAR_LENGTH instead of LENGTH. The first one counts the code points, i.e. visible characters, while the latter returns the bytes. LENGTH('?') is 4. 1 Link to comment Share on other sites More sharing options...
BitPoet Posted November 24, 2023 Share Posted November 24, 2023 I brushed up my snippet with a ___getSelectorInfo method, so Lister & Co. can offer Length as a numeric subfield and put the module on GitHub. 2 1 Link to comment Share on other sites More sharing options...
theoretic Posted November 26, 2023 Author Share Posted November 26, 2023 Wow it's just incredible! @BitPoet You're the best ) It's so rare to see a new module being created as a response to a forum question! Love the Processwire community ) Thank you fellas! 1 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