VaultWiki

VaultWiki [Paid] 4.1.7 Patch Level 1

No permission to buy ($15.00)
Hi there, I just bought the add-on but I can't get it to work, all I get are a bunch of errors. Is there an instructions file or something like that where I can setup the wiki in my board? Thanks...
 
Well I think I lost 20 dollars, this is way too much of a hassle for an add-on. I'm uninstalling this plugin, I have spent more than 8 hours just trying to test it in my site but it's impossible, the instructions are not clear enough either. I'll be looking for another wiki software for my forum.

Thanks and enjoy...
 
pegasus updated VaultWiki with a new update entry:

[IN]Compatibility with XenForo 2.2.13

Please beware that if you are using any version of VaultWiki acquired before June 1, 2023, if you have or will update to the newest XenForo version 2.2.13, you may experience fatal showstopper issues on your site while using VaultWiki, due to incompatible code changes introduced in that XenForo release, specifically while XenForo's debug mode is active.

We have now patched the issue from our end. We strongly recommend that any users running VaultWiki who also plan on upgrading to XenForo...

Read the rest of this update entry...
 
What about adding a link to the bottom where they can click next page or previous page? If someone is reading tutorials it's kind of an inconvenience for them to have to back out and scroll down to the next one.
 
What about adding a link to the bottom where they can click next page or previous page? If someone is reading tutorials it's kind of an inconvenience for them to have to back out and scroll down to the next one.
Make your tutorials as chapters of a "book" and it will handle Next / Previous links like this.

  1. Create a new wiki page and under "Treat this page as a", select "Book". Name it, for example, "Tutorials".
  2. Then in the new book, you can use the Add Chapter menu to select any existing tutorials and add them.
  3. If you need to change the order of the chapters, you can do that from the book's Options > Manage Chapters menu.
 
You didn't post the corresponding Server Error Log entry, but assuming this is the same error manually as during the batch install, this looks like you may be having a conflict between VaultWiki and another add-on which is trying to extend the same class. Since this is likely to get technical and hijack the thread, I will continue the troubleshooting with you on the main support site where I see you have already opened a ticket. Please followup there.
 
This addon has significant compatible issues with 3rd party addons due to incompatible implementation of XenForo entity framework

The entity content type field is implemented as a full class path (or points to a class which can't be autoloaded) which breaks \XF::finder("Addon:ShortName") and attempting to call \XF::em()->getEntityStructure("Addon:ShortName") would just break with class loader exceptions.

All my code does is load via standard xenforo entity class and send the content type/id to rebuildContentReactionCache to force a rebuild in cases where this is requested by admins, with code the is semantically equivalent to:
PHP:
$structure = null;
try
{
    $reactHandler = \XF::repository('XF:Reaction')->getReactionHandler($contentType, false, $isLike);
    if (!$reactHandler)
    {
        $entityName = $this->app->getContentTypeEntity($contentType, false);
        if ($entityName)
        {
            $structure = $this->app->em()->getEntityStructure($entityName);
        }
    }
}
catch(\Exception $e)
{
    \XF::logException($e, true, 'Broken reaction implementation for content-type; ' . $contentType);
    return;
}
...
\XF::repository('XF:Reaction')->rebuildContentReactionCache($contentType, $id);
Note; The real code is a little more complex, largely around error catching and extracting the primary key column and content type from $structure, and use XF's finder to load each entity and then pass extract the ID to rebuildContentReactionCache


Pegasus claims this:
Why is the add-on Content Ratings trying to apply ratings to another add-on's content-type when that content-type doesn't have a rating handler class? Unless it has a rating handler class, having a rating for a vwattachedit doesn't make much sense in a generic ratings sense, just based on what that content-type actually refers to.

In general VaultWiki, does not provide "entity" values except in rare circumstances, because the content-type data must be retrieved in a specific way, especially for history-based content types. Again, that's why we implement handler classes for each content-type, where we implement a function, such as reactions, tags, etc.

TLDR; If Content Ratings is going to magically handle content-types without those content-types having a "Content Ratings" handler class, and it is assuming that various other content-type fields exist, like it assumes "entity" exists, it can avoid errors like this by checking if all those values exist for the content-type, before trying to implement its rating system on those content-types. This is a bug in the Content Ratings add-on.

VaultWiki provides its own rating system with a special handler for history-related content-types. It is unlikely another add-on would apply its own ratings in anywhere near an expected manner (history ratings are weighted over time, against other history types, consider various flags, and contribute to the overall page rating).
VaultWiki content-types are not compatible with SV Content Ratings. Please do not enable SV Content Ratings support for those content-types. VaultWiki content-types already have their own ratings if you need similar functionality.

VaultWiki content-types have a reaction implementation that is not broken, using the classes and methods in its implementation, which follows XenForo's design of allowing for various implementations. But SV Content Ratings is trying to shoehorn a generic implementation instead, which will of course fail. This has been reported before years ago (by you it seems), but it seems like SV Content Ratings may not have taken the suggestions seriously.

  • If SV Content Ratings is in the business of interacting with other add-ons, SV Content Ratings should not assume that any add-on has a generic implementation. Assumptions like this create conflicts. If they are attempting to use a content-type field value, they should check if it exists first and not attempt any operations on a content-type that is missing a field they require.
  • SV Content Ratings should not automatically enable for any content-type. Just like other XenForo features (like reactions), a content-type should have to provide a handler_class for SV Content Ratings. Again, XenForo doesn't just automatically add reactions to a content-type and assume it to work without input from the coder of the content-type, so why does SV Content Ratings do that for its ratings?

Pegasus has publicly stated:
Yeah, this is the same error message as before, and it is caused when an add-on like Xon's assumes that another add-on's content-type "entity" field is safe to use however they want. In VaultWiki, this field is only intended to be used for type-hinting in XenForo's default Tag\Changer service. All other default uses of this field are inside content-type field handlers, and VaultWiki writes its own handlers.

Xon's add-on is ignoring the fact that VaultWiki and other add-ons might implement custom handlers for search, which leads to an error in VaultWiki.

I believe it would be possible for Xon's add-on to avoid this issue by:
- When finding the entity field, also compare the content-type's search handler. If the search handler is using the default XenForo method for ::getContent, then it is safe for Xon to implement their method. If the search handler is using a non-default method for ::getContent, then it is unsafe for Xon to implement their method, and they should fall back to the search handler's custom method instead.

Essentially, VaultWiki does not and will not implement entity content type field to point at a valid entity with a working getStructure static method.
 
If SV Content Ratings is in the business of interacting with other add-ons, SV Content Ratings should not assume that any add-on has a generic implementation. Assumptions like this create conflicts.
Translation: "I don't know how to code for XenForo and the only reason my add-on is available in the Resource Manager is that the add-on policy isn't proactively enforced" 🤣

1707841813228.webp

---

Memeing aside, outright refusing to follow XenForo standards should result in this add-on being investigated and changes mandated by the development team, IMO. The reasoning provided by the author as I quoted above is completely ridiculous. Everyone else somehow manages to follow XenForo standards, regardless of the complexity of our content.
 
The resource standards are there for a reason, and in cases where it is believed that an add-on is not following resource standards, this can be reported to us so we can investigate.

In other words, it shouldn't rely on a XF developer happening upon reports in the course of browsing the forum ;)

But, indeed, on investigation it would appear that this add-on isn't adhering to the resource standards therefore @pegasus those changes should be implemented as a matter or urgency, or the add-on shouldn't be listed for sale here.

When can we expect the changes to be implemented?
 
VaultWiki had to remove "entity" field values because of a conflict with one add-on. Then another add-on has a conflict because we removed "entity" field values. Unfortunately it's a no-win situation for us.

@Chris D, despite this, VaultWiki does have entities which extend from XenForo entities. However, we are unable to use several standard methods for writing due to "final" designations and the order of steps that take place within those "final" methods. Still, writes do go through the entity process, just with a few custom methods which are accessed through a wrapper class. Because this wrapper must be used and there were prior add-on conflicts, we no longer provide the "entity" content type field value. So regarding the XenForo standards, we never saw VaultWiki as at odds with #7, as it is currently worded (we also noted the "should" language compared to "must" language elsewhere). If you are aware of another way that VaultWiki may not be meeting minimum resource standards, please specify and I would be glad to address the issue.

For context, we did not think that field omission would ever be a major problem, as every code in XenForo that tended to access the "entity" key was something like getContent in handler functions, which could be worked around by making a custom getContent method for that handler.

On to the Content Ratings issue...

After seeing the code in Content Ratings posted above, I'm not sure why an exception is even being logged in this situation. And honestly I didn't realize it was only a logged exception. All the reports I ever received suggested it was a thrown exception and it seemed that a debug-level log would be more appropriate. So it would seem that the $throw being set to false for app->getContentTypeEntity is not working as expected, or there is other code not shown which is involved in the exception.

My critique of Content Ratings still stands. XenForo requires VaultWiki to write a handler_class in order to implement, for example, reactions. This allows VaultWiki to implement reactions in an appropriate and meaningful way. But Content Ratings implements ratings for VaultWiki without asking for a handler_class. Regardless of whether the "entity" field exists or not, or if the ratings technically work with the content-type or not, such an implementation without a handler_class risks being inappropriate for that content-type.
 
Last edited:
The resource standards are there for a reason, and in cases where it is believed that an add-on is not following resource standards, this can be reported to us so we can investigate.

In other words, it shouldn't rely on a XF developer happening upon reports in the course of browsing the forum ;)
Hahah point taken, but in my defence, I'm not personally affected by this add-on so I'm here mostly for moral support 😛

VaultWiki had to remove "entity" field values because of a conflict with one add-on. Then another add-on has a conflict because we removed "entity" field values. Unfortunately it's a no-win situation for us.
I'm struggling to understand how any other add-on can generate a conflict if you provide a getStructure() function in your entities, which is what I presume you're referring to when you say "entity field values". Could you please elaborate?

However, we are unable to use several standard methods for writing due to "final" designations and the order of steps that take place within those "final" methods. Still, writes do go through the entity process, just with a few custom methods which are accessed through a wrapper class. Because this wrapper must be used and there were prior add-on conflicts, we no longer provide the "entity" content type field value. So regarding the XenForo standards, we never saw VaultWiki as at odds with #7, as it is currently worded (we also noted the "should" language compared to "must" language elsewhere). If you are aware of another way that VaultWiki may not be meeting minimum resource standards, please specify and I would be glad to address the issue.
I'm pretty confident in categorically saying there's no use case where you need to extend any of the following entity functions due to "order of steps":
  • toApiResult - extend setupApiResultData instead
  • save - extend _preSave, _fillDeferredValues, _validateRequirements, _saveToSource or _postSave as needed
  • saveIfChanged - don't call this method if you need to inject new values on save.
  • preSave - extend _preSave
  • delete - see preDelete below
  • preDelete - extend _preDelete or _postDelete as needed

If you're having problems with running your code in _postSave or _postDelete due to reasons, don't forget about \XF::runLater(). That'll cause your code to run closer to the end of the current script - right before shutdown I believe. Or, you could defer to a job using \XF::app()->jobManager()->enqueueUnique(). If you need jobs to run in order, you can have the job run a Service that uses \XF\MultiPartRunnerTrait. Or you can use XF:Atomic as the job runner to ensure the jobs are ran in order.

But perhaps I'm just ignorant, what is it about VW that's so special it can't use any of these methods to work within the normal entity system?
 
Last edited:
Since this add-on hasn't worked properly for ages and I simply stopped caring about it, I wanted to uninstall it after this debacle. However... lol

ErrorException: [E_WARNING] Trying to access array offset on value of type bool in src\addons\vw\vw\_core\model\area\xf2.php at line 27
  1. XF::handlePhpError() in src\addons\vw\vw\_core\model\area\xf2.php at line 27
  2. vw_Area_Model_XF2->tree() in src\addons\vw\vw\Handler\Permission\Area.php at line 38
  3. vw\vw\Handler\Permission\Area->getContentTree() in src\XF\Permission\TreeContentPermissions.php at line 23
  4. XF\Permission\TreeContentPermissions->setupBuildTypeData() in src\XF\Permission\AbstractContentPermissions.php at line 48
  5. XF\Permission\AbstractContentPermissions->setupBuildData() in src\XF\Permission\AbstractContentPermissions.php at line 21
  6. XF\Permission\AbstractContentPermissions->__construct() in src\XF\Permission\Builder.php at line 116
  7. XF\Permission\Builder->getContentHandler() in src\XF\Permission\Builder.php at line 85
  8. XF\Permission\Builder->getContentHandlers() in src\XF\Permission\Builder.php at line 148
  9. XF\Permission\Builder->rebuildCombinationContent() in src\XF\Permission\Builder.php at line 142
  10. XF\Permission\Builder->rebuildCombination() in src\XF\Service\UpdatePermissions.php at line 205
  11. XF\Service\UpdatePermissions->triggerCacheRebuild() in src\XF\Service\UpdatePermissions.php at line 117
  12. XF\Service\UpdatePermissions->updatePermissions() in src\addons\DBTech\Security\XF\Service\UpdatePermissions.php at line 107
  13. DBTech\Security\XF\Service\UpdatePermissions->updatePermissions() in src\XF\Entity\Moderator.php at line 66
  14. XF\Entity\Moderator->_postDelete() in src\XF\Mvc\Entity\Entity.php at line 1664
  15. XF\Mvc\Entity\Entity->delete() in src\addons\vw\vw\_core\controller\uninstall\xf2.php at line 134
  16. vw_UnInstall_Controller_XF2->remove_insertions() in src\addons\vw\vw\_core\controller\uninstall\vw.php at line 46
  17. vw_UnInstall_Controller->insertions() in src\addons\vw\vw\Setup.php at line 1146
  18. vw\vw\Setup->uninstallStep1() in src\XF\AddOn\StepRunnerUninstallTrait.php at line 61
  19. vw\vw\Setup->uninstallStepRunner() in src\XF\AddOn\StepRunnerUninstallTrait.php at line 28
  20. vw\vw\Setup->uninstall() in src\XF\Admin\Controller\AddOn.php at line 657
  21. XF\Admin\Controller\AddOn->actionUninstall() in src\XF\Mvc\Dispatcher.php at line 352
  22. XF\Mvc\Dispatcher->dispatchClass() in src\XF\Mvc\Dispatcher.php at line 258
  23. XF\Mvc\Dispatcher->dispatchFromMatch() in src\XF\Mvc\Dispatcher.php at line 115
  24. XF\Mvc\Dispatcher->dispatchLoop() in src\XF\Mvc\Dispatcher.php at line 57
  25. XF\Mvc\Dispatcher->run() in src\XF\App.php at line 2487
  26. XF\App->run() in src\XF.php at line 524
  27. XF::runApp() in admin.php at line 13
 
But perhaps I'm just ignorant, what is it about VW that's so special it can't use any of these methods to work within the normal entity system?
VaultWiki contains what I can most accurately describe as a platform-agnostic external library that contains most of the instruction sets, similar to code in XenForo's vendor libraries. This library includes the code for how wiki data is saved. Using library hooks and library class extensions, it becomes possible to do things like: make the library use XenForo's database adapter, make the library use XenForo string manipulation, etc. In the example that's currently under discussion, this allows for the following code sequence:
  • XenForo controller runs library save controller
  • Library save controller invokes library data object
  • Library data object generates internal XenForo entity
  • XenForo entity runs library data instruction sets
  • (library instruction sets only speak to each other in terms of library data object)
  • XenForo entity saves to database using XenForo database adapter as standard

One sore point with entity->save, from what I remember (it's been many years since the entity code was first written), was that the library expects preSave and save code to be decoupled. This is just one issue, and there may be other ways to work around it, but no desire to touch it currently since it works stably... as long as no outside force generates a wiki entity and saves it without the library's knowledge. Since the library instruction sets only speak to each other in library terms, it's possible to generate entities that are missing library references or library data when generated from outside library code.

I'm struggling to understand how any other add-on can generate a conflict if you provide a getStructure() function in your entities, which is what I presume you're referring to when you say "entity field values".
With that context, I can answer this question better.

Entities have a getStructure function, but I believe what was claimed is that the getStructure output doesn't make sense if the entity was accessed without going through the library. We will investigate this and if it proves true in 2024, this is something we can probably resolve relatively easily.

However, I had thought it was fair to say (until seeing the ire in this thread) that no one wants third-parties manipulating an entity if they don't know what's going on inside that entity. An add-on can generate a conflict if they use getStructure to see an add-on's database columns, and that add-on then makes changes to the column outside the normal operation of that entity, especially without even looking at how that entity operates first. In particular, this can cause issues when dealing with wiki entities, where many changes are supposed to be stored in history.

When I refer to "entity field values", I am talking about the specific content-type field, stored in xf_content_type_field, which has "entity" as its key. VaultWiki doesn't need this key defined for any of its entities to function, especially since VaultWiki knows the names and paths of its own entities. But other add-ons tended to find this key and do things to VaultWiki entities, some of which caused data issues, some of which caused errors. So we removed the "entity" entries from that database table.
 
Since this add-on hasn't worked properly for ages and I simply stopped caring about it, I wanted to uninstall it after this debacle. However... lol

ErrorException: [E_WARNING] Trying to access array offset on value of type bool in src\addons\vw\vw\_core\model\area\xf2.php at line 27
I don't see any reports from you within the last two years, nor any reports from you that were not resolved. So I'm confused by your first statement. If you have an issue, it needs to be reported otherwise we can't do anything about it.

For this particular issue, I think this can happen if permissions try to rebuild during the same request that an area is deleted (such as same request as uninstallation), or possibly if your database contains damaged area data.
In src/addons/vw/vw/_core/model/area/xf2.php, find:
Code:
if (!$area['parentid'])
BEFORE it, add:
Code:
			if (!$area)
			{
				continue;
			}
For the uninstall case, you can edit src/addons/vw/vw/Handler/Permission/Area.php. Find:
Code:
return \vw_Hard_Core::model('Area')->tree();
BEFORE it, add:
Code:
		if (defined('VW_UNINSTALL'))
		{
			return new \XF\Tree([], 'parentid', 0);
		}
If this issue happens consistently in further testing, we may issue a new build for this fix.
 
Last edited:
VaultWiki contains what I can most accurately describe as a platform-agnostic external library that contains most of the instruction sets, similar to code in XenForo's vendor libraries. This library includes the code for how wiki data is saved. Using library hooks and library class extensions, it becomes possible to do things like: make the library use XenForo's database adapter, make the library use XenForo string manipulation, etc.
I've tried maintaining such a code base in the past, and it's pretty cursed. It's no wonder you run into these kinds of issues. Does vBulletin even have a large enough market share in 2024 for you to warrant continuing this? I understand the concept of not fixing what isn't broken, but it's reasonable to say that if you haven't already, you're at some point going to hit a point where you're spending more time fixing bugs that would never occur if your code was "fully native".

vB3/vB4 is a dead platform, as not only do they not run on the currently supported versions of PHP (i.e. still receiving security fixes), but they also don't fully support responsive styling (for mobile browsing), which is very important in today's day and age. If people are okay with leaving their site on a dead platform, I'm sure they're okay with not receiving the latest features for your addon as well :P

One sore point with entity->save, from what I remember (it's been many years since the entity code was first written), was that the library expects preSave and save code to be decoupled.
That's not an issue at all, I think you might be misunderstanding the fundamental concept of preSave(). Its purpose is to provide last-minute validation as well as being able to set certain values. For example, you may do something like this in _preSave():
PHP:
if ($this->isUpdate())
{
    $this->last_update_date = \XF::$time;
}
else
{
    $this->creation_date = \XF::$time;
}
To stop you from having to manually set that field when you create and/or update the entity.

If you're using _preSave() for anything else, you're misusing it and that code should be running outside of the entity.

However, I had thought it was fair to say (until seeing the ire in this thread) that no one wants third-parties manipulating an entity if they don't know what's going on inside that entity. An add-on can generate a conflict if they use getStructure to see an add-on's database columns, and that add-on then makes changes to the column outside the normal operation of that entity, especially without even looking at how that entity operates first. In particular, this can cause issues when dealing with wiki entities, where many changes are supposed to be stored in history.
It's very much intended for third parties to manipulate an entity even if they don't know everything that goes on inside the entity, and no one is against this behaviour. For instance, if your Page entity doesn't provide a view counter, someone might add that feature and add a view_count or similar column to your entity. 3rd party addons that extend other 3rd party addons are commonplace.
The one caveat I'll add is that if you extend either a core XF entity or another 3rd party entity, you should add a vendor prefix to your column, f.ex. dbtech_vwe_view_count for "DragonByte Tech: VaultWiki Extended" to avoid conflict should XenForo/yourself add the feature in a future update.

Also, let's not forget about the fact that (to my knowledge) your addon is the only remaining addon on XenForo that still tries to juggle this cursed multiplatform setup, so people would know what's going on inside the entity if your data management business logic was inside the entity as the XenForo gods decree ;)

When I refer to "entity field values", I am talking about the specific content-type field, stored in xf_content_type_field, which has "entity" as its key. VaultWiki doesn't need this key defined for any of its entities to function, especially since VaultWiki knows the names and paths of its own entities. But other add-ons tended to find this key and do things to VaultWiki entities, some of which caused data issues, some of which caused errors. So we removed the "entity" entries from that database table.
The entity field is required for certain kinds of content type definitions, such as alert_handler_class, approval_queue_handler_class and, indeed, reaction_handler_class.
Specifically w.r.t. reactions, you can see the code that mandates an entity field in src/XF/Reaction/AbstractHandler.php:123:
PHP:
$entityType = \XF::app()->getContentTypeEntity($this->contentType, false);
If you want to see a complete list of content types that require an entity field, run the following searches in the src/XF folder:
  • ->findByContentType(
  • ->getContentTypeEntity(

While fixing the entity field for Reactions, I'd advise you to check if you're using any of these other content types, and make sure they define an entity field as well, to avoid this issue cropping back up in the future :)
 
I want to point out that one of the third-party add-ons quoted above by Xon, was a search add-on that (and I'm going from memory of events years past) allegedly scraped all content-types with a search_handler_class and automatically replaced their search_handler_class::getContent method with the search add-on's own function, without a human checking if this would be safe to do.

In particular, VaultWiki has a search_handler_class which combines aggregate search results for multiple wiki content-types (so a user can "search all wiki content" instead of "search one kind of wiki content"). For this reason, a specific "entity" cannot be used in that specific class, or at least would be wildly inefficient. Even if the more inefficient route were taken (by having separate entities for "aggregate"), this would not resolve the conflict with the add-on. Rather, the VaultWiki search_handler_class::getContent uses the indexed IDs to reverse lookup the entity IDs and then pulls the actual content entities as search results. But since the third-party add-on had overwritten search_handler_class::getContent, this reverse lookup could not take place, and the third-party add-on crashed. It is unclear how to fix this without removing that feature entirely.
 
I want to point out that one of the third-party add-ons quoted above by Xon, was a search add-on that (and I'm going from memory of events years past) allegedly scraped all content-types with a search_handler_class and automatically replaced their search_handler_class::getContent method with the search add-on's own function, without a human checking if this would be safe to do.
The conflict was because fetching the entity definition corresponding to the search handler throws an exception.

My addon doesn't actually load any content, it just filtered out already loaded entities by using their short-name and primary id as passed to the method. If an id doesn't match existing cotent, that id is passed unmodified to the original function I was extended.

Besides the call to \XF::app()->getContentTypeEntity, \XF::app()->em()->getEntityStructure and then \XF::app()->em()->findCached() it is basically a copy of the stock getResultSetData logic wise.
 
Top Bottom