@@ -9,238 +9,238 @@ |
||
| 9 | 9 | */ |
| 10 | 10 | class SecureFileController extends Controller implements PermissionProvider { |
| 11 | 11 | |
| 12 | - /** |
|
| 13 | - * @var array Disallow all public actions on this controller |
|
| 14 | - */ |
|
| 15 | - public static $allowed_actions = array(); |
|
| 16 | - |
|
| 17 | - /** |
|
| 18 | - * @var string htaccess file as set by apache config |
|
| 19 | - */ |
|
| 20 | - protected static $htaccess_file = ".htaccess"; |
|
| 21 | - |
|
| 22 | - /** |
|
| 23 | - * @var integer Size of output chunks in kb while in PHP fread mode. |
|
| 24 | - */ |
|
| 25 | - protected static $chunck_size_kb = 32; |
|
| 26 | - |
|
| 27 | - /** |
|
| 28 | - * @var boolean Flag use X-Sendfile header mode instead of PHP fread mode. |
|
| 29 | - */ |
|
| 30 | - protected static $use_x_sendfile = false; |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * @var boolean Flag use SilverStripe send file method. |
|
| 34 | - */ |
|
| 35 | - protected static $use_ss_sendfile = false; |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * @var array i18n data for not authorized message as passed to _t |
|
| 39 | - */ |
|
| 40 | - protected static $i18n_not_authorized = array('SecureFiles.NOTAUTHORIZED', 'Not Authorized'); |
|
| 41 | - |
|
| 42 | - /** |
|
| 43 | - * @var array i18n data for not found message as passed to _t |
|
| 44 | - */ |
|
| 45 | - protected static $i18n_not_found = array('SecureFiles.NOTFOUND', 'Not Found'); |
|
| 46 | - |
|
| 47 | - /** |
|
| 48 | - * Use X-Sendfile headers to send files to the browser. |
|
| 49 | - * This is quicker than pushing files through PHP but |
|
| 50 | - * requires either Lighttpd or mod_xsendfile for Apache |
|
| 51 | - * @link http://tn123.ath.cx/mod_xsendfile/ |
|
| 52 | - */ |
|
| 53 | - static function use_x_sendfile_method() { |
|
| 54 | - self::use_default_sendfile_method(); |
|
| 55 | - self::$use_x_sendfile = true; |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * Use internal SilverStripe to send files to the browser. |
|
| 60 | - * This is the least efficient method but is useful for |
|
| 61 | - * testing. Not recommend for production |
|
| 62 | - * environments. |
|
| 63 | - */ |
|
| 64 | - static function use_ss_sendfile_method() { |
|
| 65 | - self::use_default_sendfile_method(); |
|
| 66 | - self::$use_ss_sendfile = true; |
|
| 67 | - } |
|
| 68 | - |
|
| 69 | - /** |
|
| 70 | - * Use the default chuncked file method to send files to the browser. |
|
| 71 | - * This is the default method. |
|
| 72 | - */ |
|
| 73 | - static function use_default_sendfile_method() { |
|
| 74 | - self::$use_ss_sendfile = false; |
|
| 75 | - self::$use_x_sendfile = false; |
|
| 76 | - } |
|
| 77 | - |
|
| 78 | - /** |
|
| 79 | - * Set the size of upload chunk in bytes. |
|
| 80 | - * @param int $kilobytes |
|
| 81 | - */ |
|
| 82 | - static function set_chunk_size($kilobytes) { |
|
| 83 | - $kilobytes = max(0, (int)$kilobytes); |
|
| 84 | - if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 85 | - self::$chunck_size_kb = $kilobytes; |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * Set the Apache access file name (.htaccess by default) |
|
| 90 | - * as determined by the AccessFileName Apache directive. |
|
| 91 | - * @param string $filename |
|
| 92 | - */ |
|
| 93 | - static function set_access_filename($filename) { |
|
| 94 | - self::$htaccess_file = $filename; |
|
| 95 | - } |
|
| 96 | - |
|
| 97 | - /** |
|
| 98 | - * Get the Apache access file name |
|
| 99 | - * @return string |
|
| 100 | - */ |
|
| 101 | - static function get_access_filename() { |
|
| 102 | - return self::$htaccess_file; |
|
| 103 | - } |
|
| 104 | - |
|
| 105 | - /** |
|
| 106 | - * Set a 'not authorized' message to replace the standard string |
|
| 107 | - * @param $message HTML body of 401 Not Authorized response |
|
| 108 | - * @param $i18n Reference to i18n path |
|
| 109 | - */ |
|
| 110 | - static function set_not_authorized_text($message = "Not Authorized", $i18n = "SecureFiles.NOTAUTHORIZED") { |
|
| 111 | - self::$i18n_not_authorized = array($i18n, $message); |
|
| 112 | - } |
|
| 113 | - |
|
| 114 | - /** |
|
| 115 | - * Set a 'not found' message to replace the standard string |
|
| 116 | - * @param $message HTML body of 404 Not Found response |
|
| 117 | - * @param $i18n Reference to i18n path |
|
| 118 | - */ |
|
| 119 | - static function set_not_found_text($message = "Not Found", $i18n = "SecureFiles.NOTFOUND") { |
|
| 120 | - self::$i18n_not_found = array($i18n, $message); |
|
| 121 | - } |
|
| 122 | - |
|
| 123 | - /** |
|
| 124 | - * Process incoming requests passed to this controller |
|
| 125 | - * |
|
| 126 | - * @return HTTPResponse |
|
| 127 | - */ |
|
| 128 | - function handleAction() { |
|
| 129 | - $url = array_key_exists('url', $_GET) ? $_GET['url'] : $_SERVER['REQUEST_URI']; |
|
| 130 | - $file_path = Director::makeRelative($url); |
|
| 131 | - $file = File::find($file_path); |
|
| 12 | + /** |
|
| 13 | + * @var array Disallow all public actions on this controller |
|
| 14 | + */ |
|
| 15 | + public static $allowed_actions = array(); |
|
| 16 | + |
|
| 17 | + /** |
|
| 18 | + * @var string htaccess file as set by apache config |
|
| 19 | + */ |
|
| 20 | + protected static $htaccess_file = ".htaccess"; |
|
| 21 | + |
|
| 22 | + /** |
|
| 23 | + * @var integer Size of output chunks in kb while in PHP fread mode. |
|
| 24 | + */ |
|
| 25 | + protected static $chunck_size_kb = 32; |
|
| 26 | + |
|
| 27 | + /** |
|
| 28 | + * @var boolean Flag use X-Sendfile header mode instead of PHP fread mode. |
|
| 29 | + */ |
|
| 30 | + protected static $use_x_sendfile = false; |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * @var boolean Flag use SilverStripe send file method. |
|
| 34 | + */ |
|
| 35 | + protected static $use_ss_sendfile = false; |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * @var array i18n data for not authorized message as passed to _t |
|
| 39 | + */ |
|
| 40 | + protected static $i18n_not_authorized = array('SecureFiles.NOTAUTHORIZED', 'Not Authorized'); |
|
| 41 | + |
|
| 42 | + /** |
|
| 43 | + * @var array i18n data for not found message as passed to _t |
|
| 44 | + */ |
|
| 45 | + protected static $i18n_not_found = array('SecureFiles.NOTFOUND', 'Not Found'); |
|
| 46 | + |
|
| 47 | + /** |
|
| 48 | + * Use X-Sendfile headers to send files to the browser. |
|
| 49 | + * This is quicker than pushing files through PHP but |
|
| 50 | + * requires either Lighttpd or mod_xsendfile for Apache |
|
| 51 | + * @link http://tn123.ath.cx/mod_xsendfile/ |
|
| 52 | + */ |
|
| 53 | + static function use_x_sendfile_method() { |
|
| 54 | + self::use_default_sendfile_method(); |
|
| 55 | + self::$use_x_sendfile = true; |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * Use internal SilverStripe to send files to the browser. |
|
| 60 | + * This is the least efficient method but is useful for |
|
| 61 | + * testing. Not recommend for production |
|
| 62 | + * environments. |
|
| 63 | + */ |
|
| 64 | + static function use_ss_sendfile_method() { |
|
| 65 | + self::use_default_sendfile_method(); |
|
| 66 | + self::$use_ss_sendfile = true; |
|
| 67 | + } |
|
| 68 | + |
|
| 69 | + /** |
|
| 70 | + * Use the default chuncked file method to send files to the browser. |
|
| 71 | + * This is the default method. |
|
| 72 | + */ |
|
| 73 | + static function use_default_sendfile_method() { |
|
| 74 | + self::$use_ss_sendfile = false; |
|
| 75 | + self::$use_x_sendfile = false; |
|
| 76 | + } |
|
| 77 | + |
|
| 78 | + /** |
|
| 79 | + * Set the size of upload chunk in bytes. |
|
| 80 | + * @param int $kilobytes |
|
| 81 | + */ |
|
| 82 | + static function set_chunk_size($kilobytes) { |
|
| 83 | + $kilobytes = max(0, (int)$kilobytes); |
|
| 84 | + if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 85 | + self::$chunck_size_kb = $kilobytes; |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * Set the Apache access file name (.htaccess by default) |
|
| 90 | + * as determined by the AccessFileName Apache directive. |
|
| 91 | + * @param string $filename |
|
| 92 | + */ |
|
| 93 | + static function set_access_filename($filename) { |
|
| 94 | + self::$htaccess_file = $filename; |
|
| 95 | + } |
|
| 96 | + |
|
| 97 | + /** |
|
| 98 | + * Get the Apache access file name |
|
| 99 | + * @return string |
|
| 100 | + */ |
|
| 101 | + static function get_access_filename() { |
|
| 102 | + return self::$htaccess_file; |
|
| 103 | + } |
|
| 104 | + |
|
| 105 | + /** |
|
| 106 | + * Set a 'not authorized' message to replace the standard string |
|
| 107 | + * @param $message HTML body of 401 Not Authorized response |
|
| 108 | + * @param $i18n Reference to i18n path |
|
| 109 | + */ |
|
| 110 | + static function set_not_authorized_text($message = "Not Authorized", $i18n = "SecureFiles.NOTAUTHORIZED") { |
|
| 111 | + self::$i18n_not_authorized = array($i18n, $message); |
|
| 112 | + } |
|
| 113 | + |
|
| 114 | + /** |
|
| 115 | + * Set a 'not found' message to replace the standard string |
|
| 116 | + * @param $message HTML body of 404 Not Found response |
|
| 117 | + * @param $i18n Reference to i18n path |
|
| 118 | + */ |
|
| 119 | + static function set_not_found_text($message = "Not Found", $i18n = "SecureFiles.NOTFOUND") { |
|
| 120 | + self::$i18n_not_found = array($i18n, $message); |
|
| 121 | + } |
|
| 122 | + |
|
| 123 | + /** |
|
| 124 | + * Process incoming requests passed to this controller |
|
| 125 | + * |
|
| 126 | + * @return HTTPResponse |
|
| 127 | + */ |
|
| 128 | + function handleAction() { |
|
| 129 | + $url = array_key_exists('url', $_GET) ? $_GET['url'] : $_SERVER['REQUEST_URI']; |
|
| 130 | + $file_path = Director::makeRelative($url); |
|
| 131 | + $file = File::find($file_path); |
|
| 132 | 132 | |
| 133 | - if($file instanceof File) { |
|
| 134 | - if ($file->canView()) { |
|
| 135 | - $file->extend('onAccessGranted'); |
|
| 136 | - return $this->fileFound($file, $file_path); |
|
| 137 | - } else { |
|
| 138 | - $file->extend('onAccessDenied'); |
|
| 139 | - return $this->fileNotAuthorized(call_user_func_array('_t', self::$i18n_not_authorized)); |
|
| 140 | - } |
|
| 141 | - } else { |
|
| 142 | - return $this->fileNotFound(call_user_func_array('_t', self::$i18n_not_found)); |
|
| 143 | - } |
|
| 144 | - } |
|
| 145 | - |
|
| 146 | - /** |
|
| 147 | - * File Not Found response |
|
| 148 | - * |
|
| 149 | - * @param $body Optional message body |
|
| 150 | - * @return HTTPResponse |
|
| 151 | - */ |
|
| 152 | - function fileNotFound($body = "") { |
|
| 153 | - if(ClassInfo::exists('SS_HTTPResponse')) { |
|
| 154 | - return new SS_HTTPResponse($body, 404); |
|
| 155 | - } else { |
|
| 156 | - return new HTTPResponse($body, 404); |
|
| 157 | - } |
|
| 158 | - } |
|
| 159 | - |
|
| 160 | - /** |
|
| 161 | - * File not authorized response |
|
| 162 | - * |
|
| 163 | - * @param $body Optional message body |
|
| 164 | - * @return HTTPResponse |
|
| 165 | - */ |
|
| 166 | - function fileNotAuthorized($body = "") { |
|
| 167 | - Security::permissionFailure($this, $body); |
|
| 168 | - } |
|
| 169 | - |
|
| 170 | - /** |
|
| 171 | - * File found response |
|
| 172 | - * |
|
| 173 | - * @param $file File to send |
|
| 174 | - * @param $alternate_path string If supplied, return the file from this path instead, for |
|
| 175 | - * example, resampled images. |
|
| 176 | - */ |
|
| 177 | - function fileFound(File $file, $alternate_path = null) { |
|
| 133 | + if($file instanceof File) { |
|
| 134 | + if ($file->canView()) { |
|
| 135 | + $file->extend('onAccessGranted'); |
|
| 136 | + return $this->fileFound($file, $file_path); |
|
| 137 | + } else { |
|
| 138 | + $file->extend('onAccessDenied'); |
|
| 139 | + return $this->fileNotAuthorized(call_user_func_array('_t', self::$i18n_not_authorized)); |
|
| 140 | + } |
|
| 141 | + } else { |
|
| 142 | + return $this->fileNotFound(call_user_func_array('_t', self::$i18n_not_found)); |
|
| 143 | + } |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + /** |
|
| 147 | + * File Not Found response |
|
| 148 | + * |
|
| 149 | + * @param $body Optional message body |
|
| 150 | + * @return HTTPResponse |
|
| 151 | + */ |
|
| 152 | + function fileNotFound($body = "") { |
|
| 153 | + if(ClassInfo::exists('SS_HTTPResponse')) { |
|
| 154 | + return new SS_HTTPResponse($body, 404); |
|
| 155 | + } else { |
|
| 156 | + return new HTTPResponse($body, 404); |
|
| 157 | + } |
|
| 158 | + } |
|
| 159 | + |
|
| 160 | + /** |
|
| 161 | + * File not authorized response |
|
| 162 | + * |
|
| 163 | + * @param $body Optional message body |
|
| 164 | + * @return HTTPResponse |
|
| 165 | + */ |
|
| 166 | + function fileNotAuthorized($body = "") { |
|
| 167 | + Security::permissionFailure($this, $body); |
|
| 168 | + } |
|
| 169 | + |
|
| 170 | + /** |
|
| 171 | + * File found response |
|
| 172 | + * |
|
| 173 | + * @param $file File to send |
|
| 174 | + * @param $alternate_path string If supplied, return the file from this path instead, for |
|
| 175 | + * example, resampled images. |
|
| 176 | + */ |
|
| 177 | + function fileFound(File $file, $alternate_path = null) { |
|
| 178 | 178 | |
| 179 | - // File properties |
|
| 180 | - $file_name = $file->Name; |
|
| 181 | - $file_path = Director::getAbsFile($alternate_path ? $alternate_path : $file->FullPath); |
|
| 182 | - $file_size = filesize($file_path); |
|
| 179 | + // File properties |
|
| 180 | + $file_name = $file->Name; |
|
| 181 | + $file_path = Director::getAbsFile($alternate_path ? $alternate_path : $file->FullPath); |
|
| 182 | + $file_size = filesize($file_path); |
|
| 183 | 183 | |
| 184 | - // Testing mode - return an HTTPResponse |
|
| 185 | - if(self::$use_ss_sendfile) { |
|
| 186 | - if(ClassInfo::exists('SS_HTTPRequest')) { |
|
| 187 | - return SS_HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 188 | - } else { |
|
| 189 | - return HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 190 | - } |
|
| 191 | - } |
|
| 184 | + // Testing mode - return an HTTPResponse |
|
| 185 | + if(self::$use_ss_sendfile) { |
|
| 186 | + if(ClassInfo::exists('SS_HTTPRequest')) { |
|
| 187 | + return SS_HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 188 | + } else { |
|
| 189 | + return HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 190 | + } |
|
| 191 | + } |
|
| 192 | 192 | |
| 193 | - // Normal operation: |
|
| 194 | - $mimeType = HTTP::getMimeType($file_name); |
|
| 195 | - header("Content-Type: {$mimeType}; name=\"" . addslashes($file_name) . "\""); |
|
| 196 | - header("Content-Disposition: attachment; filename=" . addslashes($file_name)); |
|
| 197 | - header("Cache-Control: max-age=1, private"); |
|
| 198 | - header("Content-Length: {$file_size}"); |
|
| 199 | - header("Pragma: "); |
|
| 193 | + // Normal operation: |
|
| 194 | + $mimeType = HTTP::getMimeType($file_name); |
|
| 195 | + header("Content-Type: {$mimeType}; name=\"" . addslashes($file_name) . "\""); |
|
| 196 | + header("Content-Disposition: attachment; filename=" . addslashes($file_name)); |
|
| 197 | + header("Cache-Control: max-age=1, private"); |
|
| 198 | + header("Content-Length: {$file_size}"); |
|
| 199 | + header("Pragma: "); |
|
| 200 | 200 | |
| 201 | - if(self::$use_x_sendfile) { |
|
| 202 | - session_write_close(); |
|
| 203 | - header('X-Sendfile: '.$file_path); |
|
| 204 | - exit(); |
|
| 205 | - } elseif($filePointer = @fopen($file_path, 'rb')) { |
|
| 206 | - session_write_close(); |
|
| 207 | - $this->flush(); |
|
| 208 | - // Push the file while not EOF and connection exists |
|
| 209 | - while(!feof($filePointer) && !connection_aborted()) { |
|
| 210 | - print(fread($filePointer, 1024 * self::$chunck_size_kb)); |
|
| 211 | - $this->flush(); |
|
| 212 | - } |
|
| 213 | - fclose($filePointer); |
|
| 214 | - exit(); |
|
| 215 | - } else { |
|
| 216 | - // Edge case - either not found anymore or can't read |
|
| 217 | - return $this->fileNotFound(); |
|
| 218 | - } |
|
| 219 | - } |
|
| 220 | - |
|
| 221 | - /** |
|
| 222 | - * Flush the output buffer to the server (if possible). |
|
| 223 | - * @see http://nz.php.net/manual/en/function.flush.php#93531 |
|
| 224 | - */ |
|
| 225 | - function flush() { |
|
| 226 | - if(ob_get_length()) { |
|
| 227 | - @ob_flush(); |
|
| 228 | - @flush(); |
|
| 229 | - @ob_end_flush(); |
|
| 230 | - } |
|
| 231 | - @ob_start(); |
|
| 232 | - } |
|
| 233 | - |
|
| 234 | - /** |
|
| 235 | - * Permission provider for access to secure files |
|
| 236 | - * |
|
| 237 | - * @return array |
|
| 238 | - */ |
|
| 239 | - function providePermissions() { |
|
| 240 | - return array( |
|
| 241 | - 'SECURE_FILE_ACCESS' => _t('SecureFiles.SECUREFILEACCESS', 'Access to Secured Files'), |
|
| 242 | - 'SECURE_FILE_SETTINGS' => _t('SecureFiles.SECUREFILESETTINGS', 'Manage File Security Settings') |
|
| 243 | - ); |
|
| 244 | - } |
|
| 201 | + if(self::$use_x_sendfile) { |
|
| 202 | + session_write_close(); |
|
| 203 | + header('X-Sendfile: '.$file_path); |
|
| 204 | + exit(); |
|
| 205 | + } elseif($filePointer = @fopen($file_path, 'rb')) { |
|
| 206 | + session_write_close(); |
|
| 207 | + $this->flush(); |
|
| 208 | + // Push the file while not EOF and connection exists |
|
| 209 | + while(!feof($filePointer) && !connection_aborted()) { |
|
| 210 | + print(fread($filePointer, 1024 * self::$chunck_size_kb)); |
|
| 211 | + $this->flush(); |
|
| 212 | + } |
|
| 213 | + fclose($filePointer); |
|
| 214 | + exit(); |
|
| 215 | + } else { |
|
| 216 | + // Edge case - either not found anymore or can't read |
|
| 217 | + return $this->fileNotFound(); |
|
| 218 | + } |
|
| 219 | + } |
|
| 220 | + |
|
| 221 | + /** |
|
| 222 | + * Flush the output buffer to the server (if possible). |
|
| 223 | + * @see http://nz.php.net/manual/en/function.flush.php#93531 |
|
| 224 | + */ |
|
| 225 | + function flush() { |
|
| 226 | + if(ob_get_length()) { |
|
| 227 | + @ob_flush(); |
|
| 228 | + @flush(); |
|
| 229 | + @ob_end_flush(); |
|
| 230 | + } |
|
| 231 | + @ob_start(); |
|
| 232 | + } |
|
| 233 | + |
|
| 234 | + /** |
|
| 235 | + * Permission provider for access to secure files |
|
| 236 | + * |
|
| 237 | + * @return array |
|
| 238 | + */ |
|
| 239 | + function providePermissions() { |
|
| 240 | + return array( |
|
| 241 | + 'SECURE_FILE_ACCESS' => _t('SecureFiles.SECUREFILEACCESS', 'Access to Secured Files'), |
|
| 242 | + 'SECURE_FILE_SETTINGS' => _t('SecureFiles.SECUREFILESETTINGS', 'Manage File Security Settings') |
|
| 243 | + ); |
|
| 244 | + } |
|
| 245 | 245 | |
| 246 | 246 | } |
| 247 | 247 | \ No newline at end of file |
@@ -80,8 +80,8 @@ discard block |
||
| 80 | 80 | * @param int $kilobytes |
| 81 | 81 | */ |
| 82 | 82 | static function set_chunk_size($kilobytes) { |
| 83 | - $kilobytes = max(0, (int)$kilobytes); |
|
| 84 | - if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 83 | + $kilobytes = max(0, (int) $kilobytes); |
|
| 84 | + if (!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 85 | 85 | self::$chunck_size_kb = $kilobytes; |
| 86 | 86 | } |
| 87 | 87 | |
@@ -130,7 +130,7 @@ discard block |
||
| 130 | 130 | $file_path = Director::makeRelative($url); |
| 131 | 131 | $file = File::find($file_path); |
| 132 | 132 | |
| 133 | - if($file instanceof File) { |
|
| 133 | + if ($file instanceof File) { |
|
| 134 | 134 | if ($file->canView()) { |
| 135 | 135 | $file->extend('onAccessGranted'); |
| 136 | 136 | return $this->fileFound($file, $file_path); |
@@ -150,7 +150,7 @@ discard block |
||
| 150 | 150 | * @return HTTPResponse |
| 151 | 151 | */ |
| 152 | 152 | function fileNotFound($body = "") { |
| 153 | - if(ClassInfo::exists('SS_HTTPResponse')) { |
|
| 153 | + if (ClassInfo::exists('SS_HTTPResponse')) { |
|
| 154 | 154 | return new SS_HTTPResponse($body, 404); |
| 155 | 155 | } else { |
| 156 | 156 | return new HTTPResponse($body, 404); |
@@ -182,8 +182,8 @@ discard block |
||
| 182 | 182 | $file_size = filesize($file_path); |
| 183 | 183 | |
| 184 | 184 | // Testing mode - return an HTTPResponse |
| 185 | - if(self::$use_ss_sendfile) { |
|
| 186 | - if(ClassInfo::exists('SS_HTTPRequest')) { |
|
| 185 | + if (self::$use_ss_sendfile) { |
|
| 186 | + if (ClassInfo::exists('SS_HTTPRequest')) { |
|
| 187 | 187 | return SS_HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
| 188 | 188 | } else { |
| 189 | 189 | return HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
@@ -198,15 +198,15 @@ discard block |
||
| 198 | 198 | header("Content-Length: {$file_size}"); |
| 199 | 199 | header("Pragma: "); |
| 200 | 200 | |
| 201 | - if(self::$use_x_sendfile) { |
|
| 201 | + if (self::$use_x_sendfile) { |
|
| 202 | 202 | session_write_close(); |
| 203 | - header('X-Sendfile: '.$file_path); |
|
| 203 | + header('X-Sendfile: ' . $file_path); |
|
| 204 | 204 | exit(); |
| 205 | - } elseif($filePointer = @fopen($file_path, 'rb')) { |
|
| 205 | + } elseif ($filePointer = @fopen($file_path, 'rb')) { |
|
| 206 | 206 | session_write_close(); |
| 207 | 207 | $this->flush(); |
| 208 | 208 | // Push the file while not EOF and connection exists |
| 209 | - while(!feof($filePointer) && !connection_aborted()) { |
|
| 209 | + while (!feof($filePointer) && !connection_aborted()) { |
|
| 210 | 210 | print(fread($filePointer, 1024 * self::$chunck_size_kb)); |
| 211 | 211 | $this->flush(); |
| 212 | 212 | } |
@@ -223,7 +223,7 @@ discard block |
||
| 223 | 223 | * @see http://nz.php.net/manual/en/function.flush.php#93531 |
| 224 | 224 | */ |
| 225 | 225 | function flush() { |
| 226 | - if(ob_get_length()) { |
|
| 226 | + if (ob_get_length()) { |
|
| 227 | 227 | @ob_flush(); |
| 228 | 228 | @flush(); |
| 229 | 229 | @ob_end_flush(); |
@@ -81,7 +81,9 @@ |
||
| 81 | 81 | */ |
| 82 | 82 | static function set_chunk_size($kilobytes) { |
| 83 | 83 | $kilobytes = max(0, (int)$kilobytes); |
| 84 | - if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 84 | + if(!$kilobytes) { |
|
| 85 | + user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 86 | + } |
|
| 85 | 87 | self::$chunck_size_kb = $kilobytes; |
| 86 | 88 | } |
| 87 | 89 | |
@@ -1,23 +1,23 @@ discard block |
||
| 1 | 1 | <?php |
| 2 | - class Advert_Controller extends Controller { |
|
| 2 | + class Advert_Controller extends Controller { |
|
| 3 | 3 | |
| 4 | 4 | |
| 5 | - /** |
|
| 6 | - * @var integer Size of output chunks in kb while in PHP fread mode. |
|
| 7 | - */ |
|
| 8 | - protected static $chunck_size_kb = 32; |
|
| 5 | + /** |
|
| 6 | + * @var integer Size of output chunks in kb while in PHP fread mode. |
|
| 7 | + */ |
|
| 8 | + protected static $chunck_size_kb = 32; |
|
| 9 | 9 | |
| 10 | - /** |
|
| 11 | - * @var boolean Flag use X-Sendfile header mode instead of PHP fread mode. |
|
| 12 | - */ |
|
| 13 | - protected static $use_x_sendfile = false; |
|
| 10 | + /** |
|
| 11 | + * @var boolean Flag use X-Sendfile header mode instead of PHP fread mode. |
|
| 12 | + */ |
|
| 13 | + protected static $use_x_sendfile = false; |
|
| 14 | 14 | |
| 15 | - /** |
|
| 16 | - * @var boolean Flag use SilverStripe send file method. |
|
| 17 | - */ |
|
| 18 | - protected static $use_ss_sendfile = false; |
|
| 15 | + /** |
|
| 16 | + * @var boolean Flag use SilverStripe send file method. |
|
| 17 | + */ |
|
| 18 | + protected static $use_ss_sendfile = false; |
|
| 19 | 19 | |
| 20 | - /* |
|
| 20 | + /* |
|
| 21 | 21 | When a URL of the following form is clicked, |
| 22 | 22 | http://SERVER/advert/26b0c28f4566dc54cc66770bdda86017851bd3dbbd4ac5868c63e003903dc8dc9b88b209bba54f1b5e6f4c3cf1295e58298e7d5a58b6c8ff02df9130ffd4ac30 |
| 23 | 23 | a search is made for the digital signature in the adverts (this is indexed in the database) |
@@ -26,44 +26,44 @@ discard block |
||
| 26 | 26 | |
| 27 | 27 | If a record is not found a 404 is returned |
| 28 | 28 | */ |
| 29 | - public function click($args) { |
|
| 30 | - $params = $args->allParams(); |
|
| 31 | - $digsig = $params['DigitalSignature']; |
|
| 29 | + public function click($args) { |
|
| 30 | + $params = $args->allParams(); |
|
| 31 | + $digsig = $params['DigitalSignature']; |
|
| 32 | 32 | |
| 33 | - $advert = Advert::get()->filter('DigitalSignature', $digsig)->first(); // should only be the one but make sure |
|
| 33 | + $advert = Advert::get()->filter('DigitalSignature', $digsig)->first(); // should only be the one but make sure |
|
| 34 | 34 | |
| 35 | - if (!$advert) { |
|
| 36 | - $this->httpError(404, 'Advert "'.$digsig.'"" not found'); |
|
| 37 | - } else { |
|
| 38 | - // record the click |
|
| 39 | - $advert->Clickthroughs = $advert->Clickthroughs + 1; |
|
| 40 | - $advert->write(); |
|
| 41 | - // documentation here states temporary directs are used, http://doc.silverstripe.org/framework/en/topics/controller |
|
| 42 | - // this means the browser wont store the redirect and thus bypass the clickthrough recording |
|
| 43 | - return $this->redirect($advert->WebsiteLink); |
|
| 44 | - } |
|
| 35 | + if (!$advert) { |
|
| 36 | + $this->httpError(404, 'Advert "'.$digsig.'"" not found'); |
|
| 37 | + } else { |
|
| 38 | + // record the click |
|
| 39 | + $advert->Clickthroughs = $advert->Clickthroughs + 1; |
|
| 40 | + $advert->write(); |
|
| 41 | + // documentation here states temporary directs are used, http://doc.silverstripe.org/framework/en/topics/controller |
|
| 42 | + // this means the browser wont store the redirect and thus bypass the clickthrough recording |
|
| 43 | + return $this->redirect($advert->WebsiteLink); |
|
| 44 | + } |
|
| 45 | 45 | |
| 46 | 46 | |
| 47 | - } |
|
| 48 | - |
|
| 49 | - |
|
| 50 | - public function image($args) { |
|
| 51 | - $params = $args->allParams(); |
|
| 52 | - $digsig = $params['DigitalSignature']; |
|
| 53 | - |
|
| 54 | - $advert = Advert::get()->filter('DigitalSignature', $digsig)->first(); // should only be the one but make sure |
|
| 55 | - if (!$advert) { |
|
| 56 | - $this->httpError(404, 'Advert "'.$digsig.'"" not found'); |
|
| 57 | - } else { |
|
| 58 | - // record the click |
|
| 59 | - $advert->Impressions = $advert->Impressions + 1; |
|
| 60 | - $advert->write(); |
|
| 61 | - // documentation here states temporary directs are used, http://doc.silverstripe.org/framework/en/topics/controller |
|
| 62 | - // this means the browser wont store the redirect and thus bypass the clickthrough recording |
|
| 63 | - |
|
| 64 | - return $this->fileFound($advert->AdvertImage()); |
|
| 65 | - } |
|
| 66 | - } |
|
| 47 | + } |
|
| 48 | + |
|
| 49 | + |
|
| 50 | + public function image($args) { |
|
| 51 | + $params = $args->allParams(); |
|
| 52 | + $digsig = $params['DigitalSignature']; |
|
| 53 | + |
|
| 54 | + $advert = Advert::get()->filter('DigitalSignature', $digsig)->first(); // should only be the one but make sure |
|
| 55 | + if (!$advert) { |
|
| 56 | + $this->httpError(404, 'Advert "'.$digsig.'"" not found'); |
|
| 57 | + } else { |
|
| 58 | + // record the click |
|
| 59 | + $advert->Impressions = $advert->Impressions + 1; |
|
| 60 | + $advert->write(); |
|
| 61 | + // documentation here states temporary directs are used, http://doc.silverstripe.org/framework/en/topics/controller |
|
| 62 | + // this means the browser wont store the redirect and thus bypass the clickthrough recording |
|
| 63 | + |
|
| 64 | + return $this->fileFound($advert->AdvertImage()); |
|
| 65 | + } |
|
| 66 | + } |
|
| 67 | 67 | |
| 68 | 68 | |
| 69 | 69 | |
@@ -72,129 +72,129 @@ discard block |
||
| 72 | 72 | |
| 73 | 73 | |
| 74 | 74 | |
| 75 | - /** |
|
| 76 | - * Use X-Sendfile headers to send files to the browser. |
|
| 77 | - * This is quicker than pushing files through PHP but |
|
| 78 | - * requires either Lighttpd or mod_xsendfile for Apache |
|
| 79 | - * @link http://tn123.ath.cx/mod_xsendfile/ |
|
| 80 | - */ |
|
| 81 | - static function use_x_sendfile_method() { |
|
| 82 | - self::use_default_sendfile_method(); |
|
| 83 | - self::$use_x_sendfile = true; |
|
| 84 | - } |
|
| 75 | + /** |
|
| 76 | + * Use X-Sendfile headers to send files to the browser. |
|
| 77 | + * This is quicker than pushing files through PHP but |
|
| 78 | + * requires either Lighttpd or mod_xsendfile for Apache |
|
| 79 | + * @link http://tn123.ath.cx/mod_xsendfile/ |
|
| 80 | + */ |
|
| 81 | + static function use_x_sendfile_method() { |
|
| 82 | + self::use_default_sendfile_method(); |
|
| 83 | + self::$use_x_sendfile = true; |
|
| 84 | + } |
|
| 85 | 85 | |
| 86 | - /** |
|
| 87 | - * Use internal SilverStripe to send files to the browser. |
|
| 88 | - * This is the least efficient method but is useful for |
|
| 89 | - * testing. Not recommend for production |
|
| 90 | - * environments. |
|
| 91 | - */ |
|
| 92 | - static function use_ss_sendfile_method() { |
|
| 93 | - self::use_default_sendfile_method(); |
|
| 94 | - self::$use_ss_sendfile = true; |
|
| 95 | - } |
|
| 86 | + /** |
|
| 87 | + * Use internal SilverStripe to send files to the browser. |
|
| 88 | + * This is the least efficient method but is useful for |
|
| 89 | + * testing. Not recommend for production |
|
| 90 | + * environments. |
|
| 91 | + */ |
|
| 92 | + static function use_ss_sendfile_method() { |
|
| 93 | + self::use_default_sendfile_method(); |
|
| 94 | + self::$use_ss_sendfile = true; |
|
| 95 | + } |
|
| 96 | 96 | |
| 97 | - /** |
|
| 98 | - * Use the default chuncked file method to send files to the browser. |
|
| 99 | - * This is the default method. |
|
| 100 | - */ |
|
| 101 | - static function use_default_sendfile_method() { |
|
| 102 | - self::$use_ss_sendfile = false; |
|
| 103 | - self::$use_x_sendfile = false; |
|
| 104 | - } |
|
| 97 | + /** |
|
| 98 | + * Use the default chuncked file method to send files to the browser. |
|
| 99 | + * This is the default method. |
|
| 100 | + */ |
|
| 101 | + static function use_default_sendfile_method() { |
|
| 102 | + self::$use_ss_sendfile = false; |
|
| 103 | + self::$use_x_sendfile = false; |
|
| 104 | + } |
|
| 105 | 105 | |
| 106 | - /** |
|
| 107 | - * Set the size of upload chunk in bytes. |
|
| 108 | - * @param int $kilobytes |
|
| 109 | - */ |
|
| 110 | - static function set_chunk_size($kilobytes) { |
|
| 111 | - $kilobytes = max(0, (int)$kilobytes); |
|
| 112 | - if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 113 | - self::$chunck_size_kb = $kilobytes; |
|
| 114 | - } |
|
| 106 | + /** |
|
| 107 | + * Set the size of upload chunk in bytes. |
|
| 108 | + * @param int $kilobytes |
|
| 109 | + */ |
|
| 110 | + static function set_chunk_size($kilobytes) { |
|
| 111 | + $kilobytes = max(0, (int)$kilobytes); |
|
| 112 | + if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 113 | + self::$chunck_size_kb = $kilobytes; |
|
| 114 | + } |
|
| 115 | 115 | |
| 116 | - /** |
|
| 117 | - * Set the Apache access file name (.htaccess by default) |
|
| 118 | - * as determined by the AccessFileName Apache directive. |
|
| 119 | - * @param string $filename |
|
| 120 | - */ |
|
| 121 | - static function set_access_filename($filename) { |
|
| 122 | - self::$htaccess_file = $filename; |
|
| 123 | - } |
|
| 116 | + /** |
|
| 117 | + * Set the Apache access file name (.htaccess by default) |
|
| 118 | + * as determined by the AccessFileName Apache directive. |
|
| 119 | + * @param string $filename |
|
| 120 | + */ |
|
| 121 | + static function set_access_filename($filename) { |
|
| 122 | + self::$htaccess_file = $filename; |
|
| 123 | + } |
|
| 124 | 124 | |
| 125 | - /** |
|
| 126 | - * Get the Apache access file name |
|
| 127 | - * @return string |
|
| 128 | - */ |
|
| 129 | - static function get_access_filename() { |
|
| 130 | - return self::$htaccess_file; |
|
| 131 | - } |
|
| 132 | - |
|
| 133 | - |
|
| 134 | - |
|
| 135 | - /** |
|
| 136 | - * File found response |
|
| 137 | - * |
|
| 138 | - * @param $file File to send |
|
| 139 | - * @param $alternate_path string If supplied, return the file from this path instead, for |
|
| 140 | - * example, resampled images. |
|
| 141 | - */ |
|
| 142 | - function fileFound(File $file, $alternate_path = null) { |
|
| 125 | + /** |
|
| 126 | + * Get the Apache access file name |
|
| 127 | + * @return string |
|
| 128 | + */ |
|
| 129 | + static function get_access_filename() { |
|
| 130 | + return self::$htaccess_file; |
|
| 131 | + } |
|
| 132 | + |
|
| 133 | + |
|
| 134 | + |
|
| 135 | + /** |
|
| 136 | + * File found response |
|
| 137 | + * |
|
| 138 | + * @param $file File to send |
|
| 139 | + * @param $alternate_path string If supplied, return the file from this path instead, for |
|
| 140 | + * example, resampled images. |
|
| 141 | + */ |
|
| 142 | + function fileFound(File $file, $alternate_path = null) { |
|
| 143 | 143 | |
| 144 | - // File properties |
|
| 145 | - $file_name = $file->Name; |
|
| 146 | - $file_path = Director::getAbsFile($alternate_path ? $alternate_path : $file->FullPath); |
|
| 147 | - $file_size = filesize($file_path); |
|
| 144 | + // File properties |
|
| 145 | + $file_name = $file->Name; |
|
| 146 | + $file_path = Director::getAbsFile($alternate_path ? $alternate_path : $file->FullPath); |
|
| 147 | + $file_size = filesize($file_path); |
|
| 148 | 148 | |
| 149 | - // Testing mode - return an HTTPResponse |
|
| 150 | - if(self::$use_ss_sendfile) { |
|
| 151 | - if(ClassInfo::exists('SS_HTTPRequest')) { |
|
| 152 | - return SS_HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 153 | - } else { |
|
| 154 | - return HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 155 | - } |
|
| 156 | - } |
|
| 149 | + // Testing mode - return an HTTPResponse |
|
| 150 | + if(self::$use_ss_sendfile) { |
|
| 151 | + if(ClassInfo::exists('SS_HTTPRequest')) { |
|
| 152 | + return SS_HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 153 | + } else { |
|
| 154 | + return HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
|
| 155 | + } |
|
| 156 | + } |
|
| 157 | 157 | |
| 158 | - // Normal operation: |
|
| 159 | - $mimeType = HTTP::get_mime_type($file_name); |
|
| 160 | - header("Content-Type: {$mimeType}; name=\"" . addslashes($file_name) . "\""); |
|
| 161 | - header("Content-Disposition: attachment; filename=" . addslashes($file_name)); |
|
| 162 | - header("Cache-Control: max-age=1, private"); |
|
| 163 | - header("Content-Length: {$file_size}"); |
|
| 164 | - header("Pragma: "); |
|
| 158 | + // Normal operation: |
|
| 159 | + $mimeType = HTTP::get_mime_type($file_name); |
|
| 160 | + header("Content-Type: {$mimeType}; name=\"" . addslashes($file_name) . "\""); |
|
| 161 | + header("Content-Disposition: attachment; filename=" . addslashes($file_name)); |
|
| 162 | + header("Cache-Control: max-age=1, private"); |
|
| 163 | + header("Content-Length: {$file_size}"); |
|
| 164 | + header("Pragma: "); |
|
| 165 | 165 | |
| 166 | - if(self::$use_x_sendfile) { |
|
| 167 | - session_write_close(); |
|
| 168 | - header('X-Sendfile: '.$file_path); |
|
| 169 | - exit(); |
|
| 170 | - } elseif($filePointer = @fopen($file_path, 'rb')) { |
|
| 171 | - session_write_close(); |
|
| 172 | - $this->flush(); |
|
| 173 | - // Push the file while not EOF and connection exists |
|
| 174 | - while(!feof($filePointer) && !connection_aborted()) { |
|
| 175 | - //error_log("Sending $chunck_size_kb kb"); |
|
| 176 | - print(fread($filePointer, 1024 * self::$chunck_size_kb)); |
|
| 177 | - $this->flush(); |
|
| 178 | - } |
|
| 179 | - fclose($filePointer); |
|
| 180 | - exit(); |
|
| 181 | - } else { |
|
| 182 | - // Edge case - either not found anymore or can't read |
|
| 183 | - return $this->fileNotFound(); |
|
| 184 | - } |
|
| 185 | - } |
|
| 166 | + if(self::$use_x_sendfile) { |
|
| 167 | + session_write_close(); |
|
| 168 | + header('X-Sendfile: '.$file_path); |
|
| 169 | + exit(); |
|
| 170 | + } elseif($filePointer = @fopen($file_path, 'rb')) { |
|
| 171 | + session_write_close(); |
|
| 172 | + $this->flush(); |
|
| 173 | + // Push the file while not EOF and connection exists |
|
| 174 | + while(!feof($filePointer) && !connection_aborted()) { |
|
| 175 | + //error_log("Sending $chunck_size_kb kb"); |
|
| 176 | + print(fread($filePointer, 1024 * self::$chunck_size_kb)); |
|
| 177 | + $this->flush(); |
|
| 178 | + } |
|
| 179 | + fclose($filePointer); |
|
| 180 | + exit(); |
|
| 181 | + } else { |
|
| 182 | + // Edge case - either not found anymore or can't read |
|
| 183 | + return $this->fileNotFound(); |
|
| 184 | + } |
|
| 185 | + } |
|
| 186 | 186 | |
| 187 | - /** |
|
| 188 | - * Flush the output buffer to the server (if possible). |
|
| 189 | - * @see http://nz.php.net/manual/en/function.flush.php#93531 |
|
| 190 | - */ |
|
| 191 | - function flush() { |
|
| 192 | - if(ob_get_length()) { |
|
| 193 | - @ob_flush(); |
|
| 194 | - @flush(); |
|
| 195 | - @ob_end_flush(); |
|
| 196 | - } |
|
| 197 | - @ob_start(); |
|
| 198 | - } |
|
| 187 | + /** |
|
| 188 | + * Flush the output buffer to the server (if possible). |
|
| 189 | + * @see http://nz.php.net/manual/en/function.flush.php#93531 |
|
| 190 | + */ |
|
| 191 | + function flush() { |
|
| 192 | + if(ob_get_length()) { |
|
| 193 | + @ob_flush(); |
|
| 194 | + @flush(); |
|
| 195 | + @ob_end_flush(); |
|
| 196 | + } |
|
| 197 | + @ob_start(); |
|
| 198 | + } |
|
| 199 | 199 | |
| 200 | 200 | } |
| 201 | 201 | \ No newline at end of file |
@@ -33,7 +33,7 @@ discard block |
||
| 33 | 33 | $advert = Advert::get()->filter('DigitalSignature', $digsig)->first(); // should only be the one but make sure |
| 34 | 34 | |
| 35 | 35 | if (!$advert) { |
| 36 | - $this->httpError(404, 'Advert "'.$digsig.'"" not found'); |
|
| 36 | + $this->httpError(404, 'Advert "' . $digsig . '"" not found'); |
|
| 37 | 37 | } else { |
| 38 | 38 | // record the click |
| 39 | 39 | $advert->Clickthroughs = $advert->Clickthroughs + 1; |
@@ -53,7 +53,7 @@ discard block |
||
| 53 | 53 | |
| 54 | 54 | $advert = Advert::get()->filter('DigitalSignature', $digsig)->first(); // should only be the one but make sure |
| 55 | 55 | if (!$advert) { |
| 56 | - $this->httpError(404, 'Advert "'.$digsig.'"" not found'); |
|
| 56 | + $this->httpError(404, 'Advert "' . $digsig . '"" not found'); |
|
| 57 | 57 | } else { |
| 58 | 58 | // record the click |
| 59 | 59 | $advert->Impressions = $advert->Impressions + 1; |
@@ -108,8 +108,8 @@ discard block |
||
| 108 | 108 | * @param int $kilobytes |
| 109 | 109 | */ |
| 110 | 110 | static function set_chunk_size($kilobytes) { |
| 111 | - $kilobytes = max(0, (int)$kilobytes); |
|
| 112 | - if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 111 | + $kilobytes = max(0, (int) $kilobytes); |
|
| 112 | + if (!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 113 | 113 | self::$chunck_size_kb = $kilobytes; |
| 114 | 114 | } |
| 115 | 115 | |
@@ -147,8 +147,8 @@ discard block |
||
| 147 | 147 | $file_size = filesize($file_path); |
| 148 | 148 | |
| 149 | 149 | // Testing mode - return an HTTPResponse |
| 150 | - if(self::$use_ss_sendfile) { |
|
| 151 | - if(ClassInfo::exists('SS_HTTPRequest')) { |
|
| 150 | + if (self::$use_ss_sendfile) { |
|
| 151 | + if (ClassInfo::exists('SS_HTTPRequest')) { |
|
| 152 | 152 | return SS_HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
| 153 | 153 | } else { |
| 154 | 154 | return HTTPRequest::send_file(file_get_contents($file_path), $file_name); |
@@ -163,15 +163,15 @@ discard block |
||
| 163 | 163 | header("Content-Length: {$file_size}"); |
| 164 | 164 | header("Pragma: "); |
| 165 | 165 | |
| 166 | - if(self::$use_x_sendfile) { |
|
| 166 | + if (self::$use_x_sendfile) { |
|
| 167 | 167 | session_write_close(); |
| 168 | - header('X-Sendfile: '.$file_path); |
|
| 168 | + header('X-Sendfile: ' . $file_path); |
|
| 169 | 169 | exit(); |
| 170 | - } elseif($filePointer = @fopen($file_path, 'rb')) { |
|
| 170 | + } elseif ($filePointer = @fopen($file_path, 'rb')) { |
|
| 171 | 171 | session_write_close(); |
| 172 | 172 | $this->flush(); |
| 173 | 173 | // Push the file while not EOF and connection exists |
| 174 | - while(!feof($filePointer) && !connection_aborted()) { |
|
| 174 | + while (!feof($filePointer) && !connection_aborted()) { |
|
| 175 | 175 | //error_log("Sending $chunck_size_kb kb"); |
| 176 | 176 | print(fread($filePointer, 1024 * self::$chunck_size_kb)); |
| 177 | 177 | $this->flush(); |
@@ -189,7 +189,7 @@ discard block |
||
| 189 | 189 | * @see http://nz.php.net/manual/en/function.flush.php#93531 |
| 190 | 190 | */ |
| 191 | 191 | function flush() { |
| 192 | - if(ob_get_length()) { |
|
| 192 | + if (ob_get_length()) { |
|
| 193 | 193 | @ob_flush(); |
| 194 | 194 | @flush(); |
| 195 | 195 | @ob_end_flush(); |
@@ -109,7 +109,9 @@ |
||
| 109 | 109 | */ |
| 110 | 110 | static function set_chunk_size($kilobytes) { |
| 111 | 111 | $kilobytes = max(0, (int)$kilobytes); |
| 112 | - if(!$kilobytes) user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 112 | + if(!$kilobytes) { |
|
| 113 | + user_error("Invalid download chunk size", E_USER_ERROR); |
|
| 114 | + } |
|
| 113 | 115 | self::$chunck_size_kb = $kilobytes; |
| 114 | 116 | } |
| 115 | 117 | |
@@ -6,15 +6,15 @@ discard block |
||
| 6 | 6 | class Advert extends DataObject { |
| 7 | 7 | |
| 8 | 8 | |
| 9 | - static $searchable_fields = array( |
|
| 9 | + static $searchable_fields = array( |
|
| 10 | 10 | 'WebsiteLink', |
| 11 | - ); |
|
| 11 | + ); |
|
| 12 | 12 | |
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | |
| 17 | - static $db = array( |
|
| 17 | + static $db = array( |
|
| 18 | 18 | // title to show in model admin |
| 19 | 19 | 'Title' => 'Varchar(255)', |
| 20 | 20 | |
@@ -39,28 +39,28 @@ discard block |
||
| 39 | 39 | // stats |
| 40 | 40 | 'Impressions' => 'Int', |
| 41 | 41 | 'Clickthroughs' => 'Int', |
| 42 | - ); |
|
| 42 | + ); |
|
| 43 | 43 | |
| 44 | 44 | |
| 45 | 45 | |
| 46 | 46 | |
| 47 | - static $has_one = array( |
|
| 47 | + static $has_one = array( |
|
| 48 | 48 | 'AdvertImage' => 'Image', |
| 49 | 49 | 'AdvertCategory' => "AdvertCategory", |
| 50 | 50 | "AdvertLayoutType" => "AdvertLayoutType" |
| 51 | - ); |
|
| 51 | + ); |
|
| 52 | 52 | |
| 53 | 53 | |
| 54 | - public static $summary_fields = array( |
|
| 54 | + public static $summary_fields = array( |
|
| 55 | 55 | 'Title' => 'Title', |
| 56 | 56 | 'AdvertCategory.Title', |
| 57 | 57 | 'AdvertLayoutType.Title', |
| 58 | 58 | 'StartDate' => 'StartDate', |
| 59 | 59 | 'FinishDate' => 'FinishDate' |
| 60 | - ); |
|
| 60 | + ); |
|
| 61 | 61 | |
| 62 | 62 | |
| 63 | - // add an index in the db for the digital signature and date ranges |
|
| 63 | + // add an index in the db for the digital signature and date ranges |
|
| 64 | 64 | static $indexes = array( |
| 65 | 65 | 'DigitalSignature' => true, |
| 66 | 66 | 'StartDate' => '(StartDate)', |
@@ -72,11 +72,11 @@ discard block |
||
| 72 | 72 | |
| 73 | 73 | |
| 74 | 74 | |
| 75 | - function getCMSFields() { |
|
| 75 | + function getCMSFields() { |
|
| 76 | 76 | |
| 77 | 77 | Requirements::javascript('weboftalent-adverts/javascript/advertedit.js'); |
| 78 | 78 | |
| 79 | - // throw away the scaffolding and start afresh |
|
| 79 | + // throw away the scaffolding and start afresh |
|
| 80 | 80 | $fields = new FieldList(); |
| 81 | 81 | |
| 82 | 82 | // add a main tab |
@@ -91,13 +91,13 @@ discard block |
||
| 91 | 91 | // a Javascript toggle on this field displays either the adbroker text field, or an image with URL |
| 92 | 92 | $fields->addFieldToTab('Root.Main', new DropdownField('AdvertSource', 'The type of advert', |
| 93 | 93 | singleton('Advert')->dbObject('AdvertSource')->enumValues() |
| 94 | - )); |
|
| 94 | + )); |
|
| 95 | 95 | |
| 96 | 96 | if ($this->ID == 0) { |
| 97 | 97 | $html = '<div class="field text">An image can be uploaded after the advert is saved for the first time</div>'; |
| 98 | 98 | $fields->addFieldToTab('Root.Main', new LiteralField('ImageInfo', $html)); |
| 99 | 99 | } else { |
| 100 | - $fields->addFieldToTab('Root.Main', $imageUploader = new UploadField('AdvertImage', |
|
| 100 | + $fields->addFieldToTab('Root.Main', $imageUploader = new UploadField('AdvertImage', |
|
| 101 | 101 | 'Image that will be shown as the actual advert')); |
| 102 | 102 | Folder::find_or_make('ads'); |
| 103 | 103 | $imageUploader->setFolderName('ads' |
@@ -129,21 +129,21 @@ discard block |
||
| 129 | 129 | $fields->addFieldToTab('Root.Main', $layoutfield); |
| 130 | 130 | |
| 131 | 131 | return $fields; |
| 132 | - } |
|
| 132 | + } |
|
| 133 | 133 | |
| 134 | 134 | |
| 135 | 135 | |
| 136 | - public function onBeforeWrite() { |
|
| 136 | + public function onBeforeWrite() { |
|
| 137 | 137 | $this->DigitalSignature = $this->CalculateDigitalSignature(); |
| 138 | 138 | //error_log("DIG SIG:".$this->DigitalSignature); |
| 139 | 139 | parent::onBeforeWrite(); |
| 140 | - } |
|
| 140 | + } |
|
| 141 | 141 | |
| 142 | 142 | |
| 143 | - /* |
|
| 143 | + /* |
|
| 144 | 144 | Calculate a digital signature from several of the fields |
| 145 | 145 | */ |
| 146 | - public function CalculateDigitalSignature() { |
|
| 146 | + public function CalculateDigitalSignature() { |
|
| 147 | 147 | //error_log("Calculating dig sig"); |
| 148 | 148 | /* because we save the impression counter on every rendition this cannot include |
| 149 | 149 | - number of impressions |
@@ -155,7 +155,7 @@ discard block |
||
| 155 | 155 | $hashed = hash('sha512', $data); |
| 156 | 156 | //error_log("HASH CREATED:".$hashed); |
| 157 | 157 | return $hashed; |
| 158 | - } |
|
| 158 | + } |
|
| 159 | 159 | |
| 160 | 160 | |
| 161 | 161 | |
@@ -85,7 +85,7 @@ discard block |
||
| 85 | 85 | |
| 86 | 86 | |
| 87 | 87 | // human readable title |
| 88 | - $fields->addFieldToTab('Root.Main', new TextField('Title', |
|
| 88 | + $fields->addFieldToTab('Root.Main', new TextField('Title', |
|
| 89 | 89 | 'Human readable title for the advert')); |
| 90 | 90 | |
| 91 | 91 | // a Javascript toggle on this field displays either the adbroker text field, or an image with URL |
@@ -107,10 +107,10 @@ discard block |
||
| 107 | 107 | |
| 108 | 108 | |
| 109 | 109 | // quick tags, faster than the grid editor - these are processed prior to save to create/assign tags |
| 110 | - $fields->addFieldToTab('Root.Main', new TextField('WebsiteLink', |
|
| 110 | + $fields->addFieldToTab('Root.Main', new TextField('WebsiteLink', |
|
| 111 | 111 | 'The URL that will be shown when the advert image is clicked')); |
| 112 | 112 | |
| 113 | - $fields->addFieldToTab('Root.Main', new TextareaField('AdbrokerJavascript', |
|
| 113 | + $fields->addFieldToTab('Root.Main', new TextareaField('AdbrokerJavascript', |
|
| 114 | 114 | 'JavaScript provided by the adbroker')); |
| 115 | 115 | |
| 116 | 116 | $fields->addFieldToTab('Root.Main', $sdf = new DateField('StartDate', 'The date the advert becomes active')); |
@@ -150,8 +150,8 @@ discard block |
||
| 150 | 150 | - last edited |
| 151 | 151 | Otherwise the clickthrough will fail |
| 152 | 152 | */ |
| 153 | - $data = $this->ID.'_'.$this->AdvertCategory()->Title.'_'.$this->AdvertLayoutType()->Title.'_'.$this->AdbrokerJavascript; |
|
| 154 | - $data .= '_'.$this->StartDate.'_'.$this->FinishDate.'_'.$this->ClickThroughs.'_advert'; |
|
| 153 | + $data = $this->ID . '_' . $this->AdvertCategory()->Title . '_' . $this->AdvertLayoutType()->Title . '_' . $this->AdbrokerJavascript; |
|
| 154 | + $data .= '_' . $this->StartDate . '_' . $this->FinishDate . '_' . $this->ClickThroughs . '_advert'; |
|
| 155 | 155 | $hashed = hash('sha512', $data); |
| 156 | 156 | //error_log("HASH CREATED:".$hashed); |
| 157 | 157 | return $hashed; |
@@ -63,7 +63,7 @@ |
||
| 63 | 63 | 50 |
| 64 | 64 | ); |
| 65 | 65 | |
| 66 | - // $df->setSize(100); |
|
| 66 | + // $df->setSize(100); |
|
| 67 | 67 | $params->push($df); |
| 68 | 68 | |
| 69 | 69 | return $params; |
@@ -29,7 +29,7 @@ |
||
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | public function sourceRecords($params = null) { |
| 32 | - return DataList::create('Advert');//->limit(10); |
|
| 32 | + return DataList::create('Advert'); //->limit(10); |
|
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | |
@@ -7,39 +7,39 @@ discard block |
||
| 7 | 7 | class AdvertLayoutType extends DataObject { |
| 8 | 8 | |
| 9 | 9 | |
| 10 | - static $searchable_fields = array( |
|
| 10 | + static $searchable_fields = array( |
|
| 11 | 11 | 'Title', |
| 12 | - ); |
|
| 12 | + ); |
|
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | |
| 17 | 17 | |
| 18 | - static $db = array( |
|
| 18 | + static $db = array( |
|
| 19 | 19 | // name of the layout type, e.g. 'main banner' or 'skyscraper' |
| 20 | 20 | 'Title' => 'Varchar(255)', |
| 21 | 21 | |
| 22 | 22 | // whether or not ads are enabled |
| 23 | 23 | 'Width' => 'Int', |
| 24 | 24 | 'Height' => 'Int' |
| 25 | - ); |
|
| 25 | + ); |
|
| 26 | 26 | |
| 27 | 27 | |
| 28 | 28 | |
| 29 | - public static $summary_fields = array( |
|
| 29 | + public static $summary_fields = array( |
|
| 30 | 30 | 'Title' => 'Title', |
| 31 | 31 | 'Width' => 'Width', |
| 32 | 32 | 'Height' => 'Height' |
| 33 | - ); |
|
| 33 | + ); |
|
| 34 | 34 | |
| 35 | - static $has_many = array( |
|
| 35 | + static $has_many = array( |
|
| 36 | 36 | 'Adverts' => 'Advert' |
| 37 | - ); |
|
| 37 | + ); |
|
| 38 | 38 | |
| 39 | 39 | |
| 40 | 40 | |
| 41 | 41 | |
| 42 | - function getCMSFields() { |
|
| 42 | + function getCMSFields() { |
|
| 43 | 43 | $fields = new FieldList(); |
| 44 | 44 | |
| 45 | 45 | // add a tab |
@@ -52,7 +52,7 @@ discard block |
||
| 52 | 52 | $fields->addFieldToTab( 'Root.Main', new NumericField( 'Height', 'The height of the advert in pixels' ) ); |
| 53 | 53 | |
| 54 | 54 | return $fields; |
| 55 | - } |
|
| 55 | + } |
|
| 56 | 56 | |
| 57 | 57 | } |
| 58 | 58 | |
@@ -43,13 +43,13 @@ |
||
| 43 | 43 | $fields = new FieldList(); |
| 44 | 44 | |
| 45 | 45 | // add a tab |
| 46 | - $fields->push( new TabSet( "Root", $mainTab = new Tab( "Main" ) ) ); |
|
| 47 | - $mainTab->setTitle( _t( 'SiteTree.TABMAIN', "Main" ) ); |
|
| 46 | + $fields->push(new TabSet("Root", $mainTab = new Tab("Main"))); |
|
| 47 | + $mainTab->setTitle(_t('SiteTree.TABMAIN', "Main")); |
|
| 48 | 48 | |
| 49 | 49 | |
| 50 | - $fields->addFieldToTab( 'Root.Main', new TextField( 'Title', 'The name of the category') ); |
|
| 51 | - $fields->addFieldToTab( 'Root.Main', new NumericField( 'Width', 'The width of the advert in pixels' ) ); |
|
| 52 | - $fields->addFieldToTab( 'Root.Main', new NumericField( 'Height', 'The height of the advert in pixels' ) ); |
|
| 50 | + $fields->addFieldToTab('Root.Main', new TextField('Title', 'The name of the category')); |
|
| 51 | + $fields->addFieldToTab('Root.Main', new NumericField('Width', 'The width of the advert in pixels')); |
|
| 52 | + $fields->addFieldToTab('Root.Main', new NumericField('Height', 'The height of the advert in pixels')); |
|
| 53 | 53 | |
| 54 | 54 | return $fields; |
| 55 | 55 | } |
@@ -2,12 +2,12 @@ |
||
| 2 | 2 | |
| 3 | 3 | class AdvertAdmin extends ModelAdmin { |
| 4 | 4 | |
| 5 | - public static $managed_models = array( //since 2.3.2 |
|
| 6 | - 'Advert','AdvertCategory','AdvertLayoutType' |
|
| 7 | - ); |
|
| 5 | + public static $managed_models = array( //since 2.3.2 |
|
| 6 | + 'Advert','AdvertCategory','AdvertLayoutType' |
|
| 7 | + ); |
|
| 8 | 8 | |
| 9 | - static $url_segment = 'adverts'; // will be linked as /admin/adverts |
|
| 10 | - static $menu_title = 'Adverts'; |
|
| 9 | + static $url_segment = 'adverts'; // will be linked as /admin/adverts |
|
| 10 | + static $menu_title = 'Adverts'; |
|
| 11 | 11 | |
| 12 | 12 | } |
| 13 | 13 | |
@@ -3,7 +3,7 @@ |
||
| 3 | 3 | class AdvertAdmin extends ModelAdmin { |
| 4 | 4 | |
| 5 | 5 | public static $managed_models = array( //since 2.3.2 |
| 6 | - 'Advert','AdvertCategory','AdvertLayoutType' |
|
| 6 | + 'Advert', 'AdvertCategory', 'AdvertLayoutType' |
|
| 7 | 7 | ); |
| 8 | 8 | |
| 9 | 9 | static $url_segment = 'adverts'; // will be linked as /admin/adverts |
@@ -3,22 +3,22 @@ |
||
| 3 | 3 | class AdvertSiteConfig extends DataExtension { |
| 4 | 4 | |
| 5 | 5 | |
| 6 | - public static $db = array( |
|
| 7 | - 'MpuAboveFoldPosition' => 'Int', |
|
| 8 | - 'MpuBelowFoldPosition' => 'Int' |
|
| 9 | - ); |
|
| 6 | + public static $db = array( |
|
| 7 | + 'MpuAboveFoldPosition' => 'Int', |
|
| 8 | + 'MpuBelowFoldPosition' => 'Int' |
|
| 9 | + ); |
|
| 10 | 10 | |
| 11 | 11 | |
| 12 | - public static $defaults = array( |
|
| 13 | - 'MpuAboveFoldPosition' => '4', |
|
| 14 | - 'MpuBelowFoldPosition' => '11' |
|
| 15 | - ); |
|
| 12 | + public static $defaults = array( |
|
| 13 | + 'MpuAboveFoldPosition' => '4', |
|
| 14 | + 'MpuBelowFoldPosition' => '11' |
|
| 15 | + ); |
|
| 16 | 16 | |
| 17 | 17 | public function updateCMSFields(FieldList $fields) { |
| 18 | - $fields->addFieldToTab("Root.Advert", new NumericField("MpuAboveFoldPosition", |
|
| 19 | - "Position the list for the MPU advert above the fold")); |
|
| 20 | - $fields->addFieldToTab("Root.Advert", new NumericField("MpuBelowFoldPosition", |
|
| 21 | - "Position the list for the MPU advert below the fold")); |
|
| 18 | + $fields->addFieldToTab("Root.Advert", new NumericField("MpuAboveFoldPosition", |
|
| 19 | + "Position the list for the MPU advert above the fold")); |
|
| 20 | + $fields->addFieldToTab("Root.Advert", new NumericField("MpuBelowFoldPosition", |
|
| 21 | + "Position the list for the MPU advert below the fold")); |
|
| 22 | 22 | |
| 23 | 23 | } |
| 24 | 24 | } |
@@ -2,19 +2,19 @@ discard block |
||
| 2 | 2 | |
| 3 | 3 | class AdvertControllerExtension extends DataExtension { |
| 4 | 4 | |
| 5 | - /* |
|
| 5 | + /* |
|
| 6 | 6 | Store id to advert category to avoid multiple same queries |
| 7 | 7 | */ |
| 8 | - private static $cachedcategories = array(); |
|
| 8 | + private static $cachedcategories = array(); |
|
| 9 | 9 | |
| 10 | - /* |
|
| 10 | + /* |
|
| 11 | 11 | In order to prevent duplicate image adverts, stores those already served this request/response cycle |
| 12 | 12 | */ |
| 13 | - private static $advertsalreadyserved = array(); |
|
| 13 | + private static $advertsalreadyserved = array(); |
|
| 14 | 14 | |
| 15 | - static $ctr = 1; |
|
| 15 | + static $ctr = 1; |
|
| 16 | 16 | |
| 17 | - /* |
|
| 17 | + /* |
|
| 18 | 18 | Work out the appropriate category and render a random advert from that category |
| 19 | 19 | @param #adverttype The type of advert, e.g. MPU or Skyscraper |
| 20 | 20 | @param $prefix HTML prefix to the advert, e.g an li wrapper |
@@ -22,67 +22,67 @@ discard block |
||
| 22 | 22 | @param $numberofads - the number of adverts to search for. Normally 1 but skyscraper needs 2 |
| 23 | 23 | @param $showonajax - set this to false to hide adverts on ajax |
| 24 | 24 | */ |
| 25 | - function RenderAdvert($cachekey,$adverttype,$template='InlineAdvert', $numberofads = 1, $showonajax = true) { |
|
| 26 | - // If we are using ajax and showonajax is set to false, return no ad |
|
| 27 | - if (Director::is_ajax()) { |
|
| 28 | - if ($showonajax !== true) { |
|
| 29 | - return ''; |
|
| 30 | - } |
|
| 31 | - } |
|
| 32 | - |
|
| 33 | - // this is from the advert model extension so will be in place |
|
| 34 | - $advertcategoryid = $this->owner->CalculateAdvertCategoryID(); |
|
| 35 | - |
|
| 36 | - if (isset($cachedcategories[$advertcategoryid])) { |
|
| 37 | - $advertcategory = $cachedcategories[$advertcategoryid]; |
|
| 38 | - } |
|
| 39 | - if (!isset($advertcategory) ){ |
|
| 40 | - $advertcategory = AdvertCategory::get()->byID($advertcategoryid); |
|
| 41 | - $cachedcategories[$advertcategoryid] = $advertcategory; |
|
| 42 | - } |
|
| 43 | - |
|
| 44 | - // check if the category is enabled, if not return a blank |
|
| 45 | - if (isset($advertcategory) && $advertcategory->Enabled) { |
|
| 46 | - $where = "AdvertLayoutType.Title = '$adverttype'"; |
|
| 47 | - |
|
| 48 | - if (isset($advertcategory)) { |
|
| 49 | - $where .= ' AND Advert.AdvertCategoryID = '.$advertcategoryid; |
|
| 50 | - $where .= ' AND (StartDate IS NULL OR !StartDate OR StartDate < NOW()) AND (FinishDate IS NULL OR !FinishDate OR NOW() < FinishDate)'; |
|
| 51 | - |
|
| 52 | - if (count(self::$advertsalreadyserved) > 0) { |
|
| 53 | - $csv = implode(',', array_keys(self::$advertsalreadyserved)); |
|
| 54 | - $where .= " and Advert.ID not in ($csv)"; |
|
| 55 | - } |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - $adverts = Advert::get()-> |
|
| 59 | - innerJoin('AdvertLayoutType', 'Advert.AdvertLayoutTypeID = AdvertLayoutType.ID') |
|
| 60 | - ->innerJoin('AdvertCategory', 'Advert.AdvertCategoryID = AdvertCategory.ID') |
|
| 61 | - |
|
| 62 | - // filter does not work here, use where instead |
|
| 63 | - ->where($where) |
|
| 64 | - ->sort('RAND()')->limit($numberofads); |
|
| 65 | - |
|
| 66 | - $firstad = null; |
|
| 67 | - |
|
| 68 | - // datalist->first() was sometimes producing the same answer twice - SS bug? |
|
| 69 | - foreach ($adverts->getIterator() as $advert) { |
|
| 70 | - self::$advertsalreadyserved[$advert->ID] = $advert->ID; |
|
| 71 | - if ($firstad === null) { |
|
| 72 | - $firstad = $advert; |
|
| 73 | - } |
|
| 74 | - } |
|
| 75 | - |
|
| 76 | - $forTemplate = new ArrayData(array( |
|
| 77 | - 'Adverts' => $adverts, |
|
| 78 | - 'Advert' => $firstad, |
|
| 79 | - 'CacheKey' => $cachekey |
|
| 80 | - )); |
|
| 81 | - return $forTemplate->renderWith($template); |
|
| 82 | - } else { |
|
| 83 | - // return a blank if the cateogry is not enabled |
|
| 84 | - return ''; |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - } |
|
| 25 | + function RenderAdvert($cachekey,$adverttype,$template='InlineAdvert', $numberofads = 1, $showonajax = true) { |
|
| 26 | + // If we are using ajax and showonajax is set to false, return no ad |
|
| 27 | + if (Director::is_ajax()) { |
|
| 28 | + if ($showonajax !== true) { |
|
| 29 | + return ''; |
|
| 30 | + } |
|
| 31 | + } |
|
| 32 | + |
|
| 33 | + // this is from the advert model extension so will be in place |
|
| 34 | + $advertcategoryid = $this->owner->CalculateAdvertCategoryID(); |
|
| 35 | + |
|
| 36 | + if (isset($cachedcategories[$advertcategoryid])) { |
|
| 37 | + $advertcategory = $cachedcategories[$advertcategoryid]; |
|
| 38 | + } |
|
| 39 | + if (!isset($advertcategory) ){ |
|
| 40 | + $advertcategory = AdvertCategory::get()->byID($advertcategoryid); |
|
| 41 | + $cachedcategories[$advertcategoryid] = $advertcategory; |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + // check if the category is enabled, if not return a blank |
|
| 45 | + if (isset($advertcategory) && $advertcategory->Enabled) { |
|
| 46 | + $where = "AdvertLayoutType.Title = '$adverttype'"; |
|
| 47 | + |
|
| 48 | + if (isset($advertcategory)) { |
|
| 49 | + $where .= ' AND Advert.AdvertCategoryID = '.$advertcategoryid; |
|
| 50 | + $where .= ' AND (StartDate IS NULL OR !StartDate OR StartDate < NOW()) AND (FinishDate IS NULL OR !FinishDate OR NOW() < FinishDate)'; |
|
| 51 | + |
|
| 52 | + if (count(self::$advertsalreadyserved) > 0) { |
|
| 53 | + $csv = implode(',', array_keys(self::$advertsalreadyserved)); |
|
| 54 | + $where .= " and Advert.ID not in ($csv)"; |
|
| 55 | + } |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + $adverts = Advert::get()-> |
|
| 59 | + innerJoin('AdvertLayoutType', 'Advert.AdvertLayoutTypeID = AdvertLayoutType.ID') |
|
| 60 | + ->innerJoin('AdvertCategory', 'Advert.AdvertCategoryID = AdvertCategory.ID') |
|
| 61 | + |
|
| 62 | + // filter does not work here, use where instead |
|
| 63 | + ->where($where) |
|
| 64 | + ->sort('RAND()')->limit($numberofads); |
|
| 65 | + |
|
| 66 | + $firstad = null; |
|
| 67 | + |
|
| 68 | + // datalist->first() was sometimes producing the same answer twice - SS bug? |
|
| 69 | + foreach ($adverts->getIterator() as $advert) { |
|
| 70 | + self::$advertsalreadyserved[$advert->ID] = $advert->ID; |
|
| 71 | + if ($firstad === null) { |
|
| 72 | + $firstad = $advert; |
|
| 73 | + } |
|
| 74 | + } |
|
| 75 | + |
|
| 76 | + $forTemplate = new ArrayData(array( |
|
| 77 | + 'Adverts' => $adverts, |
|
| 78 | + 'Advert' => $firstad, |
|
| 79 | + 'CacheKey' => $cachekey |
|
| 80 | + )); |
|
| 81 | + return $forTemplate->renderWith($template); |
|
| 82 | + } else { |
|
| 83 | + // return a blank if the cateogry is not enabled |
|
| 84 | + return ''; |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + } |
|
| 88 | 88 | } |
| 89 | 89 | \ No newline at end of file |
@@ -22,7 +22,7 @@ discard block |
||
| 22 | 22 | @param $numberofads - the number of adverts to search for. Normally 1 but skyscraper needs 2 |
| 23 | 23 | @param $showonajax - set this to false to hide adverts on ajax |
| 24 | 24 | */ |
| 25 | - function RenderAdvert($cachekey,$adverttype,$template='InlineAdvert', $numberofads = 1, $showonajax = true) { |
|
| 25 | + function RenderAdvert($cachekey, $adverttype, $template = 'InlineAdvert', $numberofads = 1, $showonajax = true) { |
|
| 26 | 26 | // If we are using ajax and showonajax is set to false, return no ad |
| 27 | 27 | if (Director::is_ajax()) { |
| 28 | 28 | if ($showonajax !== true) { |
@@ -36,7 +36,7 @@ discard block |
||
| 36 | 36 | if (isset($cachedcategories[$advertcategoryid])) { |
| 37 | 37 | $advertcategory = $cachedcategories[$advertcategoryid]; |
| 38 | 38 | } |
| 39 | - if (!isset($advertcategory) ){ |
|
| 39 | + if (!isset($advertcategory)) { |
|
| 40 | 40 | $advertcategory = AdvertCategory::get()->byID($advertcategoryid); |
| 41 | 41 | $cachedcategories[$advertcategoryid] = $advertcategory; |
| 42 | 42 | } |
@@ -46,7 +46,7 @@ discard block |
||
| 46 | 46 | $where = "AdvertLayoutType.Title = '$adverttype'"; |
| 47 | 47 | |
| 48 | 48 | if (isset($advertcategory)) { |
| 49 | - $where .= ' AND Advert.AdvertCategoryID = '.$advertcategoryid; |
|
| 49 | + $where .= ' AND Advert.AdvertCategoryID = ' . $advertcategoryid; |
|
| 50 | 50 | $where .= ' AND (StartDate IS NULL OR !StartDate OR StartDate < NOW()) AND (FinishDate IS NULL OR !FinishDate OR NOW() < FinishDate)'; |
| 51 | 51 | |
| 52 | 52 | if (count(self::$advertsalreadyserved) > 0) { |
@@ -2,91 +2,91 @@ |
||
| 2 | 2 | |
| 3 | 3 | class AdvertSiteTreeExtension extends DataExtension { |
| 4 | 4 | |
| 5 | - /* |
|
| 5 | + /* |
|
| 6 | 6 | Any page in the site tree can have an advert category. This is used to determine the category |
| 7 | 7 | of adverts served in the tree of pages below it. THe cached value is used to avoid having to |
| 8 | 8 | recalculate it by traversing the tree each time. |
| 9 | 9 | */ |
| 10 | - static $has_one = array( |
|
| 11 | - 'AdvertCategory' => 'AdvertCategory', |
|
| 12 | - 'CachedAdvertCategory' => 'AdvertCategory', |
|
| 10 | + static $has_one = array( |
|
| 11 | + 'AdvertCategory' => 'AdvertCategory', |
|
| 12 | + 'CachedAdvertCategory' => 'AdvertCategory', |
|
| 13 | 13 | |
| 14 | - // it is possible that a cached value may be null, so in order to avoid traversing the tree |
|
| 15 | - // each page load, use this flag first |
|
| 16 | - 'IsCached' => 'Boolean' |
|
| 17 | - ); |
|
| 14 | + // it is possible that a cached value may be null, so in order to avoid traversing the tree |
|
| 15 | + // each page load, use this flag first |
|
| 16 | + 'IsCached' => 'Boolean' |
|
| 17 | + ); |
|
| 18 | 18 | |
| 19 | - /* |
|
| 19 | + /* |
|
| 20 | 20 | Add a Location tab containing the map |
| 21 | 21 | */ |
| 22 | - public function updateCMSFields( FieldList $fields ) { |
|
| 23 | - $categoryfield = new DropdownField('AdvertCategoryID', 'Category', AdvertCategory::get()->sort('Title')->map('ID', 'Title')); |
|
| 22 | + public function updateCMSFields( FieldList $fields ) { |
|
| 23 | + $categoryfield = new DropdownField('AdvertCategoryID', 'Category', AdvertCategory::get()->sort('Title')->map('ID', 'Title')); |
|
| 24 | 24 | $categoryfield->setEmptyString('(Select one)'); |
| 25 | 25 | $fields->addFieldToTab( "Root.AdvertCategory", $categoryfield); |
| 26 | - } |
|
| 26 | + } |
|
| 27 | 27 | |
| 28 | - /* |
|
| 28 | + /* |
|
| 29 | 29 | Prior to an item being saved, check for the category having being changed. If so we need to clear the category cache |
| 30 | 30 | for all items in the database, and cache this one. |
| 31 | 31 | */ |
| 32 | - public function onBeforeWrite() { |
|
| 33 | - $savedpage = SiteTree::get()->byID($this->owner->ID); |
|
| 34 | - //error_log("Formerly saved category id = ".$savedpage->AdvertCategory()->Title); |
|
| 35 | - //error_log("Category before save for page ".$this->owner->ID." is :".$this->owner->AdvertCategory()->Title); |
|
| 36 | - if ($savedpage->AdvertCategoryID != $this->owner->AdvertCategoryID) { |
|
| 37 | - //error_log("RESET CACHE"); |
|
| 32 | + public function onBeforeWrite() { |
|
| 33 | + $savedpage = SiteTree::get()->byID($this->owner->ID); |
|
| 34 | + //error_log("Formerly saved category id = ".$savedpage->AdvertCategory()->Title); |
|
| 35 | + //error_log("Category before save for page ".$this->owner->ID." is :".$this->owner->AdvertCategory()->Title); |
|
| 36 | + if ($savedpage->AdvertCategoryID != $this->owner->AdvertCategoryID) { |
|
| 37 | + //error_log("RESET CACHE"); |
|
| 38 | 38 | |
| 39 | - // clear caching for live and stage subtree |
|
| 40 | - DB::query('update SiteTree_Live set IsCachedID = false, CachedAdvertCategoryID = 0;'); |
|
| 41 | - DB::query('update SiteTree set IsCachedID = false, CachedAdvertCategoryID = 0;'); |
|
| 42 | - } else { |
|
| 43 | - //error_log("CACHE CAN KEEP GOING"); |
|
| 44 | - } |
|
| 45 | - parent::onBeforeWrite(); |
|
| 39 | + // clear caching for live and stage subtree |
|
| 40 | + DB::query('update SiteTree_Live set IsCachedID = false, CachedAdvertCategoryID = 0;'); |
|
| 41 | + DB::query('update SiteTree set IsCachedID = false, CachedAdvertCategoryID = 0;'); |
|
| 42 | + } else { |
|
| 43 | + //error_log("CACHE CAN KEEP GOING"); |
|
| 44 | + } |
|
| 45 | + parent::onBeforeWrite(); |
|
| 46 | 46 | |
| 47 | - } |
|
| 47 | + } |
|
| 48 | 48 | |
| 49 | 49 | |
| 50 | - /* |
|
| 50 | + /* |
|
| 51 | 51 | Get the advert category. Either use the cached advert category, or traverse the tree towards the root looking for it |
| 52 | 52 | */ |
| 53 | - public function CalculateAdvertCategoryID() { |
|
| 54 | - // use the cached value |
|
| 55 | - $result = $this->owner->CachedAdvertCategoryID; |
|
| 53 | + public function CalculateAdvertCategoryID() { |
|
| 54 | + // use the cached value |
|
| 55 | + $result = $this->owner->CachedAdvertCategoryID; |
|
| 56 | 56 | |
| 57 | - // if the record is not marked as cached, see if it has a category |
|
| 58 | - if (!$this->owner->IsCached) { |
|
| 59 | - if($this->owner->AdvertCategoryID > 0) { |
|
| 60 | - $this->owner->CachedAdvertCategoryID = $this->owner->AdvertCategoryID; |
|
| 61 | - $this->owner->IsCached = true; |
|
| 62 | - $this->owner->write; |
|
| 63 | - $result = $this->owner->CachedAdvertCategoryID; |
|
| 64 | - } else |
|
| 65 | - // otherwise traverse each parent in turn until reaching the root of the site, i.e. no parent |
|
| 66 | - { |
|
| 67 | - $parent = SiteTree::get()->byId($this->owner->ParentID); |
|
| 68 | - if ($parent) { |
|
| 69 | - while (true) { |
|
| 70 | - //error_log("TRAVERSING UP THE TREE LOOKING FOR CATEGORY"); |
|
| 71 | - if ($parent->IsCached) { |
|
| 72 | - $this->owner->AdvertCategoryID = $parent->AdvertCategoryID; |
|
| 73 | - $this->owner->IsCached = true; |
|
| 74 | - $this->owner->write(); |
|
| 75 | - $result = $this->owner->AdvertCategoryID; |
|
| 76 | - break; |
|
| 77 | - } |
|
| 57 | + // if the record is not marked as cached, see if it has a category |
|
| 58 | + if (!$this->owner->IsCached) { |
|
| 59 | + if($this->owner->AdvertCategoryID > 0) { |
|
| 60 | + $this->owner->CachedAdvertCategoryID = $this->owner->AdvertCategoryID; |
|
| 61 | + $this->owner->IsCached = true; |
|
| 62 | + $this->owner->write; |
|
| 63 | + $result = $this->owner->CachedAdvertCategoryID; |
|
| 64 | + } else |
|
| 65 | + // otherwise traverse each parent in turn until reaching the root of the site, i.e. no parent |
|
| 66 | + { |
|
| 67 | + $parent = SiteTree::get()->byId($this->owner->ParentID); |
|
| 68 | + if ($parent) { |
|
| 69 | + while (true) { |
|
| 70 | + //error_log("TRAVERSING UP THE TREE LOOKING FOR CATEGORY"); |
|
| 71 | + if ($parent->IsCached) { |
|
| 72 | + $this->owner->AdvertCategoryID = $parent->AdvertCategoryID; |
|
| 73 | + $this->owner->IsCached = true; |
|
| 74 | + $this->owner->write(); |
|
| 75 | + $result = $this->owner->AdvertCategoryID; |
|
| 76 | + break; |
|
| 77 | + } |
|
| 78 | 78 | |
| 79 | - $parent = SiteTree::get()->byId($parent->ParentID); |
|
| 80 | - if (!$parent) { |
|
| 81 | - break; |
|
| 82 | - } |
|
| 83 | - } |
|
| 84 | - } |
|
| 85 | - } |
|
| 79 | + $parent = SiteTree::get()->byId($parent->ParentID); |
|
| 80 | + if (!$parent) { |
|
| 81 | + break; |
|
| 82 | + } |
|
| 83 | + } |
|
| 84 | + } |
|
| 85 | + } |
|
| 86 | 86 | |
| 87 | - } |
|
| 87 | + } |
|
| 88 | 88 | |
| 89 | - return $result; |
|
| 90 | - } |
|
| 89 | + return $result; |
|
| 90 | + } |
|
| 91 | 91 | |
| 92 | 92 | } |
@@ -19,10 +19,10 @@ discard block |
||
| 19 | 19 | /* |
| 20 | 20 | Add a Location tab containing the map |
| 21 | 21 | */ |
| 22 | - public function updateCMSFields( FieldList $fields ) { |
|
| 22 | + public function updateCMSFields(FieldList $fields) { |
|
| 23 | 23 | $categoryfield = new DropdownField('AdvertCategoryID', 'Category', AdvertCategory::get()->sort('Title')->map('ID', 'Title')); |
| 24 | 24 | $categoryfield->setEmptyString('(Select one)'); |
| 25 | - $fields->addFieldToTab( "Root.AdvertCategory", $categoryfield); |
|
| 25 | + $fields->addFieldToTab("Root.AdvertCategory", $categoryfield); |
|
| 26 | 26 | } |
| 27 | 27 | |
| 28 | 28 | /* |
@@ -56,7 +56,7 @@ discard block |
||
| 56 | 56 | |
| 57 | 57 | // if the record is not marked as cached, see if it has a category |
| 58 | 58 | if (!$this->owner->IsCached) { |
| 59 | - if($this->owner->AdvertCategoryID > 0) { |
|
| 59 | + if ($this->owner->AdvertCategoryID > 0) { |
|
| 60 | 60 | $this->owner->CachedAdvertCategoryID = $this->owner->AdvertCategoryID; |
| 61 | 61 | $this->owner->IsCached = true; |
| 62 | 62 | $this->owner->write; |