If given a long URL, this app generates a shortened URL, stores it in a table, and becomes a redirecter for the new shortened URL.
- PHP
- Apache
- MySQL
- phpunit
For more info about
my thought processes
scroll down to the
project checklist.
I decided to not make hashes for the URLs. The shortened URLs have a human readable mix of consonants and vowels to make them easier to remember and say. The shortened URLs end in a two-digit suffix. The URL shortener function checks the existing db to avoid a collision with existing shortened URLs. There are still over 500 million urls possible before running out of combinations.
Deploy notes for the database (MySQL). The app uses three tables:
CREATE TABLE IF NOT EXISTS sessions (
session_id serial,
user_id int NOT NULL,
date timestamp
);
CREATE TABLE IF NOT EXISTS users (
user_id serial,
email varchar(255) UNIQUE NOT NULL,
last_reset timestamp,
name varchar(60),
type varchar(12) DEFAULT 'free',
created timestamp DEFAULT '2020-01-01 11:11:11',
password varchar(32)
);
CREATE TABLE IF NOT EXISTS links (
link_id serial,
session_id int,
longurl varchar(1000) NOT NULL,
short varchar(40) UNIQUE
);
[ ] SANITIZER is too aggressive: sophisticated URLs from Amazon no longer redirect well. Use encode/decode steps, per below: html_entity_decode() Converts HTML entities to characters htmlentities() Converts characters to HTML entities
[x] Write the schema
[x] Make the Apache root directory
[x] Config file in dev and prod and .gitignore
[x] Start the rsync to the Apache root dir
run as
sudo /bin/bcompare
or sudo chown -R $USER:$USER /var/www/your_domain
[x] Serve a test page from prod
[x] Serve cards from php
[x] config file
[x] Hook up the database
[x] Basic Database Configuration.
[x] loading the homepage pings the dataconnection to get a count query of the db
[x] flushing css to bottom. Did this by making a wrap div 100% height
[x] pressing button should append a stripe div, repeatedly on the success page
[x] Make a html with put to db; every time home page loads a random url will be put to db
[x] Make a html with get from db; every time home page loads all the links retrieve and display from db
[x] Imitate a short, existing stack of yours on first run ('Worlds smallest LAMP')
[x] fix NULL in session id in links
[x] Imitate the CSS style of an admired page
[x] Ugh, whole-project pause: reorganize code to 1 class, 3 controllers, two main templates. Make sure still works.
[x] Make the shortener function
[x] Pass in the long URL from form to page 2
[x] First trivial test. Config phpunit.
[x] Make the checker for avoiding collisions, like the robot names? Use prepared statements per link below.
[x] Formify everything on the first page
[x] Make second page
[x] Configure apache to use a SQL table to do redirect
[x] Configure apache to use a rewrite table TEXTFILE to do redirect
[x] fix function notUnique; currently it is not checking anything
[x] Make a wrapper class around the DBTransaction for get/set the sql
[x] Make newlines append to the flat file used by Apache redirect
[x] button on success page should say 'make another'
[x] change menu bar to public always
[x] re-Enable --->public function notUnique(); make sure unit test still works
[x] use frontend validation
g
[x[]] Sanitize inputs using 12-1 from d powers book
[x] SQL statement is a prepared statement
[x] David Powers 11-6,
[x] Change tatll to PIKL in files
[o] CANNOT DUPLICATE BUG Reload of success page should not trigger new link making.
[x] ssh over the whole site
[x] Check location of the flat file.
[x] set up Localhost for flatfile to redirect
[ ] Apache 404 config oneliner. Prolly look in notes. Or default config grep it.
[x] run composer
[x] Check the SQL
[x] ssh keys all around: D.O., local, Github
[x] Capistrano local install
[x] Enable Beyond Compare for syncing to remote (ended up using Git to deploy instead -- too many permissions hassles)
[ ] Lint: todos. Error printers. Commented out code.
[ ] add private account
[ ] scrape new links for their favicons. Show site logos next to the long links that way.
[ ] look to see if any Composer package exists to avoid obscenity, blacklisted sites?
[ ] add a number of times clicked
[ ] Look over the actual algorithm ideas at https:// stackoverflow.com/questions/742013/ how-do-i-create-a-url-shortener
[x] Capistrano deploy needs DB and the flat file. Maybe not the config. ENDED UP using Git.
[x] Block spam with a Regex for now
[ ] Spam strategy needs a simple Captcha. By hand?
[ ] Too MVP. It's not very OOP. Move everything into classes.
[ ] leverage composer libraries (for malevolant users)
[ ] convert inputs to lower case
[ ] Write tests for addLinkToDbTest.php
[x] implement DBM with Apache. DB writes to a flat file (text, mod_rewrite)
[ ] confirm db, file errors go to logging. Get a logger from composer. Add log path to config
[ ] call logging in core/helpers/addToLinkages.php
[ ] make helpers into classes, OOP
[ ] accessibility
[ ] remove unused USE statements
[ ] Write at least three test cases in the tests/ folder. Run php bin/phpunit
[ ] Add a parser option to put the originals URL in as a dubdomain.
[ ] Add captcha?
[ ] refactor require/use/namespace everywhere, especially in tests. If desperate can try to use global namespace option onn some things per https://blog.eduonix.com/ web-programming-tutorials/namespaces-in-php/
[ ]
Your link is by default public but can also be saved to your private account. After shortening the URL, check how many clicks it received.
[ ] rightclick format document on everything or run phpcs at BASh
modules to enable sudo a2enmod rewrite sudo a2enmod dbd
enable site sudo a2ensite tatll.org
/etc/apache2/apache2.conf
#...
Nothing added here at all. Not even 'RewriteEngine on'
/etc/apache2/sites-enabled/tatll.org.conf
Note: Must set up reference map outside of the directory block. Okay to say 'rewriterule' inside of block though!
GNU nano 4.8 /etc/apache2/sites-available/tatll.org.conf
1 <VirtualHost *:80>
2 ServerName tatll.org
3 ServerAlias www.tatll.org
4 ServerAdmin webmaster@localhost
5 DocumentRoot /var/www/tatll.org
6 # LogLevel: Control the severity of messages logged to the error_log.
7 # Available values: trace8, ..., trace1, debug, info, notice, warn,
8 LogLevel trace6
9
10 ErrorLog ${APACHE_LOG_DIR}/error.log
11 CustomLog ${APACHE_LOG_DIR}/access.log combined
12 RewriteEngine on
13 RewriteMap pickleFlat txt:/home/evan/projects/do-not-commit/shortener.txt
14 <Directory /var/www/tatll.org>
15 Options Indexes FollowSymLinks
16 AllowOverride All
17 Require all granted
18 RewriteRule \/?(\w{6}\d{2})$ ${pickleFlat:$1} [L]
19 # note the slash is a literal char
20 # note the [L] is required
21
22 # For all requests where files and folders do not exist
23 RewriteCond %{REQUEST_FILENAME} !-d
24 RewriteCond %{REQUEST_FILENAME} !-f
25 RewriteRule . templates/404.php [L]
26 </Directory>
27 </VirtualHost>
28
Path projects/data/shortener.txt
Format:
abcdef12 https://example.com
Files to ignore
.gitignore
phpunit*
Folders to ignore
.git
vendor
[PDO examples for calling the db] (https://www.php.net/manual/en/pdo.prepare.php) frontend validation backend untainting