News:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu

my self-inflicted hell (a cautionary tale - also, HELP!)

Started by permutations, May 19, 2015, 09:36:21 PM

Previous topic - Next topic

live627

I haven't looked at 1.1 in over a year, so I don't remember its syntax, but I'm fairly certain that it's the same.

There is a new hook, integrate_actions, to achieve the same thing.

permutations

#81
Quote from: Kindred on May 22, 2015, 12:56:13 PM
also note that 2.0.x has a significant number of HOOKS that can be used to link external things into the SMF system.
http://wiki.simplemachines.org/smf/Category:Integrating_SMF

this might make things easier for you....

Kindred, what is the best way to install hooks? I downloaded some random mods as examples, and I saw one where the integration hooks were installed as part of the module installation using <code></code> tags. But then when I looked at docs for package-info.xml, it said that the <code></code> tags were deprecated in SMF 2.0, and <database></database> should be used instead. But this is not database code. (Also, as an aside, I don't see why <code></code> tags are deprecated - you might need some code to install a mod.)

In any case, does this mean the integration hooks should not be installed as part of the module installation? Where would I do this instead?

I looked at this page:

http://wiki.simplemachines.org/smf/Add_a_custom_action_using_integration_hooks

...and the person writing it somehow manages to NEVER say how the code to install and uninstall the hooks is called. Where are these files he says to create included?? Maybe in Settings.php??

Quote from: live627 on May 23, 2015, 06:13:44 PM
I haven't looked at 1.1 in over a year, so I don't remember its syntax, but I'm fairly certain that it's the same.

There is a new hook, integrate_actions, to achieve the same thing.

The integrate_actions hook isn't the same thing. The wrapping and catching feature is part of the template system. The function that parses it, WrapAction(), is in Theme.php. It's a short function, and the comment about its possibilities isn't mine - this is straight from the 2.0.10 source code:


// Possibly the simplest and best example of how to ues the template system.
function WrapAction()
{
global $context, $settings, $sourcedir;

// Load any necessary template(s)?
if (isset($settings['catch_action']['template']))
{
// Load both the template and language file. (but don't fret if the language file isn't there...)
loadTemplate($settings['catch_action']['template']);
loadLanguage($settings['catch_action']['template'], '', false);
}

// Any special layers?
if (isset($settings['catch_action']['layers']))
$context['template_layers'] = $settings['catch_action']['layers'];

// Just call a function?
if (isset($settings['catch_action']['function']))
{
if (isset($settings['catch_action']['filename']))
template_include($sourcedir . '/' . $settings['catch_action']['filename'], true);

$settings['catch_action']['function']();
}
// And finally, the main sub template ;).
elseif (isset($settings['catch_action']['sub_template']))
$context['sub_template'] = $settings['catch_action']['sub_template'];
}


As you can see, the use of the function is undocumented. These are notes I wrote myself - I have no idea where I got this from. I was active in the forum when I was writing my fork, and someone must have told me about it. I was playing around with it and it worked. I didn't end up really using it for anything, though. I'm not sure how I could take advantage of it, but perhaps that's a failure of imagination.

The first block of code (and comments) is from the end of the function template_init() in index.template.php in my customized SMF 1.1 Beta 3 installation.


/*
Wrapping and Catching actions:

template: (e.g. 'index' as in 'index.template.php'. File must exist.)
The template file to load when the action is "caught".  This also loads the
corresponding language file at the same time.

layers:
An array of layers.  For example, you might use array('main', 'admin')
to show the main and admin layers - just like the admin center.

sub_template:
The sub template to load - doesn't work with function/filename.

function:
The function to call.  If this is set, the sub_template option will be
ignored completely.

filename:
The name of the file to load from under the Sources directory.  This
only has affect when it is set and 'function' is set.

You can combine these like so:

$settings['catch_action'] = array(
'template' => 'CoolTemplate',
'layers' => array('main', 'coolness'),
'sub_template' => 'coolinate'
);

Or like this, using a file from Sources: (to automatically go to your profile.)

$settings['catch_action'] = array(
'filename' => 'Profile.php',
'function' => 'ModifyProfile'
);
*/
// This does same thing as this: http://mysite.com/forum/index.php?action=profile
// But you can use any source file and call any function within it.
if (@$_REQUEST['action'] == 'modify_profile')
$settings['catch_action'] = array(
'filename' => 'Profile.php',
'function' => 'ModifyProfile'
);
elseif (@$_REQUEST['action'] == 'no_layers') // No layers, no subtemplate, so just loads template file.
$settings['catch_action'] = array(
'template' => 'test', // I created a file called test.template.php
'layers' => array(), // No layers in array. If omitted, defaults to array('site', 'main').
'sub_template' => 'none' // Subtemplate (must be defined) is the page content.
);
elseif (@$_REQUEST['action'] == 'site_layer')
$settings['catch_action'] = array( // Just loads my custom 'site' layer - no forum header.
'layers' => array('site'),
'sub_template' => 'none'
);
elseif (@$_REQUEST['action'] == 'main_layer') // Just loads the SMF layer. HTML <head> is in my 'site' 
$settings['catch_action'] = array( //   layer, so this looks funny.
'layers' => array('main'),
'sub_template' => 'none'
);
else
$settings['catch_action'] = array(
'layers' => array('site', 'main'),
'sub_template' => 'action_wrap'
);


Then after the end of that function, I have some other functions that implement some test code:


function template_action_wrap()
{
global $context, $settings, $options, $scripturl, $txt;

if (@$_REQUEST['action'] == 'exhaustion')
echo '
<h3>Programmer Exhaustion</h3>
<p>The owner of this site is a very overworked programmer.</p>';
else
template_four_oh_four();
}

// do-nothing function - sub_template has to be defined.
function template_none()
{
}

function template_four_oh_four()
{
global $context, $settings, $options, $scripturl, $txt;

echo '
<h2 align="center">Page not found...</h2>
<p style="font-size:14px; margin-left:25px; margin-right:25px;">
Sorry, the page you requested does not exist. If you are looking for a newsletter,
please click the "Newsletter" button. The newsletter links have changed.
</p>
';
}

permutations

I'm asking about these things because reimplementing my payment system in SMF 2.0 has prompted a very thorough code review, not surprisingly. I'm looking at everything and thinking about ways I could do it more efficiently. I want to touch the SMF code as little as possible.

permutations

Question:

I have never understood why SMF loads the template associated with source code before setting the $context[] variables that the page uses. Why aren't the $context[] variables set before the template file is included, and how can it possible work in reverse?

This has confused me for 10 years, and I would be deeply grateful for an explanation. Staring at the code has not helped!

live627

Quote
      echo '
      <h3>Programmer Exhaustion</h3>
      <p>The owner of this site is a very overworked programmer.</p>';
lmao

QuoteBut then when I looked at docs for package-info.xml, it said that the <code></code> tags were deprecated in SMF 2.0
Rest assured, they aren't.

QuoteThe integrate_actions hook isn't the same thing.
I didn't say that. The end result is  the same, ie. adding an action.

Quote
I have never understood why SMF loads the template associated with source code before setting the $context[] variables that the page uses. Why aren't the $context[] variables set before the template file is included, and how can it possible work in reverse?
Eh?

The template files are loaded for real in ob_exit() after all the logic finishes.  loadTemplate() simply adds to the queue.

permutations

Quote from: live627 on May 23, 2015, 09:24:45 PM
The template files are loaded for real in ob_exit() after all the logic finishes.  loadTemplate() simply adds to the queue.

I finally figured that out just now, looking in Subs.php. I'm not completely clear where the output buffer is initiated and how everything gets redirected. If there's an echo statement, how does know to write to the output buffer rather than the screen? Hmmm... Well, if I were doing that, I'd change the output device somewhere. That must happen somewhere?

P.S. Too bad it's too late to delete the heavily emphasized dumb question.  :-[

I also found add_integration_function() in Subs.php, so now I get that this is actually a database write - the hook is stored in the database, and thus much be installed as part of module installation. The fog is lifting.  :laugh:

Here's the page that says <code></code> tags are deprecated for SMF 2 in package-info.xml.

http://www.simplemachines.org/community/index.php?topic=299669.0

Illori


permutations

Quote from: Illori on May 24, 2015, 06:11:53 AM
http://wiki.simplemachines.org/smf/Package-info.xml is an updated version of that topic where that error has been corrected.

Thanks very much - good to know.

I've reapplied my site formatting (I use SSI on non-forum pages) to the SMF 2.0 installation, and that's mostly working. I am documenting every single change I make in modification.xml and package-info.xml files, as I make it.

The part that's not working isn't working because of database calls. I discovered that the function smf_query() has gone away. I decided to use native PHP functions instead of SMF functions for database access because PHP will change slower than SMF. That's when I found out that the PHP "mysql" extension is deprecated and soon will go away (in favor of mysqli or pdo). And - this is the bad part - SMF 2.0 still uses it. So I have another major SMF upgrade in my not-too-distant future.  :( :( :(

When I stopped tracking the changes I was making in SMF 1.1 Beta 3, I stopped being careful about what code was part of an SMF modification and what was just site code. So to reapply it as a mod that can be installed and uninstalled, I'm having to reorganize my code quite a bit. It's very slow going, as I find every change, think about whether it can be done more efficiently, and then apply it to the SMF 2.0 site. I sure hope this doesn't take me as long as the original fork took.

I noticed that my Post Moderation code is very tightly integrated with my Paid Access changes - so much so that it may be easier to reapply both than pull out the Post Moderation piece, though I know this feature exists in SMF 2.0. (I realize a paid-subscriptions feature exists in SMF 2.0, too, but I can't use it - I need the features in the version I wrote.) I called my Paid Access piece "Paid Subscriptions", which I now regret because it supports one-time fees as well as subscriptions. I was briefly tempted to change the name, but I have enough problems without that. Maybe later.

I also no longer like my site design. It's dated. But later for that, too.

margarett

Quote from: permutations on May 25, 2015, 12:34:49 PM
The part that's not working isn't working because of database calls. I discovered that the function smf_query() has gone away. I decided to use native PHP functions instead of SMF functions for database access because PHP will change slower than SMF. That's when I found out that the PHP "mysql" extension is deprecated and soon will go away (in favor of mysqli or pdo). And - this is the bad part - SMF 2.0 still uses it. So I have another major SMF upgrade in my not-too-distant future.  :( :( :(
Nein, nein ;D

Use $smcFunc instead. It's an abstraction layer that will take care of all of that for you, taking care of sanitizing inputs and stuff along the way :)
Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair


permutations

Quote from: margarett on May 25, 2015, 01:12:20 PM
Use $smcFunc instead. It's an abstraction layer that will take care of all of that for you, taking care of sanitizing inputs and stuff along the way :)

No way. SMF already had an abstraction layer, and the developers chose to radically change the interface (like what Drupal does). I'm not taking that chance again. I will use the native PHP functions. I want code that I can maintain.

Quote from: Illori on May 25, 2015, 01:21:13 PM
there is also http://custom.simplemachines.org/mods/index.php?mod=3469

Cool! Thanks for telling me. That must have been quite an undertaking. I imagine there are quite a few database calls in SMF.

margarett

Quote from: permutations on May 25, 2015, 02:18:34 PM
Quote from: margarett on May 25, 2015, 01:12:20 PM
Use $smcFunc instead. It's an abstraction layer that will take care of all of that for you, taking care of sanitizing inputs and stuff along the way :)

No way. SMF already had an abstraction layer, and the developers chose to radically change the interface (like what Drupal does). I'm not taking that chance again. I will use the native PHP functions. I want code that I can maintain.
Nop. $smcFunc is 200% compatible with SMF 2.1 so you are guaranteed to have a working code for some more years to come. Remember that 2.0 will be maintained until a new release AFTER 2.1 comes out, then 2.1 will be maintained after that and.... You get the picture :P
Quote from: permutations on May 25, 2015, 02:18:34 PM
Quote from: Illori on May 25, 2015, 01:21:13 PM
there is also http://custom.simplemachines.org/mods/index.php?mod=3469
Cool! Thanks for telling me. That must have been quite an undertaking. I imagine there are quite a few database calls in SMF.
No, it's just really replace "mysql" with "mysqli" in Settings.php. Exactly because $smcFunc deals with the rest automagically ;)
edit: and a duplication of all *mysql.php files with *mysqli.php
Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

permutations

Quote from: margarett on May 25, 2015, 02:24:30 PM
No, it's just really replace "mysql" with "mysqli" in Settings.php. Exactly because $smcFunc deals with the rest automagically ;)
edit: and a duplication of all *mysql.php files with *mysqli.php

There is no such setting in Settings.php. I just looked at the mod. It does a lot of work. It maps existing functions to the new ones, and adds ones that are missing.

Illori


permutations

The Settings.php for the board I upgraded doesn't have that. Also, the mod you linked to doesn't change anything in Settings.php. But I also have a full install test site (not an upgrade), and I see it in that Settings.php.

Judging from what the module does, changing "mysql" to "mysqli" would not fix everything. MySQLi is not on the list of supported databases - adding it to the array is one of the things changed in the code by the mod. Also, some of the mysqli calls reverse the parameters, and there are additional features.





Advertisement: