XenForo 2.0 Discussion

Status
Not open for further replies.
I'm extremely happy with 1.5.x so far (coming from vbulletin 4.x). I think you guys are way too smart to go all vbulletin 5 on us. I recall the first time I saw vbull 5, I knew within seconds that company was over with. Keep your customers in the loop, do a lot of end user testing. Coders can often be way too logical and miss the boat when it comes to real world non-techie usability. Anyway... best of luck.
 
I'm wondering if any good has come from this thread. It's has ideas and suggestions mixed in with trolly flames but very little official feedback thus far.
 
The posts by the XenForo account, Mike and I have been useful, I think.

We probably need to look at consolidating that information to somewhere so that it is easy to find.
 
@Mike Not digging the finder or service concepts; the li3 Framework I suggested to you a few years ago is a better fit, would've saved a lot of work reinventing stuff that's already perfected; example:

xF 2 - Data Access:
PHP:
$finder = $this->em()->finder('XF:Post')
->where('thread_id', 123)
->with('Thread')
->onPage(2)
->orderByDate();

$post = $finder->fetchOne();
$thread = $post->Thread; // this was fetched with the query
$forum = $thread->Forum; // this is silently fetched as needed

if ($forum->canView()) { /* ... */ }
if ($forum->isUnread()) { /* ... */ }

xF 2 with li3 Framework - Data Access:
PHP:
$post = \xenforo\models\Post::find('first', array(
   'conditions' => array('thread_id' => 123),
   'with' => array('Threads', 'Threads.Forums'),
   'page' => 2,
   'order' => array('date' => 'DESC')
));

$thread = $post->thread;
$forum = $thread->forum;

if ($forum->canView()) { /* ... */ }
if ($forum->isUnread()) { /* ... */ }
Notice how this is plain easy-to-read PHP. This has the benefit of not requiring coders to learn the proprietary concepts or for the team to invent them.

The framework is very well documented, including the class that the Post model extends from: http://li3.me/docs/lithium/data/Model::find

With filters you can intercept model (and non-model) functions, very useful for add-ons. Although, given how some people are clamoring for 2.0, it's probably too late. :(
 
Last edited:
Respectfully, I disagree. Mostly because there's not an IDE that will suggest/auto complete an array for you. Sure you'd eventually remember the elements are "conditions", "with", "order", "page". But with the method they chose your ide will suggest "where", "with", "onPage", "orderByDate" and all other functions when you hit "->". Also, neither of those examples are hard to read.
 
Last edited:
Respectfully, I disagree. Mostly because there's not an IDE that will suggest/auto complete an array for you. Sure you'd eventually remember the elements are "conditions", "with", "order", "page". But with the method they chose your ide will suggest "where", "with", "onPage", "orderByDate" and all other functions when you hit "->". Also, neither of those examples are hard to read.
The IDE shows documentation for the function not unlike the page I linked to (including option array keys), so there is nothing to remember. Chaining methods to specify options for a query does not read well.

What context is $this? What is em()? What does 'XF : Post' reference, why do I need a $finder instance, and why do I have to know all this to get a post? I'm not asking this literally; it points to an underlying design problem.
 
Chaining methods doesn't read poorly. The IDE showing documentation requires you to put documentation.

I will give you the fact you don't know the context of $this, though I'm sure it's just one way to access it (just like $this->getModelFromCache() vs XenForo_Model::create(). As far as the finder instance goes, finder('XF: Post') and xenforo\model\post::find() aren't incredibly different. It's just a matter of design pattern choice/preference. Like any design pattern discussion goes, you inevitably have your preference and I have mine. At the end of the day, either of us would have/will adapt to their decision. We can argue till we die about which is better.
 
@Mike Not digging the finder or service concepts; the li3 Framework I suggested to you a few years ago is a better fit, would've saved a lot of work reinventing stuff that's already perfected; example:
From your example, I would say that a chainable interface is likely superior, with things like IDE hinting being more readily available. If you're looking for a query builder-style thing, that pretty much seems to be standard (Laravel/Eloquent, Doctine, etc). If anything, I would suggest that a simple array based approach is harder to read/easier to make mistakes and less flexible. Additionally it is likely further complicated where you may have conditions that involve multiple options that can be wrapped up in a simple API call.

Jumping ahead to your more recent post...
What context is $this? What is em()? What does 'XF : Post' reference, why do I need a finder instance, and why do I have to know all this to get a post? I'm not asking this literally; it points to an underlying design problem.
I think you're taking a strawman as soon as you're asking "what's $this". It should be clear that the example was explicitly written to demonstrate various options, not to say they are required. I could easily write \XF::finder($name) and that would remove that argument and provide nothing of use to the comparison as that's minor syntactic sugar.

I could apply a similar argument to your approach. It's just different approaches. I believe ours is superior for various reasons. I don't think it's particularly viable to really say X is definitively better after looking at a 10 line contextless example to show some syntax options (and to frame it in comparison to XF 1).
 
If you're looking for a query builder-style thing, that pretty much seems to be standard (Laravel/Eloquent, Doctine, etc).

It really reminds me of ActiveRecord in Rails which I've grown to love recently. One thing I'd definitely love to suggest is the ability to define 'scopes' which allow you to use predefined joins/conditionals/etc and extend on those for really common queries (For example, if you commonly load the thread data with the posts you would define a scope that is with_thread_data. Then, for example, to get the 'latest posts' you'd just call:
Code:
Posts.with_thread_data.order(:post_date => :desc).limit(5)

instead of doing:
Code:
Posts.select('threads.*, posts.*').joins(:threads).order(:post_date => :desc).limit(5)

for example.
See: http://guides.rubyonrails.org/active_record_querying.html#scopes

On an aside to that, now that for the most part people won't have to manually write all of their queries are there any plans to support anything other than MySQL?
 
Mike said:
To give an example using a new system, we're currently spending time building a generic payment framework. This is designed not only to allow different payment processors (not just PayPal) but also to be a framework to make it easy for new "purchasable" elements to be added easily (not just user upgrades). A system like this benefits the core system, but also enables new add-ons to be developed more easily. Without this, developers may discount an idea that requires payment processing because of the extra legwork required.
This will empower addon developers and allow webmasters to monetize more. Thanks for considering my suggestion.

Mike said:
As a specific example, both prefixes and custom fields are ideas used in multiple content types and add-ons. Previously, each required effectively duplicating whole files of code with minor changes. These are now built on a generic framework that can be reused for the core functionality, while simultaneously being extendable so specific features can be added where needed.
A limitation that the custom fields system in XF1 has that addon developers often encounter, is that custom fields can only be used for the item author to fill in. Often it would be useful for readers /replying members to fill in custom fields. Multiple fields then become a form. The data in these custom fields can be used for various calculations. For example: averages.
I hope to see custom fields to be more flexible in XF2.
 
One thing I'd definitely love to suggest is the ability to define 'scopes' which allow you to use predefined joins/conditionals/etc and extend on those for really common queries
That is pretty much what those methods on the finder are in the example (onPage, orderByDate). There's a base finder class that implements things like query modifiers where, with, order, limit; fetch modifiers like keyedBy and pluckFrom; and actual retrieval elements like total, fetch, fetchOne (and other bits).

Each type of entity can define a specific finder implementation to extend that and add their own methods with specific context (with full access to all other finder methods). As a specific example, the thread finder has a unreadOnly($userId) method that handles joining the necessary read marking data and adding conditions to only return unread threads (which is itself fairly complex because it involves dropping into raw SQL for some of the expressions). With this approach, you can effectively just add this to any existing thread-finding query.

On an aside to that, now that for the most part people won't have to manually write all of their queries are there any plans to support anything other than MySQL?
There are still various cases where raw SQL is needed. The goal of this really isn't DB abstraction for the purpose of changing RDBMS. So effectively, no (and it's not something I would anticipate).
 
Is XF 2's main goal to help the addon developers to add more and more addons easily so the core can be kept on the minimum?
 
Is XF 2's main goal to help the addon developers to add more and more addons easily so the core can be kept on the minimum?
It's not totally clear, but to clarify:

A major goal of 2.0 is one that is technical in nature: improve developer efficiency. While this might not be a new feature itself, it benefits all development going forward.

In some cases, these systems function similarly to XenForo 1.x, but there are other cases where we have reapproached them to ensure we have more solid structure for us and the add-on ecosystem to build on.
It's about improving developer productivity generally.
 
It's not totally clear, but to clarify:



It's about improving developer productivity generally.
Looking at the code snippets it looks like a lot of addons are going to require essentially a full rewrite to update to XF2; a mammoth task for the bigger addons I'm sure.

Just out of curiosity; is there any backward compatibility code that may allow an XF1.x structured/syntax addon to be ran on XF2 so that some, more basic, addons may remain operable (but using deprecated code) whilst a developer finds the time to rewrite? I imagine not but it's worth asking.
 
Looking at the code snippets it looks like a lot of addons are going to require essentially a full rewrite to update to XF2; a mammoth task for the bigger addons I'm sure.
We've been saying changes are needed, but the extent of the changes would vary with the add-on, how far you want to go to the new concepts, and how much you integrate into existing data structures/code (as opposed to add-ons that create new ones). Saying "full rewrite" is difficult because if you're just translating things more or less verbatim, it would be much quicker than reapproaching the code organization as well.

Just out of curiosity; is there any backward compatibility code that may allow an XF1.x structured/syntax addon to be ran on XF2 so that some, more basic, addons may remain operable (but using deprecated code) whilst a developer finds the time to rewrite? I imagine not but it's worth asking
We have played with this, but not for a while. (It's generally been easier to convert code rather than trying to use a legacy compatibility layer that isn't really complete.) So I don't know the extent of it.
 
Status
Not open for further replies.
Top Bottom