Advertisement
Guest User

Untitled

a guest
Jul 15th, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.01 KB | None | 0 0
  1. <?php
  2. /*
  3. ****Schoolzone Reports API******
  4. author: Simon Zhu
  5. last updated: 24 January 2009
  6. see schoolzone_test.php for usage examples
  7. Note: There is currently nothing you can do if a session is invalid when you call
  8. any retrival functions after a connection has been opened. However, this
  9. be unnecessary as it is inconceivable that a session would time out in the
  10. short time anything using this API should be executing in.
  11.  
  12. main class: SZ_Conn
  13. methods:
  14. Constructor: SZ_Conn( string $user,
  15. string $pass,
  16. string $schoolyear, -> e.g. "200809"
  17. [bool $keep_session, -> Persist session after API use
  18. finishes? (default := true)
  19. [string $cookiefile]] -> Location where session cookies are
  20. stored. To use the default, ensure
  21. there is a folder named sz_sessiondata
  22. in the same folder as this file. You may
  23. may want to chmod this folder 700 or 600.
  24. )
  25. open() -> opens a schoolzone session, returns false on fail
  26. getReportList() -> parse marks list into array with all relevant info and dates
  27. in unix time to the nearest day (see examples or use print_r).
  28. Returns NULL on fail
  29. getReport( int $reportid ) -> Get PDF contents of a report as binary string from
  30. its reportid, returns false on fail
  31. markReportViewed( int $reportid ) -> Marks a report as viewed (i.e. accessdate is set
  32. to current time if not already set)
  33. getAverage( string $pdf ) -> Parse contents of report id $pdf and return the average
  34. (non-progress reports only), returns false on fail.
  35. getClassAverage( string $pdf ) -> Similar to getAverage(), returns false on fail
  36. Also works with pdf contents in $pdf as binary string
  37. getStudentName() -> Name of the current student, returns false on fail
  38. logout( [string $user, [string $cookiefile]] ) -> log out of current session. optionally
  39. pass a username parameter and cookie
  40. file location and call statically to
  41. delete a saved session
  42.  
  43. Sample Array Data:
  44. [coursename] => Mathematics 31
  45. [reportno] => 1234567
  46. [postdate] => 1232953200
  47. [accessdate] => 1232953200
  48. [reportname] => Mathematics-31-Mark-Students
  49. [school] => Harry Ainlay
  50. [reporttype] => Interim Marks
  51.  
  52. *********************************
  53. */
  54. class SZ_Conn
  55. {
  56. const sz_root = 'https://schoolzone.epsb.ca/uPortal/';
  57. const sz_docroot = 'https://channela.epsb.ca/root/';
  58. const useragent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)';
  59. const defaultcookiefile = 'sz_sessiondata/sz_cookie';
  60. private $cookiefile = '';
  61. private $logged_in = false;
  62. private $sessid = '';
  63. private $sz_user = '';
  64. private $sz_pass = '';
  65. private $schoolyear = 0;
  66. private $keep_session = true;
  67. private $student_name = '';
  68.  
  69. function __construct($user, $pass, $schoolyear, $keep_session = true, $cookiefile=self::defaultcookiefile)
  70. {
  71. if ( empty($user) || empty($pass) || empty($schoolyear) ) die('Insufficient parameters provided to SZ_Conn');
  72. $this->sz_user = $user;
  73. $this->sz_pass = $pass;
  74. $this->schoolyear = $schoolyear;
  75. $this->keep_session = $keep_session;
  76. $this->cookiefile = $this->cookiefilename( $this->sz_user, $cookiefile );
  77. if ( $this->keep_session && file_exists($this->cookiefile) )
  78. {
  79. //check if the session is still valid
  80. $this->logged_in = $this->checkSession();
  81.  
  82. }
  83. }
  84.  
  85. function __destruct()
  86. {
  87. if ($this->logged_in && !$this->keep_session)
  88. $this->logout();
  89. }
  90.  
  91. function cookiefilename( $user, $cookiefile=self::defaultcookiefile )
  92. {
  93. return $cookiefile . '_' . substr( md5( strtolower($user).'lolsalt(42)!' ), 5, 15 );
  94. }
  95.  
  96. function logout( $user = false, $cookieloc = self::defaultcookiefile )
  97. {
  98. if ($user && !isset($this))
  99. {
  100. $tempcookie = self::cookiefilename($user, $cookieloc);
  101. $cr = curl_init( self::sz_root.'Logout' );
  102. curl_setopt($cr, CURLOPT_RETURNTRANSFER, true);
  103. curl_setopt($cr, CURLOPT_COOKIEJAR, $tempcookie);
  104. curl_setopt($cr, CURLOPT_COOKIEFILE, $tempcookie);
  105. curl_setopt($cr, CURLOPT_USERAGENT, self::useragent);
  106. }
  107. else
  108. {
  109. $cr = $this->init_curl( self::sz_root.'Logout' );
  110. }
  111. curl_setopt($cr, CURLOPT_REFERER, self::sz_root.'render.userLayoutRootNode.uP');
  112. curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
  113. curl_setopt($cr, CURLOPT_MAXREDIRS, 1);
  114. curl_exec($cr);
  115. curl_close($cr);
  116. //uncomment the following 2 lines and comment the line with unlink if you are using one cookie file that is chmodded to restrict access
  117. //$fh = fopen($this->cookiefile,'w');
  118. //fclose($fh); //do this instead of unlink so permissions are retained
  119. if (!isset($tempcookie))
  120. {
  121. unlink($this->cookiefile);
  122. $this->logged_in = false;
  123. }
  124. else
  125. {
  126. unlink($tempcookie);
  127. }
  128. }
  129.  
  130. function getSessionID()
  131. {
  132. return $this->sessid;
  133. }
  134.  
  135. function open()
  136. {
  137. if ($this->logged_in)
  138. {
  139. $this->sessid = substr( stristr( file_get_contents($this->cookiefile), "JSESSIONID" ), 11, 32);
  140. return true;
  141. }
  142. $cr = $this->init_curl( self::sz_root."Authentication");
  143. curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
  144. curl_setopt($cr, CURLOPT_MAXREDIRS, 1);
  145. curl_setopt($cr, CURLOPT_REFERER, self::sz_root."render.userLayoutRootNode.uP");
  146. curl_setopt($cr, CURLOPT_POST, true);
  147. curl_setopt($cr, CURLOPT_POSTFIELDS, "userName=" . $this->sz_user . "&password=" . $this->sz_pass . "&action=login");
  148. $authout = curl_exec($cr);
  149. curl_close($cr);
  150. if (empty($authout) || stristr($authout, "combination"))
  151. return false;
  152. // $this->sessid = trim(substr(file_get_contents($this->cookiefile), -33));
  153. $this->sessid = substr( stristr( file_get_contents($this->cookiefile), "JSESSIONID" ), 11, 32);
  154. $this->logged_in = true;
  155. return true;
  156. }
  157.  
  158. function getReport($id)
  159. {
  160. //figure out where the pdf is
  161. if (!$id || !$this->logged_in) return false;
  162. $cr = $this->init_curl( self::sz_docroot."SISReports/Launch.cfm?ticket=". $this->sessid . "&sequence_no=". trim($id) );
  163. curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."SISReports/results.cfm");
  164. $reporthtml = curl_exec($cr);
  165. curl_close($cr);
  166. preg_match('/(?<=location=").*.pdf/', $reporthtml, $reportloc); //(?<=location=").*.pdf
  167. //location is now in $reportloc[0], get pdf
  168. $cr = $this->init_curl( self::sz_docroot."SISReports/".$reportloc[0] );
  169. curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."SISReports/Launch.cfm");
  170. $report = curl_exec($cr);
  171. curl_close($cr);
  172. if (stristr($report, "<script>") || empty($report))
  173. return false;
  174. return $report;
  175. }
  176.  
  177. function getAverage( $pdf ) //featuring the regex from hell (revised!)
  178. {
  179. if (strlen($pdf)<15) if ( !($pdf = getReport($pdf)) ) return false; //get pdf from id if that was passed in
  180. $startpos = strrpos($pdf, "\nstream");
  181. $text = substr( $pdf, $startpos );
  182. $endpos = strpos($text, "endstream");
  183. $text = substr( $text, 8 , $endpos - 8 ); //the average is probably on the last page
  184. $text = gzuncompress($text);
  185. if (!preg_match('/\\(t\\)(?:-)?[\\d.]*(?>\\([ Mark:]\\)(?:-)?[\\d.]*){6}\\][^(]*(?:\\( \\)(?:-)?[\\d.]*)+\\((\\d*)/', $text, $avg))
  186. if (!preg_match('/\\(s\\)(?:-)?[\\d.]*(?>\\([ Average:]\\)(?:-)?[\\d.]*){9}\\][^(]*(?:\\( \\)(?:-)?[\\d.]*)+\\((\\d*)/', $text, $avg))
  187. return false;
  188. /* \(t\)(?:-)?[\d.]*(?>\([ Mark:]\)(?:-)?[\d.]*){6}\][^(]*(?:\( \)(?:-)?[\d.]*)+\((\d*) */
  189. /* \(s\)(?:-)?[\d.]*(?>\([ Average:]\)(?:-)?[\d.]*){9}\][^(]*(?:\( \)(?:-)?[\d.]*)+\((\d*) */
  190. return $avg[1];
  191. }
  192.  
  193. function getClassAverage( $pdf )
  194. {
  195. if (strlen($pdf)<15) if ( !($pdf = getReport($pdf)) ) return false; //get pdf from id if that was passed in
  196. $startpos = strrpos($pdf, "\nstream");
  197. $text = substr( $pdf, $startpos );
  198. $endpos = strpos($text, "endstream");
  199. $text = substr( $text, 8 , $endpos - 8 ); //the average is probably on the last page
  200. $text = gzuncompress($text);
  201. /* \(s\)(?:-)?[\d.]*(?>\([ Average:]\)(?:-)?[\d.]*){9}\][^*]*\*\[(?:\( \)(?:-)?[\d.]*)+\((\d*) */
  202. if (!preg_match('/\\(s\\)(?:-)?[\\d.]*(?>\\([ Average:]\\)(?:-)?[\\d.]*){9}\\][^*]*\\*\\[(?:\\( \\)(?:-)?[\\d.]*)+\\((\\d*)/', $text, $avg))
  203. return false;
  204. return $avg[1];
  205. }
  206.  
  207. function getReportPage($retries = 0) //gets the html source of the page listing all the reports
  208. {
  209. if (!$this->logged_in) return false;
  210. if ($retries < 2)
  211. {
  212. $cr = $this->init_curl( self::sz_docroot."SISReports/results.cfm?ticket=". $this->sessid . "&schlYear=". $this->schoolyear ."&sortBy=Date" );
  213. curl_setopt($cr, CURLOPT_FOLLOWLOCATION, true);
  214. curl_setopt($cr, CURLOPT_MAXREDIRS, 1);
  215. curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."reports/ReportsTitle.cfm");
  216. $reportout = curl_exec($cr);
  217. curl_close($cr);
  218. if (!stristr($reportout, "Interim Marks") || empty($reportout))
  219. {
  220. unset($reportout); //don't waste memory
  221. return $this->getReportPage($retries + 1); //sometimes this doesn't work the first time (incorrect cookies?)
  222. }
  223. else
  224. {
  225. return $reportout;
  226. }
  227. }
  228. else return false;
  229. }
  230.  
  231. function getReportList( $reportpage = false ) //parses the report page into an array
  232. {
  233. if (!$reportpage) $reportpage = $this -> getReportPage();
  234. /* <TD>(.*?)</td>\s*?<TD>(.*?) *</td>\s*?<td nowrap="yes">(.*?) *</td>\s*?<td>.*?\((\d*).*?> *(.*?) {2,}- *(.*?)\.pdf</a>.*?yes">\s*(.*?)\s*</td> */
  235. 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
  236. $size = count($regout[0]);
  237. $timezone = date_default_timezone_get();
  238. date_default_timezone_set('America/Edmonton');
  239. for( $i = 0; $i < $size; $i++ )
  240. {
  241. $out[$i] = array(
  242. "coursename" => $regout[2][$i],
  243. "reportno" => $regout[4][$i],
  244. "postdate" => strtotime($regout[3][$i]),
  245. "accessdate" => strtotime($regout[7][$i]),
  246. "reportname" => $regout[6][$i],
  247. "school" => $regout[5][$i],
  248. "reporttype" => $regout[1][$i]
  249. );
  250. }
  251. date_default_timezone_set($timezone);
  252. return $out;
  253. }
  254.  
  255. function getStudentName()
  256. {
  257. if ($this->student_name) return $this->student_name;
  258. if (!$this->logged_in) return false;
  259. $cr = $this->init_curl( self::sz_docroot."classNews/index.cfm?ticket=". $this->sessid );
  260. curl_setopt($cr, CURLOPT_REFERER, self::sz_root."render.userLayoutRootNode.uP");
  261. $newspage = curl_exec($cr);
  262. curl_close($cr);
  263.  
  264. if (empty($newspage)) return false;
  265. if (!preg_match("/Student:.*[\\r\\n\\t ]*<td>(.*?)[\r\n]/", $newspage, $match))
  266. return false;
  267. $this->student_name = $match[1];
  268. return $match[1];
  269. }
  270.  
  271. function markReportViewed($id)
  272. {
  273. if (!$id || !$this->logged_in) return false;
  274. $cr = $this->init_curl( self::sz_docroot."SISReports/results.cfm?ticket=". $this->sessid . "&schlYear=". $this->schoolyear ."&sortBy=Date" );
  275. curl_setopt($cr, CURLOPT_REFERER, self::sz_docroot."SISReports/results.cfm");
  276. curl_setopt($cr, CURLOPT_POST, true);
  277.  
  278. $postfields = array( "viewed_submit" => trim($id) );
  279. curl_setopt($cr, CURLOPT_POSTFIELDS, $postfields);
  280.  
  281. $out = curl_exec($cr);
  282. return !stristr($out, "Sorry");
  283. }
  284.  
  285. function checkSession()
  286. { // is the current session still valid? Gets news page and checks for denial string
  287. $cr = $this->init_curl( self::sz_docroot.'SchoolZoneNews/index.cfm');
  288. curl_setopt($cr, CURLOPT_REFERER, self::sz_root."render.userLayoutRootNode.uP");
  289. $testpage = curl_exec($cr);
  290. curl_close($cr);
  291. if (empty($testpage)) return false;
  292. return !( stristr($testpage, 'can only be accessed') || stristr($testpage, 'timed out') );
  293. }
  294.  
  295. private function init_curl($url)
  296. {
  297. $cr = curl_init($url);
  298. // curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, false); // you may have to uncomment this line if your server doesn't have the needed certificates
  299. curl_setopt($cr, CURLOPT_RETURNTRANSFER, true);
  300. curl_setopt($cr, CURLOPT_COOKIEJAR, $this->cookiefile);
  301. curl_setopt($cr, CURLOPT_COOKIEFILE, $this->cookiefile);
  302. curl_setopt($cr, CURLOPT_USERAGENT, self::useragent);
  303. // curl_setopt($cr, CURLOPT_HEADER, true);
  304. return $cr;
  305. }
  306.  
  307. }
  308. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement