Покажи теми - VladSun
Виж публикациите на потр. | * Виж темите на потр. | Виж прикачените файлове на потр
Страници: [1] 2 3 ... 7
1  Linux секция за напреднали / Хардуерни и софтуерни проблеми / [SOLVED] Изключително бавно доставяне на имейли с postfix -: Jan 21, 2015, 15:35
Привет!

Отдавна не ми се е налагало да инсталирам мейл съвер, но все пак се случи отново ;)
Инсталирах postfix + dovecot + mysql + amavisd + spamassasin

Всичко изглежда добре, но имам голям проблем със скороста на доставяне на пощата - около 15 минути след изпращане се получава. Виждам я да седи в опашката (mailq) и ако дам
Код
GeSHi (Bash):
  1. [root@picasse-backup ~]# postsuper -r ALL && postfix flush
  2. postsuper: Requeued: 1 message
  3.  
се получава веднага в пощенската кутия.

Конфигурация на postfix (postconf -n):
Код
GeSHi (INI):
  1. alias_database = hash:/etc/aliases
  2. alias_maps = hash:/etc/aliases
  3. broken_sasl_auth_clients = yes
  4. command_directory = /usr/sbin
  5. config_directory = /etc/postfix
  6. daemon_directory = /usr/libexec/postfix
  7. debug_peer_level = 2
  8. delay_warning_time = 4
  9. disable_vrfy_command = yes
  10. html_directory = no
  11. inet_interfaces = all
  12. mail_owner = postfix
  13. mailbox_size_limit = 2048000000
  14. mailq_path = /usr/bin/mailq.postfix
  15. manpage_directory = /usr/share/man
  16. message_size_limit = 204800000
  17. mydestination = $myhostname, localhost.$mydomain, localhost
  18. mydomain = ubiqom.eu
  19. myhostname = mail.ubiqom.eu
  20. mynetworks = $config_directory/mynetworks
  21. newaliases_path = /usr/bin/newaliases.postfix
  22. queue_directory = /var/spool/postfix
  23. recipient_delimiter = +
  24. relay_domains = proxy:mysql:/etc/postfix/mysql-relay_domains_maps.cf
  25. sendmail_path = /usr/sbin/sendmail.postfix
  26. setgid_group = postdrop
  27. smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache
  28. smtp_use_tls = yes
  29. smtpd_client_restrictions =
  30. smtpd_data_restrictions = reject_unauth_pipelining
  31. smtpd_helo_required = yes
  32. smtpd_helo_restrictions =
  33. smtpd_recipient_restrictions = permit_sasl_authenticated,
  34.         permit_mynetworks,
  35.         reject_unauth_destination,
  36.         reject_non_fqdn_sender,
  37.         reject_non_fqdn_recipient,
  38.         reject_unknown_recipient_domain,
  39.         reject_rbl_client zen.spamhaus.org,
  40.         reject_rbl_client bl.spamcop.net,
  41.         reject_rbl_client dnsbl.sorbs.net
  42. smtpd_sasl_auth_enable = yes
  43. smtpd_sasl_local_domain = $myhostname
  44. smtpd_sasl_path = private/auth
  45. smtpd_sasl_security_options = noanonymous
  46. smtpd_sasl_type = dovecot
  47. smtpd_sender_restrictions =
  48. smtpd_tls_cert_file = /etc/pki/tls/certs/mail.ubiqom.eu.crt
  49. smtpd_tls_key_file = /etc/pki/tls/private/mail.ubiqom.eu.key
  50. smtpd_tls_loglevel = 1
  51. smtpd_tls_received_header = yes
  52. smtpd_tls_security_level = may
  53. smtpd_tls_session_cache_timeout = 3600s
  54. smtpd_use_tls = yes
  55. tls_random_source = dev:/dev/urandom
  56. transport_maps = hash:/etc/postfix/transport
  57. unknown_local_recipient_reject_code = 550
  58. virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_alias_maps.cf,                     regexp:/etc/postfix/virtual_regexp
  59. virtual_gid_maps = static:12
  60. virtual_mailbox_base = /home/vmail
  61. virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains_maps.cf
  62. virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_maps.cf
  63. virtual_minimum_uid = 101
  64. virtual_transport = dovecot
  65. virtual_uid_maps = static:101
  66.  

Вече два дена ровя из нета и нищо ...
Някакви идеи?
2  Програмиране / Общ форум / Memory leaks & TDD -: Nov 28, 2011, 23:48
Пиша един daemon на C. Ползвам CUnit заради поддръжката му в Netbeans (). Така и не успях да намеря начин за проверка за memory leaks. RCunit предоставя тази възможност, но не ми се иска да го ползвам заради липсата на поддръжка в Netbeans.

Някакви идеи или опит с TDD и memory leaks?
3  Linux секция за начинаещи / Настройка на програми / Пускане на няколко програми с едно действие -: Aug 26, 2011, 09:39
Имам следния проблем - работя по няколко проекта едновременно, като разработката на всеки проект се нуждае от няколко софтуерни продукта - прим. NetBeans IDE, MysqlWorkBench, FF + FireBug, различни документации отворени в браузер. Малко досадно ми е всеки път като трябва да си  приготвя обкръжението да ги отварям едно по едно, след това да отварям в тях нужните местоположения на файлове/проекти/линкове.

Дойде ми идеята за десктоп икони, които да стартират гореизброените неща и да подават нужните параметри.

Тъй като съм малко бос в десктоп областта, си реших проблема по мой си начин:

/usr/local/bin/multirun
Код
GeSHi (Perl):
  1. #!/usr/bin/perl
  2. use POSIX;
  3.  
  4. sub afork (\@$&)
  5. {
  6. my ($data, $max, $code) = @_;
  7. my $c = 0;
  8. foreach my $data (@$data)
  9. {
  10. wait unless ++ $c <= $max;
  11. die "Fork failed: $!\n" unless defined (my $pid = fork);
  12. exit $code -> ($data) unless $pid;
  13. }
  14. 1 until -1 == wait;
  15. }
  16.  
  17.  
  18.  
  19. afork (@ARGV,10,\&run);
  20.  
  21. sub run
  22. {
  23. my $data = $_[0];
  24. `$data`;
  25. }
  26.  
  27. exit();

За всеки проект си създавам bash скрипт (може и в иконата ама е много дълго). Прим.:

Код
GeSHi (Bash):
  1. #!/bin/bash
  2.  
  3.  
  4. /usr/local/bin/multirun \
  5. "/usr/local/netbeans-7.0.1/bin/netbeans /www/site/site1" \
  6. "/usr/bin/mysql-workbench /www/site/site1/site1.mwb" \
  7. "firefox -new-window http://site1.work" \
  8. "opera http://dev.sencha.com/deploy/ext-3.3.1/docs/"

И накрая правя икона сочеща към този скрипт.

Решението работи, но се чудех дали няма някакво по-елегантно решение с инструментите на Windows manager-a (Gnome в моя случай).
4  Хумор, сатира и забава / Хумор / Share the rainbow ... -: Jul 27, 2011, 15:32
http://vimeo.com/26753142

:P
5  Програмиране / Web development / Решаване на проблема със зависимостите -: Jan 21, 2011, 01:51
Написах малък framework за управление на множества от файлове (скриптови), които съдържат зависимости един към друг.

Примери:
- CSS файлове, които трябва да се заредят в определен ред, поради промяната на стиловете;
- JS файлове, които трябва да се заредят в определен ред, поради зависимости между тях;
и т.н.

Идеята ми е да използвам PhpDoc анотации -
Код
GeSHi (PHP):
  1. /**
  2.  *
  3.  * @annoloader-requires-file 1.js
  4.  * @annoloader-requires-file 2.js
  5.  *
  6.  * @annoloader-requires-class Ext.Namespace.Class1
  7.  * @annoloader-requires-class Ext.Namespace.Class2
  8.  *
  9.  * @annoloader-requires-namespace Ext.Namespace
  10.  *
  11.  * @annoloader-requires-directory ex/grid
  12.  *
  13.  * @annoloader-requires-directory-tree ex/data
  14.  *
  15.  */

във всеки един от файловете, който е зависим от други файлове. Така зависимостта се капсулира като знание само във файла, който реално е зависим.

Имам малко проблеми с "нареждането" на "равноправни" файлове, но мисля, че beta версията си заслужава :)

Код:
http://code.google.com/p/annoloader/source/browse/trunk/AnnoLoader/

Приемам всякаква критика и предложения.
Приложил съм и PhpUnit Test файловете.
6  Хумор, сатира и забава / Хумор / Google translator :) -: Nov 17, 2010, 13:15
http://translate.google.bg/#en|bg|CVS%2C%20GIT%2C%20SVN
7  Програмиране / Web development / [MVC] CI, ACL и контекст на изгледа -: Aug 24, 2010, 00:31
Малко объркано звучи заглавието, но искам да споделя как се справям с типа на изгледа (прим. HTML, PDF, JSON и т.н.) и достъпа до определени действия за отделните потребители.

Става въпрос за CodeIgniter рамката.

Първо създавам Контролер клас, който обслужва йерархията от класове:
Код
GeSHi (PHP):
  1. <?php
  2.  
  3. /**
  4.  * Remap enabled Controller class
  5.  *
  6.  *
  7.  * @package ExtCI
  8.  * @subpackage Libraries
  9.  * @category Libraries
  10.  * @author VladSun
  11.  *
  12.  */
  13.  
  14. abstract class Remap_Controller extends Controller
  15. {
  16. public function __construct()
  17. {
  18. parent::__construct();
  19. }
  20.  
  21. protected function preRemap($method, $arguments) {}
  22. protected function postRemap($method, $arguments) {}
  23.  
  24. protected function getRemapping($method, $arguments)
  25. {
  26. $remapping = new stdClass();
  27. $remapping->method = $method;
  28. $remapping->arguments = $arguments;
  29.  
  30. return $remapping;
  31. }
  32.  
  33. public function _remap($method)
  34. {
  35. $arguments = array_slice($this->uri->segment_array(), 3);
  36. $this->preRemap($method, $arguments);
  37.  
  38. $remapping = $this->getRemapping($method, $arguments);
  39.  
  40. if ( ! in_array(strtolower($remapping->method), array_map('strtolower', get_class_methods($this))))
  41. {
  42. show_404("{".get_class($this)."}/{$remapping->method}");
  43. }
  44. else
  45. {
  46. call_user_func_array(array($this, $remapping->method),  $remapping->arguments);
  47. $this->postRemap($remapping->method, $remapping->arguments);
  48. }
  49. }
  50.  
  51. }

Класът е прост и няма много нужда от обяснения - създава getRemapping метод за всички наследници, които трябва да го извикват след методът от родителския клас.

Второ - управление на изгледите:

Код
GeSHi (PHP):
  1. <?php
  2.  
  3. /**
  4.  * View context enabled Controller class
  5.  *
  6.  *
  7.  * @package ExtCI
  8.  * @subpackage Libraries
  9.  * @category Libraries
  10.  * @author VladSun
  11.  *
  12.  * @property string $requestedViewMode
  13.  * @property string $defaultViewMode
  14.  *
  15.  */
  16.  
  17. abstract class ViewContext_Controller extends Remap_Controller
  18. {
  19. protected $requestedViewMode = null;
  20. protected $defaultViewMode = 'json';
  21.  
  22. public function __construct()
  23. {
  24. parent::__construct();
  25. }
  26.  
  27. public function view($view, $data = null, $viewMode = null)
  28. {
  29. $this->load->view($this->getViewMode($viewMode).'/'.$view, $data);
  30. }
  31.  
  32. protected function setDefaultViewMode($viewMode)
  33. {
  34. $this->defaultViewMode = $viewMode;
  35. }
  36.  
  37. protected function getViewMode($viewMode = null)
  38. {
  39. if ($viewMode)
  40. return $viewMode;
  41.  
  42. if ($this->requestedViewMode)
  43. return $this->requestedViewMode;
  44.  
  45. if ($this->defaultViewMode)
  46. return $this->defaultViewMode;
  47.  
  48. return 'html';
  49. }
  50.  
  51. protected function getRemapping($method, $arguments)
  52. {
  53. $remapping = parent::getRemapping($method, $arguments);
  54.  
  55. $mv = explode('.', $remapping->method);
  56.  
  57. if (isset($mv[1]))
  58. {
  59. if (preg_match('#^[a-zA-Z]+$#',$mv[1]))
  60. $this->requestedViewMode = $mv[1];
  61. else
  62. throw new Exception ('Грешно зададен формат.');
  63. }
  64. else
  65. {
  66. $this->requestedViewMode = null;
  67. }
  68.  
  69. $remapping->method = $mv[0];
  70.  
  71. return $remapping;
  72. }
  73. }

Класът определя въз основа на URL-a, какъв изглед трябва да се зареди. Прим. ако е изивкан http://example.com/user/get.html ще се зареди изглед с HTML формат. Ако е извикан http://example.com/user/get.pdf ще се зареди PDF формата. Това става с извикването на методa view(), който зарежда изгледа от директорията съответстваща на разширението. Прим.:

http://example.com/user/get.html => $this->view('user/get') => /html/user/get.php

Създаваме абстрактен клас за контрол на достъпа (и документиране на действията):

Код
GeSHi (PHP):
  1. /**
  2.  * Authenthification check enabled Controller class
  3.  *
  4.  * Checks for proper authenthification if $noRoleCheck is false.
  5.  *
  6.  * @package ExtCI
  7.  * @subpackage Libraries
  8.  * @category Libraries
  9.  * @author VladSun
  10.  *
  11.  * @property bool $permissionCheckRequired
  12.  * @property bool $loggingRequired
  13.  *
  14.  */
  15.  
  16. abstract class BaseAuth_Controller extends ViewContext_Controller
  17. {
  18. const WITHOUT_PERMISSION_CHECK = false;
  19. const WITH_PERMISSION_CHECK = true;
  20. const WITHOUT_LOGGING = false;
  21. const WITH_LOGGING = true;
  22.  
  23. private $loggingRequired = true;
  24. private $permissionCheckRequired = true;
  25.  
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. }
  30.  
  31. protected function suspendLogging()
  32. {
  33. $this->loggingRequired = false;
  34. }
  35.  
  36. protected function resumeLogging()
  37. {
  38. $this->loggingRequired = true;
  39. }
  40.  
  41. protected function suspendPermissionCheck()
  42. {
  43. $this->permissionCheckRequired = false;
  44. }
  45.  
  46. protected function resumePermissionCheck()
  47. {
  48. $this->permissionCheckRequired = true;
  49. }
  50.  
  51. protected function getRemapping($method, $arguments)
  52. {
  53. $remapping = parent::getRemapping($method, $arguments);
  54.  
  55. if (!$this->isPertmitted($remapping->method, $remapping->arguments))
  56. {
  57. $remapping->arguments = array($remapping->method, $remapping->arguments);
  58. $remapping->method = 'notPermitted';
  59. }
  60.  
  61. return $remapping;
  62. }
  63.  
  64. protected function postRemap($method, $arguments)
  65. {
  66. if ($this->loggingRequired)
  67. {
  68. $this->prepareToLog($method, $arguments);
  69. }
  70. }
  71.  
  72. protected function hasPermission($method, $arguments)
  73. {
  74. return false;
  75. }
  76.  
  77. protected function notPermitted($method, $arguments)
  78. {
  79. exit();
  80. }
  81.  
  82. private function prepareToLog($method, $data)
  83. {
  84. $this->log(get_class($this), $method, $data);
  85. }
  86.  
  87. protected function log($module, $action, $data)
  88. {
  89. }
  90.  
  91. private function isPertmitted($method, $arguments)
  92. {
  93. if ($this->permissionCheckRequired === self::WITHOUT_PERMISSION_CHECK)
  94. return true;
  95.  
  96. return $this->hasPermission($method, $arguments);
  97. }
  98. }

За простота ще покажа класовете необходими за една единствена роля (т.е. идентифициран и неидентифициран потребител):

Код
GeSHi (PHP):
  1. <?php
  2.  
  3. /**
  4.  * Authenthification check enabled Controller class
  5.  *
  6.  * Checks for proper authenthification if $noRoleCheck is false.
  7.  *
  8.  * @package ExtCI
  9.  * @subpackage Libraries
  10.  * @category Libraries
  11.  * @author VladSun
  12.  *
  13.  * @property CurrentUser_Model $currentUser
  14.  * @property Logger_Model $logger
  15.  *
  16.  */
  17.  
  18. abstract class Auth_Controller extends BaseAuth_Controller
  19. {
  20. function __construct()
  21. {
  22. parent::__construct();
  23. $this->load->model('application/CurrentUser_Model', 'currentUser');
  24. $this->load->model('application/Logger_Model', 'logger');
  25.  
  26. $this->logger->setCurrentUser($this->currentUser);
  27. }
  28.  
  29. protected function hasPermission($method, $arguments)
  30. {
  31. return $this->currentUser->isLogged;
  32. }
  33.  
  34. protected function notPermitted($method, $arguments)
  35. {
  36. Error::register('Не сте автентифицирали пред системата.');
  37. $this->view('error/notLogged');
  38. }
  39.  
  40. protected function log($module, $action, $data)
  41. {
  42. if (!$data)
  43. $data = array();
  44. elseif (!is_array($data))
  45. $data = array($data);
  46.  
  47. $this->logger->log($module, $action, array_merge($data, $_POST));
  48. }
  49. }

Моделът за текущия потребител:
Код
GeSHi (PHP):
  1. class CurrentUser_Model extends Model
  2. {
  3. public $isLogged = false;
  4. public $userRecord = null;
  5.  
  6. public function __construct()
  7. {
  8. parent::__construct();
  9.  
  10. $this->isLogged = empty($_SESSION) ? false : (empty($_SESSION['user_logged']) ? false : true);
  11.  
  12. if ($this->isLogged)
  13. {
  14. if (!$this->userRecord = Doctrine::getTable('RUser')->find($_SESSION['user_id']))
  15. {
  16. unset($_SESSION['user_id']);
  17. unset($_SESSION['user_logged']);
  18. $_SESSION = array();
  19. unset($this->userRecord);
  20. $this->userRecord = null;
  21. $this->isLogged = false;
  22. }
  23. }
  24. }
  25.  
  26. public function getId()
  27. {
  28. return $this->userRecord ? $this->userRecord->id : 0;
  29. }
  30.  
  31. public function getUsername()
  32. {
  33. return $this->userRecord ? $this->userRecord->username : null;
  34. }
  35.  
  36. public function doLogin()
  37. {
  38. $this->load->library('validation');
  39.  
  40. $rules = array();
  41. $fields = array();
  42.  
  43. $rules['user_name'] = "xss_clean|trim|required|min_length[3]|max_length[20]|htmlspecialchars";
  44. $rules['user_password'] = "xss_clean|trim|required|min_length[3]|max_length[20]|htmlspecialchars";
  45. $this->validation->set_rules($rules);
  46.  
  47. $fields['user_name'] = 'Потребител';
  48. $fields['user_password'] = 'Парола';
  49. $this->validation->set_fields($fields);
  50.  
  51. if ($this->isLogged)
  52. Error::register('Вече сте влезли в системата.');
  53. elseif ($this->validation->run() == false)
  54. Error::register($this->validation->error_string);
  55. elseif (!$this->login($this->validation))
  56. Error::register('Грешни потребителско име и/или парола.');
  57. else
  58. {
  59. $this->isLogged = true;
  60. $_SESSION['user_id'] = $this->userRecord->id;
  61. $_SESSION['user_logged'] = true;
  62. }
  63. }
  64.  
  65. public function doLogout()
  66. {
  67. unset($_SESSION['user_id']);
  68. unset($_SESSION['user_logged']);
  69. $_SESSION = array();
  70.  
  71. $this->isLogged = false;
  72. }
  73.  
  74. protected function login($data)
  75. {
  76. $this->userRecord = Doctrine::getTable('RUser')->findOneByUsername($data->user_name);
  77.  
  78. if ($this->userRecord)
  79. {
  80. return ($this->userRecord->userpass === $data->userpass && $this->userRecord->active);
  81. }
  82. return false;
  83. }
  84.  
  85. }


Моделът за документиране:
Код
GeSHi (PHP):
  1. <?php
  2.  
  3. class Logger_Model extends Model
  4. {
  5. private $currentUserModel = null;
  6.  
  7. public function __construct()
  8. {
  9. parent::__construct();
  10. }
  11.  
  12. public function setCurrentUser($currentUser)
  13. {
  14. $this->currentUserModel = $currentUser;
  15. }
  16.  
  17. public function log($module, $action, $data)
  18. {
  19. $record = new RAdministratorLog();
  20.  
  21. $record->FK_user_id = $this->currentUserModel->getId();
  22.  
  23. if (!$record->FK_user_id)
  24. return;
  25.  
  26. $record->module = $module;
  27. $record->action = $action;
  28. $record->data = json_encode($data);
  29.  
  30. $record->save();
  31. }
  32.  
  33. }

Изполвал съм Doctrine за ORM и DAL. По ваш избор можете да замените съответния кода за работа с ДБ.

Контролерът за login/logout:

Код
GeSHi (PHP):
  1. <?php
  2.  
  3. class CurrentUser extends Auth_Controller
  4. {
  5. function __construct()
  6. {
  7. parent::__construct();
  8.  
  9. $this->suspendPermissionCheck();
  10. }
  11.  
  12. public function login()
  13. {
  14. $this->currentUser->doLogin();
  15. $this->view('currentUser/login');
  16. }
  17.  
  18. public function logout()
  19. {
  20. $this->currentUser->doLogout();
  21. $this->view('currentUser/logout');
  22. }
  23. }
  24.  

Всеки друг Контролер, изискващ идентификация трябва да е наследник на Auth_Controller.

Вижда се, че използвам статичен Error клас за съхраняване на съобщенията за грешки - пак променяйте по ваш избор.
8  Програмиране / Web development / [РЕШЕНИЕ] Debian/Ubuntu и session garbage collector -: Aug 11, 2010, 13:56
Цитат
Message: session_start() [<a href='function.session-start'>function.session-start</a>]: ps_files_cleanup_dir: opendir(/var/lib/php5) failed: Permission denied (13) ...

Доста досадна грешка (заедно с това, че гърмях и с друга грешка след като прихващах този Exception) ...

Оправя се с редактирането на php.ini :

Код:
session.gc_probability = 0

Защо - http://somethingemporium.com/2007/06/obscure-error-with-php5-on-debian-ubuntu-session-phpini-garbage
9  Програмиране / Web development / [MVC] Старт с CodeIgniter -: Mar 18, 2010, 00:07
Както предложих в една друга тема, всеки потребител на PHP MVC framework да създаде и/или участва в тема за любимата му framework (? сносен превод).

Аз ще предложа CodeIgniter (CI), тъй като е най-лесна за работа (което не значи, че е най-добра, но за начало е)

Инсталация:
1) сваляме текущата версия на CI - http://codeigniter.com/download.php;
2) разархивираме в директория извън web root (прим. /var/www/library/ci);
3) преместваме поддиректорията application в избрана от нас директория извън web root (прим. /var/www/htdocs/mysite/application);
3) копираме index.php в web root (прим. /var/www/htdocs/mysite/www.mysite) - това е вашият Front Controller;
4) съответно редактираме index.php:
    * $system_folder = "/var/www/library/ci";
    * $application_folder = "/var/www/htdocs/mysite/application";

5) създаваме /var/www/htdocs/mysite/cache и я правиме writable за Apache потребителя;
6) редактираме /var/www/htdocs/mysite/application/config/database.php според настройките за достъп до нашата ДБ и задаваме $db['default']['cachedir'] да е /var/www/htdocs/mysite/cache;
7) редактираме /var/www/htdocs/mysite/application/config/config.php:
domain - нашият домейн, index_page= "", encryption_key= въведете нещо дълго и трудно за разгадаване;
8) в web root директорията създайте .htaccess файл със следното съдържание:

Код:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

това ще ви осигури правилно разпознаване на http://mysite.com/modulе/action/data1/data2/data3..., като http://mysite.com/index.php/modulе/action/data1/data2/data3

Е, вече имате работеща версия на CI - имате създаден един Action Controller-a (по подразбиране) - в  /var/www/htdocs/mysite/application/controllers

Структурата на директорията /var/www/htdocs/mysite/application е ясна ... тук трябва да създавате вашите контролери, модели, изгледи и др.
10  Програмиране / Конкурс bash-майсторът / [PHP] Условности 2 -: Mar 17, 2010, 14:14
Тъй като е свързано с темата, мисля да ви "погъделичкам" още малко ...

Задачка: Без да изпълнявате скрипта в PHP, какъв мислите ще е изходът от този скрипт:

Код
GeSHi (PHP):
  1. function foo($v)
  2. {
  3.    echo $v ? 'true ' : 'false ';
  4.    return !$v;
  5. }
  6.  
  7. function bar($v)
  8. {
  9.    echo !$v ? 'true ' : 'false ';
  10.    return $v;
  11. }
  12.  
  13. $v = true;
  14. echo ($v = foo($v) or bar($v)) ?  'true ' : 'false ';

 >:D >:D >:D
11  Програмиране / Web development / [ExtJS] "Централизирани" събития -: Mar 17, 2010, 13:03
Да споделя опит - трябваше ми прихващане на определени събития на *всички* инстанции на определен клас. Същото нещо е описано в http://www.extjs.com/deploy/dev/docs/output/Ext.data.DataProxy.html:

Цитат
And new in Ext version 3, attach centralized event-listeners upon the DataProxy class itself! This is a great place to implement a messaging system to centralize your application's user-feedback and error-handling.
// Listen to all "beforewrite" event fired by all proxies.

Ext.data.DataProxy.on('beforewrite', function(proxy, action) {
    console.log('beforewrite: ', action);
});

Ето как се решава този проблем:
Код
GeSHi (Javascript):
  1. Ext.namespace('Ext.App');
  2.  
  3. Ext.App.Module = function (config)
  4. {
  5. this.addEvents
  6. (
  7. 'beforeConfigure',
  8. 'afterConfigure'
  9. );
  10.  
  11. Ext.App.Module.superclass.constructor.call(this, config);
  12. Ext.App.Module.relayEvents(this, ['beforeConfigure', 'afterConfigure']);
  13. }
  14.  
  15. Ext.extend(Ext.App.Module, Ext.util.Observable,
  16. {
  17. initModule : function ()
  18. {
  19. this.fireEvent('beforeConfigure', this);
  20. // ... configure Module
  21. this.fireEvent('afterConfigure', this);
  22. }
  23. });
  24.  
  25. Ext.apply(Ext.App.Module, Ext.util.Observable.prototype);
  26. Ext.util.Observable.call(Ext.App.Module);
12  Програмиране / Web development / [MVC] Основни положения -: Mar 17, 2010, 12:06
За прочит http://bg.wikipedia.org/wiki/Model-View-Controller

Ще се опитам да дам и аз мое тълкуване на MVC архитектурата:

* Модел - съдържа единствено и цялата "бизнес" логика - "вътрешното" състояние на системата. Моделът не се интересува от това как е представен (т.е. неговите данни и вътрешно състояние) пред потребителя (който може да е и друг софтуер, не е задължително човек). Моделът също така не се интересува от къде идват новите данни и команди за промяна на състоянието му. Моделът се грижи за съхраняването и извличането на данните (ДБ, файлове и т.н.) ;

* Изглед - всеки един от тези компоненти има достъп до всички публични данни и методи на Модела и определя кои от тях и как да бъдат изобразени;

* Контролер - всеки един от тези компоненти има достъп до всички публични данни и методи на Модела. Контролерът също така определя какво е действието предприето от потребителя и какви са новите данни предоставени от потребителя. В зависимост от исканото действие, Контролерът извиква определена команда и/или променя определени данни на Модела. Контролерът също така решава кой Изглед ще се използва за визуализирането на Модела.

Цитат
Защо се прави всичко това? Ще се опитам да изясня чрез пример:

Искаме да направим софтуер за прост калкулатор - да може да вади, събира, умножава и дели числа. Създаваме web вариант на този софтуер. Ако сме следвали MVC архитектурата, то ще можем:

* да променим форматът на резултата (прим. в PDF) само чрез добавяне на нов компонент за Изглед - без да променяме нищо друго.
* да създадем CLI вариант като само променим компонентите за Контролер/Изглед.

Т.е. Моделът не се променя никога, което е от особена важност в реалните случаи, когато Моделът може да бъде изключително сложен.

Съществува така наречения Front Controller - това е специален Контролер, който осигурява една единствена входна точка (представете си main() в C ) за целия софтуер. Front Controller-а определя кой Action Controller трябва да се извика и да му се предадат входните данни. Action Controller са Контролерите, които вие ще трябва да пишете и те ще се грижат за описаните в горната дефиниция действия.

Добре е Моделът да бъде напълно капсулиран - т.е. да няма възможност за пряко модифициране или четене на данните му. Това се постига чрез използването на данни с ограничен достъп (protected/private) и публични методи за тяхното модифициране/четене.
13  Програмиране / Web development / [MVC] Frameworks -: Mar 16, 2010, 20:13
Отварям нарочна тема за използването на MVC архитектура и съществуващите PHP MVC frameworks:

* http://en.wikipedia.org/wiki/Model–view–controller

* http://framework.zend.com/
* http://cakephp.org/
* http://codeigniter.com/
* http://www.symfony-project.org/

Линкове свързани с MVC атхитектурата са добре дошли.
Линкове към други open source MVC frameworks са добре дошли (дори да не са PHP базирани).

Темеата е за дискусия относно MVC архитектурата и популяризирането й.
14  Програмиране / Web development / ExtJS -: Mar 16, 2010, 20:07
Отварям нарочна тема за ExtJS javascript framewrok, която да даде тласък на ползването й в нашата общност. Давам няколко линка към демонстрационни продукта и за разширения на ExtJS за да добиете представа за възможностите й:

* http://www.extjs.com/deploy/dev/examples/
* http://www.extjs.com/deploy/dev/examples/desktop/desktop.html
* http://extjs.eu/docs/ (за почти всеки компонент има Demo link)

Бих участвал във всяка тема свързана с ExtJS.
15  Програмиране / Конкурс bash-майсторът / [PHP] Условности -: Mar 09, 2010, 22:17
Задачка:

Напишете PHP скрипт, който да изобразява (т.е. echo)  следните стойности за Z в зависимост от стойностите на X и Y:

* ако X е по-малко от 1, то Z = 0;
* ако X е между (вкл.) 1 и 23, то Z = X + Y;
* ако X е между (вкл.) 24 и 59, то Z = X + 23;
* ако X е по-голямо от 59, то Z = X + 59.


Уловката е следната ;) :

* "if" не може да се използва повече от 2 пъти;
* "{" не може да се използва повече от 1 път;
* "else" не може да се използва изобщо;
* "?" не може да се използва изобщо;
* "eval" не може да се използва изобщо;
* "switch" не може да се използва изобщо.

Успех!
Страници: [1] 2 3 ... 7