1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: class Mage_Captcha_Model_Zend extends Zend_Captcha_Image implements Mage_Captcha_Model_Interface
35: {
36: 37: 38:
39: const SESSION_WORD = 'word';
40:
41: 42: 43:
44: const DEFAULT_WORD_LENGTH_FROM = 3;
45:
46: 47: 48:
49: const DEFAULT_WORD_LENGTH_TO = 5;
50:
51: 52: 53: 54:
55: protected $_helper = null;
56:
57: 58: 59: 60:
61: protected $_expiration;
62:
63: 64: 65: 66: 67:
68: protected $_fsize = 22;
69:
70: 71: 72: 73:
74: protected $_formId;
75:
76: 77: 78: 79: 80:
81: public function __construct($params)
82: {
83: if (!isset($params['formId'])) {
84: throw new Exception('formId is mandatory');
85: }
86: $this->_formId = $params['formId'];
87: $this->setExpiration($this->getTimeout());
88: }
89:
90: 91: 92: 93: 94: 95:
96: protected function _getFormIdKey($key)
97: {
98: return $this->_formId . '_' . $key;
99: }
100:
101: 102: 103: 104: 105:
106: public function getBlockName()
107: {
108: return 'captcha/captcha_zend';
109: }
110:
111:
112: 113: 114: 115: 116: 117:
118: public function isRequired($login = null)
119: {
120: if ($this->_isUserAuth() || !$this->_isEnabled() || !in_array($this->_formId, $this->_getTargetForms())) {
121: return false;
122: }
123:
124: return ($this->_isShowAlways() || $this->_isOverLimitAttempts($login)
125: || $this->getSession()->getData($this->_getFormIdKey('show_captcha'))
126: );
127: }
128:
129: 130: 131: 132: 133: 134:
135: protected function _isOverLimitAttempts($login)
136: {
137: return ($this->_isOverLimitIpAttempt() || $this->_isOverLimitLoginAttempts($login));
138: }
139:
140: 141: 142: 143: 144:
145: protected function _getAllowedAttemptsForSameLogin()
146: {
147: return (int)$this->_getHelper()->getConfigNode('failed_attempts_login');
148: }
149:
150: 151: 152: 153: 154:
155: protected function _getAllowedAttemptsFromSameIp()
156: {
157: return (int)$this->_getHelper()->getConfigNode('failed_attempts_ip');
158: }
159:
160: 161: 162: 163: 164:
165: protected function _isOverLimitIpAttempt()
166: {
167: $countAttemptsByIp = Mage::getResourceModel('captcha/log')->countAttemptsByRemoteAddress();
168: return $countAttemptsByIp >= $this->_getAllowedAttemptsFromSameIp();
169: }
170:
171: 172: 173: 174: 175: 176:
177: protected function _isOverLimitLoginAttempts($login)
178: {
179: if ($login != false) {
180: $countAttemptsByLogin = Mage::getResourceModel('captcha/log')->countAttemptsByUserLogin($login);
181: return ($countAttemptsByLogin >= $this->_getAllowedAttemptsForSameLogin());
182: }
183: return false;
184: }
185:
186: 187: 188: 189: 190:
191: protected function _isUserAuth()
192: {
193: return Mage::app()->getStore()->isAdmin()
194: ? Mage::getSingleton('admin/session')->isLoggedIn()
195: : Mage::getSingleton('customer/session')->isLoggedIn();
196: }
197:
198: 199: 200: 201: 202:
203: public function isCaseSensitive()
204: {
205: return (string)$this->_getHelper()->getConfigNode('case_sensitive');
206: }
207:
208: 209: 210: 211: 212:
213: public function getFont()
214: {
215: return $this->_getFontPath();
216: }
217:
218: 219: 220: 221: 222:
223: public function getTimeout()
224: {
225: if (!$this->_expiration) {
226: 227: 228: 229:
230: $this->_expiration = (int)$this->_getHelper()->getConfigNode('timeout') * 60;
231: }
232: return $this->_expiration;
233: }
234:
235: 236: 237: 238: 239:
240: public function getImgDir()
241: {
242: return $this->_helper->getImgDir();
243: }
244:
245: 246: 247: 248: 249:
250: public function getImgUrl()
251: {
252: return $this->_helper->getImgUrl();
253: }
254:
255: 256: 257: 258: 259: 260:
261: public function isCorrect($word)
262: {
263: $storedWord = $this->getWord();
264: $this->_clearWord();
265:
266: if (!$word || !$storedWord){
267: return false;
268: }
269:
270: if (!$this->isCaseSensitive()) {
271: $storedWord = strtolower($storedWord);
272: $word = strtolower($word);
273: }
274: return $word == $storedWord;
275: }
276:
277: 278: 279: 280: 281:
282: public function getSession()
283: {
284: return Mage::getSingleton('customer/session');
285: }
286:
287: 288: 289: 290: 291:
292: public function getImgSrc()
293: {
294: return $this->getImgUrl() . $this->getId() . $this->getSuffix();
295: }
296:
297: 298: 299: 300: 301: 302:
303: public function logAttempt($login)
304: {
305: if ($this->_isEnabled() && in_array($this->_formId, $this->_getTargetForms())) {
306: Mage::getResourceModel('captcha/log')->logAttempt($login);
307: if ($this->_isOverLimitLoginAttempts($login)) {
308: $this->getSession()->setData($this->_getFormIdKey('show_captcha'), 1);
309: }
310: }
311: return $this;
312: }
313:
314: 315: 316: 317: 318:
319: protected function _getFontPath()
320: {
321: $font = (string)$this->_getHelper()->getConfigNode('font');
322: $fonts = $this->_getHelper()->getFonts();
323:
324: if (isset($fonts[$font])) {
325: $fontPath = $fonts[$font]['path'];
326: } else {
327: $fontData = array_shift($fonts);
328: $fontPath = $fontData['path'];
329: }
330:
331: return $fontPath;
332: }
333:
334: 335: 336: 337: 338:
339: protected function _getHelper()
340: {
341: if (empty($this->_helper)) {
342: $this->_helper = Mage::helper('captcha');
343: }
344: return $this->_helper;
345: }
346:
347: 348: 349: 350: 351:
352: protected function _generateWord()
353: {
354: $word = '';
355: $symbols = $this->_getSymbols();
356: $wordLen = $this->_getWordLen();
357: for ($i = 0; $i < $wordLen; $i++) {
358: $word .= $symbols[array_rand($symbols)];
359: }
360: return $word;
361: }
362:
363: 364: 365: 366: 367:
368: protected function _getSymbols()
369: {
370: return str_split((string)$this->_getHelper()->getConfigNode('symbols'));
371: }
372:
373: 374: 375: 376: 377:
378: protected function _getWordLen()
379: {
380: $from = 0;
381: $to = 0;
382: $length = (string)$this->_getHelper()->getConfigNode('length');
383: if (!is_numeric($length)) {
384: if (preg_match('/(\d+)-(\d+)/', $length, $matches)) {
385: $from = (int)$matches[1];
386: $to = (int)$matches[2];
387: }
388: } else {
389: $from = (int)$length;
390: $to = (int)$length;
391: }
392:
393: if (($to < $from) || ($from < 1) || ($to < 1)) {
394: $from = self::DEFAULT_WORD_LENGTH_FROM;
395: $to = self::DEFAULT_WORD_LENGTH_TO;
396: }
397:
398: return mt_rand($from, $to);
399: }
400:
401: 402: 403: 404: 405:
406: protected function _isShowAlways()
407: {
408: if ((string)$this->_getHelper()->getConfigNode('mode') == Mage_Captcha_Helper_Data::MODE_ALWAYS) {
409: return true;
410: }
411:
412: $alwaysFor = $this->_getHelper()->getConfigNode('always_for');
413: foreach ($alwaysFor as $nodeFormId => $isAlwaysFor) {
414: if ($isAlwaysFor && $this->_formId == $nodeFormId) {
415: return true;
416: }
417: }
418:
419: return false;
420: }
421:
422: 423: 424: 425: 426:
427: protected function _isEnabled()
428: {
429: return (string)$this->_getHelper()->getConfigNode('enable');
430: }
431:
432: 433: 434: 435: 436: 437: 438:
439: protected function _getTargetForms()
440: {
441: $formsString = (string) $this->_getHelper()->getConfigNode('forms');
442: return explode(',', $formsString);
443: }
444:
445: 446: 447: 448: 449:
450: public function getWord()
451: {
452: $sessionData = $this->getSession()->getData($this->_getFormIdKey(self::SESSION_WORD));
453: return time() < $sessionData['expires'] ? $sessionData['data'] : null;
454: }
455:
456: 457: 458: 459: 460: 461:
462: protected function _setWord($word)
463: {
464: $this->getSession()->setData($this->_getFormIdKey(self::SESSION_WORD),
465: array('data' => $word, 'expires' => time() + $this->getTimeout())
466: );
467: $this->_word = $word;
468: return $this;
469: }
470:
471: 472: 473: 474: 475:
476: protected function _clearWord()
477: {
478: $this->getSession()->unsetData($this->_getFormIdKey(self::SESSION_WORD));
479: $this->_word = null;
480: return $this;
481: }
482:
483: 484: 485: 486: 487: 488:
489: protected function _randomSize()
490: {
491: return mt_rand(280, 300) / 100;
492: }
493:
494: 495: 496: 497: 498: 499:
500: protected function _gc()
501: {
502:
503: }
504: }
505: