Sie sind auf Seite 1von 35

Student Sponsorship Web Application

Documentation
Charles Thompson • charliet@gmail.com

i
Contents
Contents.......................................................................................................................................... ii

Introduction..................................................................................................................................... 1

Conceptual Framework................................................................................................................... 2

Tools and Methods.......................................................................................................................... 3

Server2Go....................................................................................................................................3

PHP Portable SMTP Server for Windows.......................................................................................4

Geany........................................................................................................................................... 5

MySQL Query Browser.................................................................................................................6

phpMyAdmin................................................................................................................................ 6

Datejs........................................................................................................................................... 6

AJAX.............................................................................................................................................7

Anatomy of an AJAX function call..............................................................................................7

Viewing asynchronous PHP output............................................................................................8

Firebug......................................................................................................................................... 9

dBug............................................................................................................................................. 9

Login Management....................................................................................................................10

Header and Footer.....................................................................................................................11

encabezado.php......................................................................................................................11

pie.php....................................................................................................................................11

conectar.php........................................................................................................................... 11

Database....................................................................................................................................... 12

estudiante..................................................................................................................................12

necesidad...................................................................................................................................12

patrocinio................................................................................................................................... 13

ii
users..........................................................................................................................................13

Front End....................................................................................................................................... 15

index.php...................................................................................................................................15

Search.....................................................................................................................................15

Recientes Patrocinios..............................................................................................................15

Pendientes Necesidades......................................................................................................... 16

Donation Interface..................................................................................................................17

visualizar_estudiante.php..........................................................................................................19

Student Details.......................................................................................................................19

Student Images....................................................................................................................... 19

Necesidades............................................................................................................................ 20

Patrocinios..............................................................................................................................20

Historia...................................................................................................................................21

usuario.php................................................................................................................................ 22

User Details............................................................................................................................ 22

Patrocinios..............................................................................................................................22

buscar.php.................................................................................................................................23

Site Administration........................................................................................................................24

estudiante.php........................................................................................................................... 24

actualizar_estudiante.php.......................................................................................................24

Student Details.......................................................................................................................25

Necesidades............................................................................................................................ 26

borrar_necesidad.................................................................................................................... 27

Patrocinios..............................................................................................................................28

borrar_beca............................................................................................................................. 29

admin.php.................................................................................................................................. 30

iii
Pendientes Patrocinios............................................................................................................30

Recientes Patrocinios..............................................................................................................31

Pendientes Necesidades......................................................................................................... 31

iv
Introduction
The Student Sponsorship Web Application was developed for two purposes, fundraising and
record management. Fundraising is accomplished by providing a simple, transparent means by
which members of the public can sponsor individual students through a the worldwide web.
Record management is performed through the capture of information as it is entered into the
application for display to the public and as records are created to account for and display
sponsorships.

The application consists of a MySQL Database and a PHP front end. At the time of this
documentation there are 6 PHP scripts—4 that render publicly accessible pages and 2 that
render password-protected administrative pages—that make up the core of the application. In
addition, there are 9 PHP scripts that make up the application's login/session-handling and 6 PHP
scripts that perform other functions for a total of 21 files at the root level. The database consists
of a single schema with four tables.

1
Conceptual Framework
The design of the Student Sponsorship Web Application follows a simple flow from a student's
need to a sponsor's satisfaction of that need. The process begins when a student enrolls in his or
her first class at Enlace Quiche. At the time of his or her enrollment, a student record is created
along with a record of the course in which he or she has been enrolled (see estudiante.php). The
course record represents a need the student has and includes a need amount that is equal to his
or her unmet tuition costs. Every need pertains to exactly one student for exactly one course.
From this point forward, that need is published on the web for review by potential sponsors.

At this point, sponsors can pledge all or part of the student's needed tuition for the course via
Enlace Quiche's account at clickandpledge.com. When a sponsor pledges a sponsorship, a record
is created by capturing the sponsor's ID and the ID of the need toward which the sponsor is
donating. A need may have no sponsors, it may have one sponsor, or it may have many
sponsors. It remains available to be sponsored until it's total amount has been pledged.

When a pledge is recieved its status is considered "no aprobado" or "prometido", meaning
pledged amount has been promised, but not yet received. Accordingly, it appears to
administrators in red. Once the pledge is recieved, the administrator is notified and he/or she
uses the application to change the sponsorship to green, signifying "aprobado" or "recibido".

2
Tools and Methods
The Student Sponsorship Web Application was developed using Server2Go, a light-weight,
portable WAMPP (Windows, Apache, MySQL, PHP, and PERL) stack using a number of free, open-
source applications and libraries. For flexibility, the PHP code does not rely on any particular
development framework or content management system. In addition, JavaScript was used to
accomplish certain tasks such as input validation and asynchronous HTTP requests (AJAX).

Server2Go
Unlike other server platforms, the servers in Server2Go are not run as Windows services, but
rather processes that start when the Server2Go application is started. The version used was
1.6.0, which includes the following:

Apache/2.2.6 (Win32)

PHP/5.2.6

SQLite 2

MySQL 5.0.41-community-nt

Perl 5.8

To "install" it, simply extract the files within the zip archive to C:\server2go. To launch it, run
Server2Go.exe within the server2go folder. You can change certain aspects of the way
Server2Go runs by manipulating the variables found in its config file, "pms_config.ini". Since I
made heavy use of a MySQL database I paid special attention to the section of pms_config.ini
labeled "[database]". Since Server2Go is designed to run on a portable drive or even a CD, it is
designed to allow for database to be written to a temp drive and deleted when Server2Go.exe is
stopped. Since our intention is to model the Student Sponsorship Application the way it would
run on the web, there is no need for Server2Go to behave in this way. For this reason it is
necessary that the variables LocalMirror, OverwriteLocalMirror, and DeleteDatabaseFiles be set
to zero.

Anything you put at the web root, htdocs inside the server2go folder will appear on localhost on
port 4001 (http://localhost:4001). The Student Sponsorship Application is located in the folder
C:\server2go\htdocs\becas the folder "old" under htdocs contains some older versions of the
application. Note that if you want to view them, you must move them back out of "old" and into
htdocs since they contain relative links that would otherwise be broken. If you do this, be sure to
rename the current "becas" folder so that it is not overwritten.

It should be noted that Version 1.6.0 didn't work correctly at first. It turned out that a number of
changes were necessary to the Apache config file, httpd.conf located in
C:\server2go\server\config_tpl

3
The changes were as follows:

On line 232:

index.php index.html index.htm index.php4 index.php3 index.cgi index.pl


index.html.var index.phtml default.htm default.html

becomes:

DirectoryIndex index.php index.html index.htm index.php4 index.php3


index.cgi index.pl index.html.var index.phtml default.htm default.html

On lines 316 and 317:

ScriptAlias /cgi-bin/ "%CDPMS:BASEDIR%/cgi-bin/"


Alias /phpmyadmin "%CDPMS:BASEDIR%/admin/phpmyadmin/"

becomes:

ScriptAlias /cgi-bin "%CDPMS:BASEDIR%cgi-bin"


Alias /phpmyadmin "%CDPMS:BASEDIR%admin\phpmyadmin"

And on line 334:

<Directory "%CDPMS:BASEDIR%/admin/phpmyadmin">

becomes:

<Directory "%CDPMS:BASEDIR%admin\phpmyadmin">

Solutions to a variety of developer issues are available on the Server2Go forums at


http://www.server2go-web.de/forum/

PHP Portable SMTP Server for Windows


One thing that was needed, but was not included in the Server2Go bundle was a mail server.
Luckily, I was able to locate online a portable SMTP server written in PHP. It can be downloaded
at http://sourceforge.net/projects/smtpserverwin/. When dealing with this application, however,
one must exercise caution; when I unpacked the zip archive I downloaded from SourceForge I
was alerted by my antivirus software that it had intercepted "Trojan.Agent.FNM". For this reason
I recommend that it be used as little as possible and that the aspects of development that
involve mail be taken care off once the application has been put on a real server with a better
mail transfer agent.

"PHP Portable SMTP Server for Windows" comes with the uncompiled PHP script, "smtp.php", to
make the server executable file along with a DLL and some files used compile it. Simply alter the
PHP to reflect your server settings and run the batch file "compile.bat". As a result, the server
executable file, "smtp.exe" is created. For the Server2Go configuration, I replaces lines 63-65 of
smtp.php:

4
$str=exec("nslookup -q=mx $domain");
$tmp=split("=",$str);
$smtp_server=trim($tmp[2]);

with:

$smtp_server='mail.enlacequiche.org';

It should be noted that running compile.bat sometimes raises another warning for
"Trojan.Agent.FNM". I was unable to determine what was different between times when the
Trojan warning was created and times when it wasn't.

Geany
Early on in the development process, it was necessary to find an IDE that wouldn't freeze up the
development computer when it was run at the same time at Mozilla Firefox. The solution to the
problem proved to be Geany. Geany is exceptionally light-weight because it is designed to use
other applications and utilities to perform task which other development environments have
built-in. For example, to find a string of text in multiple files, it uses the utility, "grep". In order to
supply this, I downloaded a collection of GNU utilities called "UnxUtils"
(http://unxutils.sourceforge.net/).

Once downloaded, I extracted the contents of the UnxUtils zip archive to C:\tools\unxutils. Then I
assigned the UnxUtils grep utility as the application used by Geany to do greps (for performing
regular expression searches on multiple files. This is done by first running Geany and navigating
to Edit > Preferences > Tools. In the field labeled "Grep" enter
C:\tools\unxutils\usr\local\wbin\grep.exe. Press, "Apply" and then "OK".

In order for the UnxUtils utilities to run from the command prompt, you still have to add them to
the Window Path variable. To do this, first open the System Properties dialog by right-clicking My
Computer in the Start menu and clicking Properties. Next click the "Advanced" tab and click the
button labeled "Environment Variables". After that, click "Path" in the box labeled "System
Variables" and click the "Edit" button. In the box labeled "Variable value", add the strings,
"C:\unxutils\bin\" and "C:\unxutils\usr\local\wbin\" separated from one another and from the rest
of the contents of the box by semicolons. Click OK to set the Path variable, OK, to close the
Environment Variables dialog and OK to close the System Properties dialog.

Geany comes with a number of plugins included. The only one I used, which proved
indispensible, was File Browser, a pane on the left side of the editor that shows a list of file in the
project you're working on and allows you to open them with ease. To make sure it's turned on,
Tools > Plugin Manager.

Geany uses a kind of project file (*.geany) to remember where the a files within a project are
located and which were open in the tabs in the editor when Geany was last closed. It is a good
idea to create a project before you begin developing. This is doing by going to Project > New.
The name you give it will be the same as the project file name with the extension ".geany". I
named the Student Sponsorship Web Application project "scholarships" and left the file path and
name as the default, C:\Documents and Settings\Administrator\projects\scholarships.geany.

5
The base path I changed to the application's folder under the Server2Go web root,

C:\server2go\htdocs\becas

MySQL Query Browser


Another tool that has proven indispensible during the development process is MySQL Query
Browser, an application put out by Sun Microsystems and available as part of the MySQL GUI
tools available on the MySQL website at http://dev.mysql.com/downloads/gui-tools/.

MySQL Query Browser provides a tabbed GUI with inputs for SQL scripts and spreadsheet-like
query results along with a useful error console and tree-style schema/table browser. It was
particularly helpful whenever I was developing a PHP script and I got the error "supplied
argument is not a valid MySQL result resource". Whenever this happened, I simply modified my
PHP to echo the query before it is executed and cut and paste the echoed query from my
browser into MySQL Query Browser. Often MySQL Query Browser's syntax highlighting was
enough to show me where I was going wrong. If not, I could always go through trial-and-error
with the query getting constant feedback from the query results and/or warnings and errors.

phpMyAdmin
An unfortunate consequence of running MySQL as a process instead of a service is that you can't
run the various command-line utilities that come with MySQL such as mysqldump, a utility which
generates a script to create a table or an entire schema including table contents. This is
extremely useful when backing up large sets of data before attempting changes to table
structure.

To accomplish this without mysqldump I found I was able instead to use phpMyAdmin. To access
phpMyAdmin, simply point your browser at the web root, http://localhost:4001, and click the link
on the right under "tools" to phpMyAdmin.

Once in phpMyAdmin, select "becas" from the drop-down menu on the left. To generate a dump
of the entire schema, click the tab labeled "export". Otherwise, click the browse button next to
the table you want to dump and then click export. The only change to make to the export form is
at the bottom to check the box next to "Save as file". Click "Go" and save the SQL script file
(*.sql) to your hard drive. To restore the schema or table, simply open the script in MySQL Query
Browser and click "Execute".

Datejs
When it came time to test the Student Sponsorship Web Application, I found myself needing to
handle a wide variety date formats. To accomplish this, I employed a remarkably flexible
JavaScript library called Datejs.

To use this library, I just had to put a single Guatemala-specific .js file in the js folder under
"becas" and link to it in encabezado.php:

<script src="js/date-es-GT.js" type="text/javascript"></script>

6
After that, I had access to a number a great number of functions for parse and evaluating dates.
Parsing a date from virtually any valid format to MySQL's native YYYY-MM-DD was as easy as:

myDate = Date.parse(inpDate).toString('yyyy-MM-dd');

More usage info can be found on Google Code at:


http://code.google.com/p/datejs/wiki/APIDocumentation

AJAX
Most SQL statements used to input and delete user info from the database are executed using
asynchronous JavaScript and XML (AJAX). The nucleus of the XMLHttpRequest object which is
used to contact the HTTP server without reloading the page.

I must admit, AJAX is not my strong suit. My AJAX scripts leave much room for code reuse and I
often left many lines in them commented out for debugging and out of a fear that if I deleted
them and then needed them again I would be hard-pressed to reproduce them.

Anatomy of an AJAX function call


All of my AJAX functions can be found in C:\server2go\htdocs\becas\js and most of them follow
the following basic model:

function GetXmlHttpObject(){
var xmlHttp=null;
try{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e){
//Internet Explorer
try{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}

function ajaxFunction(doFunc, element, value){


xmlHttp=GetXmlHttpObject()
if (xmlHttp==null){
alert ("Browser does not support HTTP Request")
return
}
url="ajax/query_script.php"
params="param="+value
xmlHttp.onreadystatechange= function() {
if (xmlHttp.readyState==4)
if (xmlHttp.status==200)
doFunc(xmlHttp, element);
}
xmlHttp.open("POST",url,true)

7
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", params.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.send(params)
}

function callBackFunction(req, element) {


Code to manipulate element with xmlHttp.responseText
}

To call the function, the following is put in the onclick attribute of an html element in the
application:

ajaxFunction(callBackFunction, element, value);

In this function, we instantiate an XMLHttpRequest object called xmlHttp via the function
GetXmlHttpObject. Next, we assemble a URL for the object to open and append to it parameters
passed to the AJAX function. We then open the URL using the XMLHttpRequest's "open" method,
making sure the HTTP server uses the POST method.

The URL points to a PHP script to which we want to make the parameters available. All the scripts
that the Student Sponsorship Web Application runs using AJAX are located in
C:\server2go\htdocs\becas\ajax. The script runs a query using the parameters from the AJAX
function which it obtains from the $_POST global variable. When the script has finished
executing, the callback function is called and changes are made to the element that was passed
the the AJAX function on the page where it was called. The variable xmlHttp.responseText
contains anything echoed by the PHP script run by the AJAX function.

Viewing asynchronous PHP output


Sometimes you want to see the results of the PHP script run via AJAX. This is especially often the
case when debugging. Imagine, for example, that you want to dump your script's $_POST query
results to the screen. Because the script was run via the AJAX function, it doesn't postback to the
screen so unless you print your HTTP response text, you have no visual output of the dump. In
order to view it, you have to manually display xmlHttp.responseText in your AJAX callback
function.

Here's how it's done; put the following someplace in your script:

echo "<pre>";
echo var_dump($_POST);
echo"</pre>";

Next, outside of any PHP tags (e.g. <?php ?>) add the following markup:

<div id="debug"></div>

Next, in the callback function called by your AJAX function add:

document.getElementById('debug').innerHTML = elem.innerHTML

8
Now when you call the function output from your script will appear where you placed the div
called "debug".

Firebug
Another useful means of viewing output from scripts called by AJAX is by using an extension for
Firefox called Firebug (http://getfirebug.com/). The Firebug extension produces a pane on the
bottom of your Firefox browser window, shown and hidden by clicking on an icon in the bottom-
righthand side of the Firefox browser window, that can perform a number of useful debugging
tasks.

To use Firebug to view output resulting from AJAX function calls, begin by navigating to
http://localhost:4001/becas. Open Firebug, click the boxes next to "console", "script", and "net"
and click the button labeled "enable selected panels ...". Click the "Console" tab and then trigger
an AJAX function call, for example, click the button labeled "+" or "-" next to a sponsorship
(patrocinio) row in estudiante.php (you must have a student record page open that contains at
least one sponsorship).

A row should appear in the Firebug console that reads "POST


http://localhost:4001/becas/ajax/toggle_beca.php". This is because the AJAX function created an
XMLHttpRequest object that used POST method to make an HTTP request for the page
toggle_beca.php in the ajax folder under becas. If you click the plus sign next to this line in the
console, you will see three tabs that hold different information about the request, "Headers",
"Post", and "Response".

In the Response tab, click "Load Response". You should see a zero or a one, representing the
value to which "aprobado" was set in the sponsorship's record when you clicked the "+" or "-"
button. This number appears because it is echoed in toggle_beca.php. Anything you echo, dump,
print, etc will appear. Errors and warnings will also be shown in this tab.

Next, where it says "Response", click "Post". This tab contains all the values sent as parameters
by the AJAX function to toggle_beca.php as members of the array, $_POST. This post only
contains one member, "id" which was passed to the AJAX function and appended to the URL used
in the HTTP request of toggle_beca.php. Thus, it was in the $_POST array in toggle_beca.php and
its value was used to query the patrocinio table to update the sponsorship's status.

dBug
dBug (http://dbug.ospinto.com/) is modeled after ColdFusion’s cfdump tag. It is a function that
takes a string, array, object, database resource or xml resource and displays it in a color-coded,
collapsible collection of nested tables that is easily understood and interpreted. This is useful
because it eliminates the need to loop through query results in order to view them. Simply
supply the raw result to dBug and it prints it.

To use dBug, simply download the zip archive from the dBug website and extract dBug.php to
the folder containing the script in which you want to use it. Then all you have to do is include it in
your script with

9
include_once("dBug.php");

And then invoke it with

new dBug($myVariable);

This is an excellent way to dump to a debug div using the technique describe above under
"Viewing asynchronous PHP output". I put the include_once of dbug.php in encabezado.php so
that it's available to most of the application, but you have to include it in each PHP script that get
run by via AJAX since these don't include encabezado.php.

Login Management
To manage user authentication, I opted to used "PHP Login Script" (http://www.php-login-
script.com/) a free, open-source collection of PHP scripts for managing logins and access levels
with built-in anti-spam protection. PHP Login Script includes 9 PHP scripts that do things like
register users, activate their accounts, reset their passwords, log them in, and log them out.

To implement PHP Login Script on my website I first moved all the files from the PHP Login Script
zip archive into the becas folder. I then ran a SQL script found on the PHP Login Script website
that builds the "user" table. This is nearly the same as the user table used by the Student
Sponsorship Web Application. The only difference is that the Application's user table has an extra
field for user access level:

`access_level` int(1) unsigned NOT NULL default '2'

After that, just change the database connection settings in dbc.php to the following:

$dbname = 'beca';
$link = mysql_connect("localhost","root","") or die("Couldn't make connection.");
$db = mysql_select_db($dbname, $link) or die("Couldn't select database");

Once you have the login management up and running, it's important that every page the user
interacts with contain "<?php session_start(); ?>" before any other PHP or markup. This is
because the session must be started on each page in order for the access constraints to be
enforced and for login-specific content to be displayed to the user.

The Student Sponsorship Web Application remembers what user is logged in by storing three
pieces of variables in the global variable $_SESSION based on the login credentials provided to
login.php. Those variables are the user's ID, and his or her username and access level. It then
uses these to determine what should and shouldn't be shown to the user.

There are two access levels. The first is level 1. This level is for site administrators. Users with
level-1 access can access pages for changing student records, adding and deleting student
needs, and changing sponsorship status. The second access level, level 2, is for general users.
Users with this access level can view fields the fields that allow them to make donations.

10
Header and Footer
For the sake of conformity and modular design, the scripts that generate the pages of the
Student Sponsorship Web Application each include the header encabezado.php and the footer
pie.php.

encabezado.php
encabezado.php contains the markup that tells the browser what CSS scripts and JavaScript files
to link to as well as the script to display certain navigation menu items depending on the user's
access level. The files linked via HTML are:

display.css Contains the style information for color-coding sponsorships according to their
status
ajax.js Contains all the AJAX functions and their callback functions. An AJAX function is a
function that makes an HTTP request without reloading the page.
site.js Contains other functions that toggle pages elements and validate input.
date-es-GT.jsJ JavaScript library for handling dates (see the section labeled "Datejs")

The PHP to display the navigation menu first evaluates the "user" member of the $_SESSION
array, which gets set to the user's username when they log in. If they have logged in--and "user"
is therefore set--the navigation menu links displayed lead to "Settings" (settings.php), "Logout"
(logout.php), and Home (index.php). Otherwise, The navigation menu links are "Login"
(login.php), Register (register.php), and Home. In addition, a user is logged in and his or her user
level is 1, he or she sees a link labeled "Administration" that leads to admin.php, a script for a
page meant to be a sort of administrative dashboard.

When included in a script using include 'encabezado.php' the header adds markup that tells
the browser to interpret the generated page as HTML and that links needed files and it makes it
so that the first things to load on the page is the navigation menu.

pie.php
pie.php is included at the end of each script that creates a page. Its purpose is just to close out
the body and html sections of the HTML document that encabezado.php opens.

conectar.php
It should also be noted that the server connection details are stored in a little script called
conectar.php so that when the application is migrated from one server to another the hostname,
login, and password only have to be changed in one place. conectar.php is included in every
script that needs to query the database.

11
Database
The MySQL database for the Student Sponsorship Web Application contains the single schema
"beca" with the tables "estudiante", "necesidad", "patrocinio", and "users". In most cases, efforts
were taken in naming tables and fields to make them transparent to Spanish-speaking
developers and administrators.

estudiante
The "estudiante" table contains basic information on each student.

id ID number automatically generated for each student record (primary key).


nombre Student's first, middle, and last names
ciudad This field was originally intended to hold the city where the student lives, but when
importing information from Enlace files it worked best to use this field to display
whether the student's home was "urban" or "rural"
escuela School the student attends
nivel Grade of student in school

CREATE script for the estudiante table:

DROP TABLE IF EXISTS `beca`.`estudiante`;


CREATE TABLE `beca`.`estudiante` (
`id` int(10) unsigned NOT NULL auto_increment,
`nombre` varchar(100) collate latin1_general_ci NOT NULL,
`ciudad` varchar(45) collate latin1_general_ci NOT NULL,
`escuela` varchar(45) collate latin1_general_ci NOT NULL,
`nivel` varchar(45) collate latin1_general_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1127 DEFAULT CHARSET=latin1
COLLATE=latin1_general_ci;

necesidad
Records in the "necesidad" table contain information about a particular course taken by a
particular student for which the student needs sponsors.

id ID number automatically generated for each need (primary key)


id_estudiante ID number of student who has the need (foreign key from "estudiante" table)
curso Course for which the student has the need
fecha_inic Start Date of the course
fecha_culm End Date of the course
cantidad Amount of money needed for the course
satisfecho Binary variable to represent whether or not the need has been satisfied

CREATE script for the necesidad table:

12
DROP TABLE IF EXISTS `beca`.`necesidad`;
CREATE TABLE `beca`.`necesidad` (
`id` int(10) unsigned NOT NULL auto_increment,
`id_estudiante` varchar(45) collate latin1_general_ci NOT NULL,
`curso` varchar(45) collate latin1_general_ci NOT NULL,
`fecha_inic` date NOT NULL,
`fecha_culm` date NOT NULL,
`cantidad` varchar(45) collate latin1_general_ci NOT NULL,
`satisfecho` int(1) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1950 DEFAULT CHARSET=latin1
COLLATE=latin1_general_ci;

patrocinio
Records in the "patrocinio" table contain information about a particular sponsorship of a need.

Id ID number automatically generated for each sponsorship (primary key)


id_nec ID number of the need toward which the sponsorship is promised (foreign key from
"necesidad" table)
id_user ID number of the user providing the sponsorship (foreign key from "user" table)
cantidad Amount of sponsorship
fecha Date of sponsorship (when it was created)
aprobado Binary variable to represent whether or not the sponsorship has been approved

CREATE script for the patrocinio table:

DROP TABLE IF EXISTS `beca`.`patrocinio`;


CREATE TABLE `beca`.`patrocinio` (
`id` int(10) unsigned NOT NULL auto_increment,
`id_nec` varchar(45) collate latin1_general_ci NOT NULL,
`id_user` varchar(45) collate latin1_general_ci NOT NULL,
`cantidad` varchar(45) collate latin1_general_ci NOT NULL,
`fecha` date NOT NULL,
`aprobado` int(1) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=124 DEFAULT CHARSET=latin1
COLLATE=latin1_general_ci;

users
Records in the "user" table contain information about a particular user; a person with an account
on the website who can sponsor students.

13
Id ID number automatically generated for each user (primary key)
full_name Name of user
user_name Username chosen by the user for him/herself
user_pwd Password chosen by user
user_email E-mail address of user
activation_code Code generated for use by the application that is emailed to the user when
he/she registers
joined Date when user registered
country User's country of residence
user_activated Binary variable to represent whether or not the user's registration has been
activated.
access_level An integer used by PHP scripts to determine what parts of the application the user
can view

CREATE script for the users table:

DROP TABLE IF EXISTS `beca`.`users`;


CREATE TABLE `beca`.`users` (
`id` int(20) NOT NULL auto_increment,
`full_name` varchar(200) collate latin1_general_ci NOT NULL default '',
`user_name` varchar(200) collate latin1_general_ci NOT NULL default '',
`user_pwd` varchar(200) collate latin1_general_ci NOT NULL default '',
`user_email` varchar(200) collate latin1_general_ci NOT NULL default '',
`activation_code` int(10) NOT NULL default '0',
`joined` date NOT NULL default '0000-00-00',
`country` varchar(100) collate latin1_general_ci NOT NULL default '',
`user_activated` int(1) NOT NULL default '0',
`access_level` int(1) unsigned NOT NULL default '2',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
COLLATE=latin1_general_ci;

14
Front End
The portion of the site seen by members of the public consists of four pages: index.php,
visualizar_estudiante.php, usuario.php, and buscar.php. These four pages are meant to comprise
a "sponsorship" portion of the Enlace Quiche website.

index.php
It was intended that the first page the user sees upon visiting the sponsorship section of Enlace
Quiche's website was the Student Sponsorship Web Application homepage, index.php. This page
features a search field followed by two main sections: Recientes Patrocinios, Pendientes
Necesidades. It was decided that section labels on all pages be in Spanish in order to aid the
developer in explaining the site to Enlace Quiche staff and management.

Search
The search form consists of a single text field and a button that submits its contents. The form's
target is buscar.php a simple script that queries the "estudiante" table and displays the results in
the table.

Recientes Patrocinios
The section of index.php labeled "Recientes Patrocinios" consists of a table that contains the
fifteen most recent sponsorships. Each row of the table represents a sponsorship. The columns
are as follows:

Estudiante – Student who recieved the sponsorship


Curso – Course for which the student received the sponsorship
Patrocinador – Sponsor
Cantidad – Amount of the sponsorship
Fecha – Date on which the sponsor pledged the sponsorship

In order to assemble all this information for each record, index.php queries every table. The first
query gets the fifteen most recently collected (WHERE aprobado = 1) sponsorships from the
patrocinio table:

SELECT *
FROM patrocinio
WHERE aprobado = 1
ORDER BY fecha DESC LIMIT 15

Then for each result found by the first query, the users table is queried for the username of the
user who provided the sponsorship:

SELECT user_name
FROM users
WHERE id = $row['id_user']

15
Next, the needs table is queried to get the course and the ID of the student associated with the
sponsorship:

SELECT curso, id_estudiante


FROM necesidad
WHERE id = $row['id_nec']

Finally, the student table is queried for the student name in the record corresponding to the
student ID returned by the previous query (the query of the needs table).

SELECT nombre
FROM estudiante
WHERE id = $id_estud

The various data sought by each query are stored in different variables and printed together in
each row producing the output seen in the table.

Pendientes Necesidades
After "Recientes Patrocinios", index.php contains a section labeled "Pendientes Necesidades".
This section contains a list of fifteen pending needs. Each row represents a need a student has
for sponsorship of a particular course. The columns are:

Estudiante – Student who has the need


Curso – Course associated with the need
Fecha de Inicio – Course start date
Fecha de Culminacion – Course end date
Costo
Total – Cost amount found in the need's record
Met – Sum of amounts found in sponsorship records that pertain to the need
Unmet – Difference of "Met" from "Total"
Cantidad de Donacion – A donation text field appears here when a user is logged in.

The SQL used to produce the table consists of three queries. The first query assembles a list of
needs.

SELECT * FROM necesidad


WHERE satisfecho = 0
AND fecha_culm > CURDATE()
ORDER BY fecha_inic ASC LIMIT 15";

This query requires that each need is not already satisfied (satisfecho = 0) and that the course
associated with the need isn't already over (fecha_culm > CURDATE()). Courses with the earliest
start date are shown first (ORDER BY fecha_inic).

When rendering the table for the "Pendientes Necesidades" section, index.php loops through the
results of the first two queries and performs two more queries. The first gets the name of the
student using the student ID returned by the first query:

16
SELECT nombre
FROM estudiante
WHERE id = $id_estud

The second looks for sponsorships of this need and finds the sum of their amounts:

SELECT SUM(cantidad)
FROM patrocinio
WHERE id_nec = $row['id']

This sum represents the total amount of the need which has already been met. This amount is
then subtracted from the total cost associated with the need to obtain the amount of unmet
need.

Donation Interface
When a user is logged in, an input box appears in every row of the Pendientes Necesidades table
with a button labeled “donar”. To sponsor a student, the user enters a sponsorship amount into
the box and clicks the donar button. When clicked, the button calls a function, evalBeca, defined
in site.js. The function takes three arguments:

evalBeca(id_necesidad, unmet, qty)

id_necesidad – the need for which the sponsorship is to be created


unmet – the amount of the need not yet satisfied by sponsorships
qty – the total amount of the need

In index.php, these values are printed as the function’s arguments in the button’s onclick
attribute in each row in much the same fashion as values are printed in the table cells. evalBeca
compares the amount of the user has entered with the amount of unmet need, and notifies the
user if they have entered too great an amount. It then calls the function hacer_beca which takes
three arguments as well:

hacer_beca(doFunc, val, qty)

doFunc – callback function to call when execution of hacer_beca has completed


val – ID of need, used to identify the input containing the entered sponsorship amount
qty – the total amount of the need

hacer_beca is called with the callback function becaCallback and the need ID and need amount
that were passed to evalBeca. It makes an HTTP request using the POST method to execute
hacer_beca.php with the need ID (id), sponsorship amount (amt) and need amount (qty) as URL
parameters. hacer_beca.php then obtains these data from the $_POST array and uses them to
create a record of the sponsorship in the database:

REPLACE INTO patrocinio (id_nec, id_user, cantidad, fecha)


VALUES (POST['id'],$_SESSION['user_id'],$_POST['amt'],date('Y-m-d'))

17
Once the new sponsorship has been created, hacer_beca.php queries the database for the sum
of sponsorships toward the same need, including the one it just created:

18
SELECT SUM(cantidad)
FROM patrocinio
WHERE id_nec = $_POST['id']

It then compares this to the total amount of the need and if it the sum of the sponsorships is
greater than or equal to the total amount of need, it sets the value in the need’s “satisfecho”
column to 1, signifying that the need has been satisfied:

UPDATE necesidad
SET satisfecho = 1
WHERE id = $_POST['id']

When hacer_beca.php is finished the function hacer_beca calls the callback function
becaCallback which is only used for debugging.

visualizar_estudiante.php
visualizar_estudiante.php is the script used to display student profiles. It takes a single
parameter, a student ID, and displays the corresponding student's image and details as well as
lists of his or her sponsorships and past and current courses. As such, it's four sections can be
labeled Student Details, Necesidades, Patrocinios, and Historia.

Student Details
At the beginning of each student profile, visualizar_estudiante.php displays an image of the
student along with his or her city, school and grade. The city, school and grade are obtained
pretty simply:

SELECT *
FROM estudiante
WHERE id = [id parameter from URL]

Here it should be noted that in order for visualizar_estudiante.php to display a student's


information it's URL must contain the parameter, "id". Thus the URL

http://localhost:4001/becas/visualizar_estudiante.php?id=83

points the browser at http://localhost:4001/becas/visualizar_estudiante.php and gives it the id


83. This is the student ID used in the queries that generate the various sections of the page.

To display the student details, the script merely queries the student table for the entire row
corresponding to the student ID from the URL and puts the city, school, and grade columns in an
associative array called "row". It then echoes their corresponding array elements ($row['ciudad']
for city and so forth) in the appropriate spaces in the markup.

Student Images
Student images are created in the folder "imagenes" within the becas folder. Each image of a
student has the same number for its filename as the student's ID, followed by the file extension
".jpg". For example, the image for the student with the id 83 is called 83.jpg its path is
/becas/imagenes/83.jpg under the web root. To display the image with the student's profile,
19
visualizar_estudiante.php simply searches the imagenes folder for the image with the filename
83.jpg.

Necesidades
The "Necesidades" section contains a table that lists the student's outstanding needs. Each row
contains a class for which the student needs sponsored. The columns of the Necesidades section
are as follows; they are almost identical to those of the "Pendientes Necesidades" section of
index.php, the only difference is that there is no "Estudiante" column since all of the rows pertain
to the same student:

Curso – Course associated with the need


Fecha de Inicio – Course start date
Fecha de Culminacion – Course end date
Costo
Total – Cost amount found in the need's record
Met – Sum of amounts found in sponsorship records that pertain to the need
Unmet – Difference of "Met" from "Total"
Cantidad de Donacion – A donation text field appears here when a user is logged in.

visualizar_estudiante.php use two queries to retrieve need information from the database for
display under Necesidades. The first query selects all rows whose values in the id_estudiante
field match the ID supplied in the URL and which represent classes that haven't already ended
(AND fecha_culm > CURDATE()).

SELECT *
FROM necesidad
WHERE id_estudiante = [student ID]
AND fecha_culm > CURDATE()

Next, it loops through the result of the first query and for each need it sums the amounts of
sponsorships of that need that have been received (aprobado = 1).

SELECT SUM(cantidad)
FROM patrocinio
WHERE id_nec = [ID of need returned by query of necesidad table]
AND aprobado = 1

After performing the second query, visualizar_estudiante.php does the same arithmetic as
described in the section of this document labeled "Pendientes Necesidades" under "index.php" to
obtain the amounts in the cost columns of the Necesidades table.

Patrocinios
The patrocinios table displays a list of sponsorships of classes the student has taken. It’s columns
resemble those of the Recientes Patrocinios of index.php, except it lack the estudiante column
because every sponsorship on the student profile page pertains to the same student:

Curso – Course for which the student received the sponsorship


Patrocinador – Sponsor
20
Cantidad – Amount of the sponsorship
Fecha – Date on which the sponsor pledged the sponsorship

The first query made for the patrocinios section contains a nested query for IDs of need records
containing student IDs that match the student ID the URL. The outer query then returns
approved (received) sponsorship records whose IDs are in the list returned by the next query.

SELECT *
FROM patrocinio
WHERE id_nec in (SELECT id
FROM necesidad
WHERE id_estudiante = [student ID])
AND aprobado = 1

For each sponsorship returned, the script performs two more simple queries to obtain the course
associated with the sponsorship and username of the sponsor:

SELECT curso
FROM necesidad
WHERE id = [need ID returned by query of patrocinio table]

SELECT user_name
FROM users
WHERE id = [user ID returned by query of patrocinio table]

Because each of these queries returns only one row, we are able to use the syntax

$curso = mysql_result($curso_result,0);

to store course and sponsorship where $curso_result is the result set of the query and 0 is the
index of the column (0 for the first position, 1 for the second, a so forth).

Historia
Historia is basically the same as Necesidades except it contains every need the student has had
in the past. Thus, its query of necesidad returns only needs who end date has already come to
pass:

SELECT *
FROM necesidad
WHERE id_estudiante = [student ID]
AND fecha_culm > CURDATE()

The query to get the sum of sponsorships of each need is identical to the one used for
Necesidades:

SELECT SUM(cantidad)
FROM patrocinio
WHERE id_nec = [ID of need returned by query of necesidad table]
AND aprobado = 1
21
usuario.php
usuario.php presents a user profile with information the user has entered about him- or herself
and sponsorships he or she has given. Like visualizar_estudiante.php it takes one parameter, id.
The id parameter corresponds to a user ID. Each user profile has two sections; User Details and
Patrocinios.

User Details
Details about the user are retrieved from the database quite simply with:

SELECT *
FROM users
WHERE id = [User ID from URL]

The details are loaded into a row array and echoed using the key corresponding to their
database table column.

Patrocinios
The Patrocinios section of the user profile consists of a table that contains information on all the
sponsorships a sponsor has given. The table columns are:

Curso – Course for which the student received the sponsorship


Estudiante – Student who recieved the sponsorship
Cantidad – Amount of the sponsorship
Fecha – Date on which the sponsor pledged the sponsorship
Estatus – Whether or not the sponsorship has been approved by Enlace (This happens when
payment is received).

The SQL usuario.php uses to generate the Patrocinios section is a bit more complicated. First it
querys for a list of sponsorship rows containing the user’s ID:

SELECT *
FROM patrocinio
WHERE id_user = [user ID from URL]
ORDER BY fecha DESC

Notice newer sponsorships come first (ORDER BY fecha DESC). Next, to obtain the course name
and and student ID associated with the sponsorship, we query the needs table for need records
whose id is the same as the need ID from the previous query:

SELECT curso, id_estudiante


FROM necesidad
WHERE id = [need ID from sponsorship query]

And finally, to get the student’s name who is being sponsored we query the students table for
students whose id match the student ID returned by the query of the needs table.

SELECT nombre
FROM estudiante

22
WHERE id = [student ID from need query]

buscar.php
buscar.php comprises the search functionality of the Student Sponsorship Web Application. It is
only reached via the search box on index.php. buscar.php contains a form with a single search
box and the special PHP action $PHP_SELF which directs the browser to the same page from
which the form is submitted. Thus, when performing a search on buscar.php the page reloads
with the search parameter from the search boxed loaded into the $_GET array and thus
displayed in the URL. For example searching for the search term “Jose” directs the browser to:

http://localhost:4001/becas/buscar.php?search=Jose

buscar.php then loads the search parameter into the query:

SELECT *
FROM estudiante
WHERE nombre LIKE '%[search parameter]%'

This query returns student records with student names matching all or part of the search
parameter. Note the percent signs. These assure that the string of characters entered into the
search box can appear anywhere in the student name.

23
Site Administration
In addition to the publicly accessible pages, there are two scripts that display administrative
pages for the management of students, needs, and sponsorships. These pages are only
accessible to users with administrative credentials.

estudiante.php
When an administrator is logged in, visualizar_estudiante.php displays an extra link, “Editar”,
before the student name. This link points to estudiante.php, a script used to change or create
student details, create needs for them, and update the status of their sponsorships.

estudiante.php has one form called “detalles” that encompasses both the student details and the
needs (Necesidades) sections of the page. The form uses the post method to pass form field
contents to itself (the form’s action is the PHP variable $_SERVER['PHP_SELF']). Interaction with
the database is performed by the script actualizar_estudiante.php, included after the usual
Student Sponsorship Web Application includes of encabezado.php and conectar.php.

actualizar_estudiante.php
Virtually every PHP script that adds or deletes records from the database is run using an AJAX
function that gets called from one of the application pages. In contrast, actualizar_estudiante.php
is included in estudiante.php and is not run using AJAX. This is done to take advantage of PHP’s
built-in file uploading faculties. In PHP, any file input via an HTML form input element of type
“file” is automatically added to the global array $_FILES when the form is submitted. Like with
$_POST, the file is made available to the script in the form’s “action” attribute. In the case of
estudiante.php, since the action attribute directs the browser back to estudiante.php itself and
since estudiante.php includes actualizar_estudiante.php, any file stored within $_FILES (and any
string within $_POST) upon clicking “submit” is made available to actualizar_estudiante.php.

actualizar_estudiante.php serves two purposes: to update a student’s details and to update a


student’s needs. To accomplish this, it has two functions: actualizar_detalles and
actualizar_necesidades. Each of these functions takes a single parameter, an array of strings
sent from the form elements in estudiante.php. To create these arrays, $_POST is parsed into the
array $detalles which contains the first four $_POST members and $necesidad which contains the
remaining five. $detalles is supplied to actualizar_detalles where it becomes part of a query that
updates the estudiante table:

REPLACE INTO estudiante (id, nombre, ciudad, escuela, nivel)


VALUES ([values stored in $detalles])

Directly after it modifies or creates a student record, actualizar_detalles queries the student
table again for the ID of the last inserted or replaced record:

SELECT last_insert_id()

24
The result of this query is used to name the student image if one is uploaded and to supply the
foreign key “id_estudiante” in a need record if one is created for the student.

Within actualizar_detalles, an “image manager” script called manejadorImagenes.php is included


with additional functions it then uses to process any image found in the $_FILES array, resizing it
and copying it to the imagenes folder with the proper filename (see the section labeled “Student
Images”).

Before it is supplied to actualizar_necesidades, $necesidad first has the value appended to it of a


hidden input in estudiante.php that stores the student ID of the student whose record is to be
updated:

array_push($necesidad,$_POST['id']);

Unlike visualizar_estudiante.php, estudiante.php does not require that the URL contain a student
ID parameter. When no parameter is supplied, rather than modify an existing student, the script
serves to create a new student and assign him or her a need. Thus, when creating a new
student, the hidden student ID input is empty and the ‘id’ member appended to $necesidad is
zero.

Once a student’s details have been updated in the database, visualizar_estudiante.php can
proceed to create a need record for the student using the input elements from the
“Necesidades” portion of the page. Before doing this, however, the script must determine that
these fields are not empty. To do this, the ID is removed from the array, it’s members are joined
into a string and the string’s length is evaluated. If all of the fields for the need are empty, the
string’s length is zero and no record will be created. Otherwise, the student ID in $necesidad is
replaced with the ID of the last student replace or insert returned by actualizar_detalles and
$necesidad is passed to actualizar_necesidades. Finally, actualizar_necesidades uses the
information from $necesidad to insert a record of the need into the “necesidad” table:

REPLACE INTO necesidad (curso, fecha_inic, fecha_culm, cantidad, id_estudiante)


VALUES ([values stored in $detalles])

Student Details
At the top of the page generated by estudiante.php there is a section with a student’s image and
several inputs for editing the student’s details. These inputs load with the values in their
corresponding columns from the student’s record in the estudiante table. To obtain these values,
estudiante.php executes the following query:

SELECT *
FROM estudiante
WHERE id = [student ID from URL]

Each value returned by this query is then echoed in the appropriate “value” attribute of an input
element in this section. These details are then sent to the database when the user clicks
“submit”. See the section labeled actualizar_estudiante.php for details on how this is done.

25
Necesidades
In the section of estudiante.php labeled “Necesidades”, above the inputs for new needs, there is
a table containing needs that have already been entered. Each row contains information
pertaining to a need along with a button to remove the need from the database. The SQL to
display this section is quite simply:

26
SELECT *
FROM necesidad
WHERE id_estudiante = [student ID]
ORDER BY id

The script then loops through the results of this query, printing each result in its own row with
the value in each row in its own table cell. At the end of each row it prints the markup for an
input of type “button” that contains the following onclick event (shown here with proper code
formatting:

if(confirm('Borrar necesidad permanentemente?')){


borrar_necesidad(borrarFila,this.parentNode.parentNode,this.id)
}

This code tells the browser to ask the user if he or she wishes to the delete the need of the
current row and if yes, to call the AJAX function that removes it from the database and deletes its
row from the needs section of the current page.

Below the existing needs there are four inputs to accept data for a new need. These are sent to
the database when the user clicks “submit”. See the section labeled actualizar_estudiante.php
for details on how this is done.

borrar_necesidad
To erase a need record from the database, the Student Sponsorship Web Application uses
borrar_necesidad, an AJAX function defined in ajax.js in the js folder under becas.
borrar_necesidad takes three parameters, doFunc, elem, and val. DoFunc is the callback function
to be called when the function has successfully sent an HTTP request and gotten a response.
elem is an html element, specifically the table row containing the button which calls the function.
val corresponds to the ID of the need to be deleted from the necesidad table. When a user clicks
the button to delete a need, the function is called with the callback function borrarFila, the row
element is defined as the DOM object this.parentNode.parentNode where “this” is the button
itself, the first parentNode is the cell that contains the button and the second parentNode is the
row containing the cell. The need ID is the DOM object this.id which refers to the id of the button.
This is where the ID of the need to be deleted is stored.

Upon clicking a need row’s delete button and thus executing borrar_necesidad, that function
send a request to the HTTP server for the script “borrar_necesidad.php” with the parameter “id”
assigned the value of need ID to be deleted. Thus borrar_necesidad.php is run with the member
“id” in its POST array containing the ID of the row to be deleted. borrar_necesidad.php then
performs two queries. The first deletes any sponsorships of the need to be deleted:

DELETE FROM patrocinio


WHERE id_nec = $_POST["id"]

The second deletes the need itself:

DELETE FROM necesidad


WHERE id = $_POST["id"]
27
Once the script has successfully executed, the function borrar_necesidad calls the callback
function borrarFila. borrarFila sets the display attribute of the row of the deleted need to “none”
causing it to disappear from the screen. Next, borrarFila calls another function,
“arreglar_patrocinios” that takes the callback function “refreshPats” and the ID of the current
student as parameters. arreglar_patrocinios runs the script patrocinios.php with the ID as a
parameter which it then uses to perform the same queries and echoes performed by
estudiante.php to display its Patrocinios section. After that, the XMLHttpRequest’s responseText
property containing the output of patrocinios.php is displayed in the div, “patrocinios” that
contains estudiante.php’s Patrocinios section. This has the effect of refreshing i. Once refreshed,
it does not include sponsorships of the need that has been deleted.

Patrocinios
The Patrocinios section of estudiante.php displays a table with sponsorships of needs the student
has. Each row in the table represents a sponsorship. If the sponsorship has been received its row
is green. If it has only been promised but not yet received, its row is pink. The data to assemble
the sponsorship rows are retrieved from the database using four queries. The first query is
nested within the second:

SELECT *
FROM patrocinio
WHERE id_nec IN (SELECT id
FROM necesidad
WHERE id_estudiante = [Student ID])

First the necesidad table is queried for needs the student has, then the patrocinio table is
queried for sponsorships of those needs. The results returned by the query of the patrocinio table
are then looped through and for each sponsorship, the following two queries are performed to
retrieve further data about the sponsorship from the necesidad and users tables:

SELECT curso, cantidad


FROM necesidad
WHERE id = [Need ID returned by query of patrocinio]

SELECT user_name
FROM users
WHERE id = [User ID returned by query of patrocinios]

When printing a table row in the Patrocinios section of estudiante.php, the script evaluates the
value in the “aprobado” column of each sponsorship record to determine whether or not the
sponsorship has been received. Accordingly, it sets the value stored in two variables; $color and
$symbol:

$color = ($row['aprobado']) ? "aprobado" : "no_aprobado";


$symbol = ($row['aprobado']) ? "-" : "+";

$color stores the name of the class of the sponsorship’s row in the HTML table. $symbol stores
the plus or minus sign that will appear on the button at the end of the sponsorship’s row to
describe the action to be performed with respect to its status.
28
When printing a sponsorship row, estudiante.php echoes the row class inside the row’s opening
<tr> tag. When the browser interprets this markup, it uses the stylesheet display.css which
contains the selectors for the two classes that appear in tr elements:

tr.aprobado td {background-color:lightgreen;}
tr.no_aprobado td {background-color:pink;}

These selectors specify that any td element that is nested within a tr element of class
“aprobado” should have a light green background and that any td element that is nested within
a tr element of class “no_aprobado” should a pink background. Thus, when the browser displays
the markup generated by estudiante.php to display the sponsorship table, sponsorships had
have been received (and thus have the status “aprobado”) are highlighted in light green while
sponsorships that have not been received (and thus have the status “no_aprobado”) are
highlighted in pink.

In addition to the plus/minus button at the end of each sponsorship row, there is also a button
labeled with an “x”. This button functions to delete the sponsorship represented by the row. The
button’s onclick attribute contains the AJAX function borrar_beca.

borrar_beca
borrar_beca takes five arguments:

borrar_beca(doFunc, elem, val, nec, ctd)

doFunc – callback function


elem – html row element to hide when done deleting the sponsorship
val – id of sponsorship to be deleted
nec – id of need which toward which the sponsorship has been applied
ctd – need amount

When called within estudiante.php the callback function is “borrarFila”. The sponsorship’s row
object is referenced using the DOM object this.parentNode.parentNode, where “this” is the
button calling the function, the first parentNode is the is the cell containing the button and the
second parentNode is the row containing the cell. The ID’s of the sponsorship and need and the
amount of the need come directly from the query results from which the rest of the row’s
contents are also echoed. When called, borrar_beca sends a request to the HTTP server that runs
the script borrar_beca.php with the sponsorship ID, need ID and need amount as parameters in
the URL. borrar_beca.php first executes the SQL to delete the sponsorship from the database:

DELETE
FROM patrocinio
WHERE id = [sponsorship ID from POST]

Next, it uses the need ID to determine the amount of the need that remains sponsored now that
the sponsorship has been deleted:

SELECT SUM(cantidad)
FROM patrocinio
29
WHERE id_nec = [need ID from POST]

If the sum of sponsorships toward the need no longer equal or exceed the amount of the need,
then the need’s “satisfecho” value is set back to zero, signifying that the need is not currently
satisfied by sponsorships:

UPDATE necesidad

SET satisfecho = 0

WHERE id = [need ID from POST]

When borrar_beca.php is finished running, the callback function borrarFila is called which sets
the display attribute of the deleted sponsorship’s row to “none”, making it disappear from the
screen.

admin.php
The rightmost link that appears in the navigation menu labeled “administration” leads to
admin.php, a page intended as a dashboard for administrators of the student sponsorship
program. The page displayed by admin.php contains three sections: Pendientes Patrocinios,
Recientes Patrocinios, and Pendientes Necesidades.

Pendientes Patrocinios
The section of admin.php labeled “Pendientes Patrocinios” contains a list of recent student
sponsorships which have been promised but have not been received. It performs more or less
the same function as the “Patrocinios” section of estudiante.php whereby the user can toggle
the status of various sponsorships or delete them. In contrast, however, the sponsorships that
appear on admin.php pertain to many students and are all unapproved (promised) when the
page loads. Thus the principal query is:

SELECT *
FROM patrocinio
WHERE aprobado = 0

The results of this query are then looped through and for each result the user name of the
sponsor is retrieved from the users table and the course and student ID are retrieved from the
needs table in the database:

SELECT user_name
FROM users
WHERE id = [user ID from sponsorship record]

SELECT curso, id_estudiante


FROM necesidad
WHERE id = [need ID from sponsorship record]

The results of the query of the needs table are then looped through and for each result the
student table is queried for the student name:

30
SELECT nombre
FROM estudiante
WHERE id = [student ID from the need record]

Recientes Patrocinios
The Recientes Patrocinios section displayed by admin.php is identical to the Recientes
Patrocinios section displayed by index.php. For further information on this topic see the section
of this documents labeled “Recientes Patrocinios” under the heading “index.php”.

Pendientes Necesidades
The Pendientes Necesidades section displayed by admin.php is identical to the Pendientes
Necesidades section displayed by index.php except in one aspect. Whereas index.php’s needs
table only includes sponsorship amounts that have been received,

SELECT SUM(cantidad)

FROM patrocinio

WHERE id_nec = [need ID returned by query of needs table]

AND aprobado = 1

the table displayed by admin.php includes amounts of scholarships that have only been
promised and ones that have been received:

SELECT SUM(cantidad)

FROM patrocinio

WHERE id_nec = [need ID returned by query of needs table]

Thus, the amounts shown in the “Costo” section of the table reflect both scholarships that have
been promised and scholarships that have been received.

31

Das könnte Ihnen auch gefallen