Daily Lucky Numbers:
4
9
22
32
41
45

Retrieving a line from a text file via tags

Started by Aaron, June 08, 2022, 11:34:19 PM

Previous topic - Next topic

Aaron

I'm trying to figure out how to retrieve a specific line from a text file hosted on the root of my site through tags:

array(
'tag' => 'test',
'type' => 'unparsed_content',
'before' => '[test]',
'after' => '[/test]',
'validate' => function(&$tag, $url)
{
if (preg_match('%([^"&?/ ])%i', $url, $match)) {$file = file_get_contents("./list.txt"); $match = explode(PHP_EOL,$file); $array = array_filter($m); $value = $match[1];
$tag['content'] = '<a="'. $value .'">Test Link</a>';
}
else
$tag['content'] = '<a href="$1" class="bbc_link" target="_blank" rel="noopener">$1</a>';
},
'trim' => 'both',
'quoted' => 'optional',
),

Basically trying to have the number placed in the [test][/test] tags retrieve the line number (for example 123 retrieves 124 etc.) which will then be placed within the anchor. This code reads the text file but only retrieves line 2 (because of the $match[1]).

I'm also not sure if theres a more efficient way of doing this (currently the file is small at 18KB but will grow).

Thanks

Chen Zhen

#1
A more efficient way would be to store the data in your database.
Does the source have to be a text file?

If you must use a file why not a CSV file?
You can put the file into an array & then just use the key (line #) that you're after.

Here is an example of a file named list.csv that contains links with their text:
https://simplemachines.org, SMF
https://web-develop.ca, WebDev

Here is an example of your BBCODE that brings up a link by line #:
            array(
                'tag' => 'test',
                'type' => 'unparsed_content',
                'before' => '[test]',
                'after' => '[/test]',
                'validate' => function(&$tag, $url) {
                    if (preg_match('%([^"&?/ ])%i', $url, $match)) {
                        $rows = array_map('str_getcsv', file('./list.csv'));
                        $csv = array();
                        foreach ($rows as $row) {
                          $csv[] = $row;
                        }
                        $value = !empty($match[1]) && abs($match[1]) > 0 ? abs($match[1]) - 1 : 0;
                        $tag['content'] = !empty($csv[$value]) ? '<a href="'. $csv[$value][0] .'">' . $csv[$value][1] . '</a>' : '<a href="$1" class="bbc_link" target="_blank" rel="noopener">$1</a>';
                    }
                    else
                        $tag['content'] = '<a href="$1" class="bbc_link" target="_blank" rel="noopener">$1</a>';
                },
                'trim' => 'both',
                'quoted' => 'optional',
            ),


If you put something like this BBC:
Quote[test]1[/test]

.. it should show the following:
WebDev


I haven't tested this but you should have an idea of what to do.
Yes a lengthy file will cause a delay when using line breaks to separate data.

Chen Zhen

#2
If you really need to use a .txt file then try this...

contents for file : list.txt
https://simplemachines.org, SMF
https://web-develop.ca, WebDev

BBCode insert for your SMF source file:
            array(
                'tag' => 'test',
                'type' => 'unparsed_content',
                'before' => '[test]',
                'after' => '[/test]',
                'validate' => function(&$tag, $url) {
                    if (preg_match('%([^"&?/ ])%i', $url, $match)) {
                        $f = fopen('./list.txt', 'r');
                        list($lines, $value) = array(array(), array());
                        if (!empty($f)) {
                            while (!feof($f)) {
                                $lines[] = fgets($f);
                            }
                            $lineValue = !empty($match[1]) && abs($match[1]) > 0 ? abs($match[1]) - 1 : 0;
                            if (!empty($lines[$lineValue])) {
                                $value = explode(',', $lines[$lineValue]);
                                $tag['content'] = !empty($value) && count($value) > 1 ? '<a href="' . $value[0] . '">' . $value[1] . '</a>' : '<a href="$1" class="bbc_link" target="_blank" rel="noopener">$1</a>';
                            }
                        }
                        if (count($value) < 2)
                            $tag['content'] = '<a href="$1" class="bbc_link" target="_blank" rel="noopener">$1</a>';
                    }
                    else
                        $tag['content'] = '<a href="$1" class="bbc_link" target="_blank" rel="noopener">$1</a>';
                },
                'trim' => 'both',
                'quoted' => 'optional',
            ),

I still included the link & text since it makes more sense to do it that way.

Aaron

How would I do it via database? I originally thought of doing it that way but I thought a file would be easier to update/upload but not overloading my server is the number 1 priority lol

Chen Zhen

#4
vbgamer has a mod that stores links in the database.
Its copyright allows me to edit it & post it on the forum.
I'm attaching it to this post so you can use it for your needs.

Mod Details:
- can change the permissions of adding/editing links to admin only (if that's your preference)
- BBCode option to allow you to use links as an ID#
- BBC membergroup permission is available for the admin which can set the permission to allow/disallow all BBC links as BBC (admin permissions)
- BBC membergroup permission to allow/disallow all BBC per category (mod admin)
- option to allow same window / external window for the BBC link
- each link shows its ID# to the left of its name in each category list
- each link shows its ID# in the edit link template
- option to provide a unique BBC name

If the membergroup has the permission to view the link & use the BBC then it will count the hits.
However if you only have the allow BBC checked then it will not count the hits.