News:

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

Main Menu

Some new coding techniques

Started by NanoSector, May 05, 2012, 05:13:12 PM

Previous topic - Next topic

NanoSector

Hi all!

I've been playing around with SMF some more lately, writing a couple of mods, hence some more bug reports around here.
I decided to write a lightweight Mod Site for personal use. It's nothing compared to the mod site here, though :P

I wanted to learn some new coding techniques for handling such mods, or rather plugins. However you want to call them.
Maybe also some general techniques will be useful.

This is my "bootstrapping" file:
<?php

function ModHome()
{
    global 
$context$user_info$txt$scripturl;
    
    
// This is just a quick redirector for the main functions. Nothing special.
    
if (!isset($_REQUEST['sa']))
        
$_REQUEST['sa'] = 'home';
    
    
// Actions, array('Source function', 'Template function')
    
$actions = array(
        
'author' => array('ByAuthor''byauthor'),
        
'home' => array('BrowseHome''home'),
        
'browseall' => array('BrowseMods''browseall'),
        
'view' => array('ViewMod''view'),
    );
    
    
// Load the language and templates...
    
loadLanguage('ModSite');
    
loadTemplate('ModSite');
    
    
// Setup the linktree for a bit...
    
$context['linktree'][] = array(
        
'url' => $scripturl '?action=mods',
        
'name' => $txt['modsite']
    );
    
    
// Then setup everything from here!
    
$context['sub_template'] = 'modsite_' $actions[$_REQUEST['sa']][1];
    
$actions[$_REQUEST['sa']][0]();
}

function 
BrowseHome()
{
    global 
$context$user_info$smcFunc$modSettings$txt;
    
    
// Okay, gather all of our materials. Latest mods first.
    
$latestmods_result $smcFunc['db_query']('''
        SELECT id, name
        FROM {db_prefix}modsite_mods
        ORDER BY id DESC
        LIMIT 0,{int:limit}'
,
        array(
            
// To how many would we like to limit 'em?
            
'limit' => 5
        
));
    
    
// Start empty, of course.
    
$latestmods = array();
    
    
// Then start filling it like a geek.
    
while ($lmod $smcFunc['db_fetch_assoc']($latestmods_result))
        
$latestmods[] = $lmod;
    
    
// Now build up the context.
    
$context['modsite']['home'] = array(
        
'latestmods' => $latestmods,
        
    );
}

function 
ByAuthor()
{
    global 
$context$txt$smcFunc$user_profile;
    
    if (!
loadMemberData($_REQUEST['uid']))
        
fatal_lang_error('user_no_exists');
        
    
$context['modsite']['author'] = $user_profile[$_REQUEST['uid']];
    
    
// This is just a simple list of all mods by this author... So keep it simple!
    
$result $smcFunc['db_query']('''
        SELECT id, name, shortdesc
        FROM {db_prefix}modsite_mods
        WHERE authorid = {int:id}
        ORDER BY id DESC'
,
        array(
            
'id' => $_REQUEST['uid'],
        ));
        
    
$mods = array();
    while (
$mod $smcFunc['db_fetch_assoc']($result))
    {
        
$mods[] = array(
            
'id' => $mod['id'],
            
'name' => $mod['name'],
            
'sd' => parse_bbc($mod['shortdesc']),
        );
    }
        
    
$context['modsite']['mods'] = $mods;
    
    
// Setup the linktree again...
    
$context['linktree'][] = array(
        
'url' => $scripturl '?action=mods;sa=author;uid=' $_REQUEST['uid'],
        
'name' => $txt['browse_by_user']
    );
}

function 
BrowseMods()
{
    
}

function 
BrowseMod()
{
    
}

function 
ViewMod()
{
    global 
$context$user_info$user_profile$smcFunc$scripturl$settings;
    
    
// Load the mod data. Grab the ID too so it's complete.
    
$mod_data_result $smcFunc['db_query']('''
        SELECT id, name, authorid, descr
        FROM {db_prefix}modsite_mods
        WHERE id = {int:modid}'
,
        array(
            
'modid' => $_REQUEST['mod'],
        ));
        
    
// Since we have only one result (probably), only fetch it once.
    
$mod_data $smcFunc['db_fetch_assoc']($mod_data_result);
    
    
// Also load the attachments.
    
$mod_attach_result $smcFunc['db_query']('''
        SELECT id, is_current, filename
        FROM {db_prefix}modsite_attachments
        WHERE modid = {int:modid}'
,
        array(
            
'modid' => $mod_data['id']
        ));
        
    
// Okay, fetch it and while we are at it sort them.
    
$attachments = array();
    while (
$attach $smcFunc['db_fetch_assoc']($mod_attach_result))
    {
        
// Okay, sort 'em out!
        
$current $attach['is_current'] ? 'current' 'archive';
        
        
// Get rid of this one since we are sorting it out anyway.
        
unset($attach['is_current']);
        
        
// Put it in the respective group.
        
$attachments[$current][$attach['id']] = $attach;
    }
    
    
// Load the member data.
    
loadMemberData($mod_data['authorid']);
    
    
// And setup the mod context.
    
$context['currentmod'] = array(
        
'author' => $user_profile[$mod_data['authorid']],
        
'name' => $mod_data['name'],
        
'id' => $mod_data['id'],
        
'description' => parse_bbc($mod_data['descr']),
        
'is_own' => $mod_data['authorid'] === $user_info['id'],
        
'attachments' => $attachments,
    );
    
    
// Setup the linktree, too.
    
$context['linktree'][] = array(
        
'url' => $scripturl '?action=mods;sa=view;mod=' $_REQUEST['mod'],
        
'name' => $mod_data['name'],
    );
}

?>


This is my template:
<?php

// ModSite template

function template_modsite_home()
{
    global 
$context$txt$scripturl;
    echo 
'
        <div class="cat_bar">
            <h3 class="catbg">
                '
$txt['modsite_latestmods'], '
            </h3>
        </div>
        <div class="plainbox">'
;
        
        
//echo var_dump($context['modsite']['home']['latestmods']);
        
$i 1;
        foreach (
$context['modsite']['home']['latestmods'] as $mod)
        {
            echo 
$i'. <a href="'$scripturl'?action=mods;sa=view;mod='$mod['id'], '">'$mod['name'], '</a><br />';
            
$i++;
        }
        
        echo 
'
        </div>
        <br class="clear" />'
;
}

function 
template_modsite_browseall()
{
}

function 
template_modsite_view()
{
    global 
$context$txt$scripturl$modSettings$settings;
    echo 
'
        <div class="cat_bar">
            <h3 class="catbg">
                '
$context['currentmod']['name'], '
            </h3>
        </div>
        <table style="width:100%;">
            <tr>
                <td style="width:50%;">
                    <div class="title_bar">
                        <h3 class="titlebg">
                            '
$txt['downloads'], '
                        </h3>
                    </div>
                    <span class="upperframe"><span></span></span>
                    <div class="roundframe">'
;
                    
                    if (!empty(
$context['currentmod']['attachments']['current']))
                    {
                        echo 
'
                        <strong>' 
$txt['latest_version'] . ':</strong><br />';
                        
                        
// Go through all of the attachments and create a link.
                        
foreach ($context['currentmod']['attachments']['current'] as $attach)
                        {
                            echo 
'
                        <a href="'
$scripturl'?action=mods;sa=dlattach;attachid='$attach['id'], '">'$attach['filename'], '</a><br />';   
                        }
                        
                        echo 
'<br />';
                    }
                    echo 
'
                    </div>
                    <span class="lowerframe"><span></span></span>
                </td>
                <td style="width:50%;">
                    <div class="title_bar">
                        <h3 class="titlebg">
                            '
$txt['author_info'], '
                        </h3>
                    </div>
                    <span class="upperframe"><span></span></span>
                    <div class="roundframe">
                        <div class="centertext">
                            <a href="'
$scripturl'?action=profile;u='$context['currentmod']['author']['id_member'], '" class="subject">
                                '
$context['currentmod']['author']['member_name'], '
                            </a>
                            '
, !empty($context['currentmod']['author']['member_group_color']) ? '
                            <div style="color:' 
$context['currentmod']['author']['member_group_color'] . ';">
                                ' 
$context['currentmod']['author']['member_group'] . '
                            </div>' 
$context['currentmod']['author']['member_group'];
                            
                            
$stars explode('#'$context['currentmod']['author']['stars']);
                            echo 
str_repeat('<img src="' $settings['images_url'] . '/' $stars[1] . '" alt="#" />'$stars[0]), '
                            
                            '
, !empty($context['currentmod']['author']['avatar']) ? '<br /><img src="' $context['currentmod']['author']['avatar'] . '" style="max-height:' $modSettings['avatar_max_height_external'] . 'px;max-width:' $modSettings['avatar_max_width_external'] . 'px;" alt="" />' '',
                               !empty(
$context['currentmod']['author']['personal_text']) ? '<br /><em>"' $context['currentmod']['author']['personal_text'] . '"</em>' '''
                               
                            <br /><br /><a href="'
$scripturl'?action=mods;sa=author;uid='$context['currentmod']['author']['id_member'], '">'$txt['view_more_author'], '</a>
                        </div>
                    </div>
                    <span class="lowerframe"><span></span></span>
                </td>
            </tr>
        </table>
        <div class="title_bar">
            <h3 class="titlebg">
                '
$txt['description'], '
            </h3>
        </div>
        <div class="plainbox">
            '
$context['currentmod']['description'], '
            '
var_dump($context['currentmod']), '
        </div>
        <br class="clear" />'
;
}

function 
template_modsite_byauthor()
{
    global 
$context$txt$scripturl;
    
    echo 
'
        <div class="cat_bar">
            <h3 class="catbg">
                '
sprintf($txt['mods_by'], $context['modsite']['author']['member_name']), '
            </h3>
        </div>'
;
        
    foreach (
$context['modsite']['mods'] as $mod)
    {
        echo 
'
        <div class="title_bar">
            <h3 class="titlebg">
                <a href="'
$scripturl'?action=mods;sa=view;mod='$mod['id'], '">'$mod['name'], '</a>
            </h3>
        </div>
        <div class="plainbox">'
$mod['sd'], '</div>';
    }
    
    echo 
'
        <br class="clear" />'
;
}

?>


And these are my language strings:
<?php

$txt
['modsite_latestmods'] = 'Latest mods';
$txt['author_info'] = 'Author info';
$txt['latest_version'] = 'Current version(s)';
$txt['old_versions'] = 'Archive';

$txt['modsite'] = 'Mod Site';
$txt['downloads'] = 'Downloads';
$txt['description'] = 'Description';

$txt['view_more_author'] = 'View more mods by this author';

$txt['user_no_exists'] = 'This user doesn\'t exist.';
$txt['browse_by_user'] = 'Browse by author';

$txt['mods_by'] = 'Mods by %s';

?>


Live example:
http://map3cms.co.cc/?action=mods

Does anybody have some huge/tiny suggestions for that?
I know the code isn't valid for the mod site by far. Maybe also some suggestions on that?

Oh, I know that I can use OOP, by the way, but I just didn't feel like it lol.

Thanks a bunch!
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

Matthew K.


Iomega0318

No kidding man, nice job! I'd love to see this as a mod!
UOFreeshards.net
UOFreeshards.net 2.1 Aplha Test Site
"I believe in Christianity as I believe in the sun...
not because I see it but because by it I see everything else."
C.S. Lewis

Heed what I say, for it shall be mentioned only once.

vbgamer45

Good start I do like the view mod page looks nice.
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

NanoSector

Thanks all! :)

I might be releasing it as a package, not sure, maybe a DIY package. Oh well, we'll see :)

Lately I finished the attachments a bit more, so it now also displays the archived, non-current files, in the Downloads box. When that lot is finished, I'll start with editing and deleting mods, including a separate page for managing added files.

I'll keep you updated :)

Though, did ya lot find any obvious errors I skipped over? :P
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

emanuele

* emanuele wonders if there is a repo somewhere : P


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

NanoSector

#6
Quote from: emanuele on May 07, 2012, 04:02:36 AM
* emanuele wonders if there is a repo somewhere : P
Nope, sorry.

I'll set one up in a while.

EDIT: Got a GitHub repo:
https://github.com/Yoshi2889/tinymodsite
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

Robert.

Nice work! :) If I may suggest though, what about adding random mods on the frontpage? And top mods, etc? :P

NanoSector

Quote from: 医生唱片骑师 on May 07, 2012, 03:02:45 PM
Nice work! :) If I may suggest though, what about adding random mods on the frontpage? And top mods, etc? :P
Random mod? That's fine.

Top mods are added in the last GitHub commit, based on downloads :)
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

The Craw

You might change the foreach in your template to a for loop instead, since you're using using incrementing numbers. Not that it matters either way, just a matter of preference.


        $mods = $context['modsite']['home']['latestmods'];
        for ($i = 0, $c = 1; $i > count($mods); $i++, $c++)
        echo $c, '. <a href="', $scripturl, '?action=mods;sa=view;mod=', $mods[$i]['id'], '">', $mods[$i]['name'], '</a><br />';

Matthew K.

Actually, there's no need to do that ;)

You can use an ordered list which works out even better.

Suki

I've been doing working on something similar: https://github.com/MissAllSunday/ModSite  is been built as generic as possible and with github integration (gotta write some very basic php API first), still working on the background stuff.

Perhaps we can merge those and make a unique script.
Disclaimer: unless otherwise stated, all my posts are personal and does not represent any views or opinions held by Simple Machines.

NanoSector

Quote from: Suki on May 08, 2012, 10:55:51 AM
I've been doing working on something similar: https://github.com/MissAllSunday/ModSite  is been built as generic as possible and with github integration (gotta write some very basic php API first), still working on the background stuff.

Perhaps we can merge those and make a unique script.
That'd be cool :)

If you could merge them, then, and shoot both Lab and me the details of what you are working on we might get somewhere :)

Attached is the SQL for this mod site.
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

Matthew K.

They'd probably be difficult to 'merge' since one is OOP and one is procedural. Probably best if anything to just go with the OOP and build from there.

NanoSector

Quote from: Labradoodle-360 on May 08, 2012, 11:54:30 AM
They'd probably be difficult to 'merge' since one is OOP and one is procedural. Probably best if anything to just go with the OOP and build from there.
Yeah.

I'll install Suki's one somewhere later on today ,first have to finish my homework for now (ain't that much, I'm online in the meantime)
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

vbgamer45

You should add some indexing keys on

`authorid` int(11) NOT NULL,
`modid` int(11) NOT NULL,

Simple to do
ALTER TABLE tablename add index (authorid)

Generally with indexes you add index if you are searching/loooking up data on the where clause and not using true/false.
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

NanoSector

Quote from: vbgamer45 on May 08, 2012, 02:35:15 PM
You should add some indexing keys on

`authorid` int(11) NOT NULL,
`modid` int(11) NOT NULL,

Simple to do
ALTER TABLE tablename add index (authorid)

Generally with indexes you add index if you are searching/loooking up data on the where clause and not using true/false.
Oh, thanks! I thought I was doing lots of things wrong in the database lol.

Probably done in Suki's version already, though :)
My Mods / Mod Builder - A tool to easily create mods / Blog
"I've heard from a reliable source that the Answer is 42. But, still no word on what the question is."

Advertisement: