Commit 059c98d4 authored by Shakarim Sapa's avatar Shakarim Sapa

Merge remote-tracking branch 'origin/master'

parents 14dcce89 36128716
<?php
namespace common\components;
/**
* File: Browser.php
* Author: Chris Schuld (http://chrisschuld.com/)
* Last Modified: August 20th, 2010
* @version 1.9
* @package PegasusPHP
*
* Copyright (C) 2008-2010 Chris Schuld (chris@chrisschuld.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details at:
* http://www.gnu.org/copyleft/gpl.html
*
*
* Typical Usage:
*
* $browser = new Browser();
* if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 2 ) {
* echo 'You have FireFox version 2 or greater';
* }
*
* User Agents Sampled from: http://www.useragentstring.com/
*
* This implementation is based on the original work from Gary White
* http://apptools.com/phptools/browser/
*
* UPDATES:
*
* 2010-08-20 (v1.9):
* + Added MSN Explorer Browser (legacy)
* + Added Bing/MSN Robot (Thanks Rob MacDonald)
* + Added the Android Platform (PLATFORM_ANDROID)
* + Fixed issue with Android 1.6/2.2 (Thanks Tom Hirashima)
*
* 2010-04-27 (v1.8):
* + Added iPad Support
*
* 2010-03-07 (v1.7):
* + *MAJOR* Rebuild (preg_match and other "slow" routine removal(s))
* + Almost allof Gary's original code has been replaced
* + Large PHPUNIT testing environment created to validate new releases and additions
* + Added FreeBSD Platform
* + Added OpenBSD Platform
* + Added NetBSD Platform
* + Added SunOS Platform
* + Added OpenSolaris Platform
* + Added support of the Iceweazel Browser
* + Added isChromeFrame() call to check if chromeframe is in use
* + Moved the Opera check in front of the Firefox check due to legacy Opera User Agents
* + Added the __toString() method (Thanks Deano)
*
* 2009-11-15:
* + Updated the checkes for Firefox
* + Added the NOKIA platform
* + Added Checks for the NOKIA brower(s)
*
* 2009-11-08:
* + PHP 5.3 Support
* + Added support for BlackBerry OS and BlackBerry browser
* + Added support for the Opera Mini browser
* + Added additional documenation
* + Added support for isRobot() and isMobile()
* + Added support for Opera version 10
* + Added support for deprecated Netscape Navigator version 9
* + Added support for IceCat
* + Added support for Shiretoko
*
* 2010-04-27 (v1.8):
* + Added iPad Support
*
* 2009-08-18:
* + Updated to support PHP 5.3 - removed all deprecated function calls
* + Updated to remove all double quotes (") -- converted to single quotes (')
*
* 2009-04-27:
* + Updated the IE check to remove a typo and bug (thanks John)
*
* 2009-04-22:
* + Added detection for GoogleBot
* + Added detection for the W3C Validator.
* + Added detection for Yahoo! Slurp
*
* 2009-03-14:
* + Added detection for iPods.
* + Added Platform detection for iPhones
* + Added Platform detection for iPods
*
* 2009-02-16: (Rick Hale)
* + Added version detection for Android phones.
*
* 2008-12-09:
* + Removed unused constant
*
* 2008-11-07:
* + Added Google's Chrome to the detection list
* + Added isBrowser(string) to the list of functions special thanks to
* Daniel 'mavrick' Lang for the function concept (http://mavrick.id.au)
*
*
* Gary White noted: "Since browser detection is so unreliable, I am
* no longer maintaining this script. You are free to use and or
* modify/update it as you want, however the author assumes no
* responsibility for the accuracy of the detected values."
*
* Anyone experienced with Gary's script might be interested in these notes:
*
* Added class constants
* Added detection and version detection for Google's Chrome
* Updated the version detection for Amaya
* Updated the version detection for Firefox
* Updated the version detection for Lynx
* Updated the version detection for WebTV
* Updated the version detection for NetPositive
* Updated the version detection for IE
* Updated the version detection for OmniWeb
* Updated the version detection for iCab
* Updated the version detection for Safari
* Updated Safari to remove mobile devices (iPhone)
* Added detection for iPhone
* Added detection for robots
* Added detection for mobile devices
* Added detection for BlackBerry
* Removed Netscape checks (matches heavily with firefox & mozilla)
*
*/
class Browser {
private $_agent = '';
private $_browser_name = '';
private $_version = '';
private $_platform = '';
private $_os = '';
private $_is_aol = false;
private $_is_mobile = false;
private $_is_robot = false;
private $_aol_version = '';
const BROWSER_UNKNOWN = 'unknown';
const VERSION_UNKNOWN = 'unknown';
const BROWSER_OPERA = 'Opera'; // http://www.opera.com/
const BROWSER_OPERA_MINI = 'Opera Mini'; // http://www.opera.com/mini/
const BROWSER_WEBTV = 'WebTV'; // http://www.webtv.net/pc/
const BROWSER_IE = 'Internet Explorer'; // http://www.microsoft.com/ie/
const BROWSER_POCKET_IE = 'Pocket Internet Explorer'; // http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
const BROWSER_KONQUEROR = 'Konqueror'; // http://www.konqueror.org/
const BROWSER_ICAB = 'iCab'; // http://www.icab.de/
const BROWSER_OMNIWEB = 'OmniWeb'; // http://www.omnigroup.com/applications/omniweb/
const BROWSER_FIREBIRD = 'Firebird'; // http://www.ibphoenix.com/
const BROWSER_FIREFOX = 'Firefox'; // http://www.mozilla.com/en-US/firefox/firefox.html
const BROWSER_ICEWEASEL = 'Iceweasel'; // http://www.geticeweasel.org/
const BROWSER_SHIRETOKO = 'Shiretoko'; // http://wiki.mozilla.org/Projects/shiretoko
const BROWSER_MOZILLA = 'Mozilla'; // http://www.mozilla.com/en-US/
const BROWSER_AMAYA = 'Amaya'; // http://www.w3.org/Amaya/
const BROWSER_LYNX = 'Lynx'; // http://en.wikipedia.org/wiki/Lynx
const BROWSER_SAFARI = 'Safari'; // http://apple.com
const BROWSER_IPHONE = 'iPhone'; // http://apple.com
const BROWSER_IPOD = 'iPod'; // http://apple.com
const BROWSER_IPAD = 'iPad'; // http://apple.com
const BROWSER_CHROME = 'Chrome'; // http://www.google.com/chrome
const BROWSER_ANDROID = 'Android'; // http://www.android.com/
const BROWSER_GOOGLEBOT = 'GoogleBot'; // http://en.wikipedia.org/wiki/Googlebot
const BROWSER_SLURP = 'Yahoo! Slurp'; // http://en.wikipedia.org/wiki/Yahoo!_Slurp
const BROWSER_W3CVALIDATOR = 'W3C Validator'; // http://validator.w3.org/
const BROWSER_BLACKBERRY = 'BlackBerry'; // http://www.blackberry.com/
const BROWSER_ICECAT = 'IceCat'; // http://en.wikipedia.org/wiki/GNU_IceCat
const BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser'; // http://en.wikipedia.org/wiki/Web_Browser_for_S60
const BROWSER_NOKIA = 'Nokia Browser'; // * all other WAP-based browsers on the Nokia Platform
const BROWSER_MSN = 'MSN Browser'; // http://explorer.msn.com/
const BROWSER_MSNBOT = 'MSN Bot'; // http://search.msn.com/msnbot.htm
// http://en.wikipedia.org/wiki/Msnbot (used for Bing as well)
const BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator'; // http://browser.netscape.com/ (DEPRECATED)
const BROWSER_GALEON = 'Galeon'; // http://galeon.sourceforge.net/ (DEPRECATED)
const BROWSER_NETPOSITIVE = 'NetPositive'; // http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
const BROWSER_PHOENIX = 'Phoenix'; // http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
const PLATFORM_UNKNOWN = 'unknown';
const PLATFORM_WINDOWS = 'Windows';
const PLATFORM_WINDOWS_CE = 'Windows CE';
const PLATFORM_APPLE = 'Apple';
const PLATFORM_LINUX = 'Linux';
const PLATFORM_OS2 = 'OS/2';
const PLATFORM_BEOS = 'BeOS';
const PLATFORM_IPHONE = 'iPhone';
const PLATFORM_IPOD = 'iPod';
const PLATFORM_IPAD = 'iPad';
const PLATFORM_BLACKBERRY = 'BlackBerry';
const PLATFORM_NOKIA = 'Nokia';
const PLATFORM_FREEBSD = 'FreeBSD';
const PLATFORM_OPENBSD = 'OpenBSD';
const PLATFORM_NETBSD = 'NetBSD';
const PLATFORM_SUNOS = 'SunOS';
const PLATFORM_OPENSOLARIS = 'OpenSolaris';
const PLATFORM_ANDROID = 'Android';
const OPERATING_SYSTEM_UNKNOWN = 'unknown';
public function Browser($useragent="") {
$this->reset();
if( $useragent != "" ) {
$this->setUserAgent($useragent);
}
else {
$this->determine();
}
}
/**
* Reset all properties
*/
public function reset() {
$this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
$this->_browser_name = self::BROWSER_UNKNOWN;
$this->_version = self::VERSION_UNKNOWN;
$this->_platform = self::PLATFORM_UNKNOWN;
$this->_os = self::OPERATING_SYSTEM_UNKNOWN;
$this->_is_aol = false;
$this->_is_mobile = false;
$this->_is_robot = false;
$this->_aol_version = self::VERSION_UNKNOWN;
}
/**
* Check to see if the specific browser is valid
* @param string $browserName
* @return True if the browser is the specified browser
*/
function isBrowser($browserName) { return( 0 == strcasecmp($this->_browser_name, trim($browserName))); }
/**
* The name of the browser. All return types are from the class contants
* @return string Name of the browser
*/
public function getBrowser() { return $this->_browser_name; }
/**
* Set the name of the browser
* @param $browser The name of the Browser
*/
public function setBrowser($browser) { return $this->_browser_name = $browser; }
/**
* The name of the platform. All return types are from the class contants
* @return string Name of the browser
*/
public function getPlatform() { return $this->_platform; }
/**
* Set the name of the platform
* @param $platform The name of the Platform
*/
public function setPlatform($platform) { return $this->_platform = $platform; }
/**
* The version of the browser.
* @return string Version of the browser (will only contain alpha-numeric characters and a period)
*/
public function getVersion() { return $this->_version; }
/**
* Set the version of the browser
* @param $version The version of the Browser
*/
public function setVersion($version) { $this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/','',$version); }
/**
* The version of AOL.
* @return string Version of AOL (will only contain alpha-numeric characters and a period)
*/
public function getAolVersion() { return $this->_aol_version; }
/**
* Set the version of AOL
* @param $version The version of AOL
*/
public function setAolVersion($version) { $this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/','',$version); }
/**
* Is the browser from AOL?
* @return boolean True if the browser is from AOL otherwise false
*/
public function isAol() { return $this->_is_aol; }
/**
* Is the browser from a mobile device?
* @return boolean True if the browser is from a mobile device otherwise false
*/
public function isMobile() { return $this->_is_mobile; }
/**
* Is the browser from a robot (ex Slurp,GoogleBot)?
* @return boolean True if the browser is from a robot otherwise false
*/
public function isRobot() { return $this->_is_robot; }
/**
* Set the browser to be from AOL
* @param $isAol
*/
public function setAol($isAol) { $this->_is_aol = $isAol; }
/**
* Set the Browser to be mobile
* @param boolean $value is the browser a mobile brower or not
*/
protected function setMobile($value=true) { $this->_is_mobile = $value; }
/**
* Set the Browser to be a robot
* @param boolean $value is the browser a robot or not
*/
protected function setRobot($value=true) { $this->_is_robot = $value; }
/**
* Get the user agent value in use to determine the browser
* @return string The user agent from the HTTP header
*/
public function getUserAgent() { return $this->_agent; }
/**
* Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
* @param $agent_string The value for the User Agent
*/
public function setUserAgent($agent_string) {
$this->reset();
$this->_agent = $agent_string;
$this->determine();
}
/**
* Used to determine if the browser is actually "chromeframe"
* @since 1.7
* @return boolean True if the browser is using chromeframe
*/
public function isChromeFrame() {
return( strpos($this->_agent,"chromeframe") !== false );
}
/**
* Returns a formatted string with a summary of the details of the browser.
* @return string formatted string with a summary of the browser
*/
public function __toString() {
return "<strong>Browser Name:</strong>{$this->getBrowser()}<br/>\n" .
"<strong>Browser Version:</strong>{$this->getVersion()}<br/>\n" .
"<strong>Browser User Agent String:</strong>{$this->getUserAgent()}<br/>\n" .
"<strong>Platform:</strong>{$this->getPlatform()}<br/>";
}
/**
* Protected routine to calculate and determine what the browser is in use (including platform)
*/
protected function determine() {
$this->checkPlatform();
$this->checkBrowsers();
$this->checkForAol();
}
/**
* Protected routine to determine the browser type
* @return boolean True if the browser was detected otherwise false
*/
protected function checkBrowsers() {
return (
// well-known, well-used
// Special Notes:
// (1) Opera must be checked before FireFox due to the odd
// user agents used in some older versions of Opera
// (2) WebTV is strapped onto Internet Explorer so we must
// check for WebTV before IE
// (3) (deprecated) Galeon is based on Firefox and needs to be
// tested before Firefox is tested
// (4) OmniWeb is based on Safari so OmniWeb check must occur
// before Safari
// (5) Netscape 9+ is based on Firefox so Netscape checks
// before FireFox are necessary
$this->checkBrowserWebTv() ||
$this->checkBrowserInternetExplorer() ||
$this->checkBrowserOpera() ||
$this->checkBrowserGaleon() ||
$this->checkBrowserNetscapeNavigator9Plus() ||
$this->checkBrowserFirefox() ||
$this->checkBrowserChrome() ||
$this->checkBrowserOmniWeb() ||
// common mobile
$this->checkBrowserAndroid() ||
$this->checkBrowseriPad() ||
$this->checkBrowseriPod() ||
$this->checkBrowseriPhone() ||
$this->checkBrowserBlackBerry() ||
$this->checkBrowserNokia() ||
// common bots
$this->checkBrowserGoogleBot() ||
$this->checkBrowserMSNBot() ||
$this->checkBrowserSlurp() ||
// WebKit base check (post mobile and others)
$this->checkBrowserSafari() ||
// everyone else
$this->checkBrowserNetPositive() ||
$this->checkBrowserFirebird() ||
$this->checkBrowserKonqueror() ||
$this->checkBrowserIcab() ||
$this->checkBrowserPhoenix() ||
$this->checkBrowserAmaya() ||
$this->checkBrowserLynx() ||
$this->checkBrowserShiretoko() ||
$this->checkBrowserIceCat() ||
$this->checkBrowserW3CValidator() ||
$this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
);
}
/**
* Determine if the user is using a BlackBerry (last updated 1.7)
* @return boolean True if the browser is the BlackBerry browser otherwise false
*/
protected function checkBrowserBlackBerry() {
if( stripos($this->_agent,'blackberry') !== false ) {
$aresult = explode("/",stristr($this->_agent,"BlackBerry"));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_BLACKBERRY;
$this->setMobile(true);
return true;
}
return false;
}
/**
* Determine if the user is using an AOL User Agent (last updated 1.7)
* @return boolean True if the browser is from AOL otherwise false
*/
protected function checkForAol() {
$this->setAol(false);
$this->setAolVersion(self::VERSION_UNKNOWN);
if( stripos($this->_agent,'aol') !== false ) {
$aversion = explode(' ',stristr($this->_agent, 'AOL'));
$this->setAol(true);
$this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
return true;
}
return false;
}
/**
* Determine if the browser is the GoogleBot or not (last updated 1.7)
* @return boolean True if the browser is the GoogletBot otherwise false
*/
protected function checkBrowserGoogleBot() {
if( stripos($this->_agent,'googlebot') !== false ) {
$aresult = explode('/',stristr($this->_agent,'googlebot'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion(str_replace(';','',$aversion[0]));
$this->_browser_name = self::BROWSER_GOOGLEBOT;
$this->setRobot(true);
return true;
}
return false;
}
/**
* Determine if the browser is the MSNBot or not (last updated 1.9)
* @return boolean True if the browser is the MSNBot otherwise false
*/
protected function checkBrowserMSNBot() {
if( stripos($this->_agent,"msnbot") !== false ) {
$aresult = explode("/",stristr($this->_agent,"msnbot"));
$aversion = explode(" ",$aresult[1]);
$this->setVersion(str_replace(";","",$aversion[0]));
$this->_browser_name = self::BROWSER_MSNBOT;
$this->setRobot(true);
return true;
}
return false;
}
/**
* Determine if the browser is the W3C Validator or not (last updated 1.7)
* @return boolean True if the browser is the W3C Validator otherwise false
*/
protected function checkBrowserW3CValidator() {
if( stripos($this->_agent,'W3C-checklink') !== false ) {
$aresult = explode('/',stristr($this->_agent,'W3C-checklink'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_W3CVALIDATOR;
return true;
}
else if( stripos($this->_agent,'W3C_Validator') !== false ) {
// Some of the Validator versions do not delineate w/ a slash - add it back in
$ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
$aresult = explode('/',stristr($ua,'W3C_Validator'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_W3CVALIDATOR;
return true;
}
return false;
}
/**
* Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
* @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
*/
protected function checkBrowserSlurp() {
if( stripos($this->_agent,'slurp') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Slurp'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->_browser_name = self::BROWSER_SLURP;
$this->setRobot(true);
$this->setMobile(false);
return true;
}
return false;
}
/**
* Determine if the browser is Internet Explorer or not (last updated 1.7)
* @return boolean True if the browser is Internet Explorer otherwise false
*/
protected function checkBrowserInternetExplorer() {
// Test for v1 - v1.5 IE
if( stripos($this->_agent,'microsoft internet explorer') !== false ) {
$this->setBrowser(self::BROWSER_IE);
$this->setVersion('1.0');
$aresult = stristr($this->_agent, '/');
if( preg_match('/308|425|426|474|0b1/i', $aresult) ) {
$this->setVersion('1.5');
}
return true;
}
// Test for versions > 1.5
else if( stripos($this->_agent,'msie') !== false && stripos($this->_agent,'opera') === false ) {
// See if the browser is the odd MSN Explorer
if( stripos($this->_agent,'msnb') !== false ) {
$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'MSN'));
$this->setBrowser( self::BROWSER_MSN );
$this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
return true;
}
$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'msie'));
$this->setBrowser( self::BROWSER_IE );
$this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
return true;
}
// Test for Pocket IE
else if( stripos($this->_agent,'mspie') !== false || stripos($this->_agent,'pocket') !== false ) {
$aresult = explode(' ',stristr($this->_agent,'mspie'));
$this->setPlatform( self::PLATFORM_WINDOWS_CE );
$this->setBrowser( self::BROWSER_POCKET_IE );
$this->setMobile(true);
if( stripos($this->_agent,'mspie') !== false ) {
$this->setVersion($aresult[1]);
}
else {
$aversion = explode('/',$this->_agent);
$this->setVersion($aversion[1]);
}
return true;
}
return false;
}
/**
* Determine if the browser is Opera or not (last updated 1.7)
* @return boolean True if the browser is Opera otherwise false
*/
protected function checkBrowserOpera() {
if( stripos($this->_agent,'opera mini') !== false ) {
$resultant = stristr($this->_agent, 'opera mini');
if( preg_match('/\//',$resultant) ) {
$aresult = explode('/',$resultant);
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$aversion = explode(' ',stristr($resultant,'opera mini'));
$this->setVersion($aversion[1]);
}
$this->_browser_name = self::BROWSER_OPERA_MINI;
$this->setMobile(true);
return true;
}
else if( stripos($this->_agent,'opera') !== false ) {
$resultant = stristr($this->_agent, 'opera');
if( preg_match('/Version\/(10.*)$/',$resultant,$matches) ) {
$this->setVersion($matches[1]);
}
else if( preg_match('/\//',$resultant) ) {
$aresult = explode('/',str_replace("("," ",$resultant));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$aversion = explode(' ',stristr($resultant,'opera'));
$this->setVersion(isset($aversion[1])?$aversion[1]:"");
}
$this->_browser_name = self::BROWSER_OPERA;
return true;
}
return false;
}
/**
* Determine if the browser is Chrome or not (last updated 1.7)
* @return boolean True if the browser is Chrome otherwise false
*/
protected function checkBrowserChrome() {
if( stripos($this->_agent,'Chrome') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Chrome'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_CHROME);
return true;
}
return false;
}
/**
* Determine if the browser is WebTv or not (last updated 1.7)
* @return boolean True if the browser is WebTv otherwise false
*/
protected function checkBrowserWebTv() {
if( stripos($this->_agent,'webtv') !== false ) {
$aresult = explode('/',stristr($this->_agent,'webtv'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_WEBTV);
return true;
}
return false;
}
/**
* Determine if the browser is NetPositive or not (last updated 1.7)
* @return boolean True if the browser is NetPositive otherwise false
*/
protected function checkBrowserNetPositive() {
if( stripos($this->_agent,'NetPositive') !== false ) {
$aresult = explode('/',stristr($this->_agent,'NetPositive'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion(str_replace(array('(',')',';'),'',$aversion[0]));
$this->setBrowser(self::BROWSER_NETPOSITIVE);
return true;
}
return false;
}
/**
* Determine if the browser is Galeon or not (last updated 1.7)
* @return boolean True if the browser is Galeon otherwise false
*/
protected function checkBrowserGaleon() {
if( stripos($this->_agent,'galeon') !== false ) {
$aresult = explode(' ',stristr($this->_agent,'galeon'));
$aversion = explode('/',$aresult[0]);
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_GALEON);
return true;
}
return false;
}
/**
* Determine if the browser is Konqueror or not (last updated 1.7)
* @return boolean True if the browser is Konqueror otherwise false
*/
protected function checkBrowserKonqueror() {
if( stripos($this->_agent,'Konqueror') !== false ) {
$aresult = explode(' ',stristr($this->_agent,'Konqueror'));
$aversion = explode('/',$aresult[0]);
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_KONQUEROR);
return true;
}
return false;
}
/**
* Determine if the browser is iCab or not (last updated 1.7)
* @return boolean True if the browser is iCab otherwise false
*/
protected function checkBrowserIcab() {
if( stripos($this->_agent,'icab') !== false ) {
$aversion = explode(' ',stristr(str_replace('/',' ',$this->_agent),'icab'));
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_ICAB);
return true;
}
return false;
}
/**
* Determine if the browser is OmniWeb or not (last updated 1.7)
* @return boolean True if the browser is OmniWeb otherwise false
*/
protected function checkBrowserOmniWeb() {
if( stripos($this->_agent,'omniweb') !== false ) {
$aresult = explode('/',stristr($this->_agent,'omniweb'));
$aversion = explode(' ',isset($aresult[1])?$aresult[1]:"");
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_OMNIWEB);
return true;
}
return false;
}
/**
* Determine if the browser is Phoenix or not (last updated 1.7)
* @return boolean True if the browser is Phoenix otherwise false
*/
protected function checkBrowserPhoenix() {
if( stripos($this->_agent,'Phoenix') !== false ) {
$aversion = explode('/',stristr($this->_agent,'Phoenix'));
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_PHOENIX);
return true;
}
return false;
}
/**
* Determine if the browser is Firebird or not (last updated 1.7)
* @return boolean True if the browser is Firebird otherwise false
*/
protected function checkBrowserFirebird() {
if( stripos($this->_agent,'Firebird') !== false ) {
$aversion = explode('/',stristr($this->_agent,'Firebird'));
$this->setVersion($aversion[1]);
$this->setBrowser(self::BROWSER_FIREBIRD);
return true;
}
return false;
}
/**
* Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
* NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
* @return boolean True if the browser is Netscape Navigator 9+ otherwise false
*/
protected function checkBrowserNetscapeNavigator9Plus() {
if( stripos($this->_agent,'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i',$this->_agent,$matches) ) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
return true;
}
else if( stripos($this->_agent,'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i',$this->_agent,$matches) ) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
return true;
}
return false;
}
/**
* Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
* @return boolean True if the browser is Shiretoko otherwise false
*/
protected function checkBrowserShiretoko() {
if( stripos($this->_agent,'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i',$this->_agent,$matches) ) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_SHIRETOKO);
return true;
}
return false;
}
/**
* Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
* @return boolean True if the browser is Ice Cat otherwise false
*/
protected function checkBrowserIceCat() {
if( stripos($this->_agent,'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i',$this->_agent,$matches) ) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_ICECAT);
return true;
}
return false;
}
/**
* Determine if the browser is Nokia or not (last updated 1.7)
* @return boolean True if the browser is Nokia otherwise false
*/
protected function checkBrowserNokia() {
if( preg_match("/Nokia([^\/]+)\/([^ SP]+)/i",$this->_agent,$matches) ) {
$this->setVersion($matches[2]);
if( stripos($this->_agent,'Series60') !== false || strpos($this->_agent,'S60') !== false ) {
$this->setBrowser(self::BROWSER_NOKIA_S60);
}
else {
$this->setBrowser( self::BROWSER_NOKIA );
}
$this->setMobile(true);
return true;
}
return false;
}
/**
* Determine if the browser is Firefox or not (last updated 1.7)
* @return boolean True if the browser is Firefox otherwise false
*/
protected function checkBrowserFirefox() {
if( stripos($this->_agent,'safari') === false ) {
if( preg_match("/Firefox[\/ \(]([^ ;\)]+)/i",$this->_agent,$matches) ) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_FIREFOX);
return true;
}
else if( preg_match("/Firefox$/i",$this->_agent,$matches) ) {
$this->setVersion("");
$this->setBrowser(self::BROWSER_FIREFOX);
return true;
}
}
return false;
}
/**
* Determine if the browser is Firefox or not (last updated 1.7)
* @return boolean True if the browser is Firefox otherwise false
*/
protected function checkBrowserIceweasel() {
if( stripos($this->_agent,'Iceweasel') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Iceweasel'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_ICEWEASEL);
return true;
}
return false;
}
/**
* Determine if the browser is Mozilla or not (last updated 1.7)
* @return boolean True if the browser is Mozilla otherwise false
*/
protected function checkBrowserMozilla() {
if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent) && stripos($this->_agent,'netscape') === false) {
$aversion = explode(' ',stristr($this->_agent,'rv:'));
preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent,$aversion);
$this->setVersion(str_replace('rv:','',$aversion[0]));
$this->setBrowser(self::BROWSER_MOZILLA);
return true;
}
else if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i',$this->_agent) && stripos($this->_agent,'netscape') === false ) {
$aversion = explode('',stristr($this->_agent,'rv:'));
$this->setVersion(str_replace('rv:','',$aversion[0]));
$this->setBrowser(self::BROWSER_MOZILLA);
return true;
}
else if( stripos($this->_agent,'mozilla') !== false && preg_match('/mozilla\/([^ ]*)/i',$this->_agent,$matches) && stripos($this->_agent,'netscape') === false ) {
$this->setVersion($matches[1]);
$this->setBrowser(self::BROWSER_MOZILLA);
return true;
}
return false;
}
/**
* Determine if the browser is Lynx or not (last updated 1.7)
* @return boolean True if the browser is Lynx otherwise false
*/
protected function checkBrowserLynx() {
if( stripos($this->_agent,'lynx') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Lynx'));
$aversion = explode(' ',(isset($aresult[1])?$aresult[1]:""));
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_LYNX);
return true;
}
return false;
}
/**
* Determine if the browser is Amaya or not (last updated 1.7)
* @return boolean True if the browser is Amaya otherwise false
*/
protected function checkBrowserAmaya() {
if( stripos($this->_agent,'amaya') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Amaya'));
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
$this->setBrowser(self::BROWSER_AMAYA);
return true;
}
return false;
}
/**
* Determine if the browser is Safari or not (last updated 1.7)
* @return boolean True if the browser is Safari otherwise false
*/
protected function checkBrowserSafari() {
if( stripos($this->_agent,'Safari') !== false && stripos($this->_agent,'iPhone') === false && stripos($this->_agent,'iPod') === false ) {
$aresult = explode('/',stristr($this->_agent,'Version'));
if( isset($aresult[1]) ) {
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setBrowser(self::BROWSER_SAFARI);
return true;
}
return false;
}
/**
* Determine if the browser is iPhone or not (last updated 1.7)
* @return boolean True if the browser is iPhone otherwise false
*/
protected function checkBrowseriPhone() {
if( stripos($this->_agent,'iPhone') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Version'));
if( isset($aresult[1]) ) {
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setMobile(true);
$this->setBrowser(self::BROWSER_IPHONE);
return true;
}
return false;
}
/**
* Determine if the browser is iPod or not (last updated 1.7)
* @return boolean True if the browser is iPod otherwise false
*/
protected function checkBrowseriPad() {
if( stripos($this->_agent,'iPad') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Version'));
if( isset($aresult[1]) ) {
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setMobile(true);
$this->setBrowser(self::BROWSER_IPAD);
return true;
}
return false;
}
/**
* Determine if the browser is iPod or not (last updated 1.7)
* @return boolean True if the browser is iPod otherwise false
*/
protected function checkBrowseriPod() {
if( stripos($this->_agent,'iPod') !== false ) {
$aresult = explode('/',stristr($this->_agent,'Version'));
if( isset($aresult[1]) ) {
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setMobile(true);
$this->setBrowser(self::BROWSER_IPOD);
return true;
}
return false;
}
/**
* Determine if the browser is Android or not (last updated 1.7)
* @return boolean True if the browser is Android otherwise false
*/
protected function checkBrowserAndroid() {
if( stripos($this->_agent,'Android') !== false ) {
$aresult = explode(' ',stristr($this->_agent,'Android'));
if( isset($aresult[1]) ) {
$aversion = explode(' ',$aresult[1]);
$this->setVersion($aversion[0]);
}
else {
$this->setVersion(self::VERSION_UNKNOWN);
}
$this->setMobile(true);
$this->setBrowser(self::BROWSER_ANDROID);
return true;
}
return false;
}
/**
* Determine the user's platform (last updated 1.7)
*/
protected function checkPlatform() {
if( stripos($this->_agent, 'windows') !== false ) {
$this->_platform = self::PLATFORM_WINDOWS;
}
else if( stripos($this->_agent, 'iPad') !== false ) {
$this->_platform = self::PLATFORM_IPAD;
}
else if( stripos($this->_agent, 'iPod') !== false ) {
$this->_platform = self::PLATFORM_IPOD;
}
else if( stripos($this->_agent, 'iPhone') !== false ) {
$this->_platform = self::PLATFORM_IPHONE;
}
elseif( stripos($this->_agent, 'mac') !== false ) {
$this->_platform = self::PLATFORM_APPLE;
}
elseif( stripos($this->_agent, 'android') !== false ) {
$this->_platform = self::PLATFORM_ANDROID;
}
elseif( stripos($this->_agent, 'linux') !== false ) {
$this->_platform = self::PLATFORM_LINUX;
}
else if( stripos($this->_agent, 'Nokia') !== false ) {
$this->_platform = self::PLATFORM_NOKIA;
}
else if( stripos($this->_agent, 'BlackBerry') !== false ) {
$this->_platform = self::PLATFORM_BLACKBERRY;
}
elseif( stripos($this->_agent,'FreeBSD') !== false ) {
$this->_platform = self::PLATFORM_FREEBSD;
}
elseif( stripos($this->_agent,'OpenBSD') !== false ) {
$this->_platform = self::PLATFORM_OPENBSD;
}
elseif( stripos($this->_agent,'NetBSD') !== false ) {
$this->_platform = self::PLATFORM_NETBSD;
}
elseif( stripos($this->_agent, 'OpenSolaris') !== false ) {
$this->_platform = self::PLATFORM_OPENSOLARIS;
}
elseif( stripos($this->_agent, 'SunOS') !== false ) {
$this->_platform = self::PLATFORM_SUNOS;
}
elseif( stripos($this->_agent, 'OS\/2') !== false ) {
$this->_platform = self::PLATFORM_OS2;
}
elseif( stripos($this->_agent, 'BeOS') !== false ) {
$this->_platform = self::PLATFORM_BEOS;
}
elseif( stripos($this->_agent, 'win') !== false ) {
$this->_platform = self::PLATFORM_WINDOWS;
}
}
}
?>
......@@ -30,7 +30,6 @@ class SessionAdminController extends AdminController
'Extend1' => 'Продление сессии для компании',
'Delete' => 'Удаление сессии',
'Manage' => 'Управление сессиями',
'Import-passings' => 'Импорт пользователей для прохождения тестирования',
'ExportSessionResult' => 'Экспорт результата сессии',
'SendMessage' => 'Отправить пользователю сообщение о назначенных тестах',
'SendMessageToAll' => 'Отправить сообщения о назначенных тестах всем пользователям',
......@@ -200,214 +199,214 @@ class SessionAdminController extends AdminController
));
}
public function actionImportPassings($id)
{
$model = $this->findModel($id);
$group = new UserGroup;
$params = ['model' => $model, 'group' => $group];
if (Yii::$app->request->isPost)
{
$model->attributes = Yii::$app->request->post('Session');
$group->attributes = Yii::$app->request->post('UserGroup');
$group->session_id = $model->id;
if($model->validate() && $group->validate())
{
$group->save(false);
$model->csv_file = UploadedFile::getInstance($model, 'csv_file');
if($model->upload())
{
try
{
$log = [];
// public function actionImportPassings($id)
// {
// $model = $this->findModel($id);
// $group = new UserGroup;
set_time_limit(60*5); // Максимальное время выполнения скрипта - 5 минуты
// $params = ['model' => $model, 'group' => $group];
$usersCount = 0; // кол-во загруженных пользователей
$passingsCount = 0; // кол-во назначенных тестов
// if (Yii::$app->request->isPost)
// {
// $model->attributes = Yii::$app->request->post('Session');
// $group->attributes = Yii::$app->request->post('UserGroup');
$assigned = []; //Для проверки на дубликаты
$test_ids = array_keys(ArrayHelper::map(Test::find()->where(['session_id' => $model->id])->all(), 'id', 'name'));
if(!empty($test_ids))
{
$passings = Passing::find()->where(['test_id' => $test_ids])->all();
foreach($passings as $passing)
{
$assigned[$passing->user_id][] = $passing->test_id;
}
}
$inputFileType = \PHPExcel_IOFactory::identify($model->file);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($model->file);
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$mixCreate = true;
for ($i = 3; $i <= $sheet->getHighestRow(); $i++)
{
// извлечение переменных из XLS
$sex = trim($sheet->getCell('A' . $i)->getValue());
$last_name = trim($sheet->getCell('B' . $i)->getValue());
$first_name = trim($sheet->getCell('C' . $i)->getValue());
$patronymic = trim($sheet->getCell('D' . $i)->getValue());
$company_name = trim(preg_replace('/\s+/', ' ', $sheet->getCell('E' . $i)->getValue()));
$city = trim($sheet->getCell('F' . $i)->getValue());
$email = trim($sheet->getCell('G' . $i)->getValue());
$login = trim($sheet->getCell('H' . $i)->getValue());
$password = trim($sheet->getCell('I' . $i)->getValue());
// Извлеченние данных о назначенных тестах
$usertests = [];
for ($j = 10; $j <= $sheet->getHighestColumn(); $j++)
{
$testName = trim($sheet->getCellByColumnAndRow($j, 2)->getValue());
$test = trim($sheet->getCellByColumnAndRow($j, $i)->getValue());
if(in_array($testName, Test::$mix_test_titles) && $mixCreate)
{
$mixModel = Test::model()->findByAttributes(array('name'=>'Комбинированный тест', 'session_id'=>$model->id));
if(!$mixModel)
{
$mixModel = new Test;
$mixModel->session_id = $model->id;
$mixModel->name = 'Комбинированный тест';
$mixModel->mix = true;
$mixModel->save();
}
$mixCreate = false;
}
$usertests[] = $test;
}
// если первый столбец не указывает на пол - вся строка неправильная
if (($sex <> 'м') && ($sex <> 'ж') && ($sex <> 'М') && ($sex <> 'Ж')) continue;
$usersCount++;
// поиск или создание пользователя
$user = User::find()->where([
'first_name' => $first_name,
'last_name' => $last_name,
'patronymic' => $patronymic,
'company_name' => $company_name,
])->one();
if (!$user)
{
$user = new User;
$user->attributes = [
'last_name' => $last_name,
'first_name' => $first_name,
'patronymic' => $patronymic,
'company_name' => $company_name,
'sex' => (($sex == 'Ж') || ($sex == 'ж')) ? 0 : 1,
];
}
$user->email = $email;
$user->manager_id = Yii::$app->user->id;
$user->city = $city;
$user->login = $login;
$user->password = $password;
if($user->save())
{
$user_group_assign = new UserGroupAssign;
$user_group_assign->attributes = [
'user_id' => $user->id,
'group_id' => $group->id,
'session_id' => $model->id
];
}
else
{
$log[] = 'Ошибка при сохранении пользователя '.$last_name.' '.$first_name.' '.$patronymic.' ["'.$company_name.'"]!';
break;
}
// назначение тестов
$testings = Test::find()->where(['session_id' => $model->id]);
// проверка на то, создано ли достаточное кол-во тестов в пределах текущей сессии
if (count($usertests) > count($testings))
{
throw new NotFoundHttpException('Загружено недостаточное количество тестов в пределах текущей сессии!');
}
foreach ($usertests as $index => $test)
{
if(in_array($test, array('да','Да','ДА','y','yes','1','Y')))
{
if(!isset($testings[$index]))
{
continue;
}
if(isset($assigned[$user->id]) && in_array($testings[$index]->id, $assigned[$user->id]))
{
$log[] = "Пользователю {$user->id} уже назначен тест № {$testings[$index]->id}";
continue;
}
$pass = new Passing;
$pass->user_id = $user->id;
$pass->percent_rights = 0;
$pass->test_id = $testings[$index]->id;
if ($pass->save())
{
$passingsCount++;
$assigned[$user->id][$index] = $testings[$index]->id;
}
else
{
$log[] = 'Ошибка при назначении теста "'.$testings[$index]->name.'"';
}
}
}
}
// добавляем отчёт о кол-ве назначенных тестов
Yii::$app->session->setFlash('flash', '<i>Всего назначено <b>' .$passingsCount. '</b> тестов <b>'.$usersCount. '</b> пользователям. Перейти к '.Html::a('списку назначенных тестов', ['/testings/user-admin/manage', 'session'=>$model->id]).'.</i>');
$params = array(
'model' => $model,
'group' => $group,
'log' => implode('<br />',$log),
);
}
catch (Exception $e)
{
$params['log'] = 'Импорт прошел неудачно: ' . $e->getMessage();
}
}
else
{
Yii::$app->session->setFlash('flash', 'Произошла ошибка при загрузке файла. Обратитесь к администратору!');
}
}
}
// $group->session_id = $model->id;
// if($model->validate() && $group->validate())
// {
// $group->save(false);
// $model->csv_file = UploadedFile::getInstance($model, 'csv_file');
// if($model->upload())
// {
// try
// {
// $log = [];
// set_time_limit(60*5); // Максимальное время выполнения скрипта - 5 минуты
// $usersCount = 0; // кол-во загруженных пользователей
// $passingsCount = 0; // кол-во назначенных тестов
// $assigned = []; //Для проверки на дубликаты
// $test_ids = array_keys(ArrayHelper::map(Test::find()->where(['session_id' => $model->id])->all(), 'id', 'name'));
// if(!empty($test_ids))
// {
// $passings = Passing::find()->where(['test_id' => $test_ids])->all();
// foreach($passings as $passing)
// {
// $assigned[$passing->user_id][] = $passing->test_id;
// }
// }
// $inputFileType = \PHPExcel_IOFactory::identify($model->file);
// $objReader = \PHPExcel_IOFactory::createReader($inputFileType);
// $objPHPExcel = $objReader->load($model->file);
// $sheet = $objPHPExcel->getSheet(0);
// $highestRow = $sheet->getHighestRow();
// $highestColumn = $sheet->getHighestColumn();
// $mixCreate = true;
// for ($i = 3; $i <= $sheet->getHighestRow(); $i++)
// {
// // извлечение переменных из XLS
// $sex = trim($sheet->getCell('A' . $i)->getValue());
// $last_name = trim($sheet->getCell('B' . $i)->getValue());
// $first_name = trim($sheet->getCell('C' . $i)->getValue());
// $patronymic = trim($sheet->getCell('D' . $i)->getValue());
// $company_name = trim(preg_replace('/\s+/', ' ', $sheet->getCell('E' . $i)->getValue()));
// $city = trim($sheet->getCell('F' . $i)->getValue());
// $email = trim($sheet->getCell('G' . $i)->getValue());
// $login = trim($sheet->getCell('H' . $i)->getValue());
// $password = trim($sheet->getCell('I' . $i)->getValue());
// // Извлеченние данных о назначенных тестах
// $usertests = [];
// for ($j = 10; $j <= $sheet->getHighestColumn(); $j++)
// {
// $testName = trim($sheet->getCellByColumnAndRow($j, 2)->getValue());
// $test = trim($sheet->getCellByColumnAndRow($j, $i)->getValue());
// if(in_array($testName, Test::$mix_test_titles) && $mixCreate)
// {
// $mixModel = Test::model()->findByAttributes(array('name'=>'Комбинированный тест', 'session_id'=>$model->id));
// if(!$mixModel)
// {
// $mixModel = new Test;
// $mixModel->session_id = $model->id;
// $mixModel->name = 'Комбинированный тест';
// $mixModel->mix = true;
// $mixModel->save();
// }
// $mixCreate = false;
// }
// $usertests[] = $test;
// }
// // если первый столбец не указывает на пол - вся строка неправильная
// if (($sex <> 'м') && ($sex <> 'ж') && ($sex <> 'М') && ($sex <> 'Ж')) continue;
// $usersCount++;
// // поиск или создание пользователя
// $user = User::find()->where([
// 'first_name' => $first_name,
// 'last_name' => $last_name,
// 'patronymic' => $patronymic,
// 'company_name' => $company_name,
// ])->one();
// if (!$user)
// {
// $user = new User;
// $user->attributes = [
// 'last_name' => $last_name,
// 'first_name' => $first_name,
// 'patronymic' => $patronymic,
// 'company_name' => $company_name,
// 'sex' => (($sex == 'Ж') || ($sex == 'ж')) ? 0 : 1,
// ];
// }
// $user->email = $email;
// $user->manager_id = Yii::$app->user->id;
// $user->city = $city;
// $user->login = $login;
// $user->password = $password;
// if($user->save())
// {
// $user_group_assign = new UserGroupAssign;
// $user_group_assign->attributes = [
// 'user_id' => $user->id,
// 'group_id' => $group->id,
// 'session_id' => $model->id
// ];
// }
// else
// {
// $log[] = 'Ошибка при сохранении пользователя '.$last_name.' '.$first_name.' '.$patronymic.' ["'.$company_name.'"]!';
// break;
// }
// // назначение тестов
// $testings = Test::find()->where(['session_id' => $model->id]);
// // проверка на то, создано ли достаточное кол-во тестов в пределах текущей сессии
// if (count($usertests) > count($testings))
// {
// throw new NotFoundHttpException('Загружено недостаточное количество тестов в пределах текущей сессии!');
// }
// foreach ($usertests as $index => $test)
// {
// if(in_array($test, array('да','Да','ДА','y','yes','1','Y')))
// {
// if(!isset($testings[$index]))
// {
// continue;
// }
return $this->render('import-passings', $params);
}
// if(isset($assigned[$user->id]) && in_array($testings[$index]->id, $assigned[$user->id]))
// {
// $log[] = "Пользователю {$user->id} уже назначен тест № {$testings[$index]->id}";
// continue;
// }
// $pass = new Passing;
// $pass->user_id = $user->id;
// $pass->percent_rights = 0;
// $pass->test_id = $testings[$index]->id;
// if ($pass->save())
// {
// $passingsCount++;
// $assigned[$user->id][$index] = $testings[$index]->id;
// }
// else
// {
// $log[] = 'Ошибка при назначении теста "'.$testings[$index]->name.'"';
// }
// }
// }
// }
// // добавляем отчёт о кол-ве назначенных тестов
// Yii::$app->session->setFlash('flash', '<i>Всего назначено <b>' .$passingsCount. '</b> тестов <b>'.$usersCount. '</b> пользователям. Перейти к '.Html::a('списку назначенных тестов', ['/testings/user-admin/manage', 'session'=>$model->id]).'.</i>');
// $params = array(
// 'model' => $model,
// 'group' => $group,
// 'log' => implode('<br />',$log),
// );
// }
// catch (Exception $e)
// {
// $params['log'] = 'Импорт прошел неудачно: ' . $e->getMessage();
// }
// }
// else
// {
// Yii::$app->session->setFlash('flash', 'Произошла ошибка при загрузке файла. Обратитесь к администратору!');
// }
// }
// }
// return $this->render('import-passings', $params);
// }
public function actionExportSessionResult($id)
{
......
<?php
class TestingTestController extends BaseController
{
const AUTH_COOKIE = 'test_user_cookie';
const PASS_COOKIE = 'test_pass_cookie';
const BROWSER_COOKIE = 'test_browser_cookie';
namespace common\modules\testings\controllers;
use Yii;
use yii\web\NotFoundHttpException;
use yii\helpers\Json;
use common\modules\testings\models\Test;
use common\modules\testings\models\Passing;
use common\modules\testings\models\QuestionPassing;
class TestController extends \common\components\BaseController
{
public static function actionsTitles()
{
return array(
'Index' => 'Тестирование',
'Info' => 'Начало теста',
'Pass' => 'Тестирование',
'FinishTest' => 'Завершение теста',
'Login' => 'Авторизация',
'Logout' => 'Деавторизация',
'SetAnswer' => 'Запись ответа на вопрос',
'GenPass' => 'Генерация тестирования',
'Finish-test' => 'Завершение теста',
'Set-answer' => 'Запись ответа на вопрос',
'Gen-pass' => 'Генерация тестирования',
'Statistic' => 'Статистика тестирования',
'SendNotAttempt' => 'Отправка письма при использовании попыток',
'Send-not-attempt' => 'Отправка письма при использовании попыток',
);
}
public function filters() {
return CMap::mergeArray(parent::filters(), array(
'checkAuth - login',
));
}
private function encodePassword($pass) {
return md5($pass.'the.longest.salt.ever.dont.even.try.to.decode.lol');
}
public $layout = '/layouts/testing';
public $page_subtitle;
public $logined_user;
public function filterCheckAuth($filterChain) {
// проверим для начала наличие куков
if (!isset(Yii::app()->request->cookies[self::AUTH_COOKIE])
|| !isset(Yii::app()->request->cookies[self::PASS_COOKIE]))
public function actionInfo($id)
{
$this->redirect('/testings/testingTest/login');
}
// во вторую очередь проверим, есть ли такой юзер с таким айди
$id = (int) Yii::app()->request->cookies[self::AUTH_COOKIE]->value;
$pass = Yii::app()->request->cookies[self::PASS_COOKIE]->value;
$user = TestingUser::model()->findByPk($id);
$passing = $this->findModel($id);
if (!$user) {
$this->redirect('/testings/testingTest/login');
if(
$model
// && $model->user_id == Yii::app()->request->cookies[self::AUTH_COOKIE]->value
// && $model->status == TestingPassing::NOT_STARTED
)
{
return $this->render('info', [
'model' => $model
]);
}
// в конце проверим, совпадает ли пароль
if ($this->encodePassword($user->password) <> $pass) {
$this->redirect('/testings/testingTest/login');
else
{
throw new NotFoundHttpException('The requested page does not exist.');
}
$this->logined_user = $user;
$filterChain->run();
}
public function actionSendNotAttempt($id)
{
if(Yii::app()->request->isAjaxRequest)
if(Yii::$app->request->isAjax)
{
$model = TestingPassing::model()->findByPK($id);
$passing = $this->findModel($id);
if($model && $model->sendNotAttempt(Yii::app()->request->getPost('message')))
if($model && $model->sendNotAttempt(Yii::$app->request->post('message')))
{
echo CJavaScript::jsonEncode(array(
echo Json::encode([
'success' => true,
'message' => 'Сообщение отправлено!'
));
]);
}
}
else
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}
public function actionLogin() {
unset(Yii::app()->request->cookies[self::BROWSER_COOKIE]);
if (isset($_POST['username']) && isset($_POST['password'])) {
$user = TestingUser::model()->find('login = :login',array('login'=>$_POST['username']));
// авторизация
if ($user) {
if ($user->password == $_POST['password']) {
$cookie = new CHttpCookie(self::AUTH_COOKIE,$user->id);
Yii::app()->request->cookies[self::AUTH_COOKIE] = $cookie;
$cookie2 = new CHttpCookie(self::PASS_COOKIE, $this->encodePassword($user->password));
Yii::app()->request->cookies[self::PASS_COOKIE] = $cookie2;
$this->redirect('/testings/testingTest/index');
}
}
Yii::app()->user->setFlash('flash','Введён неверный логин или пароль!');
}
$this->layout = '/layouts/auth';
$this->render('auth_page');
}
public function actionLogout() {
unset(Yii::app()->request->cookies[self::AUTH_COOKIE]);
unset(Yii::app()->request->cookies[self::PASS_COOKIE]);
unset(Yii::app()->request->cookies[self::BROWSER_COOKIE]);
$this->redirect('index');
}
public function actionInfo($id)
{
$passing = TestingPassing::model()->findByPk($id);
if($passing
&& $passing->user_id == Yii::app()->request->cookies[self::AUTH_COOKIE]->value
&& $passing->status == TestingPassing::NOT_STARTED)
{
$this->render('info', array(
'model' => $passing
));
}
else
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
throw new NotFoundHttpException('The requested page does not exist.');
}
public function actionIndex()
{
$user_id = Yii::app()->request->cookies[self::AUTH_COOKIE]->value;
//отмечаем что пользователь авторизовывался
$user = TestingUser::model()->findByPk($user_id);
$user->is_auth = 1;
$user->save();
$cr3 = new CDbCriteria;
$cr3->with = 'test.session';
$cr3->addCondition('user_id = :user_id');
$cr3->addCondition('test.id != 39');
$cr3->addCondition('STR_TO_DATE(`session`.`start_date`,"%d.%m.%Y %H:%i") <= NOW()');
$cr3->addCondition('(STR_TO_DATE(`session`.`end_date`,"%d.%m.%Y %H:%i") > NOW()) OR (STR_TO_DATE(`t`.`end_date`,"%d.%m.%Y %H:%i") > NOW())');
$cr3->params = array(
'user_id' => $user_id,
);
$cr3->group = 't.id';
$cr3->together = true;
$this->render('index', array(
'present' => new ActiveDataProvider(
'TestingPassing',
array(
'criteria' => $cr3,
'pagination' => array(
'pageSize' => TestingPassing::PAGE_SIZE
)
)
),
));
}
public function actionSetAnswer($id)
{
if(Yii::$app->request->isAjax)
{
header('Content-type: application/json');
if(Yii::app()->request->isAjaxRequest)
{
$passing = TestingPassing::model()->findByPk($id);
$passing = $this->findModel($id);
$cr = new CDbCriteria;
$cr->addCondition('question_id = :question_id');
$cr->addCondition('passing_id = :passing_id');
$cr->params = array(
':question_id' => $_POST['question_id'],
':passing_id' => $passing->id,
);
$pq = QuestionPassing::find()->where([
'question_id' => $_POST['question_id'],
'passing_id' => $passing->id,
])->one();
$pq = TestingQuestionPassing::model()->find($cr);
$pq->user_answer = $_POST['userAnswer'];
$pq->answer_time = ceil($_POST['time']);
......@@ -187,63 +87,39 @@ class TestingTestController extends BaseController
$passing->recountPassResult();
$passing->percent_rights = $passing->getPercent();
if($passing->is_passed == TestingPassing::PASSED)
if($passing->is_passed == Passing::PASSED)
{
$passing->pass_date = date('d.m.Y H:i:s');
}
$passing->save();
$data = array(
return Json::encode([
'success' => true,
'percent' => $pq->passing->percent,
);
$pstep = $pq->passing->messageStep;
if(is_array($pstep))
{
$data['messageStep'] = $pstep['message'];
$data['percentStep'] = $pstep['percent'];
]);
}
else
{
$data['messageStep'] = null;
$data['percentStep'] = null;
return Json::encode([
'massage' => 'Временные неполадки на сервере, попробуйте еще раз.'
]);
}
echo CJavaScript::jsonEncode($data);
Yii::app()->end();
}
else
{
echo CJavaScript::jsonEncode(array(
'massage' => 'Временные неполадки на сервере, попробуйте еще раз.'
));
Yii::app()->end();
throw new NotFoundHttpException('The requested page does not exist.');
}
}
else
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}
public function actionFinishTest($id)
{
// we only allow deletion via POST request
if(Yii::app()->request->isPostRequest)
if(Yii::$app->request->isPost)
{
Yii::log("POST FinisTest $id", 'error', 'testings');
$log['get'] = CVarDumper::dumpAsString($_GET);
$log['post'] = CVarDumper::dumpAsString($_POST);
$log['server'] = CVarDumper::dumpAsString($_SERVER);
$log['errors'] = array();
$passing = TestingPassing::model()->findByPk($id);
$this->layout = false;
header('Content-type: application/json');
$passing = $this->findModel($id);
// если тест сдан, результаты модифицировать нельзя
if ($passing->pass_date === null)
{
......@@ -252,34 +128,25 @@ class TestingTestController extends BaseController
$passing->recountPassResult();
$passing->percent_rights = $passing->getPercent();
if(!$passing->save()) {
$log['errors'][] = array(
'attributes' => $passing->attributes,
'errors' => $passing->errors,
);
} else {
$log['passing-save'][] = array(
'attributes' => $passing->attributes,
'errors' => $passing->errors,
);
}
echo json_encode(array('status'=>'ok'));
Yii::app()->end();
} else {
Yii::log('Тест уже был сдан!', 'error', 'testings');
echo json_encode(array('massage'=>'Тест уже был сдан!'));
Yii::app()->end();
$passing->save();
return Json::encode(['status' => 'ok']);
}
else
{
return Json::encode(['massage'=>'Тест уже был сдан!']);
}
}
else
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
{
throw new NotFoundHttpException('The requested page does not exist.');
}
}
public function actionGenPass($id)
{
$passing = TestingPassing::model()->findByPk($id);
$passing = $this->findModel($id);
$mg_gammas = array();
$te_gammas = array();
......@@ -602,111 +469,94 @@ class TestingTestController extends BaseController
if (($passing->pass_date === null) && ($passing->is_passed === TestingPassing::FAILED))
{
$this->redirect(Yii::app()->createUrl('/testings/testingTest/pass', array('id' => $passing->id)));
$this->redirect(Yii::app()->createUrl('/testings/test/pass', array('id' => $passing->id)));
}
else
{
$this->redirect(Yii::app()->createUrl('/testings/testingTest/statistic', array('id' => $passing->id)));
$this->redirect(Yii::app()->createUrl('/testings/test/statistic', array('id' => $passing->id)));
}
}
}
public function actionPass($id)
{
$this->layout = '/layouts/test';
$passing = TestingPassing::model()->findByPk($id);
if(!$passing)
{
$this->redirect('/testings/testingTest/index');
}
$passing = $this->findModel($id);
switch ($passing->status)
{
case TestingPassing::STARTED :
case Passing::STARTED :
$passing->attempt += 1;
$passing->save(false, array('attempt'));
$passing->save(false, ['attempt']);
$count_answer = TestingQuestionPassing::model()->countByAttributes(array('passing_id' => $id), 'user_answer IS NOT NULL');
$count_answer = QuestionPassing::find()->where(['passing_id' => $id])->andWhere(['not', 'user_answer', null])->count();
$this->render('pass_testing', array(
return $this->render('pass_testing', [
'model' => $passing,
'current_answer' => $count_answer + 1
));
Yii::app()->end();
]);
break;
case TestingPassing::FAILED :
case Passing::FAILED :
if($passing->attempt < $passing->test->attempt && strtotime($passing->pass_date_start) + ($passing->test->minutes * 60) >= time())
{
$this->redirect(Yii::app()->createUrl('/testings/testingTest/statistic', array('id' => $passing->id)));
Yii::app()->end();
return $this->redirect(['/testings/test/statistic', ['id' => $passing->id]);
}
else
{
if($passing->attempt >= $passing->test->attempt)
{
$this->render('pass_not_attempt', array(
return $this->render('pass_not_attempt', [
'model' => $passing,
));
]);
}
elseif(strtotime($passing->pass_date_start) + ($passing->test->minutes * 60) < time())
{
$this->render('pass_not_time', array(
return $this->render('pass_not_time', [
'model' => $passing,
));
]);
}
Yii::app()->end();
return;
}
break;
case TestingPassing::PASSED :
$this->redirect(Yii::app()->createUrl('/testings/testingTest/statistic', array('id' => $passing->id)));
Yii::app()->end();
case Passing::PASSED :
return $this->redirect(['/testings/test/statistic', 'id' => $passing->id]);
break;
}
}
public function actionStatistic($id)
{
$passing = TestingPassing::model()->findByPk($id);
if(!$passing)
{
$this->redirect('/testings/testingTest/index');
}
$passing = $this->findModel($id);
switch ($passing->status)
{
case TestingPassing::FAILED :
case TestingPassing::PASSED :
$this->render('pass_statistics', array(
return $this->render('pass_statistics', [
'model' => $passing,
));
Yii::app()->end();
]);
break;
default :
$this->redirect('/testings/testingTest/index');
return $this->redirect(['/testings/test/index']);
break;
}
}
public function loadModel($id)
/**
* Finds the Faq model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Faq the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
$model = TestingTest::model()->findByPk((int)$id);
if($model === null)
{
$this->pageNotFound();
}
if (($model = Passing::findOne($id)) !== null) {
return $model;
}
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax'] === 'testing-test-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
<?php
namespace common\modules\testings\controllers;
use Yii;
use common\components\AdminController;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use common\modules\testings\components\MarkBoxBehavior;
use common\modules\testings\models\User;
use common\modules\testings\models\SearchUser;
use common\modules\testings\models\SearchUserGroup;
class UserAdminController extends AdminController
{
public static function actionsTitles()
{
return array(
'View' => 'Просмотр пользователя',
'Create' => 'Создание пользователя',
'Update' => 'Редактирование пользователя',
'Delete' => 'Удаление пользователя',
'Manage' => 'Управление пользователями',
'Manage-group' => 'Управление группами',
'Update-mark' => 'Пометка пользователй',
'Reset-mark' => 'Сброс пометок',
);
}
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
'marked' => [
'class' => MarkBoxBehavior::className(),
'session_key' => 'user-admin',
]
];
}
public function actions()
{
return [
'update-mark' => [
'class' => \common\modules\testings\components\MarkBoxAction::className(),
]
];
}
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
public function actionCreate()
{
$model = new User;
Yii::$app->controller->page_title = 'Добавить пользователя';
Yii::$app->controller->breadcrumbs = [
['Список пользователей' => '/testings/user-admin/manage'],
'Добавить пользователя'
];
if ($model->load(Yii::$app->request->post()))
{
$model->manager_id = Yii::app()->user->id;
if($model->validate())
{
$model->login = $model->generateLogin();
$model->password = PasswordGenerator::generate(6);
$model->save();
return $this->redirect(['manage']);
}
}
$form = new \common\components\BaseForm('/common/modules/testings/forms/UserForm', $model);
return $this->render('create', [
'model' => $model,
'form' => $form->out
]);
}
public function actionUpdate($id)
{
Yii::$app->controller->page_title = 'Редактировать пользователя';
Yii::$app->controller->breadcrumbs = [
['Список пользователей' => '/testings/user-admin/manage'],
'Редактировать пользователя'
];
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()))
{
$model->manager_id = Yii::app()->user->id;
if($model->validate())
{
$model->save();
return $this->redirect(['manage']);
}
}
$form = new \common\components\BaseForm('/common/modules/testings/forms/AnswerForm', $model);
return $this->render('update', [
'model' => $model,
'form' => $form->out
]);
}
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['manage']);
}
public function actionManage()
{
$searchModel = new SearchUser();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
Yii::$app->controller->page_title = 'Список назначений тестов пользователям';
Yii::$app->controller->breadcrumbs = [
'Список назначений тестов пользователям',
];
return $this->render('manage', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function actionManageGroup()
{
$searchModel = new SearchUserGroup();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
Yii::$app->controller->page_title = 'Список групп';
Yii::$app->controller->breadcrumbs = [
'Список групп',
];
return $this->render('manage-group', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Finds the Faq model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Faq the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = User::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
......@@ -12,6 +12,8 @@ $elements = [
'minutes' => ['type' => 'text'],
'questions' => ['type' => 'text'],
'pass_percent' => ['type' => 'text'],
'passed_scores' => ['type' => 'text'],
'notpassed_scores' => ['type' => 'text'],
'attempt' => ['type' => 'text']
];
......
<?php
namespace common\modules\testings\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\modules\testings\models\User;
use common\modules\testings\models\UserGroup;
use common\modules\testings\models\SendHistory;
use common\modules\testings\models\Test;
class SearchUser extends User
{
public $filter_group_id;
public $filter_history_status;
public function rules()
{
return [
[['id', 'sex', 'manager_id', 'is_auth', 'filter_group_id'], 'integer'],
[['id', 'sex', 'first_name', 'patronymic', 'last_name', 'company_name', 'email', 'manager_id', 'create_date', 'is_auth', 'filter_history_status', 'filter_group_id'], 'safe'],
];
}
/**
* @inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params, $order = null, $limit = null)
{
$query = User::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => ['pageSize' => self::PAGE_SIZE],
'sort'=>array(
'defaultOrder'=>'t.id DESC',
),
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'sex' => $this->sex,
'manager_id' => $this->manager_id,
'is_auth' => $this->is_auth,
]);
$query->andFilterWhere(['like', 'first_name', $this->first_name])
->andFilterWhere(['like', 'patronymic', $this->patronymic])
->andFilterWhere(['like', 'last_name', $this->last_name])
->andFilterWhere(['like', 'company_name', $this->company_name])
->andFilterWhere(['like', 'email', $this->email])
->andFilterWhere(['like', 'tki', $this->tki])
->andFilterWhere(['like', 'create_date', $this->create_date]);
$with = ['passings.test'];
$query->groupBy([User::tableName() . '.id']);
if($this->filter_group_id || Yii::$app->request->get('group'))
{
$with[] = 'groupRelated.group';
if($this->filter_group_id)
{
$query->andFilterWhere([
UserGroup::tableName() . '.id' => $this->filter_group_id,
]);
}
if(Yii::$app->request->get('group'))
{
$query->andFilterWhere([
UserGroup::tableName() . '.id' => Yii::$app->request->get('group')
]);
}
}
if($this->filter_history_status)
{
$with[] = 'history';
$query->andFilterWhere([
SendHistory::tableName() . '.unisender_status' => $this->filter_history_status
]);
}
if (Yii::$app->request->get('session'))
{
$query->andFilterWhere([
Test::tableName() . '.session_id' => Yii::$app->request->get('session')
]);
}
$query->joinWith($with);
if(!empty($order))
$query->orderBy($order);
if(!empty($limit))
$query->limit($limit);
return $dataProvider;
}
}
<?php
namespace common\modules\testings\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\modules\testings\models\UserGroup;
class SearchUserGroup extends UserGroup
{
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id', 'session_id'], 'integer'],
[['id', 'name', 'created', 'session_id'], 'safe'],
];
}
/**
* @inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params, $order = null, $limit = null)
{
$query = UserGroup::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => ['pageSize' => self::PAGE_SIZE],
'sort'=>array(
'defaultOrder'=>'created DESC',
),
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'name' => $this->name,
'created' => $this->created,
]);
if(Yii::$app->request->get('session'))
{
$query->andFilterWhere([
'session_id' => Yii::$app->request->get('session'),
]);
}
else
{
$query->andFilterWhere([
'session_id' => $this->session_id,
]);
}
if(!empty($order))
$query->orderBy($order);
if(!empty($limit))
$query->limit($limit);
return $dataProvider;
}
}
......@@ -189,203 +189,4 @@ class Session extends \common\components\ActiveRecordModel
unlink($this->file);
}
}
public function sendMailByList($users)
{
for ($i = 0; $i < count($users); $i++)
{
$dublicates = array($users[$i]);
$email = $users[$i]->email;
$users[$i] = null;
for ($j = 0; $j < count($users); $j++)
{
if($users[$j] && $email == $users[$j]->email)
{
array_push($dublicates, $users[$j]);
$users[$j] = null;
}
}
if(isset($dublicates[0]))
{
$this->sendMessage($dublicates);
}
}
}
private function sendMessage($users)
{
if(!is_array($users) || count($users) == 1)
{
if(is_array($users))
{
$model = $users[0];
}
$tests = $model->assignedTestsForSession($this->id);
if ($tests)
{
if (count($tests) > 1)
{
$this->sendEmailToUser_MultipleTest($model, $tests, $this->id);
}
else
{
$this->sendEmailToUser_SingleTest($model, $tests, $this->id);
}
}
unset($tests);
}
else
{
$this->sendEmailToUser_MultipleUser($users, $this->id);
}
}
public function sendEmailToUser_MultipleTest($user, $tests, $session_id, $notified = false)
{
if($notified)
{
$body = Setting::getValue('email_testing_passing_tracking_body');
$subject = Setting::getValue('email_testing_passing_tracking_subject');
}
else
{
$body = Setting::getValue('email_multiple_test_notice_body');
$subject = Setting::getValue('email_test_notice_head');
}
$test_list = '<ul>';
$test_time_list = '<ul>';
$test_pass_limit_list = '<ul>';
foreach ($tests as $test)
{
if($test->name != '.') $test_list .= '<li>"'.$test->name.'"</li>';
$test_time_list .= '<li>"'.$test->name.'" - не более '.$test->minutes.' минут</li>';
$test_pass_limit_list .= '<li>"'.$test->name.'" - '.$test->pass_percent.'% правильных ответов от предложенных вопросов</li>';
}
$test_list .= '</ul>';
$test_time_list .= '</ul>';
$test_pass_limit_list .= '</ul>';
$history = TestingSendHistory::model()->findByAttributes(array('session_id' => $session_id, 'user_id' => $user->id));
if(!$history)
{
$history = new TestingSendHistory();
}
$history->session_id = $session_id;
$history->email = $user->email;
$history->user_id = $user->id;
$history->unisender_status = TestingSendHistory::STATUS_NOT_SENT;
$history->save();
$mailer_letter = MailerLetter::model();
$body = $mailer_letter->compileText($body, array(
'polite' => ($user->sex == TestingUser::MAN) ? 'уважаемый' : 'уважаемая',
'user' => $user,
'password' => $user->password,
'test_list' => $test_list,
'test_time_list' => $test_time_list,
'test_pass_limit_list' => $test_pass_limit_list,
'session' => TestingSession::model()->findByPk($session_id),
'test_info_link' => CHtml::link(Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest'), Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest')),
'test_link' => CHtml::link(Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest'), Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest')),
));
unset($mailer_letter);
MailerModule::sendMailUniSender($user->email, $subject, $body, $history);
}
public function sendEmailToUser_SingleTest($user, $tests, $session_id, $notified = false)
{
if($notified)
{
$body = Setting::getValue('email_testing_passing_tracking_body');
$subject = Setting::getValue('email_testing_passing_tracking_subject');
}
else
{
$body = Setting::getValue('email_single_test_notice_body');
$subject = Setting::getValue('email_test_notice_head');
}
$test_list = '';
$test_time_list = '';
$test_pass_limit_list = '';
foreach ($tests as $test)
{
$test_list = $test->name;
$test_time_list = $test->minutes;
$test_pass_limit_list = $test->pass_percent;
}
$history = TestingSendHistory::model()->findByAttributes(array('session_id' => $session_id, 'user_id' => $user->id));
if(!$history)
{
$history = new TestingSendHistory();
}
$history->session_id = $session_id;
$history->user_id = $user->id;
$history->email = $user->email;
$history->unisender_status = TestingSendHistory::STATUS_NOT_SENT;
$history->save();
$mailer_letter = MailerLetter::model();
$body = $mailer_letter->compileText($body, array(
'polite' => ($user->sex == TestingUser::MAN) ? 'уважаемый' : 'уважаемая',
'user' => $user,
'password' => $user->password,
'test_list' => $test_list,
'test_time_list' => $test_time_list,
'test_pass_limit_list' => $test_pass_limit_list,
'session' => TestingSession::model()->findByPk($session_id),
'test_info_link' => CHtml::link(Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest'),Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest')),
'test_link' => CHtml::link(Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest'),Yii::app()->request->hostInfo . Yii::app()->urlManager->createUrl('/testings/testingTest')),
));
unset($mailer_letter);
MailerModule::sendMailUniSender($user->email, $subject, $body, $history);
}
private function sendEmailToUser_MultipleUser($users, $session_id)
{
foreach($users as $user)
{
$body = Setting::getValue('email_multiple_user_test_notice_body');
$subject = Setting::getValue('email_test_notice_head');
$history = TestingSendHistory::model()->findByAttributes(array('session_id' => $session_id, 'user_id' => $user->id));
if(!$history)
{
$history = new TestingSendHistory();
}
$filename = $history->generateFile($users, $session_id);
$history->session_id = $session_id;
$history->email = $user->email;
$history->user_id = $user->id;
$history->unisender_status = TestingSendHistory::STATUS_NOT_SENT;
$history->save();
$attachments = array(
$filename => $history->getFilePath()
);
$mailer_letter = MailerLetter::model();
$body = $mailer_letter->compileText($body, array(
'test_link' => CHtml::link(Yii::app()->controller->createAbsoluteUrl('/testings/testingTest'), Yii::app()->controller->createAbsoluteUrl('/testings/testingTest')),
));
unset($mailer_letter);
MailerModule::sendMailUniSender($users[0]->email, $subject, $body, $history, $attachments);
}
}
}
\ No newline at end of file
......@@ -57,9 +57,9 @@ class Test extends \common\components\ActiveRecordModel
public function rules()
{
return [
[['session_id', 'name'], 'required', 'except' => self::SCENARIO_UPLOAD],
[['session_id', 'name', 'passed_scores', 'notpassed_scores'], 'required', 'except' => self::SCENARIO_UPLOAD],
[['minutes', 'questions', 'pass_percent', 'attempt'], 'requiredNotMix', 'except' => self::SCENARIO_UPLOAD],
[['session_id', 'minutes', 'questions', 'pass_percent', 'attempt', 'mix'], 'integer', 'except' => self::SCENARIO_UPLOAD],
[['session_id', 'minutes', 'questions', 'pass_percent', 'attempt', 'mix', 'passed_scores', 'notpassed_scores'], 'integer', 'except' => self::SCENARIO_UPLOAD],
[['name'], 'string', 'max' => 200, 'except' => self::SCENARIO_UPLOAD],
[['csv_file'], 'file', 'skipOnEmpty' => false, 'extensions' => 'xls, xlsx', 'on' => self::SCENARIO_UPLOAD],
[['mix'], 'safe'],
......@@ -85,6 +85,8 @@ class Test extends \common\components\ActiveRecordModel
'questions' => 'Количество вопросов в тесте',
'pass_percent' => 'Лимит прохождения, %',
'create_date' => 'Время создания',
'passed_scores' => 'Количество баллов за сданный тест',
'notpassed_scores' => 'Количество баллов за не сданный тест'
];
}
......
<?php
namespace common\modules\testings\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;
use common\modules\testings\models\Passing;
use common\modules\testings\models\UserGroupAssign;
use common\modules\testings\models\SendHistory;
use common\modules\users\models\User as Manager;
class User extends \common\components\ActiveRecordModel
{
const PAGE_SIZE = 10;
const WOMAN = 0;
const MAN = 1;
public static $sex_list = [
self::WOMAN => 'Женский',
self::MAN => 'Мужской',
];
public static function tableName()
{
return 'testings_users';
}
/**
* @inheritdoc
*/
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'create_date',
'updatedAtAttribute' => null,
'value' => new Expression('NOW()'),
],
];
}
public function name()
{
return 'Пользователи';
}
public function attributeLabels()
{
return [
'company_name' => 'Компания',
'is_auth' => 'sd',
'filter_group_id' => 'Группа',
'sex' => 'Пол',
'first_name' => 'Имя',
'patronymic' => 'Отчество',
'last_name' => 'Фамилия',
'company_name' => 'Наименование компании',
'city' => 'Город',
'login' => 'Логин',
'password' => 'Пароль',
'email' => 'Email',
'manager_id' => 'Ответственный менеджер',
'create_date' => 'Время создания',
];
}
public function rules()
{
return [
[['sex', 'first_name', 'last_name', 'company_name', 'email', 'manager_id'], 'required'],
[['sex', 'is_auth'], 'integer'],
[['first_name', 'patronymic', 'last_name'], 'string', 'max' => 50],
[['company_name'], 'string', 'max' => 250],
[['email'], 'string', 'max' => 150],
[['city'], 'string', 'max' => 100],
[['manager_id'], 'string', 'max' => 11],
];
}
public function getPassings()
{
return $this->hasMany(Passing::className(), ['user_id' => 'id']);
}
public function getManager()
{
return $this->hasOne(Manager::className(), ['id' => 'manager_id']);
}
public function getGroupRelated()
{
return $this->hasOne(UserGroupAssign::className(), ['user_id' => 'id'])->andWhere([
UserGroupAssign::tableName() . '.session_id' => Yii::$app->request->get('session')
]);
}
public function getHistory()
{
return $this->hasOne(SendHistory::className(), ['user_id' => 'id'])->andWhere([
SendHistory::tableName() . '.session_id' => Yii::$app->request->get('session')
]);
}
public function getFio()
{
return $this->last_name . ' ' . $this->first_name . ' ' . $this->patronymic;
}
public function generateLogin()
{
return 'testlogin' . $this->id;
}
public function assignedTestsForSession($session_id)
{
$cr = new CDbCriteria;
$cr->with = 'passings';
$cr->addCondition('passings.user_id = :user_id');
$cr->addCondition('session_id = :session_id');
$cr->params = array(
':user_id'=>$this->id,
':session_id'=>$session_id,
);
$cr->together = true;
$cr->group = 't.id';
return TestingTest::model()->findAll($cr);
}
public static function getCompaniesList()
{
return Yii::app()->db->createCommand('SELECT DISTINCT `company_name` FROM `testings_users`')->queryAll();
}
}
<?php
namespace common\modules\testings\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;
class UserGroup extends \common\components\ActiveRecordModel
{
const PAGE_SIZE = 10;
/**
* @inheritdoc
*/
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created',
'updatedAtAttribute' => null,
'value' => new Expression('NOW()'),
],
];
}
public static function tableName()
{
return 'testings_users_groups';
}
public function name()
{
return 'Группы пользователей';
}
public function attributeLabels()
{
return [
'name' => 'Название группы',
'created' => 'Дата импорта',
'session_id' => 'Сессия',
];
}
public function rules()
{
return [
[['name'], 'required'],
[['created', 'session_id'], 'safe'],
];
}
}
<?php
namespace common\modules\testings\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;
class UserGroupAssign extends \common\components\ActiveRecordModel
{
const PAGE_SIZE = 10;
/**
* @inheritdoc
*/
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created',
'updatedAtAttribute' => null,
'value' => new Expression('NOW()'),
],
];
}
public static function tableName()
{
return 'testings_users_groups_assign';
}
public function name()
{
return 'Связка пользователей и групп';
}
public function attributeLabels()
{
return [
'group_id' => 'Группа',
'user_id' => 'Пользователь',
'session_id' => 'Сессия',
];
}
public function rules()
{
return [
[['group_id', 'user_id', 'session_id'], 'required'],
];
}
public function getGroup()
{
return $this->hasOne(UserGroup::className(), ['id' => 'group_id']);
}
}
......@@ -71,7 +71,7 @@ use \common\components\zii\AdminGrid;
'format' => 'html',
'value' => function($model)
{
return Html::a("Список пользователей", ["/testings/user-admin/manage", "session" => $model->id]);
// return Html::a("Список пользователей", ["/testings/user-admin/manage", "session" => $model->id]);
},
],
[
......@@ -82,14 +82,14 @@ use \common\components\zii\AdminGrid;
return Html::a("Список прохождений", ["/testings/passing-admin/manage", "session" => $model->id]);
},
],
[
'header' => 'Статистика прохождений',
'format' => 'html',
'value' => function($model)
{
return Html::a("Статистика прохождений", ["/testings/passing-admin/statistics", "session" => $model->id]);
},
],
// [
// 'header' => 'Статистика прохождений',
// 'format' => 'html',
// 'value' => function($model)
// {
// return Html::a("Статистика прохождений", ["/testings/passing-admin/statistics", "session" => $model->id]);
// },
// ],
[
'class' => 'common\components\ColorActionColumn',
'template' => '{view} {update}',
......
<?php
use yii\helpers\Html;
?>
<section class="top_line_testing">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<strong>Тест:</strong>
<p><?=$model->test->name?></p>
</div>
</div>
</div>
</section>
<section class="testing_block">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<h1 class="successfully_title">Вы собираетесь сдать экзамен:</h1>
<h6>«<?=$model->test->name?>»</h6>
</div>
</div>
<div class="test_parameters">
<div class="row">
<div class="col-md-6 col-xs-6 col-sm-12">
<img src="/images/icon/test_parameters_icon_1.png" height="83" width="70" alt="">
<h4><?=$model->test->minutes?> минут</h4>
</div>
<div class="col-md-6 col-xs-6 col-sm-12">
<img src="/images/icon/test_parameters_icon_2.png" height="83" width="62" alt="">
<h4><?=$model->test->questions?> вопросов</h4>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 col-xs-12 col-sm 12">
<ul class="ul_box">
<li>После подтверждения ответа вы не сможете проверить или изменить его.</li>
<li>Если время закончится до того, как вы дадите достаточное количество правильных ответов, тест не будет сдан.</li>
<li>Если вы перезагрузите страницу, закроете вкладку браузера, выключите компьютер и т.д., то сможете продолжить прохождение теста с последнего места.</li>
</ul>
<?=Html::a('Начать тест', ["/testings/test/gen-pass", "id" => $model->id], ['class' => 'start_test_btn'])?>
</div>
</div>
</div>
</section>
<?php echo $this->render('@app/views/layouts/footer-testing'); ?>
<?php
use yii\helpers\Html;
?>
<section class="top_line_testing">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<strong>Тест:</strong>
<p><?=$model->test->name?></p>
</div>
</div>
</div>
</section>
<section class="testing_block">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<h1 class="successfully_title">Тестирование не завершено.</h1>
<h6>Для переназначения теста позвоните в службу поддержки по телефону +7 903 961-42-29</h6>
</div>
</div>
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<div class="error_fedback clearfix">
<h6>Обратная связь</h6>
<?=Html::beginForm();?>
<h6>Обратная связь</h6>
<?=Html::textArea('message', '', ['placeholder' => 'Введите сообщение']);?>
<?=Html::ajaxSubmitButton(
'Отправить',
Url::to(['/testings/testingTest/sendNotAttempt', 'id' => $model->id]),
[
'dataType' => 'json',
'success' => 'js:function(data){
if(data.success)
{
console.log("+");
$(".error_fedback").html("<div class=\"row\"><div class=\"col-sm-8\" style=\"margin:0 auto;float:none;\"><div class=\"gray_box\"><p>" + data.message + "</p></div></div></div>");
}
}'
],
[
'class' => 'error_fedback_btn'
]
);?>
<div class="clear"></div>
<?=Html::endForm();?>
</div>
</div>
</div>
<!-- <div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<div class="list_back">
<a href="/testings/test/index">Вернуться к списку тестов <span>↑</span></a>
</div>
</div>
</div> -->
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<div class="read_box_wr">
<div class="read_box">
<p>Тестирование не завершено.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<?php echo $this->render('@app/views/layouts/footer-testing'); ?>
\ No newline at end of file
<section class="top_line_testing">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<strong>Тест:</strong>
<p><?=$model->test->name?></p>
</div>
</div>
</div>
</section>
<section class="testing_block">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<?php if ($model->is_passed == TestingPassing::PASSED) : ?>
<h1 class="successfully_title">Поздравляем, Вы сдали тест</h1>
<div class="successfully_subtitle">Тестирование завершено</div>
<?php elseif ($model->is_passed == TestingPassing::FAILED) : ?>
<h1 class="successfully_title">Тест не сдан!</h1>
<div class="successfully_subtitle">Тестирование завершено</div>
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col-md-6 col-xs-6 col-sm-12">
<div class="succes_title_block">Тест пройден на:</div>
<div class="succes_block_cont"><?php echo $model->percent;?>%</div>
</div>
<div class="col-md-6 col-xs-6 col-sm-12">
<div class="succes_title_block">Прохождение теста у Вас заняло:</div>
<?php
$minutesText = Passing::declOfNum(floor($model->time / 60), [' минута ', ' минуты ', ' минут ']);
$secondsText = Passing::declOfNum($model->time % 60, [' секунда', ' секунды', ' секунд']);
?>
<div class="succes_block_cont"><?=$minutesText?> <?=$secondsText?></div>
</div>
</div>
<!-- <div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<ul class="stat_testing">
<li><span>15%</span> Компактные панели оператора Magelis (Промышленная гамма)</li>
<li><span>43%</span> Вспомогательное оборудование автоматизации (Промышленная гамма)</li>
<li><span>22%</span> Автоматические выключатели, УЗО и Дифференциальные автоматы серии Домовой (Строительная гамма)</li>
<li><span>99%</span> Автоматические выключатели Compact и выключатели-разъединители Interpact (Строительная гамма)</li>
</ul>
</div>
</div> -->
</div>
</section>
<section class="testing_foot">
<div class="container">
<div class="row">
<div class="test_ft clearfix">
<div class="col-md-6 col-xs-8 col-sm-12">
<div class="testing_votes">Вопрос <strong><?=$model->test->questions?></strong> из <strong><?=$model->test->questions?></strong></div>
<div class="testing_progress"><div class="testing_progress_proc" style="width:100%;"></div></div>
</div>
<div class="col-md-6 col-xs-4 col-sm-12">
<div class="testing_time">До конца осталось: <span><?=date("H:i:s", mktime(0, 0, $model->time));?></span></div>
</div>
</div>
</div>
</div>
</section>
\ No newline at end of file
<?php
$this->page_title = $model->test->session->name;
$this->crumbs = array(
'Тестирование' => false,
$model->test->name => false,
);
use common\modules\testings\widgets\NotCloseTabsWidget;
use common\modules\testings\models\Question;
?>
<?php $this->widget('application.modules.testings.widgets.NotCloseTabsWidget'); ?>
<?= NotCloseTabsWidget::widget() ?>
<?php if (Yii::app()->user->hasFlash('flash')) : ?>
<div class="message"><span>
<?php echo Yii::app()->user->getFlash('flash'); ?>
</span></div>
<?php endif; ?>
<?php
$questions = array();
$questions = [];
$count = 0;
foreach ($model->questions as $question) {
foreach ($model->questions as $question)
{
$count++;
$pictures = array();
foreach ($question->question->files as $file) {
$pictures = [];
foreach ($question->question->files as $file)
{
$pictures[] = $file->url;
}
$answers = array();
$answers = [];
// если ответ вводит сам пользователь, нельзя отправлять ответ - поскольку в нём указан верный ответ.
foreach ($question->question->answers as $answer) {
if ($question->question->type <> TestingQuestion::USER_ANSWER) {
foreach ($question->question->answers as $answer)
{
if ($question->question->type <> Question::USER_ANSWER)
{
$answers[] = $answer->text;
} else {
}
else
{
$answers[] = 'тут должен быть ответ';
}
}
$questions[$count] = array(
$questions[$count] = [
'id' => $question->question->id,
'text' => $question->question->text,
'type' => $question->question->type,
......@@ -46,54 +43,14 @@
'userAnswer' => '',
'time' => 0,
'gamma' => $question->question->gamma->name,
);
];
}
?>
<style type="text/css">
body {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
#sendInfoBox p {
text-align: center;
padding-top: 10px;
}
span.fakeLink {
color: #008800;
text-decoration: underline;
cursor: pointer;
}
.user-warning-message {
padding: 10px 15px 10px 40px;
margin: 10px 0;
font-weight: bold;
overflow: hidden;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #bbdbe0;
background-color: #ecf9ff;
color: #0888c3;
}
[data-toggle=buttons] .btn input {
position: absolute;
clip: rect(0,0,0,0);
pointer-events: none;
}
</style>
<script type="text/javascript">
function updatePicture(link) {
function updatePicture(link)
{
var img = $(link).prev('img');
var imgCopy = img.clone();
img.remove();
......@@ -471,75 +428,77 @@
});
</script>
<br>
<div class="row">
<div class="col-sm-12">
<div class="questions_box">
<div class="number_questions questionNumber">1</div>
<p class="gray_text" id="questionGammaBox"></p>
<h2 id="questionTextBox"></h2>
<section class="top_line_testing">
<div class="container">
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<strong>Тест:</strong>
<!-- <p>Базовые знания интернет-маркетинг для бизнеса | Как правильно общаться с заказчиком?</p> -->
</div>
</div>
</div>
</section>
<section class="testing_block">
<div class="container">
<div class="row">
<div class="col-md-1 col-xs-1 col-sm-2">
<span class="testing_num questionNumber">1</span>
</div>
<div class="col-md-11 col-xs-11 col-sm-10">
<h1 class="testing_block_title" id="questionTextBox"></h1>
</div>
</div>
<div class="row">
<div class="col-md-4 col-xs-4 col-sm-12">
<div class="number_questions_img_box" id="questionPictureBox"></div>
<!-- <div class="testing_img_block">
<img src="/images/testing_img.jpg" height="123" width="203" alt="">
</div> -->
</div>
</div>
<div class="row">
<div class="col-md-12 col-xs-12 col-sm-12">
<form class="testing_form">
<div class="questions" id="answerBox" data-toggle="buttons" class="btn-group"></div>
<div class="answer" id="sendInfoBox"></div>
<br>
<button type="submit" class="green_button" id="clickNext" onClick="tester.nextQuestion();">Подтвердить ответ</button>
<br>
<br>
<div class="congratulations_text">
<h4 id="messageStep50"></h4>
<h4 id="messageStep75"></h4>
<h4 id="messageStep100"></h4>
<!-- <div class="input_bg">
<input id="radio1" type="radio" name="radio" class="radio" checked>
<label for="radio1">Только макет в PSD</label>
</div>
<div class="input_bg">
<input id="checkbox1" type="checkbox" class="checkbox">
<label for="checkbox1">Макет и техническое задание по проекту</label>
</div>
<div class="input_bg">
<input id="radio2" type="radio" name="radio" class="radio">
<label for="radio2">Макет и задание описывающее краткий функционал front-end (дизайна)</label>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="green_wr">
<div class="green_box">
<div class="progress_ins">
<span class="col_text">Вопрос <strong class="green_text questionNumber">1</strong> из <strong class="green_text"><?=count($questions)?></strong></span>
<div class="progress_wr">
<div class="progress">
<div class="progress-bar progress-bar-success" id="progressbar" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 0">
<span class="sr-only">40% Complete (success)</span>
<div class="input_bg">
<input type="text" placeholder="Ваш ответ">
</div> -->
<button class="testing_form_btn" onClick="tester.nextQuestion();">Подтвердить ответ</button>
</form>
</div>
</div>
<div class="row col-md-12 col-xs-12 col-sm-12">
<h4 class="testing_info_foot" id="messageStep50"></h4>
<h4 class="testing_info_foot" id="messageStep75"></h4>
<h4 class="testing_info_foot" id="messageStep100"></h4>
</div>
<div class="progress_done">
Выполнено <span id="progressbarText">0</span>%
</div>
</section>
<section class="testing_foot">
<div class="container">
<div class="row">
<div class="test_ft clearfix">
<div class="col-md-6 col-xs-8 col-sm-12">
<div class="testing_votes">Вопрос <strong class="questionNumber">1</strong> из <strong><?=count($questions)?></strong></div>
<div class="testing_progress"><div class="testing_progress_proc" id="progressbar" style="width:0%;"></div></div>
</div>
<div class="time_progress">
<p>До конца осталось:</p>
<span class="timer" id="countdown_timer"></span>
<div class="col-md-6 col-xs-4 col-sm-12">
<div class="testing_time">До конца осталось: <span id="countdown_timer"></span></div>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
<div class="clear"></div>
</section>
\ No newline at end of file
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'testing-test-form',
'enableAjaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'session_id'); ?>
<?php echo $form->textField($model,'session_id'); ?>
<?php echo $form->error($model,'session_id'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>200)); ?>
<?php echo $form->error($model,'name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'minutes'); ?>
<?php echo $form->textField($model,'minutes'); ?>
<?php echo $form->error($model,'minutes'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'questions'); ?>
<?php echo $form->textField($model,'questions'); ?>
<?php echo $form->error($model,'questions'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'pass_percent'); ?>
<?php echo $form->textField($model,'pass_percent'); ?>
<?php echo $form->error($model,'pass_percent'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'mg_percent'); ?>
<?php echo $form->textField($model,'mg_percent'); ?>
<?php echo $form->error($model,'mg_percent'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'te_percent'); ?>
<?php echo $form->textField($model,'te_percent'); ?>
<?php echo $form->error($model,'te_percent'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'mg_count'); ?>
<?php echo $form->textField($model,'mg_count'); ?>
<?php echo $form->error($model,'mg_count'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'te_count'); ?>
<?php echo $form->textField($model,'te_count'); ?>
<?php echo $form->error($model,'te_count'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'create_date'); ?>
<?php echo $form->textField($model,'create_date'); ?>
<?php echo $form->error($model,'create_date'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
\ No newline at end of file
<div class="wide form">
<?php $form=$this->beginWidget('CActiveForm', array(
'action'=>Yii::app()->createUrl($this->route),
'method'=>'get',
)); ?>
<div class="row">
<?php echo $form->label($model,'id'); ?>
<?php echo $form->textField($model,'id'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'session_id'); ?>
<?php echo $form->textField($model,'session_id'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'name'); ?>
<?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>200)); ?>
</div>
<div class="row">
<?php echo $form->label($model,'minutes'); ?>
<?php echo $form->textField($model,'minutes'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'questions'); ?>
<?php echo $form->textField($model,'questions'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'pass_percent'); ?>
<?php echo $form->textField($model,'pass_percent'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'mg_percent'); ?>
<?php echo $form->textField($model,'mg_percent'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'te_percent'); ?>
<?php echo $form->textField($model,'te_percent'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'mg_count'); ?>
<?php echo $form->textField($model,'mg_count'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'te_count'); ?>
<?php echo $form->textField($model,'te_count'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'create_date'); ?>
<?php echo $form->textField($model,'create_date'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Search'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- search-form -->
\ No newline at end of file
<?php
$this->breadcrumbs=array(
'Testing Tests'=>array('index'),
'Manage',
);
$this->menu=array(
array('label'=>'List TestingTest', 'url'=>array('index')),
array('label'=>'Create TestingTest', 'url'=>array('create')),
);
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
$('.search-form').toggle();
return false;
});
$('.search-form form').submit(function(){
$.fn.yiiGridView.update('testing-test-grid', {
data: $(this).serialize()
});
return false;
});
");
?>
<h1>Manage Testing Tests</h1>
<p>
You may optionally enter a comparison operator (<b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b>
or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done.
</p>
<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div><!-- search-form -->
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'testing-test-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'session_id',
'name',
'minutes',
'questions',
'pass_percent',
/*
'mg_percent',
'te_percent',
'mg_count',
'te_count',
'create_date',
*/
array(
'class'=>'CButtonColumn',
),
),
)); ?>
<?php
$this->crumbs = array(
'Тестирование' => array('//testings/testingTest/index'),
'Вход в раздел тестирование' => false,
);
?>
<div class="center">
<form method="post">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td class="first_col">Логин</td>
<td class="second_col">
<p><input name="username" type="text" value="" /></p>
</td>
</tr>
<tr>
<td class="first_col">Пароль</td>
<td class="second_col">
<input name="password" type="password" value="" /> &nbsp;
</td>
</tr>
<tr>
<td class="first_col">&nbsp;</td>
<td class="second_col">
<input type="submit" value="Войти" class="submit" />
<div class="clear"></div>
</td>
</tr>
</table>
</form>
</div>
\ No newline at end of file
<?php echo $form; ?>
\ No newline at end of file
<?php
$this->crumbs = false;
?>
<br>
<?php
$this->widget('application.components.zii.GridView', array(
'dataProvider' => $present,
'emptyText' => 'Тестов в этой категории нет',
// 'enablePagination' => false,
'template' => '{items} <div class="row"><div class="col-sm-12"><div class="pages">{pager}</div></div></div>',
'pagerCssClass' => '',
'pager' => array(
'header' => '',
'firstPageLabel' => 'Первая',
'cssFile' => false,
'prevPageLabel' => '',
'nextPageLabel' => '',
'lastPageLabel' => 'Последняя',
),
'summaryText' => false,
'ajaxUpdate' => false,
'columns' => array(
array('name' => 'test.session.name'),
array(
'name' => 'test.name',
'value' => '"<b>".$data->test->name."</b>"',
'type' => 'html',
),
array(
// 'name' => 'is_passed',
'header' => 'Состояние',
'value' => 'TestingPassing::$state_list[$data->status]',
),
array(
'header' => 'Сдать до',
'value' => '($data->status === null OR $data->status==TestingPassing::NOT_STARTED) ? $data->test->session->end_date : ""',
),
array(
'header' => 'Информация',
'value' => function($data) {
if($data->status === null OR $data->status==TestingPassing::NOT_STARTED)
{
return CHtml::link("Пройти тестирование >>", array("/testings/testingTest/info", "id"=>$data->id));
}
elseif($data->status==TestingPassing::STARTED AND $data->attempt < $data->test->attempt AND strtotime($data->pass_date_start) + ($data->test->minutes * 60) >= time())
{
return CHtml::link("Пройти тестирование >>", array("/testings/testingTest/pass", "id"=>$data->id));
}
elseif($data->status == TestingPassing::PASSED || (int)$data->status === (int)TestingPassing::FAILED)
{
return CHtml::link("Статистика", array("/testings/testingTest/statistic", "id"=>$data->id));
}
},
'type' => 'html',
),
),
'itemsCssClass' => 'sale_table',
));
<?php
$this->page_title = $model->test->session->name;
$this->crumbs = array(
'Начало тестирования' => array('/testings/testingTest/index'),
$model->test->name => false,
);
?>
<?php if (Yii::app()->user->hasFlash('flash')) : ?>
<div class="message"><span>
<?php echo Yii::app()->user->getFlash('flash'); ?>
</span></div>
<?php endif; ?>
<div class="row">
<div class="col-sm-12">
<div class="before_test_text">
<h3>Вы собираетесь сдать экзамен:</h3>
<h5>«<?=$model->test->name?>»</h5>
</div>
</div>
</div>
<div class="test_parameters">
<div class="row">
<div class="col-sm-6">
<img src="/images/testing/test_parameters_icon_1.png" height="83" width="70" alt="">
<h4><?=$model->test->minutes?> минут</h4>
</div>
<div class="col-sm-6">
<img src="/images/testing/test_parameters_icon_2.png" height="83" width="62" alt="">
<h4><?=$model->test->questions?> вопросов</h4>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-12">
<ul class="ul_box">
<li>После подтверждения ответа вы не сможете проверить или изменить его.</li>
<li>Если время закончится до того, как вы дадите достаточное количество правильных ответов, тест не будет сдан.</li>
<li>Если вы перезагрузите страницу, закроете вкладку браузера, выключите компьютер и т.д., то сможете продолжить прохождение теста с последнего места.</li>
</ul>
<br>
<?=CHtml::link('Начать тест', array("/testings/testingTest/genPass", "id" => $model->id), array('class' => 'green_button_big'))?>
</div>
</div>
</div>
<?php
$this->page_title = $model->test->session->name;
$this->crumbs = array(
'Начало тестирования' => array('/testings/testingTest/index'),
$model->test->name => false,
);
?>
<style type="text/css">
[data-toggle=buttons] .btn input {
position: absolute;
clip: rect(0,0,0,0);
pointer-events: none;
}
.gray_wr {
padding: 5px 14px;
margin-bottom: 6px;
}
</style>
<?php if (Yii::app()->user->hasFlash('flash')) : ?>
<div class="message"><span>
<?php echo Yii::app()->user->getFlash('flash'); ?>
</span></div>
<?php endif; ?>
<script type="text/javascript">
jQuery(function(){
var mg_need = <?php echo $model->test->mg_count; ?>;
var te_need = <?php echo $model->test->te_count; ?>;
var submit_button = jQuery('#submit_button');
var check_number = function()
{
var mg = jQuery("input:checkbox[id^=mg]:checked").length;
var te = jQuery("input:checkbox[id^=te]:checked").length;
if (mg_need <= mg && te_need <= te) {
submit_button.removeAttr('disabled');
} else {
submit_button.attr('disabled','disabled');
}
}
check_number();
$('input:checkbox').change(check_number);
});
</script>
<br>
<form method="post" id="choose-gammas-form">
<h2>Выберите гаммы продукции, из которых будет формироваться ваш тест</h2>
<br />
<?php if($model->test->gammasMG) { ?>
<h6>Выберите несколько гамм продукции (не менее <?php echo $model->test->mg_count; ?>) из строительной гаммы:</h6>
<div data-toggle="buttons" class="btn-group">
<?=NHtml::checkBoxList('mg', $mg_gammas, CHtml::listData($model->test->gammasMG, 'id', 'name'), array(
'template' => '<div class="gray_wr checkbox_button_wr_2">{beginLabel}{input}{labelTitle}{endLabel}</div>',
'labelOptions' => array(
'class' => 'btn btn-primary'
),
'autocomplete' => 'off',
'separator' => false
));?>
</div>
<br />
<br />
<?php } ?>
<?php if($model->test->gammasTE) { ?>
<h6>Выберите несколько гамм продукции (не менее <?php echo $model->test->te_count; ?>) из промышленной гаммы:</h6>
<div data-toggle="buttons" class="btn-group">
<?=NHtml::checkBoxList('te', $te_gammas, CHtml::listData($model->test->gammasTE, 'id', 'name'), array(
'template' => '<div class="gray_wr checkbox_button_wr_2">{beginLabel}{input}{labelTitle}{endLabel}</div>',
'labelOptions' => array(
'class' => 'btn btn-primary'
),
'autocomplete' => 'off',
'separator' => false
));?>
</div>
<br />
<br />
<? } ?>
<div class="row">
<div class="col-sm-12">
<button type="submit" id="submit_button" class="green_button">Подтвердить</button>
</div>
</div>
</form>
<br style="clear: both;" />
<?php
$this->page_title = $model->test->session->name;
$this->crumbs = array(
'Тестирование' => array('/testings/testingTest/index'),
$model->test->name => false,
);
?>
<?php if (Yii::app()->user->hasFlash('flash')) : ?>
<div class="message"><span>
<?php echo Yii::app()->user->getFlash('flash'); ?>
</span></div>
<?php endif; ?>
<div class="row">
<div class="col-sm-12">
<div class="error_box_text">
<h3>Тестирование не завершено.</h3>
<h6><?=Setting::getValue('not_attempt_message')?></h6>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="error_fedback">
<?=CHtml::beginForm();?>
<h6>Обратная связь</h6>
<?=CHtml::textArea('message', '');?>
<?=CHtml::ajaxSubmitButton(
'Отправить',
Yii::app()->createUrl('/testings/testingTest/sendNotAttempt', array('id' => $model->id)),
array(
'dataType' => 'json',
'success' => 'js:function(data){
if(data.success)
{
console.log("+");
$(".error_fedback").html("<div class=\"row\"><div class=\"col-sm-8\" style=\"margin:0 auto;float:none;\"><div class=\"gray_box\"><p>" + data.message + "</p></div></div></div>");
}
}'
),
array(
'class' => 'green_button f_r'
)
);?>
<div class="clear"></div>
<?=CHtml::endForm();?>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="list_back">
<a href="/testings/testingTest/index">Вернуться к списку тестов <span>&uarr;</span></a>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="read_box_wr">
<div class="read_box">
<p>Тестирование не завершено.</p>
</div>
</div>
</div>
</div>
<br>
\ No newline at end of file
<?php
$this->page_title = $model->test->session->name;
$this->crumbs = array(
'Тестирование' => array('/testings/testingTest/index'),
$model->test->name => false,
);
?>
<?php if (Yii::app()->user->hasFlash('flash')) : ?>
<div class="message"><span>
<?php echo Yii::app()->user->getFlash('flash'); ?>
</span></div>
<?php endif; ?>
<div class="row">
<div class="col-sm-12">
<?php if ($model->is_passed == TestingPassing::PASSED) : ?>
<div class="passed_text">
<h3>Поздравляем, Вы сдали тест</h3>
<h5>Тестирование завершено</h5>
</div>
<?php elseif ($model->is_passed == TestingPassing::FAILED) : ?>
<div class="not_passed_text">
<h3>Тест не сдан!</h3>
<h5>Тестирование завершено</h5>
</div>
<?php endif; ?>
</div>
</div>
<div class="test_parameters <?if($model->is_passed == TestingPassing::FAILED){?>not_passed_test<?}?>">
<div class="row">
<div class="col-sm-6">
<h6>Тест пройден на:</h6>
<h5><?php echo $model->percent; ?>%</h5>
</div>
<div class="col-sm-6">
<h6>Прохождение теста у Вас заняло:</h6>
<?php
$minutesText = TestingPassing::declOfNum(floor($model->time / 60), array(' минута ', ' минуты ', ' минут '));
$secondsText = TestingPassing::declOfNum($model->time % 60, array(' секунда', ' секунды', ' секунд'));
?>
<h5><?=$minutesText?><?=$secondsText?></h5>
</div>
</div>
<br>
</div>
<?php if($model->is_passed == TestingPassing::FAILED && $model->gammas && !$model->test->mix) : ?>
<div class="row">
<div class="col-sm-12">
<div class="statistics_test_wr">
<ul class="statistics_test">
<?php foreach ($model->gammas as $gamma) : ?>
<li><span><?php echo $model->gammaPercent($gamma->id); ?>%</span><?php echo $gamma->name; ?> (<?php echo TestingGamma::$type_list[$gamma->type]; ?>)</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<?php endif; ?>
<div class="row">
<div class="col-sm-12">
<div class="list_back">
<a href="/testings/testingTest/index">Вернуться к списку тестов <span></span></a>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="green_wr <?if($model->is_passed == TestingPassing::FAILED){?>not_passed_test_progress<?}?>">
<div class="green_box">
<div class="progress_ins">
<span class="col_text">Вопрос <strong class="green_text"><?=$model->test->questions?></strong> из <strong class="green_text"><?=$model->test->questions?></strong></span>
<div class="progress_wr">
<div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%">
<span class="sr-only">100% Complete (success)</span>
</div>
</div>
</div>
<div class="progress_done">
Выполнено 100%
</div>
</div>
<div class="time_progress">
<p>Затраченное время:</p>
<span><?=date("H:i:s", mktime(0, 0, $model->time));?></span>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
<br>
\ No newline at end of file
<?php echo $form; ?>
\ No newline at end of file
<?php
$this->widget('zii.widgets.CDetailView', array(
'data' => $model,
'attributes' => array(
'id',
'session_id',
'name',
'minutes',
'questions',
'pass_percent',
'mg_percent',
'te_percent',
'mg_count',
'te_count',
'create_date',
),
));
?>
<?php
use yii\helpers\Html;
use \common\components\zii\AdminGrid;
/* @var $this yii\web\View */
/* @var $dataProvider yii\data\ActiveDataProvider */
?>
<?php echo AdminGrid::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
// ['class' => 'yii\grid\SerialColumn'],
'name',
[
'attribute' => 'created',
'value' => function($model)
{
return date("d.m.Y H:i:s", $model->created);
}
],
[
'header' => 'Список пользователей',
'value' => function($model) {
return Html::a('Список пользователей', [
"/testings/user-admin/manage",
"session" => \Yii::$app->request->get('session'),
"group" => $model->id,
]);
},
'format' => 'html',
],
],
]); ?>
\ No newline at end of file
<?php
use yii\helpers\Html;
use \common\components\zii\AdminGrid;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use common\modules\testings\models\User;
use common\modules\testings\models\UserGroup;
use common\modules\testings\models\SendHistory;
use common\modules\testings\models\Session;
use common\modules\testings\models\Passing;
/* @var $this yii\web\View */
/* @var $dataProvider yii\data\ActiveDataProvider */
$session = null;
if (\Yii::$app->request->get('session'))
{
$session = Session::findOne(\Yii::$app->request->get('session'));
}
?>
<p>
<?= Html::a('Добавить', ['create'], ['class' => 'btn btn-success']) ?>
<?php if($session) : ?>
<?= Html::a('Разослать уведомления всем', ['/testings/session-admin/send-message-to-all', 'id' => $session->id], ['class' => 'btn btn-info']) ?>
<?= Html::a('История отправки дубликатов', ['/testings/send-history-admin/manage', 'session' => $session->id], ['class' => 'btn btn-info']) ?>
<?= Html::a('Импорт пользователей из XLS', ['/testings/session-admin/import-passings', 'id' => $session->id], ['class' => 'btn btn-info']) ?>
<?php endif; ?>
</p>
<?php if (\Yii::$app->session->hasFlash('flash')) : ?>
<div class="message"><span>
<?php echo \Yii::$app->session->getFlash('flash'); ?>
</span></div>
<?php endif; ?>
<?php
$columns = [
[
'attribute' => 'sex',
'value' => function($model)
{
return User::$sex_list[$model->sex];
},
'filter' => User::$sex_list,
'visible' => !\Yii::$app->request->get('session'),
],
'last_name',
'first_name',
'patronymic',
'company_name',
[
'attribute' => 'filter_group_id',
'value' => function($model)
{
return $model->groupRelated->group->name;
},
'filter' => ArrayHelper::map(UserGroup::find()->where(['session_id' => \Yii::$app->request->get('session')])->all(), 'id', 'name')
],
[
'attribute' => 'email',
'value' => function($model)
{
return Html::a($model->email, "mailto:" . $model->email);
},
'format' => 'html',
],
[
'header' => 'Статус отправки',
'attribute' => 'filter_history_status',
'filter' => SendHistory::getStatusTitle(),
'format' => 'raw',
'value' => function($model)
{
if($model->history)
{
return SendHistory::getStatusTitle($model->history->unisender_status);
}
},
],
[
'header' => 'Время отправки',
'value' => function($model)
{
if($model->history)
{
return date('d.m.Y H:i:s', $model->history->sended);
}
},
],
[
'attribute' => 'manager_id',
'value' => function($model)
{
if($model->manager)
{
return Html::a($model->manager->name, ["/users/user-admin/view", "id" => $model->manager_id]);
}
else
{
return "Пользователь удалён";
}
},
'format' => 'html',
],
'tki'
];
$link = '';
if ($session)
{
$marked = \Yii::$app->controller->getMarked($session->id);
$qty = count($marked);
$style = ($qty) ? '' : 'display:none;';
$send = Html::a("Разослать выделенным ($qty)",
['testings/session-admin/send-message-to-marked', 'id' => $session->id],
['style' => $style, 'id' => 'sendMarkup']
);
$clear = Html::a("[сброс]",
['update-mark', 'session' => $session->id],
['style' => $style, 'id' => 'resetMarkup']
);
$link = $send . ' ' . $clear . '<br><br>';
echo $link;
array_unshift(
$columns,
[
'class' => 'common\modules\testings\components\MarkBoxColumn',
'updateUrl' => Url::to(['update-mark', 'session' => $session->id]),
]
);
foreach($session->tests as $test)
{
$columns = ArrayHelper::merge(
$columns,
[
[
'header' => $test->name,
'value' => function($model) use($test)
{
$passing = Passing::find()->where([
'test_id' => $test->id,
'user_id' => $model->id
])->one();
if($passing)
{
return Html::a("Да", ["/testings/passing-admin/change-status", "user"=>$model->id, "test" => $test->id], ["title" => "Изменить на НЕТ"]);
}
else
{
return Html::a("Нет", ["/testings/passing-admin/change-status", "user"=>$model->id, "test" => $test->id], ["title" => "Изменить на ДА"]);
}
},
'format' => 'html',
]
]
);
}
$buttons = [
[
'class' => \common\components\ColorActionColumn::className(),
'template' => '{send} {view} {update}',
'buttons' => [
'send' => function ($url, $model, $key) use($session)
{
return Html::a('<i class="fa fa-envelope fa-lg"></i>', Url::to(['testings/session-admin/send-message', 'id' => $session->id, 'user' => $model->id]), [
'title' => 'Уведомить о тестировании',
'data-toggle' => 'tooltip',
'data-pjax' => '0',
]);
},
]
]
];
$columns = ArrayHelper::merge($columns, $buttons);
}
echo AdminGrid::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => $columns,
]);
\ No newline at end of file
<?php
echo $form;
\ No newline at end of file
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
use common\modules\testings\models\User;
/* @var $this yii\web\View */
/* @var $model common\modules\faq\models\Faq */
?>
<div class="faq-view">
<h1><?= Html::encode($model->fio) ?></h1>
<p>
<?= Html::a(Yii::t('content', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
</p>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
[
'attribute' => 'sex',
'value' => User::$sex_list[$model->sex],
'filter' => false
],
'first_name',
'patronymic',
'last_name',
'company_name',
'city',
'login',
'email:email',
[
'attribute' => 'manager_id',
'value' => ($model->manager)?$model->manager->name:"Пользователь удалён"
],
'tki',
'region',
'create_date',
],
]) ?>
</div>
<?php
class BrowsersCheckWidget extends Portlet
{
const BROWSER_COOKIE = 'test_browser_cookie';
namespace common\modules\testings\widgets;
public $model;
use Yii;
use yii\base\Widget;
use yii\helpers\Html;
public function renderContent()
{
if(!Yii::app()->request->cookies[self::BROWSER_COOKIE]->value && $browser = $this->check())
{
$cookie = new CHttpCookie(self::BROWSER_COOKIE, 1);
Yii::app()->request->cookies[self::BROWSER_COOKIE] = $cookie;
use common\components\Browser;
$this->render('BrowsersCheckWidget', compact('browser'));
}
}
class BrowsersCheckWidget extends Widget
{
const BROWSER_COOKIE = 'test_browser_cookie';
private function check()
{
......@@ -30,4 +25,16 @@ class BrowsersCheckWidget extends Portlet
return $browser;
}
}
public function run()
{
$cookies = Yii::$app->request->cookies;
if(!$cookies->get(self::BROWSER_COOKIE) && $browser = $this->check())
{
$cookies->add(new \yii\web\Cookie([self::BROWSER_COOKIE => 1]));
}
return $this->render('BrowsersCheckWidget', compact('browser'));
}
}
<?php
class NotCloseTabsWidget extends CWidget
namespace common\modules\testings\widgets;
use yii\base\Widget;
use common\models\Settings;
class NotCloseTabsWidget extends Widget
{
public function run()
{
$this->render('NotCloseTabsWidget');
return $this->render('NotCloseTabsWidget', [
'message' => Settings::getValue('not_close_tabs_message');
]);
}
}
?>
\ No newline at end of file
<div class="row">
<div class="col-sm-12">
<div class="col-md-12 col-xs-12 col-sm-12">
<div class="read_box">
<p>Вы используете браузер <?=$browser->getBrowser();?> <?=$browser->getVersion()?>. <br> Для корректной работы приложения тестирования рекомендуем использовать браузер Chrome.</p>
<div class="read_box_off box_off">закрыть <strong>&times;</strong></div>
<div class="read_box_off box_off">закрыть <strong>×</strong></div>
</div>
</div>
</div>
\ No newline at end of file
<div class="row">
<div class="col-sm-12">
<div class="col-md-12 col-xs-12 col-sm-12">
<div class="gray_box">
<p><?=Setting::getValue('not_close_tabs_message');?></p>
<p><?=$message?></p>
</div>
</div>
</div>
\ No newline at end of file
<?php
use yii\db\Schema;
use yii\db\Migration;
class m160128_182951_add_columns_test extends Migration
{
public function safeUp()
{
$this->addColumn('testings_tests', 'passed_scores', Schema::TYPE_INTEGER . '(11) NOT NULL');
$this->addColumn('testings_tests', 'notpassed_scores', Schema::TYPE_INTEGER . '(11) NOT NULL');
}
public function safeDown()
{
$this->dropColumn('testings_tests', 'passed_scores');
$this->dropColumn('testings_tests', 'notpassed_scores');
}
}
......@@ -20,6 +20,7 @@ return [
'faq' => ['class' => 'common\modules\faq\Module'],
'main' => ['class' => 'common\modules\main\main'],
'school' => ['class' => 'common\modules\school\Module',],
'testings' => ['class' => 'common\modules\testings\Module',],
'sitemap' => [
'class' => 'himiklab\sitemap\Sitemap',
'models' => [
......
......@@ -33,7 +33,7 @@
</div>
<div class="col-md-4 col-xs-4 col-sm-12"><a href="#zvonok_form" class="zvonok_bt popup-form"><span>Заказать звонок</span></a></div>
<div class="col-md-4 col-xs-4 col-sm-12">
<div class="phone_hover_foot">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div>
<!-- <div class="phone_hover_foot">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div> -->
<span class="foot_phone"><?=\common\models\Settings::getValue('content-phone');?></span>
</div>
</div>
......
<footer class="testing_footer">
<div class="container">
<div class="row">
<div class="col-md-2 col-xs-2 col-sm-12">
<div class="taskon_testing">
<img src="/images/taskon.png" height="31" width="100" alt="">
</div>
</div>
<div class="col-md-5 col-xs-5 col-sm-12">
<div class="inf_foot_testing">Система дистанционного обучения на базе Taskon</div>
</div>
<div class="col-md-2 col-md-offset-3 col-xs-2 col-sm-12">
<a href="#" class="help_btn">Справка</a>
</div>
</div>
</div>
</footer>
\ No newline at end of file
......@@ -6,7 +6,7 @@
</div>
<div class="col-md-4 col-xs-4 col-sm-12"><a href="#zvonok_form" class="zvonok_bt popup-form"><span>Заказать звонок</span></a></div>
<div class="col-md-4 col-xs-4 col-sm-12">
<div class="phone_hover_foot">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div>
<!-- <div class="phone_hover_foot">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div> -->
<span class="foot_phone"><?=\common\models\Settings::getValue('content-phone');?></span>
</div>
</div>
......
<header>
<div class="container">
<div class="row">
<div class="col-md-2 col-xs-12 col-sm-12">
<a href="http://mikulin.cz/project/artproject/" class="logo_testing">
<img src="images/logo.png" height="34" width="125" alt="">
</a>
</div>
<div class="col-md-5 col-md-offset-1 col-xs-7 col-sm-12">
<div class="ball-block_testing">Накоплено баллов:
<span class="col-ball_testing">99 999</span>
<a href="#" class="ball-link_testing">Как увеличить?</a>
<div class="ball_hover">Текст как увеличить,<br/> текст как увеличить,</div>
</div>
</div>
<div class="col-md-3 col-md-offset-1 col-xs-5 col-sm-12">
<div class="prof_block_testing">
<span class="prof_name_testing">Дмитрий</span><a href="#">Выход</a>
</div>
</div>
</div>
</div>
</header>
\ No newline at end of file
<nav class="menu">
<div class="toggle_block"><a href="#" class="toggle-mnu"><span></span></a></div>
<div class="phone_menu"><?=\common\models\Settings::getValue('content-phone')?></div>
<ul>
<li><a href="/about" class="link">О компании</a></li>
<li><a href="/case" class="link">Кейсы</a></li>
<li><a href="#" class="link">Блог</a></li>
<?php /*<li><a href="/school" class="link">Школа аналитики</a></li>*/ ?>
<li><a href="/contacts" class="link">Контакты</a></li>
</ul>
</nav>
<header>
<div class="container">
<div class="row">
<div class="col-md-2 col-xs-3 col-sm-12">
<a href="/" class="logo">
<img src="/images/logo.png" height="34" width="125" alt="">
</a>
</div>
<div class="col-md-7 col-xs-6 col-sm-12">
<nav class="top_nav clearfix">
<ul>
<li><a href="/about">О компании</a></li>
<li><a href="/case">Кейсы</a></li>
<li><a href="#">Блог</a></li>
<?php /*<li><a href="/school">Школа аналитики</a></li>*/ ?>
<li><a href="/contacts">Контакты</a></li>
<li><a href="#">ENG</a></li>
<!-- <li><a href="#">RUS</a></li> -->
</ul>
</nav>
<!-- <div class="lang_check">
<a href="#" class="d_menu"><i class="icon-arrowDown"></i>ENG</a>
<a href="#" class="d_menu_hide"><i class="icon-arrowRight"></i>RUS</a>
</div> -->
</div>
<div class="col-md-3 col-xs-3 col-sm-12">
<span class="top_phone"><?=\common\models\Settings::getValue('content-phone')?></span>
<!-- <div class="phone_hover_head">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div> -->
</div>
</div>
</div>
</header>
\ No newline at end of file
......@@ -25,50 +25,7 @@ AppAsset::register($this);
<?php $this->beginBody() ?>
<nav class="menu">
<div class="toggle_block"><a href="#" class="toggle-mnu"><span></span></a></div>
<div class="phone_menu"><?=\common\models\Settings::getValue('content-phone')?></div>
<ul>
<li><a href="/about" class="link">О компании</a></li>
<li><a href="/case" class="link">Кейсы</a></li>
<li><a href="#" class="link">Блог</a></li>
<li><a href="/school" class="link">Школа аналитики</a></li>
<li><a href="/contacts" class="link">Контакты</a></li>
</ul>
</nav>
<header>
<div class="container">
<div class="row">
<div class="col-md-2 col-xs-3 col-sm-12">
<a href="/" class="logo">
<img src="/images/logo.png" height="34" width="125" alt="">
</a>
</div>
<div class="col-md-7 col-xs-6 col-sm-12">
<nav class="top_nav clearfix">
<ul>
<li><a href="/about">О компании</a></li>
<li><a href="/case">Кейсы</a></li>
<li><a href="#">Блог</a></li>
<li><a href="/school">Школа аналитики</a></li>
<li><a href="/contacts">Контакты</a></li>
<li><a href="#">ENG</a></li>
<!-- <li><a href="#">RUS</a></li> -->
</ul>
</nav>
<!-- <div class="lang_check">
<a href="#" class="d_menu"><i class="icon-arrowDown"></i>ENG</a>
<a href="#" class="d_menu_hide"><i class="icon-arrowRight"></i>RUS</a>
</div> -->
</div>
<div class="col-md-3 col-xs-3 col-sm-12">
<span class="top_phone"><?=\common\models\Settings::getValue('content-phone')?></span>
<div class="phone_hover_head">Стоимость звонка 0 руб,<br/> в том числе с мобильного</div>
</div>
</div>
</div>
</header>
<?php echo $this->render('header'); // Добавить проверку на авторизацию и вывести другую шапку header-auth.php ?>
<?php echo $content ?>
......
frontend/web/images/about_img.jpg

128 KB | W: | H:

frontend/web/images/about_img.jpg

213 KB | W: | H:

frontend/web/images/about_img.jpg
frontend/web/images/about_img.jpg
frontend/web/images/about_img.jpg
frontend/web/images/about_img.jpg
  • 2-up
  • Swipe
  • Onion skin
frontend/web/images/logoart.png

1.41 KB | W: | H:

frontend/web/images/logoart.png

4.88 KB | W: | H:

frontend/web/images/logoart.png
frontend/web/images/logoart.png
frontend/web/images/logoart.png
frontend/web/images/logoart.png
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment