Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- ****Schoolzone Reports API******
- author: Simon Zhu
- last updated: 24 January 2009
- see schoolzone_test.php for usage examples
- Note: There is currently nothing you can do if a session is invalid when you call
- any retrival functions after a connection has been opened. However, this
- be unnecessary as it is inconceivable that a session would time out in the
- short time anything using this API should be executing in.
- main class: SZ_Conn
- methods:
- Constructor: SZ_Conn( string $user,
- string $pass,
- string $schoolyear, -> e.g. "200809"
- [bool $keep_session, -> Persist session after API use
- finishes? (default := true)
- [string $cookiefile]] -> Location where session cookies are
- stored. To use the default, ensure
- there is a folder named sz_sessiondata
- in the same folder as this file. You may
- may want to chmod this folder 700 or 600.
- )
- open() -> opens a schoolzone session, returns false on fail
- getReportList() -> parse marks list into array with all relevant info and dates
- in unix time to the nearest day (see examples or use print_r).
- Returns NULL on fail
- getReport( int $reportid ) -> Get PDF contents of a report as binary string from
- its reportid, returns false on fail
- markReportViewed( int $reportid ) -> Marks a report as viewed (i.e. accessdate is set
- to current time if not already set)
- getAverage( string $pdf ) -> Parse contents of report id $pdf and return the average
- (non-progress reports only), returns false on fail.
- getClassAverage( string $pdf ) -> Similar to getAverage(), returns false on fail
- Also works with pdf contents in $pdf as binary string
- getStudentName() -> Name of the current student, returns false on fail
- logout( [string $user, [string $cookiefile]] ) -> log out of current session. optionally
- pass a username parameter and cookie
- file location and call statically to
- delete a saved session
- Sample Array Data:
- [coursename] => Mathematics 31
- [reportno] => 1234567
- [postdate] => 1232953200
- [accessdate] => 1232953200
- [reportname] => Mathematics-31-Mark-Students
- [school] => Harry Ainlay
- [reporttype] => Interim Marks
- *********************************
- */
- class SZ_Conn
- {
- const sz_root = 'https://schoolzone.epsb.ca/uPortal/';
- const sz_docroot = 'https://channela.epsb.ca/root/';
- const useragent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)';
- const defaultcookiefile = 'sz_sessiondata/sz_cookie';
- private $cookiefile = '';
- private $logged_in = false;
- private $sessid = '';
- private $sz_user = '';
- private $sz_pass = '';
- private $schoolyear = 0;
- private $keep_session = true;
- private $student_name = '';
- function __construct($user, $pass, $schoolyear, $keep_session = true, $cookiefile=self::defaultcookiefile)
- {
- if ( empty($user) || empty($pass) || empty($schoolyear) ) die('Insufficient parameters provided to SZ_Conn');
- $this->sz_user = $user;
- $this->sz_pass = $pass;
- $this->schoolyear = $schoolyear;
- $this->keep_session = $keep_session;
- $this->cookiefile = $this->cookiefilename( $this->sz_user, $cookiefile );
- if ( $this->keep_session && file_exists($this->cookiefile) )
- {
- //check if the session is still valid
- $this->logged_in = $this->checkSession();
- }
- }
- function __destruct()
- {
- if ($this->logged_in && !$this->keep_session)
- $this->logout();
- }
- function cookiefilename( $user, $cookiefile=self::defaultcookiefile )
- {
- return $cookiefile . '_' . substr( md5( strtolower($user).'lolsalt(42)!' ), 5, 15 );
- }
- function logout( $user = false, $cookieloc = self::defaultcookiefile )
- {
- if ($user && !isset($this))
- {
- $tempcookie = self::cookiefilename($user, $cookieloc);
- $cr = curl_init( self::sz_root.'Logout' );
- curl_setopt($cr, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cr, CURLOPT_COOKIEJAR, $tempcookie);
- curl_setopt($cr, CURLOPT_COOKIEFILE, $tempcookie);
- curl_setopt($cr, CURLOPT_USERAGENT, self::useragent);
- }
- else
- {
- $cr = $this->init_curl( self::sz_root.'Logout' );
- }
- curl_setopt($cr, CURLOPT_REFERER, self::sz_root.'render.userLayoutRootNode.uP');
- curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($cr, CURLOPT_MAXREDIRS, 1);
- curl_exec($cr);
- curl_close($cr);
- //uncomment the following 2 lines and comment the line with unlink if you are using one cookie file that is chmodded to restrict access
- //$fh = fopen($this->cookiefile,'w');
- //fclose($fh); //do this instead of unlink so permissions are retained
- if (!isset($tempcookie))
- {
- unlink($this->cookiefile);
- $this->logged_in = false;
- }
- else
- {
- unlink($tempcookie);
- }
- }
- function getSessionID()
- {
- return $this->sessid;
- }
- function open()
- {
- if ($this->logged_in)
- {
- $this->sessid = substr( stristr( file_get_contents($this->cookiefile), "JSESSIONID" ), 11, 32);
- return true;
- }
- $cr = $this->init_curl( self::sz_root."Authentication");
- curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($cr, CURLOPT_MAXREDIRS, 1);
- curl_setopt($cr, CURLOPT_REFERER, self::sz_root."render.userLayoutRootNode.uP");
- curl_setopt($cr, CURLOPT_POST, true);
- curl_setopt($cr, CURLOPT_POSTFIELDS, "userName=" . $this->sz_user . "&password=" . $this->sz_pass . "&action=login");
- $authout = curl_exec($cr);
- curl_close($cr);
- if (empty($authout) || stristr($authout, "combination"))
- return false;
- // $this->sessid = trim(substr(file_get_contents($this->cookiefile), -33));
- $this->sessid = substr( stristr( file_get_contents($this->cookiefile), "JSESSIONID" ), 11, 32);
- $this->logged_in = true;
- return true;
- }
- function getReport($id)
- {
- //figure out where the pdf is
- if (!$id || !$this->logged_in) return false;
- $cr = $this->init_curl( self::sz_docroot."SISReports/Launch.cfm?ticket=". $this->sessid . "&sequence_no=". trim($id) );
- curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."SISReports/results.cfm");
- $reporthtml = curl_exec($cr);
- curl_close($cr);
- preg_match('/(?<=location=").*.pdf/', $reporthtml, $reportloc); //(?<=location=").*.pdf
- //location is now in $reportloc[0], get pdf
- $cr = $this->init_curl( self::sz_docroot."SISReports/".$reportloc[0] );
- curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."SISReports/Launch.cfm");
- $report = curl_exec($cr);
- curl_close($cr);
- if (stristr($report, "<script>") || empty($report))
- return false;
- return $report;
- }
- function getAverage( $pdf ) //featuring the regex from hell (revised!)
- {
- if (strlen($pdf)<15) if ( !($pdf = getReport($pdf)) ) return false; //get pdf from id if that was passed in
- $startpos = strrpos($pdf, "\nstream");
- $text = substr( $pdf, $startpos );
- $endpos = strpos($text, "endstream");
- $text = substr( $text, 8 , $endpos - 8 ); //the average is probably on the last page
- $text = gzuncompress($text);
- if (!preg_match('/\\(t\\)(?:-)?[\\d.]*(?>\\([ Mark:]\\)(?:-)?[\\d.]*){6}\\][^(]*(?:\\( \\)(?:-)?[\\d.]*)+\\((\\d*)/', $text, $avg))
- if (!preg_match('/\\(s\\)(?:-)?[\\d.]*(?>\\([ Average:]\\)(?:-)?[\\d.]*){9}\\][^(]*(?:\\( \\)(?:-)?[\\d.]*)+\\((\\d*)/', $text, $avg))
- return false;
- /* \(t\)(?:-)?[\d.]*(?>\([ Mark:]\)(?:-)?[\d.]*){6}\][^(]*(?:\( \)(?:-)?[\d.]*)+\((\d*) */
- /* \(s\)(?:-)?[\d.]*(?>\([ Average:]\)(?:-)?[\d.]*){9}\][^(]*(?:\( \)(?:-)?[\d.]*)+\((\d*) */
- return $avg[1];
- }
- function getClassAverage( $pdf )
- {
- if (strlen($pdf)<15) if ( !($pdf = getReport($pdf)) ) return false; //get pdf from id if that was passed in
- $startpos = strrpos($pdf, "\nstream");
- $text = substr( $pdf, $startpos );
- $endpos = strpos($text, "endstream");
- $text = substr( $text, 8 , $endpos - 8 ); //the average is probably on the last page
- $text = gzuncompress($text);
- /* \(s\)(?:-)?[\d.]*(?>\([ Average:]\)(?:-)?[\d.]*){9}\][^*]*\*\[(?:\( \)(?:-)?[\d.]*)+\((\d*) */
- if (!preg_match('/\\(s\\)(?:-)?[\\d.]*(?>\\([ Average:]\\)(?:-)?[\\d.]*){9}\\][^*]*\\*\\[(?:\\( \\)(?:-)?[\\d.]*)+\\((\\d*)/', $text, $avg))
- return false;
- return $avg[1];
- }
- function getReportPage($retries = 0) //gets the html source of the page listing all the reports
- {
- if (!$this->logged_in) return false;
- if ($retries < 2)
- {
- $cr = $this->init_curl( self::sz_docroot."SISReports/results.cfm?ticket=". $this->sessid . "&schlYear=". $this->schoolyear ."&sortBy=Date" );
- curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($cr, CURLOPT_MAXREDIRS, 1);
- curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."reports/ReportsTitle.cfm");
- $reportout = curl_exec($cr);
- curl_close($cr);
- if (!stristr($reportout, "Interim Marks") || empty($reportout))
- {
- unset($reportout); //don't waste memory
- return $this->getReportPage($retries + 1); //sometimes this doesn't work the first time (incorrect cookies?)
- }
- else
- {
- return $reportout;
- }
- }
- else return false;
- }
- function getReportList( $reportpage = false ) //parses the report page into an array
- {
- if (!$reportpage) $reportpage = $this -> getReportPage();
- /* <TD>(.*?)</td>\s*?<TD>(.*?) *</td>\s*?<td nowrap="yes">(.*?) *</td>\s*?<td>.*?\((\d*).*?> *(.*?) {2,}- *(.*?)\.pdf</a>.*?yes">\s*(.*?)\s*</td> */
- preg_match_all('/<TD>(.*?)<\/td>\\s*?<TD>(.*?) *<\/td>\\s*?<td nowrap="yes">(.*?) *<\/td>\\s*?<td>.*?\\((\\d*).*?> *(.*?) {2,}- *(.*?)\\.pdf<\/a>.*?yes">\\s*(.*?)\\s*<\/td>/s', $reportpage, $regout); //$1 type, $2 coursename, $3 postdate, $4 reportno, $5 school, $6 reportname, $7 accessdate
- $size = count($regout[0]);
- $timezone = date_default_timezone_get();
- date_default_timezone_set('America/Edmonton');
- for( $i = 0; $i < $size; $i++ )
- {
- $out[$i] = array(
- "coursename" => $regout[2][$i],
- "reportno" => $regout[4][$i],
- "postdate" => strtotime($regout[3][$i]),
- "accessdate" => strtotime($regout[7][$i]),
- "reportname" => $regout[6][$i],
- "school" => $regout[5][$i],
- "reporttype" => $regout[1][$i]
- );
- }
- date_default_timezone_set($timezone);
- return $out;
- }
- function getStudentName()
- {
- if ($this->student_name) return $this->student_name;
- if (!$this->logged_in) return false;
- $cr = $this->init_curl( self::sz_docroot."classNews/index.cfm?ticket=". $this->sessid );
- curl_setopt($cr, CURLOPT_REFERER, self::sz_root."render.userLayoutRootNode.uP");
- $newspage = curl_exec($cr);
- curl_close($cr);
- if (empty($newspage)) return false;
- if (!preg_match("/Student:.*[\\r\\n\\t ]*<td>(.*?)[\r\n]/", $newspage, $match))
- return false;
- $this->student_name = $match[1];
- return $match[1];
- }
- function markReportViewed($id)
- {
- if (!$id || !$this->logged_in) return false;
- $cr = $this->init_curl( self::sz_docroot."SISReports/results.cfm?ticket=". $this->sessid . "&schlYear=". $this->schoolyear ."&sortBy=Date" );
- curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."SISReports/results.cfm");
- curl_setopt($cr, CURLOPT_POST, true);
- $postfields = array( "viewed_submit" => trim($id) );
- curl_setopt($cr, CURLOPT_POSTFIELDS, $postfields);
- $out = curl_exec($cr);
- return !stristr($out, "Sorry");
- }
- function checkSession()
- { // is the current session still valid? Gets news page and checks for denial string
- $cr = $this->init_curl( self::sz_docroot.'SchoolZoneNews/index.cfm');
- curl_setopt($cr, CURLOPT_REFERER, self::sz_root."render.userLayoutRootNode.uP");
- $testpage = curl_exec($cr);
- curl_close($cr);
- if (empty($testpage)) return false;
- return !( stristr($testpage, 'can only be accessed') || stristr($testpage, 'timed out') );
- }
- private function init_curl($url)
- {
- $cr = curl_init($url);
- // curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, false); // you may have to uncomment this line if your server doesn't have the needed certificates
- curl_setopt($cr, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($cr, CURLOPT_COOKIEJAR, $this->cookiefile);
- curl_setopt($cr, CURLOPT_COOKIEFILE, $this->cookiefile);
- curl_setopt($cr, CURLOPT_USERAGENT, self::useragent);
- // curl_setopt($cr, CURLOPT_HEADER, true);
- return $cr;
- }
- }
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement