XF 2.2 Finder question

Anatoliy

Well-known member
I have "Thread Titles" add-on, I'm thinking about to share it with the community, I need to make a minor change, and I'm stuck.

Right now I have this in repository:

PHP:
    public function findTooLongTitles()
    {
        $finder = $this->finder('\XF:Thread');
        $expression = $finder->expression('CHAR_LENGTH(%s)', 'title');
        $finder
        ->setDefaultOrder('thread_id')
        ->where($expression, '>', 50)
        ->where('discussion_state', 'visible')
        ->where('discussion_type', '!=', 'redirect');

        return $finder;
    }

I consider the title as too long if its length is > 70. As a thread title is "Thread title | Board title", and my board title length is 20, ->where($expression, '>', 50) works for me just fine. But if people will use this add-on and their board titles are different I thought to add $limit = 70 - $bordTitleLenght and to use ->where($expression, '>', $limit).

So what should I use instead of $bordTitleLenght? I tried $xf.options.boardTitle and $thread.Forum.Node.title but it gives me an error.

Please advise.
 

Lukas W.

Well-known member
Dot syntax is not valid in PHP and limited to templates. PHP uses dots exclusively to concatenate strings. To access a property in PHP, you'll need to use arrow notation $object->property, or if you're working with an array, you need to access it via $array['index']. There's also no globally available variables in PHP, but you'll find that the repository has a handy shortcut function to access the options object. For all other places you can use the static method on the XF object: \XF::options()->optionId.
 

Anatoliy

Well-known member
Dot syntax is not valid in PHP and limited to templates. PHP uses dots exclusively to concatenate strings. To access a property in PHP, you'll need to use arrow notation $object->property, or if you're working with an array, you need to access it via $array['index']. There's also no globally available variables in PHP, but you'll find that the repository has a handy shortcut function to access the options object. For all other places you can use the static method on the XF object: \XF::options()->optionId.
Thanks Lukas!
I can't say that I understood a word, but I tried $limit = 70 - strlen(\XF::options()->boardTitle); and it looks like it woks. )
 

Anatoliy

Well-known member
What if the board title is 71 characters (or more) ?

be careful
I guess then every single thread title will be considered as "too long" and the " | Board title" will be dropped for all of them.
Or I don't understand something?
 

Anatoliy

Well-known member
yeah, be sure to run the query with limit -1 to see what happens
I knew you were talking about some kind of "oops" )
How should I protect it from kaboom? Will this do the trick?

PHP:
$limit = 70 - strlen(\XF::options()->boardTitle);
if($limit < 0){$limit = 0;}
 

briansol

Well-known member
I don't think you want 0 either.

going by your first post, you want 50 char titles and accounting for the length of the board title, right?

So, why are you subtracting :)
Code:
$limit = strlen(\XF::options()->boardTitle) + 50;
no ?

it will always be at least 50, and only get larger. never 0. never negative.
 

Anatoliy

Well-known member
I don't think you want 0 either.

going by your first post, you want 50 char titles and accounting for the length of the board title, right?

So, why are you subtracting :)
Code:
$limit = strlen(\XF::options()->boardTitle) + 50;
no ?

it will always be at least 50, and only get larger. never 0. never negative.
first I started to reply "no, you didn't understand". then I stopped and said "you are genius, it was me not knowing what I'm doing".
now I understand that I have such a mess in my head that I don't understand if I understand myself. )

If the length of "Thread title | Board title" > 70 it's a too long title.
So that's actually what should go in the code.
kind of like ->where(Thread title | Board title, '>', 70)
But I don't know how. )
I'm as a little kid that can build only from those pieces of Lego that he has in hands. I have the code I posted above and I understood that I have to replace "50" with a variable that will be equal to 70 - Board title length.
But yeah, your are right. I'd better not deduct. )

Could you please teach me how I should modify the code?
 

briansol

Well-known member
Code:
$limit = strlen(\XF::options()->boardTitle) + 50;
Code:
 ->where($expression, '>', $limit)

should do it, no?
 

Anatoliy

Well-known member
Code:
$limit = strlen(\XF::options()->boardTitle) + 50;
Code:
 ->where($expression, '>', $limit)

should do it, no?
no )

if strlen(\XF::eek:ptions()->boardTitle) is say 30, then $limit will be 80. And finder will show as too long titles those, that are > 80. but 71 is already too long. I guess what I need is not to mess with $limit (70 should be instead of $limit), but put in $expression length of "Thread title I Board title", and not just length of "Thread title" as it's now.
then ->where($expression, '>', 70) will do it.

and sorry for my English )
 

briansol

Well-known member
you can do some fuzzy math by picking the min of
title length + any constant like 50
and
hard coded limit, like 70

and then take the min() of either of those products.

Code:
$limit = min(70, strlen(\XF::options()->boardTitle) + 50);
 

Anatoliy

Well-known member
you can do some fuzzy math by picking the min of
title length + any constant like 50
and
hard coded limit, like 70

and then take the min() of either of those products.

Code:
$limit = min(70, strlen(\XF::options()->boardTitle) + 50);
may be I need some rest, but it looks to me that you don't understand me. )
and I quite understand, that it's very probably that it's me not understanding you. ))

I probably will use this for now (maybe later I'll understand what you tried to tell me)
Code:
$limit = $this->options()->threadTitlesMax - strlen(\XF::options()->boardTitle);
        if($limit < 0){$limit = 1;}

thanks anyway!
 

briansol

Well-known member
if your board title is
"This is my super long board title and i need to hit a pretty high character limit | powered by Xenforo software | Thread Title here"
you'll end up with 1 as a result.

Making your query return everything with a title longer than 1, which is basically every thread on your site.
 

Anatoliy

Well-known member
if your board title is
"This is my super long board title and i need to hit a pretty high character limit | powered by Xenforo software | Thread Title here"
you'll end up with 1 as a result.

Making your query return everything with a title longer than 1, which is basically every thread on your site.
ok. I guess I finally understand why we don't understand each other
(I mean you don't understand me) :)

there is a template modification that turns "Thread title | Board title" into "Thread title" if length of "Thread title | Board title" > 70

find
Code:
<title><xf:title formatter="%s | %s" fallback="{$xf.options.boardTitle}" page="{$pageNumber}" /></title>
replace with
Code:
<title>
<xf:if is="{{strlen($pageTitle ?: '') > 70 - strlen($xf.options.boardTitle)}}">
<xf:title formatter="%s" fallback="{$xf.options.boardTitle}" page="{$pageNumber}" />
<xf:else />
<xf:title formatter="%s | %s" fallback="{$xf.options.boardTitle}" page="{$pageNumber}" />
</xf:if>
</title>

now in repository I have 2 functions findTooLongTitles() and findStillLongTitles().

findTooLongTitles() is used just to pass $total to the "Too Long Title" template to show in ACP a line of text Found xxx threads with too long titles. Their titles were modified from "Thread title | Board title" to "Thread title".

findStillLongTitles() lists the threads with titles > 70. (regardless what's the Board title is). Thread title in this case is what goes in h1 tag.

Code:
public function findTooLongTitles()
    {
        $limit = $this->options()->threadTitlesMax - strlen(\XF::options()->boardTitle);
        if($limit < 0){$limit = 1;}
        $finder = $this->finder('\XF:Thread');
        $expression = $finder->expression('CHAR_LENGTH(%s)', 'title');
        $finder
        ->setDefaultOrder('thread_id')
        ->where($expression, '>', $limit)
        ->where('discussion_state', 'visible')
        ->where('discussion_type', '!=', 'redirect');

        return $finder;
    }

    public function findStillLongTitles()
    {
        $finder = $this->finder('\XF:Thread');

        $expression = $finder->expression('CHAR_LENGTH(%s)', 'title');
        $finder
        ->setDefaultOrder('thread_id')
        ->where($expression, '>', $this->options()->threadTitlesMax)
        ->where('discussion_state', 'visible')
        ->where('discussion_type', '!=', 'redirect');

        return $finder;
    }

So yeah, if we have "Some thread title | And a very very very very very ... very long board title", it will make my query to return everything with a title longer than 1, which is basically every thread on a site. But tat would be truth - all those titles would be too long. And add-on will not list all of them as too long titles. It will just count them and will say in ACP "zillion of your threads are with too long titles. Their titles were modified from "Thread title | Board title" to "Thread title". )

and below will be a list from findStillLongTitles() but "Some thread title" will not be listed as it's < 70.

🕺
 

Anatoliy

Well-known member
hah! and I guess you helped me to find another error )

<xf:if is="{{strlen($pageTitle ?: '') > 70 - strlen($xf.options.boardTitle)}}">
by my plan should be actually
<xf:if is="{{strlen($pageTitle ?: '') + strlen($xf.options.boardTitle) + 3 > 70 }}">
 

Kirby

Well-known member
This thread confuses the hell out if me, lol :D

Assuming that threadTitlesMax (this violates resource standards rules!) is the option name for the maximum acceptable title length, i'd probably just use

Code:
<xf:if is="$pageTitle && strlen($pageTitle . ' | ' . $xf.options.boardTitle) > $xf.options.threadTitlesMax">

Why would I do it this way? It's easy to read and understand, requires only 1 function call and shortcut evaluation if no title is present avoids the function call entirely.
 

Anatoliy

Well-known member
This thread confuses the hell out if me, lol :D
I know! )
Assuming that threadTitlesMax (this violates resource standards rules!) is the option name for the maximum acceptable title length, i'd probably just use

Code:
<xf:if is="$pageTitle && strlen($pageTitle . ' | ' . $xf.options.boardTitle) > $xf.options.threadTitlesMax">

Why would I do it this way? It's easy to read and understand, requires only 1 function call and shortcut evaluation if no title is present avoids the function call entirely.
$pageTitle ! Yeah!!!
Now my mumbling will be a little bit less confusing . )
$pageTitle, $threadTitle, $boardTitle.
strlen($pageTitle) === strlen($threadTitle) + strlen($boardTitle) + 3;

Thank you!
 

Anatoliy

Well-known member
$pageTitle ! Yeah!!!
Now my mumbling will be a little bit less confusing . )
$pageTitle, $threadTitle, $boardTitle.
strlen($pageTitle) === strlen($threadTitle) + strlen($boardTitle) + 3;
or may be not...
in the template $pageTitle means (holds) "Thread title". correct?
went making another cup of coffee...
 
Top