[DigitalPoint] Better Google Analytics

[DigitalPoint] Better Google Analytics 1.1.2.3

No permission to download
Well I'm 100% certain there is nothing in the addon that would ever write any value to that option other than a 32-byte string. So if it's being erased somehow, it's something outside the addon.

Just to make sure there's not some random debugging code left in there, I grepped every occurrence of baAnalyticsKey in the code, and it's all as expected.

Bash:
twin1:/home/sites/sexytime.site/web/src/addons/DigitalPoint/Analytics # grep -R baAnalyticsKey *
Setup.php:                        if (function_exists('sodium_crypto_secretbox') && strlen(\XF::options()->baAnalyticsKey) != SODIUM_CRYPTO_SECRETBOX_KEYBYTES)
Setup.php:                        \XF::repository('XF:Option')->updateOption('baAnalyticsKey', \XF::generateRandomString(SODIUM_CRYPTO_SECRETBOX_KEYBYTES));
Util/Crypt.php:                   return \XF::options()->baAnalyticsKey;
XF/Admin/Controller/Tools.php:    \XF::repository('XF:Option')->updateOption('baAnalyticsKey', \XF::generateRandomString(SODIUM_CRYPTO_SECRETBOX_KEYBYTES));

In the Setup.php file, during installation it checks if Sodium is installed and that the option is not 32 bytes, and if Sodium is installed and the option isn't a 32-byte string, it writes a 32-byte string.

In the Util/Crypt.php file, it reads the option for using it to encrypt something (what's causing your problem since there's no string there).

The XF/Admin/Controller/Tools.php file will write a 32-byte string to the option when you ask it to generate a new string.

...and that's it. It's really not a lot of convoluted usage of the option that could get mixed up somewhere.

There is nothing in the addon that would ever erase the option value (the only 2 uses of updateOption() is when it clearly is writing a randomly generated 32-byte string when it's supposed to... during install or on request to reset it).

That being said, it's not a "read-only" database record or option (that's not a thing in XenForo). So anything with write access to your MySQL database could in theory change that value... so that could be any process doing anything with MySQL or some other addon (not sure what it would be, just saying it's a possibility).

What if that value has never been filled? How can I re-generate the value? Where is the button to redo that?

This is what I see in the Admin CP... but I don't see anything about re-generating a secret key.
 

Attachments

  • Screenshot 2025-01-22 at 6.25.43 PM.webp
    Screenshot 2025-01-22 at 6.25.43 PM.webp
    81.3 KB · Views: 6
What if that value has never been filled? How can I re-generate the value? Where is the button to redo that?

This is what I see in the Admin CP... but I don't see anything about re-generating a secret key.
Admin -> Tools -> Rebuild caches -> Reset analytics encryption key
 
@digitalpoint hello! I have some improvements. Can you check these please?

1) xf:js is not used in the macro named body in the helper_js_analytics template. It should be used.

2) In the ba_google_analytics template, script is used instead of xf:js. I wrote it so you can check which one is more suitable.

3) In the modification with helper_js_global_1_ba modification key, the find part is "#(<xf:corejs />.*?<script>)#si". Instead, <!--XF:JS--> should be used. If suggestion number 1 is not done (which would be very strange), xf:js should be used here.

This is the case in some of our themes. When the template modification is plain <script>, it does not work.

Code:
<xf:corejs />

<script{{ $xf.request.isRocketLoaderDisabled() ? ' data-cfasync="false"' : ''}}>
 
@digitalpoint hello! I have some improvements. Can you check these please?

1) xf:js is not used in the macro named body in the helper_js_analytics template. It should be used.
Arguable... using xf:js adds extra bytes to the page source. That being said, a change was made to make it a little more universal (especially in the newer versions of XF) as part of the next version.


2) In the ba_google_analytics template, script is used instead of xf:js. I wrote it so you can check which one is more suitable.
It's intentional. See above.
 
Arguable... using xf:js adds extra bytes to the page source. That being said, a change was made to make it a little more universal (especially in the newer versions of XF) as part of the next version.



It's intentional. See above.

Okay, whats about third information?
 
It's all the same thing, no? The helper_js_global_1_ba modification key is what's calling the helper_js_analytics template (your item #1).
 
It's all the same thing, no? The helper_js_global_1_ba modification key is what's calling the helper_js_analytics template (your item #1).

I wanted to clarify my concerns regarding the issue with gtag in the add-on. Right now, the helper_js_analytics template has three macros, two of which include <xf:js>, while the third is pure JavaScript without being wrapped in a <script> tag or <xf:js>. This macro is injected into the site via the helper_js_global_1_ba template modification within XenForo’s own script.

The issue occurs because gtag is sometimes undefined when the script attempts to call it, leading to an error. Since helper_js_global_1_ba contains essential XenForo functionality, this error stops its execution, effectively breaking the site. While the root cause is the missing gtag function, simply placing the JavaScript code inside a dedicated <script> tag (with or without <xf:js>) would prevent this problem.

Additionally, this issue happens when a user clears their cache and cookies. Another unexpected behavior I noticed is that my script tag right after <xf:corejs /> includes Rocket Loader code. This makes the template modification ineffective because the expected match doesn’t occur. I’m not sure how Rocket Loader was added—some templates show it was manually edited (visible in the template history), while others, like embed_view, contain Rocket Loader code but have no history of being modified. Since I’m currently facing hosting issues, I can’t check the database for more details. If you have any suggestions for further investigation, I’d appreciate your input.

Regarding the gtag issue: the function is created in the ba_google_analytics template, which is added by the PAGE_CONTAINER_1_ba template modification. However, the final PAGE_CONTAINER structure calls <xf:macro id="helper_js_global::head" arg-app="public" arg-jsState="{$jsState}" /> before including <xf:include template="ba_google_analytics" />. This suggests that gtag is being referenced before it is defined.

That’s why I originally suggested using <xf:js>. Even after adding a <script> tag manually, I still encountered a "gtag is not defined" error. However, this approach at least prevented the website from crashing. Wrapping the script in <xf:js> would ensure it runs slightly later, after gtag has been defined, eliminating the issue entirely.

I hope this explanation clarifies my concerns. Let me know your thoughts @digitalpoint.
 
If you are having a timing issue with Google Analytics trying to log an event before the gtag() function is defined, you are going to have that same issue in XenForo in general. If you look in XenForo's google_analytics template, they do the same thing (not wrapping it in xf:js). The reason is because it's important to get gtag() defined asap and not lazy-loaded or later down the page. Using xf:js would actually end up making the timing issue worse, not better because it potentially runs that JavaScript later than injecting it directly with <script> tags. Basically there's a reason it's done that way (even in XenForo default), because the goal is to get gtag() defined as soon as possible.

I do understand the concern about putting it in it's own <script> tag, but I'm not sure that's better in the end. You are talking about something unexpected causing an issue so you immediately know, vs. something unexpected not causing an issue, so instead you just potentially go months with no analytics happening.

Using xf:js for the initial defining of the gtag() function will definitely be problematic because moving it down in the execution chain means legitimate events are trying to fire before it's defined. The real issue is gtag() never got defined because of the Rocket Loader thing that was added.

Again, there's a reason <script> tags are used directly and certain code is injected as far up the execution chain as possible (while other code uses async loading and xf:js tags). And it's not just because someone was lazy and simply didn't want to use those mechanisms. ;)
 
If you look in XenForo's google_analytics template, they do the same thing (not wrapping it in xf:js).

But they place it inside a separate <script> tag. Wouldn't it be possible to do the same? That way, you wouldn't need to include the "script" part in the find regex of the template modification. Simply adding it after <xf:corejs /> should be enough. Would this cause any issues?
 
I understand what you are saying... but just like there's no guarantee that the <script> tag doesn't change (it did when they added the Rocket Loader stuff), there's also no guarantee that <xf:corejs /> never changes either.

The upside to having a separate <script> tag would help if malformed JavaScript were to be injected, but that wasn't the issue... the issue is that no JavaScript was injected because of the <script> tag change. So adding extra <script> tags doesn't really solve anything.
 
I wanted to clarify my concerns regarding the issue with gtag in the add-on. Right now, the helper_js_analytics template has three macros, two of which include <xf:js>, while the third is pure JavaScript without being wrapped in a <script> tag or <xf:js>. This macro is injected into the site via the helper_js_global_1_ba template modification within XenForo’s own script.

The issue occurs because gtag is sometimes undefined when the script attempts to call it, leading to an error. Since helper_js_global_1_ba contains essential XenForo functionality, this error stops its execution, effectively breaking the site. While the root cause is the missing gtag function, simply placing the JavaScript code inside a dedicated <script> tag (with or without <xf:js>) would prevent this problem.

Additionally, this issue happens when a user clears their cache and cookies. Another unexpected behavior I noticed is that my script tag right after <xf:corejs /> includes Rocket Loader code. This makes the template modification ineffective because the expected match doesn’t occur. I’m not sure how Rocket Loader was added—some templates show it was manually edited (visible in the template history), while others, like embed_view, contain Rocket Loader code but have no history of being modified. Since I’m currently facing hosting issues, I can’t check the database for more details. If you have any suggestions for further investigation, I’d appreciate your input.

Regarding the gtag issue: the function is created in the ba_google_analytics template, which is added by the PAGE_CONTAINER_1_ba template modification. However, the final PAGE_CONTAINER structure calls <xf:macro id="helper_js_global::head" arg-app="public" arg-jsState="{$jsState}" /> before including <xf:include template="ba_google_analytics" />. This suggests that gtag is being referenced before it is defined.

That’s why I originally suggested using <xf:js>. Even after adding a <script> tag manually, I still encountered a "gtag is not defined" error. However, this approach at least prevented the website from crashing. Wrapping the script in <xf:js> would ensure it runs slightly later, after gtag has been defined, eliminating the issue entirely.

I hope this explanation clarifies my concerns. Let me know your thoughts @digitalpoint.

This is the solve for us, we edited template modification by hand. @ekool
 
Back
Top Bottom