diff --git a/README.md b/README.md index 20fc24f..5c608a1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,104 @@ -# EwoMail -EwoMail邮件服务器软件 +### 1.05更新内容 + + +1、兼容centos7 + + 将部分主要的组件重新打包,测试,并且兼容centos6和centos7。 + +2、新加nginx + + 默认绑定80端口,需手动启动。 + +3、新加php-fpm + + 可以利用nginx配置php-fpm或apache,php-fpm默认端口9000,需手动启动。 + +4、apache + + 取消apache绑定的80端口,邮箱管理后台与webmail保留端口,保持原来的apache运行。 + +### EwoMail开源邮件服务器软件 + + +EwoMail是基于Linux的开源邮件服务器软件,集成了众多优秀稳定的组件,是一个快速部署、简单高效、多语言、安全稳定的邮件解决方案,帮助你提升运维效率,降低 IT 成本,兼容主流的邮件客户端,同时支持电脑和手机邮件客户端。 + +### 集成组件 + + +Postfix:邮件服务器 + +Dovecot:IMAP/POP3/邮件存储 + +Amavisd:反垃圾和反病毒 + +fail2ban:监控策略 + +LNAMP:apache2.2,nginx1.8,mysql5.5,php5.4 + +EwoMail-Admin:WEB邮箱管理后台 + +Rainloop:webmail + +### 安装环境 + +centos6/7系统,服务器需要干净环境,最好是全新安装的系统。 + +最低配置要求 + +CPU:1核 + +内存:1G + +硬盘:40G + +### 检查swap + +安装前需要swap缓存,请务必先检查swap是否已经启动。 + +### 手动安装 + +下载并重新命名为ewomail.zip + + +``` +解压安装 +unzip -o ewomail.zip +cd EwoMail/install +#需要输入一个邮箱域名,不需要前缀,列如下面的ewomail.cn +sh ./start.sh ewomail.cn +``` + +### 文档教程 + +在线安装、配置等等的更多详细教程请查看 + +[EwoMail在线文档](http://doc.ewomail.com/ewomail) + +### EwoMail-Admin + +EwoMail-Admin是一个多语言邮箱管理后台,用PHP语言开发,开源免费。 + +自主原生开发,没有采用第三方框架,简单高效、易二次开发。 + +需要搭配EwoMail邮件服务器软件使用。 + +环境要求:PHP5.4+,MYSQL5.5+ + +EwoMail-Admin集成了前端框架、后台敏捷开发框架,利用这些框架可以很容易的进行二次开发,定制化功能来满足你的邮件服务器更多需求。 + + **主要功能** + +1、权限管理(管理员权限分配) +2、邮箱管理 +3、邮箱域名管理 +4、多语言 + +[EwoMail-Admin开发教程](http://doc.ewomail.com/ewomail-admin) + +![ewomail-admin](https://box.kancloud.cn/c362878ba731559b09eae36b7236bde5_1366x609.png "ewomail-admin") + +### webmail + +![webmail](https://box.kancloud.cn/3de1da2809f14048fb4cb3b32d0408d1_1183x476.png "webmail") + +官方群:458861632 \ No newline at end of file diff --git a/ewomail-admin/.htaccess b/ewomail-admin/.htaccess new file mode 100644 index 0000000..2406140 --- /dev/null +++ b/ewomail-admin/.htaccess @@ -0,0 +1,11 @@ + + +RewriteEngine on + +RewriteCond %{REQUEST_FILENAME} !-d + +RewriteCond %{REQUEST_FILENAME} !-f + +RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L] + + \ No newline at end of file diff --git a/ewomail-admin/api/Admin.class.php b/ewomail-admin/api/Admin.class.php new file mode 100644 index 0000000..ad1a331 --- /dev/null +++ b/ewomail-admin/api/Admin.class.php @@ -0,0 +1,365 @@ + +// +---------------------------------------------------------------------- +/** + * 管理员操作类 + * Class Admin + */ +class Admin extends App +{ + //管理员登陆ID + public static $aid; + + //管理员登陆信息 + public static $info; + + /** + * 获取管理员一条信息 + * @param $id + * @return mixed + */ + public function getOne($id) + { + $data = App::$db->getOne("select * from ".table('admin')." where aid=".$id); + if(!$data){ + E::error(1005); + } + return $data; + } + + /** + * 设置导航菜单和权限 + * $menu_id 菜单id + * $title 替换当前标题 + * */ + public static function setMenu($menu_id,$title='') + { + $auth = []; + $admin = new Admin(); + $adminData = $admin->getOne(self::$aid); + if($adminData['gid'] && !$adminData['super']){ + //获取管理员数据 + $groupData = App::$db->getOne("select * from ".table('admin_group')." where gid=".$adminData['gid']); + $auth = unserialize($groupData['auth']); + } + + //访问权限检查 + if($menu_id && !$adminData['super']){ + $menuRow = App::$db->getOne("select * from ".table('admin_menu')." where menu_id=$menu_id"); + if(!$menuRow){ + //菜单栏目数据不存在 + E::sys(1112); + } + + $m_id = $menuRow['edit_id']?$menuRow['edit_id']:$menu_id; + if(Rout::$method=='get'){ + if(!$auth[$m_id]['view']){ + E::error(1004); + } + }else if(Rout::$method=='put'){ + if(!$auth[$m_id]['edit']){ + E::error(1004); + } + }else if(Rout::$method=='delete'){ + if(!$auth[$m_id]['del']){ + E::error(1004); + } + }else{ + E::error(1004); + } + } + + + $bar = ''; + $menu = App::$db->select("select * from ".table("admin_menu")." where top_id=0 order by menu_id asc,sort desc"); + foreach($menu as $k=>$v){ + $v['title'] = L($v['lang']); + $data = App::$db->select("select * from ".table("admin_menu")." where top_id=$v[menu_id] order by menu_id asc,sort desc"); + foreach($data as $kk=>$d){ + //菜单按照权限显示 + if(!$adminData['super']){ + if($d['edit_id']){ + if(!$auth[$d['edit_id']]['edit']){ + unset($data[$kk]); + continue; + } + }else if(!$auth[$d['menu_id']]['view']){ + unset($data[$kk]); + continue; + } + } + $d['title'] = L($d['lang']); + if($d['menu_id']==$menu_id){ + //当前匹配的菜单 + $title = $title?$title:$d['title']; + $bar = ''.$v['title'].''.$title.''; + $data[$kk]['sd'] = true; + $menu[$k]['sd'] = true; + } + $data[$kk]['title'] = $d['title']; + + } + $menu[$k]['title'] = $v['title']; + $menu[$k]['child'] = $data; + + } + + if(!$bar){ + $bar = ''.$title.''; + } + + $arr = [ + 'admin_menu'=>$menu, + 'admin_bar'=>$bar, + ]; + Tp::assign($arr); + + } + + /** + * 管理员添加/修改 + * @param array $data + * @param int $id + * @return int + */ + public function save($data=[],$id=0) + { + istatic($data); + $username = strtolower(ipost('username')); + $name = ipost('name'); + $gid = intval(ipost('gid')); + $super = intval(ipost('super')); + $active = intval(ipost('active')); + $password = ipost('password'); + $password2 = ipost('password2'); + $is_password = intval(ipost('is_password')); + $is_webmail = intval(ipost('is_webmail')); + istatic([]); + + if(!$id){ + if(strlen($username)<3 || strlen($username)>15){ + //账号格式错误 + E::error(2019); + } + if(!preg_match("/[a-z0-9_]+$/i",$username)) { + E::error(2019); + } + } + + + //修改资料时检查是否修改密码 + if(!$id || ($id && $is_password)){ + User::checkPassword($password,$password2); + } + + if($id){ + $row = $this->getOne($id); + $username = $row['username']; + //更新数据 + $newData = [ + 'name'=>$name, + 'gid'=>$gid, + 'super'=>$super, + 'is_webmail'=>$is_webmail, + 'active'=>$active + ]; + if($is_password){ + $newData['password'] = md5($password); + } + App::$db->update("admin",$newData,"aid=$id"); + }else{ + //新加数据 + $date = new Date(); + if(App::$db->getOne("select aid from ".table("admin")." where username='$username'")){ + E::error(2022); + } + $newData = [ + 'username'=>$username, + 'name'=>$name, + 'password'=>md5($password), + 'gid'=>$gid, + 'super'=>$super, + 'is_webmail'=>$is_webmail, + 'active'=>$active, + 'ctime'=>$date->format() + ]; + $id = App::$db->insert("admin",$newData); + } + + $logData = [ + 'ac'=>$id?'edit':'add', + 'c'=>'管理员账号:'.$username + ]; + AdminLog::save($logData); + + return $id; + } + + /** + * 更新管理员资料 + * */ + public function updateInfo($data=[]) + { + istatic($data); + $name = ipost('name'); + $password = ipost('password'); + $new_password = ipost('new_password'); + $new_password2 = ipost('new_password2'); + $is_password = ipost('is_password'); + istatic([]); + + if(md5($password)!=self::$info['password']){ + E::error(2030); + } + + if($is_password){ + User::checkPassword($new_password,$new_password2); + } + + $newData = [ + 'name'=>$name, + 'password'=>md5($new_password) + ]; + App::$db->update("admin",$newData,"aid=".self::$aid); + } + + /** + * 删除管理员 + * @param $id + */ + public function delete($id) + { + $row = $this->getOne($id); + if($row['username']=='admin'){ + E::error(2036); + } + $where = "aid=$id"; + App::$db->delete("admin",$where); + $logData = [ + 'ac'=>'del', + 'c'=>'管理员账号:'.$row['username'] + ]; + AdminLog::save($logData); + } + + /** + * 管理员登录 + */ + public function login() + { + $username = strtolower(ipost('username')); + $password = ipost('password'); + $captcha = ipost('captcha'); + + if(!$username){ + E::error(L(1107).L(2008)); + } + if(!$password){ + E::error(L(1107).L(2016)); + } + if(!$captcha){ + E::error(L(1107).L(1211)); + } + + $simpleCaptcha = new SimpleCaptcha(); + if(!$simpleCaptcha->isCode($captcha)){ + //验证码错误 + E::error(L(1211).L(1207)); + } + + $row = App::$db->getOne("select * from ".table("admin")." where username='$username'"); + if(!$row){ + E::error(2024); + } + + if(!$row['active']){ + E::error(2041); + } + + $this->checkLoginIp($username,0); + + if($row['password']!=md5($password)){ + $this->checkLoginIp($username,1); + E::error(2025); + } + $this->checkLoginIp($username,2); + + $arr = [ + 'username'=>$row['username'], + 'aid'=>$row['aid'] + ]; + Session::set("loginInfo",$arr); + + $logData = [ + 'ac'=>'login', + 'c'=>'登录账号:'.$username + ]; + AdminLog::save($logData); + } + + /** + * 检查登录IP,密码错误次数超出5次并禁止在一个小时内登录 + * @param $username + * @param int $level 0:检查IP登录 1:写入登录失败次数 2:登录成功后删除缓存文件 + */ + public function checkLoginIp($username,$level=0) + { + $cache_dir = PATH.'/cache/login'; + $username_dir = $cache_dir.'/'.$username; + $ip = get_client_ip(); + $file = $username_dir.'/'.$ip.'.log'; + + static $data = []; + if(!$data){ + //读取与创建缓存文件 + if(!file_exists($username_dir)){ + mkdir($username_dir); + } + if(!file_exists($file)){ + $data = [ + 'ip'=>$ip, + 'num'=>0,//失败次数 + 'time'=>App::$format,//时间 + ]; + }else{ + $data = file_get_contents($file); + $data = unserialize($data); + } + } + + + if($level==0){ + //检查是否禁止登录,失败次数超过5次,一个小时内不能登录 + if($data['num']>=5){ + $cur_time = time(); + $date = new Date(); + $dtime = $date->parse($data['time'])-3600; + if($dtime<$cur_time){ + $logData = [ + 'ac'=>'login', + 'c'=>'登录失败次数超过5次,禁止该IP一个小时内登录该账号:'.$username + ]; + AdminLog::save($logData); + E::error(2042); + } + } + }elseif($level==1){ + //统计登录失败次数 + $data['num']++; + $data['time'] = App::$format; + $data = serialize($data); + file_put_contents($file,$data); + }elseif($level==2){ + //登录成功,删除文件 + @unlink($file); + } + } +} +?> \ No newline at end of file diff --git a/ewomail-admin/api/AdminLog.class.php b/ewomail-admin/api/AdminLog.class.php new file mode 100644 index 0000000..4f286d1 --- /dev/null +++ b/ewomail-admin/api/AdminLog.class.php @@ -0,0 +1,45 @@ + +// +---------------------------------------------------------------------- +/** + * 管理员日志操作类 + * */ +class AdminLog extends App +{ + + private static $ac = [ + 'login'=>'登陆', + 'add'=>'添加', + 'edit'=>'修改', + 'del'=>'删除' + ]; + + public static function save($data) + { + + $ac = $data['ac'];//操作 + $c = $data['c'];//内容 + $ac_str = ""; + if($ac){ + $ac_str = "[操作:".self::$ac[$ac]."]"; + } + + $explain = $ac_str.$c; + + $newData = [ + 'ip'=>get_client_ip(), + 'username'=>Admin::$info['username'], + 'explain'=>$explain, + 'ctime'=>self::$format, + ]; + + $id = App::$db->insert("admin_log",$newData); + } +} \ No newline at end of file diff --git a/ewomail-admin/api/App.class.php b/ewomail-admin/api/App.class.php new file mode 100644 index 0000000..3af1db2 --- /dev/null +++ b/ewomail-admin/api/App.class.php @@ -0,0 +1,121 @@ + +// +---------------------------------------------------------------------- +/** + * 基础类 + * Class App + */ +class App +{ + /** + * 数据库变量 + * @var Db + */ + public static $db; + + //当前的格式化时间 + public static $format; + + + //指定管理员id,只用在类的继承 + public $admin_id = 0; + + //版本号 + public static $version = ''; + + + public function __construct() + { + + } + + /** + * 程序初始化(包含语言包加载、数据库链接、常用变量初始化定义) + */ + public static function init() + { + //数据库链接 + self::$db = new Db(); + self::$db->connect(C('dbhost'),C('dbuser'),C('dbpw'),C('dbname'),C('dbcharset')); + + //设置当前时间变量 + $date = new Date(); + self::$format = $date->format(); + + //当前语言 + $lang = Cookie::get('lang'); + if(!$lang){ + $lang = SystemConfig::get('lang'); + } + + //语言包路径 + $langPath = PATH."/lang/$lang.php"; + //加载语言包 + if(!file_exists($langPath)){ + Cookie::set('lang',''); + E::sys('语言包不存在,'.$langPath); + } + $L = L('',$langPath); + $langData = SystemConfig::getLang(); + + //版本号 + self::$version = @file_get_contents(PATH.'/core/version'); + + //将一些常用变量注入到模板变量 + $arr = [ + 'L'=>$L,//当前加载的语言包变量 + 'L_ALL'=>SystemConfig::getLang(),//语言包配置的国家语言种类 + 'LANG'=>$lang,//当前国家语言编号 + 'LANG_NAME'=>$langData[$lang],//当前国家语言名称 + 'WEB_TITLE'=>SystemConfig::get('title'),//网站标题 + 'WEB_COPYRIGHT'=>SystemConfig::get('copyright'),//网站授权信息 + 'WEB_ICP'=>SystemConfig::get('icp'),//网站icp信息 + ]; + + Tp::assign($arr); + } + + /** + * 检查是否已登陆 + * */ + public static function checkLogin() + { + $loginInfo = Session::get('loginInfo'); + //跳过Index控制器的登陆检查 + if(MODULE!='Index' && !$loginInfo){ + header("Location:/Index/login"); + exit; + } + Admin::$aid = $loginInfo['aid']; + } + + /** + * 设置登陆信息 + * */ + public static function setLoginInfo() + { + if(Admin::$aid){ + $admin = new Admin(); + $adminData = $admin->getOne(Admin::$aid); + if($adminData['super']){ + $adminData['type_title'] = L(2013); + }else{ + $adminData['type_title'] = L(2012); + } + Admin::$info = $adminData; + $arr = [ + 'adminData'=>$adminData + ]; + Tp::assign($arr); + } + } + +} +?> \ No newline at end of file diff --git a/ewomail-admin/api/Domains.class.php b/ewomail-admin/api/Domains.class.php new file mode 100644 index 0000000..9e34c4b --- /dev/null +++ b/ewomail-admin/api/Domains.class.php @@ -0,0 +1,111 @@ + +// +---------------------------------------------------------------------- +/** + * 邮件域名操作类 + * Class Domains + */ +class Domains extends App +{ + /** + * 获取一条数据 + * @param $id + * @return mixed + */ + public function getOne($id) + { + $data = App::$db->getOne("select * from ".table('domains')." where id=".$id); + if(!$data){ + E::error(1005); + } + return $data; + } + + /** + * 添加/修改 + * @param array $data + * @param int $id + */ + public function save($data=[],$id=0) + { + istatic($data); + $name = strtolower(ipost('name')); + $active = intval(ipost('active')); + $s_num = intval(ipost('s_num')); + $c_num = intval(ipost('c_num')); + $c_ip = intval(ipost('c_ip')); + $g = intval(ipost('g')); + $g_boundary = intval(ipost('g_boundary')); + istatic([]); + + if($id){ + $row = App::$db->getOne("select * from ".table("domains")." where id=$id"); + if(!$row) E::error(1005); + $name = $row['name']; + $newData = [ + 'active'=>$active, + 's_num'=>$s_num, + 'c_num'=>$c_num, + 'c_ip'=>$c_ip, + 'g_boundary'=>$g_boundary, + 'g'=>$g + ]; + App::$db->update("domains",$newData,"id=$id"); + }else{ + + if(!check_domain($name)){ + E::error(3010); + } + + if(App::$db->count("select count(id) from ".table("domains")." where name='$name'")){ + E::error(3011); + } + + $newData = [ + 'name'=>$name, + 'active'=>$active, + 's_num'=>$s_num, + 'c_num'=>$c_num, + 'c_ip'=>$c_ip, + 'g'=>$g, + 'g_boundary'=>$g_boundary, + 'ctime'=>App::$format + ]; + + $r = App::$db->insert('domains',$newData); + } + + $logData = [ + 'ac'=>$id?'edit':'add', + 'c'=>'邮件域名:'.$name + ]; + AdminLog::save($logData); + + } + + /** + * 删除 + * @param $id + */ + public function delete($id) + { + $row = $this->getOne($id); + $where = "id=$id"; + App::$db->delete("domains",$where); + + $logData = [ + 'ac'=>'del', + 'c'=>'邮件域名:'.$row['name'] + ]; + AdminLog::save($logData); + } + +} +?> \ No newline at end of file diff --git a/ewomail-admin/api/Http.class.php b/ewomail-admin/api/Http.class.php new file mode 100644 index 0000000..883de9a --- /dev/null +++ b/ewomail-admin/api/Http.class.php @@ -0,0 +1,45 @@ + +// +---------------------------------------------------------------------- +/** + * http远程操作类 + * Class Http + */ +class Http +{ + + //超时秒 + public static $out_time = 5; + + public function __construct($m) + { + + } + + /** + * post + * @param $url + * @param array $data + * @return mixed + */ + public static function post($url,$data=[]) + { + $con = curl_init(); + curl_setopt($con, CURLOPT_URL,$url); + curl_setopt($con, CURLOPT_HEADER, false); + curl_setopt($con, CURLOPT_POST,true); + curl_setopt($con, CURLOPT_RETURNTRANSFER,true); + curl_setopt($con, CURLOPT_TIMEOUT,self::$out_time); + curl_setopt($con, CURLOPT_POSTFIELDS, $data); + $r = curl_exec($con); + return $r; + } + +} \ No newline at end of file diff --git a/ewomail-admin/api/MailConfig.class.php b/ewomail-admin/api/MailConfig.class.php new file mode 100644 index 0000000..1bd43d2 --- /dev/null +++ b/ewomail-admin/api/MailConfig.class.php @@ -0,0 +1,56 @@ + +// +---------------------------------------------------------------------- +/** + * 邮件配置类 + * Class MailConfig + */ +class MailConfig extends App +{ + /** + * 获取一条配置数据 + * @param $name + * @return mixed + */ + public static function get($name) + { + $row = App::$db->getOne("select value from ".table("mail_config")." where name='$name'"); + return $row['value']; + } + + /** + * 保存数据 + * @param $data + */ + public function save($data) + { + foreach($data as $k=>$v){ + $newData = [ + 'value'=>$v + ]; + App::$db->update('mail_config',$newData,"name='$k'"); + } + } + + /** + * 获取全部数据 + * @return array + */ + public function getAll() + { + $data = App::$db->select("select * from ".table("mail_config")); + $newData = []; + foreach($data as $v){ + $newData[$v['name']] = $v['value']; + } + return $newData; + } + +} \ No newline at end of file diff --git a/ewomail-admin/api/SystemConfig.class.php b/ewomail-admin/api/SystemConfig.class.php new file mode 100644 index 0000000..e13d66b --- /dev/null +++ b/ewomail-admin/api/SystemConfig.class.php @@ -0,0 +1,74 @@ + +// +---------------------------------------------------------------------- +/** + * 系统配置类 + * Class SystemConfig + */ +class SystemConfig extends App +{ + /** + * 获取一条数据 + * @param $name + * @return mixed + */ + public static function get($name) + { + $row = App::$db->getOne("select value from ".table("system_config")." where name='$name'"); + return $row['value']; + } + + /** + * 获取当前配置语言 + * @return array|mixed + */ + public static function getLang() + { + static $r = []; + if(!$r){ + $r = include PATH.'/lang/config.php'; + } + return $r; + } + + /** + * 保存数据 + * @param $data + */ + public function save($data) + { + foreach($data as $k=>$v){ + $newData = [ + 'value'=>$v + ]; + App::$db->update('system_config',$newData,"name='$k'"); + } + $logData = [ + 'ac'=>'edit', + 'c'=>'系统设置' + ]; + AdminLog::save($logData); + } + + /** + * 获取全部数据 + * @return array + */ + public function getAll() + { + $data = App::$db->select("select * from ".table("system_config")); + $newData = []; + foreach($data as $v){ + $newData[$v['name']] = $v['value']; + } + return $newData; + } + +} \ No newline at end of file diff --git a/ewomail-admin/api/User.class.php b/ewomail-admin/api/User.class.php new file mode 100644 index 0000000..6150640 --- /dev/null +++ b/ewomail-admin/api/User.class.php @@ -0,0 +1,174 @@ + +// +---------------------------------------------------------------------- +/** + * 邮件用户操作类 + * Class User + */ +class User extends App +{ + /** + * 获取一条数据 + * @param $id + * @return mixed + */ + public function getOne($id) + { + $data = App::$db->getOne("select * from ".table('users')." where id=".$id); + if(!$data){ + E::error(1005); + } + return $data; + } + + /** + * 添加/修改数据 + * @param array $data + * @param int $id + */ + public function save($data=[],$id=0) + { + istatic($data); + $email = strtolower(ipost('email')); + $password = ipost('password'); + $password2 = ipost('password2'); + $is_password = intval(ipost('is_password')); + $active = intval(ipost('active')); + $limits = intval(ipost('limits')); + $limitg = intval(ipost('limitg')); + $uname = ipost('uname'); + $tel = ipost('tel'); + istatic([]); + + //修改资料时检查是否修改密码 + if(!$id || ($id && $is_password)){ + self::checkPassword($password,$password2); + } + + if($id){ + $row = $this->getOne($id); + if(!$row) E::error(1005); + $email = $row['email']; + $newData = [ + 'active'=>$active, + 'limits'=>$limits, + 'limitg'=>$limitg, + 'uname'=>$uname, + 'tel'=>$tel + ]; + + if($is_password){ + $newData['password'] = md5($password); + } + App::$db->update("users",$newData,"id=$id"); + }else{ + + if(!check_email($email)){ + E::error(L(1107).L(90103)); + } + + $arr = explode('@',$email); + $name = $arr[0]; + $domain = $arr[1]; + + if(strlen($name)<2){ + E::error(3074); + } + + + $domainRow = App::$db->getOne("select * from ".table("domains")." where name='$domain'"); + if(!$domainRow){ + E::error(3016); + } + + if(App::$db->count("select count(id) from ".table("users")." where email='$email'")){ + E::error(3017); + } + + $newData = [ + 'email'=>$email, + 'active'=>$active, + 'domain_id'=>$domainRow['id'], + 'password'=>md5($password), + 'limits'=>$limits, + 'limitg'=>$limitg, + 'uname'=>$uname, + 'tel'=>$tel, + 'maildir'=>$this->createMailDir($name,$domain), + 'ctime'=>App::$format, + ]; + App::$db->insert('users',$newData); + } + + $logData = [ + 'ac'=>$id?'edit':'add', + 'c'=>'邮件地址:'.$email + ]; + AdminLog::save($logData); + } + + /** + * 创建邮件地址路径 + * */ + public function createMailDir($name,$domain) + { + $str1 = substr($name,0,1); + $str2 = substr($name,1,1); + $str3 = substr($name,2,1); + if(!$str3){ + $str3 = $str2; + } + $date = new Date(); + $format = $date->format("%Y%m%d"); + $dir = C('maildir')."/vmail/$domain/$str1/$str2/$str3/$name.$format"; + return $dir; + } + + /** + * 删除数据 + * @param $id + */ + public function delete($id) + { + $row = $this->getOne($id); + $where = "id=$id"; + App::$db->delete("users",$where); + $logData = [ + 'ac'=>'del', + 'c'=>'邮件地址:'.$row['email'] + ]; + AdminLog::save($logData); + } + + /** + * 检查密码 + * @param $password + * @param $password2 + */ + public static function checkPassword($password,$password2) + { + if(strlen($password)<8 || strlen($password)>20){ + //密码字符数错误 + E::error(2020); + } + /* + if(!preg_match("/[a-z]+[0-9]+/i",$password)){ + //密码必须包含字母和数字 + E::error(2040); + } + */ + if($password!=$password2){ + //2个密码不一致 + E::error(2021); + } + } + +} +?> \ No newline at end of file diff --git a/ewomail-admin/cache/.htaccess b/ewomail-admin/cache/.htaccess new file mode 100644 index 0000000..c59c358 --- /dev/null +++ b/ewomail-admin/cache/.htaccess @@ -0,0 +1,4 @@ +Deny from all + +Options -Indexes + \ No newline at end of file diff --git a/ewomail-admin/cache/login/index.html b/ewomail-admin/cache/login/index.html new file mode 100644 index 0000000..e69de29 diff --git a/ewomail-admin/cache/templates/c/index.html b/ewomail-admin/cache/templates/c/index.html new file mode 100644 index 0000000..e69de29 diff --git a/ewomail-admin/core/class/Cookie.class.php b/ewomail-admin/core/class/Cookie.class.php new file mode 100644 index 0000000..26b1109 --- /dev/null +++ b/ewomail-admin/core/class/Cookie.class.php @@ -0,0 +1,59 @@ + +// +---------------------------------------------------------------------- +/** + * cookie类 + * */ +class Cookie{ + + /** + * 设置cookie值 + * @param $key + * @param string $value + * @param int $expire 过期时间,秒为单位 + */ + public static function set($key,$value='',$expire=0) + { + $key = C('prefix').$key; + if(!$value){ + setcookie($key,'',time()-3600,'/'); + }else{ + $value = json_encode($value); + $value = authcode($value,'ENCODE'); + setcookie($key,$value,time()+$expire,'/'); + } + + } + + /** + * 获取cookie值 + * @param $key + * @return mixed + */ + public static function get($key) + { + $key = C('prefix').$key; + $value = $_COOKIE[$key]; + if($value){ + $value = json_decode(authcode($value),true); + } + return $value; + } + + /** + * 清除所有cookie + */ + public static function clear() + { + $_COOKIE = null; + } + + +} \ No newline at end of file diff --git a/ewomail-admin/core/class/Date.class.php b/ewomail-admin/core/class/Date.class.php new file mode 100644 index 0000000..9c16060 --- /dev/null +++ b/ewomail-admin/core/class/Date.class.php @@ -0,0 +1,562 @@ + +// +---------------------------------------------------------------------- +/** + * 日期时间操作类 + */ +class Date { + + /** + * 日期的时间戳 + * @var integer + * @access protected + */ + protected $date; + + /** + * 时区 + * @var integer + * @access protected + */ + protected $timezone; + + /** + * 年 + * @var integer + * @access protected + */ + protected $year; + + /** + * 月 + * @var integer + * @access protected + */ + protected $month; + + /** + * 日 + * @var integer + * @access protected + */ + protected $day; + + /** + * 时 + * @var integer + * @access protected + */ + protected $hour; + + /** + * 分 + * @var integer + * @access protected + */ + protected $minute; + + /** + * 秒 + * @var integer + * @access protected + */ + protected $second; + + /** + * 星期的数字表示 + * @var integer + * @access protected + */ + protected $weekday; + + /** + * 星期的完整表示 + * @var string + * @access protected + */ + protected $cWeekday; + + /** + * 一年中的天数 0-365 + * @var integer + * @access protected + */ + protected $yDay; + + /** + * 月份的完整表示 + * @var string + * @access protected + */ + protected $cMonth; + + /** + * 日期CDATE表示 + * @var string + * @access protected + */ + protected $CDATE; + + /** + * 日期的YMD表示 + * @var string + * @access protected + */ + protected $YMD; + + /** + * 时间的输出表示 + * @var string + * @access protected + */ + protected $CTIME; + + // 星期的输出 + protected $Week = array("日","一","二","三","四","五","六"); + + /** + * 架构函数 + * 创建一个Date对象 + * @param mixed $date 日期 + * @static + * @access public + */ + public function __construct($date='') { + //分析日期 + $this->date = $this->parse($date); + $this->setDate($this->date); + } + + /** + * 日期分析 + * 返回时间戳 + * @static + * @access public + * @param mixed $date 日期 + * @return string + */ + public function parse($date) { + if (is_string($date)) { + if (($date == "") || strtotime($date) == -1) { + //为空默认取得当前时间戳 + $tmpdate = time(); + } else { + //把字符串转换成UNIX时间戳 + $tmpdate = strtotime($date); + } + } elseif (is_null($date)) { + //为空默认取得当前时间戳 + $tmpdate = time(); + + } elseif (is_numeric($date)) { + //数字格式直接转换为时间戳 + $tmpdate = $date; + + } else { + if (get_class($date) == "Date") { + //如果是Date对象 + $tmpdate = $date->date; + } else { + //默认取当前时间戳 + $tmpdate = time(); + } + } + return $tmpdate; + } + + /** + * 验证日期数据是否有效 + * @access public + * @param mixed $date 日期数据 + * @return string + */ + public function valid($date) { + + } + + /** + * 日期参数设置 + * @static + * @access public + * @param integer $date 日期时间戳 + * @return void + */ + public function setDate($date) { + $dateArray = getdate($date); + $this->date = $dateArray[0]; //时间戳 + $this->second = $dateArray["seconds"]; //秒 + $this->minute = $dateArray["minutes"]; //分 + $this->hour = $dateArray["hours"]; //时 + $this->day = $dateArray["mday"]; //日 + $this->month = $dateArray["mon"]; //月 + $this->year = $dateArray["year"]; //年 + + $this->weekday = $dateArray["wday"]; //星期 0~6 + $this->cWeekday = '星期'.$this->Week[$this->weekday];//$dateArray["weekday"]; //星期完整表示 + $this->yDay = $dateArray["yday"]; //一年中的天数 0-365 + $this->cMonth = $dateArray["month"]; //月份的完整表示 + + $this->CDATE = $this->format("%Y-%m-%d");//日期表示 + $this->YMD = $this->format("%Y%m%d"); //简单日期 + $this->CTIME = $this->format("%H:%M:%S");//时间表示 + + return ; + } + + /** + * 日期格式化 + * 默认返回 1970-01-01 11:30:45 格式 + * @access public + * @param string $format 格式化参数 + * @return string + */ + public function format($format = "%Y-%m-%d %H:%M:%S") { + return strftime($format, $this->date); + } + + /** + * 是否为闰年 + * @static + * @access public + * @return string + */ + public function isLeapYear($year='') { + if(empty($year)) { + $year = $this->year; + } + return ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0)); + } + + /** + * 计算日期差 + * + * w - weeks + * d - days + * h - hours + * m - minutes + * s - seconds + * @static + * @access public + * @param mixed $date 要比较的日期 + * @param string $elaps 比较跨度 + * @return integer + */ + public function dateDiff($date, $elaps = "d") { + $__DAYS_PER_WEEK__ = (7); + $__DAYS_PER_MONTH__ = (30); + $__DAYS_PER_YEAR__ = (365); + $__HOURS_IN_A_DAY__ = (24); + $__MINUTES_IN_A_DAY__ = (1440); + $__SECONDS_IN_A_DAY__ = (86400); + //计算天数差 + $__DAYSELAPS = ($this->parse($date) - $this->date) / $__SECONDS_IN_A_DAY__ ; + switch ($elaps) { + case "y"://转换成年 + $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_YEAR__; + break; + case "M"://转换成月 + $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_MONTH__; + break; + case "w"://转换成星期 + $__DAYSELAPS = $__DAYSELAPS / $__DAYS_PER_WEEK__; + break; + case "h"://转换成小时 + $__DAYSELAPS = $__DAYSELAPS * $__HOURS_IN_A_DAY__; + break; + case "m"://转换成分钟 + $__DAYSELAPS = $__DAYSELAPS * $__MINUTES_IN_A_DAY__; + break; + case "s"://转换成秒 + $__DAYSELAPS = $__DAYSELAPS * $__SECONDS_IN_A_DAY__; + break; + } + return $__DAYSELAPS; + } + + /** + * 人性化的计算日期差 + * @static + * @access public + * @param mixed $time 要比较的时间 + * @param mixed $precision 返回的精度 + * @return string + */ + public function timeDiff( $time ,$precision=false) { + if(!is_numeric($precision) && !is_bool($precision)) { + static $_diff = array('y'=>'年','M'=>'个月','d'=>'天','w'=>'周','s'=>'秒','h'=>'小时','m'=>'分钟'); + return ceil($this->dateDiff($time,$precision)).$_diff[$precision].'前'; + } + $diff = abs($this->parse($time) - $this->date); + static $chunks = array(array(31536000,'年'),array(2592000,'个月'),array(604800,'周'),array(86400,'天'),array(3600 ,'小时'),array(60,'分钟'),array(1,'秒')); + $count =0; + $since = ''; + for($i=0;$i=$chunks[$i][0]) { + $num = floor($diff/$chunks[$i][0]); + $since .= sprintf('%d'.$chunks[$i][1],$num); + $diff = (int)($diff-$chunks[$i][0]*$num); + $count++; + if(!$precision || $count>=$precision) { + break; + } + } + } + return $since.'前'; + } + + /** + * 返回周的某一天 返回Date对象 + * @access public + * @return Date + */ + public function getDayOfWeek($n){ + $week = array(0=>'sunday',1=>'monday',2=>'tuesday',3=>'wednesday',4=>'thursday',5=>'friday',6=>'saturday'); + return (new Date($week[$n])); + } + + /** + * 计算周的第一天 返回Date对象 + * @access public + * @return Date + */ + public function firstDayOfWeek() { + return $this->getDayOfWeek(1); + } + + /** + * 计算月份的第一天 返回Date对象 + * @access public + * @return Date + */ + public function firstDayOfMonth() { + return (new Date(mktime(0, 0, 0,$this->month,1,$this->year ))); + } + + /** + * 计算年份的第一天 返回Date对象 + * @access public + * @return Date + */ + public function firstDayOfYear() { + return (new Date(mktime(0, 0, 0, 1, 1, $this->year))); + } + + /** + * 计算周的最后一天 返回Date对象 + * @access public + * @return Date + */ + public function lastDayOfWeek() { + return $this->getDayOfWeek(0); + } + + /** + * 计算月份的最后一天 返回Date对象 + * @access public + * @return Date + */ + public function lastDayOfMonth() { + return (new Date(mktime(0, 0, 0, $this->month + 1, 0, $this->year ))); + } + + /** + * 计算年份的最后一天 返回Date对象 + * @access public + * @return Date + */ + public function lastDayOfYear() { + return (new Date(mktime(0, 0, 0, 1, 0, $this->year + 1))); + } + + /** + * 计算月份的最大天数 + * @access public + * @return integer + */ + public function maxDayOfMonth() { + $result = $this->dateDiff(strtotime($this->dateAdd(1,'m')),'d'); + return $result; + } + + /** + * 取得指定间隔日期 + * + * yyyy - 年 + * q - 季度 + * m - 月 + * y - day of year + * d - 日 + * w - 周 + * ww - week of year + * h - 小时 + * n - 分钟 + * s - 秒 + * @access public + * @param integer $number 间隔数目 + * @param string $interval 比较类型 + * @return Date + */ + public function dateAdd($number = 0, $interval = "d") { + $hours = $this->hour; + $minutes = $this->minute; + $seconds = $this->second; + $month = $this->month; + $day = $this->day; + $year = $this->year; + + switch ($interval) { + case "yyyy": + //---Add $number to year + $year += $number; + break; + + case "q": + //---Add $number to quarter + $month += ($number*3); + break; + + case "m": + //---Add $number to month + $month += $number; + break; + + case "y": + case "d": + case "w": + //---Add $number to day of year, day, day of week + $day += $number; + break; + + case "ww": + //---Add $number to week + $day += ($number*7); + break; + + case "h": + //---Add $number to hours + $hours += $number; + break; + + case "n": + //---Add $number to minutes + $minutes += $number; + break; + + case "s": + //---Add $number to seconds + $seconds += $number; + break; + } + + return (new Date(mktime($hours, + $minutes, + $seconds, + $month, + $day, + $year))); + + } + + /** + * 日期数字转中文 + * 用于日和月、周 + * @static + * @access public + * @param integer $number 日期数字 + * @return string + */ + public function numberToCh($number) { + $number = intval($number); + $array = array('一','二','三','四','五','六','七','八','九','十'); + $str = ''; + if($number ==0) { $str .= "十" ;} + if($number < 10){ + $str .= $array[$number-1] ; + } + elseif($number < 20 ){ + $str .= "十".$array[$number-11]; + } + elseif($number < 30 ){ + $str .= "二十".$array[$number-21]; + } + else{ + $str .= "三十".$array[$number-31]; + } + return $str; + } + + /** + * 年份数字转中文 + * @static + * @access public + * @param integer $yearStr 年份数字 + * @param boolean $flag 是否显示公元 + * @return string + */ + public function yearToCh( $yearStr ,$flag=false ) { + $array = array('零','一','二','三','四','五','六','七','八','九'); + $str = $flag? '公元' : ''; + for($i=0;$i<4;$i++){ + $str .= $array[substr($yearStr,$i,1)]; + } + return $str; + } + + /** + * 判断日期 所属 干支 生肖 星座 + * type 参数:XZ 星座 GZ 干支 SX 生肖 + * + * @static + * @access public + * @param string $type 获取信息类型 + * @return string + */ + public function magicInfo($type) { + $result = ''; + $m = $this->month; + $y = $this->year; + $d = $this->day; + + switch ($type) { + case 'XZ'://星座 + $XZDict = array('摩羯','宝瓶','双鱼','白羊','金牛','双子','巨蟹','狮子','处女','天秤','天蝎','射手'); + $Zone = array(1222,122,222,321,421,522,622,722,822,922,1022,1122,1222); + if((100*$m+$d)>=$Zone[0]||(100*$m+$d)<$Zone[1]) + $i=0; + else + for($i=1;$i<12;$i++){ + if((100*$m+$d)>=$Zone[$i]&&(100*$m+$d)<$Zone[$i+1]) + break; + } + $result = $XZDict[$i].'座'; + break; + + case 'GZ'://干支 + $GZDict = array( + array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸'), + array('子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥') + ); + $i= $y -1900+36 ; + $result = $GZDict[0][$i%10].$GZDict[1][$i%12]; + break; + + case 'SX'://生肖 + $SXDict = array('鼠','牛','虎','兔','龙','蛇','马','羊','猴','鸡','狗','猪'); + $result = $SXDict[($y-4)%12]; + break; + + } + return $result; + } + + public function __toString() { + return $this->format(); + } +} \ No newline at end of file diff --git a/ewomail-admin/core/class/Db.class.php b/ewomail-admin/core/class/Db.class.php new file mode 100644 index 0000000..275d658 --- /dev/null +++ b/ewomail-admin/core/class/Db.class.php @@ -0,0 +1,295 @@ + +// +---------------------------------------------------------------------- +/** + * 数据库操作类 + * Class Db + */ +class Db +{ + protected $pdo; + + // PDO操作实例 + protected $PDOStatement = null; + // 当前SQL指令 + protected $queryStr = ''; + + // 返回或者影响记录数 + protected $numRows = 0; + + // 错误信息 + protected $error = ''; + + // 查询次数 + protected $queryTimes = 0; + + //事务检查 + public $trans = false; + + + // PDO连接参数 + protected $options = array( + PDO::ATTR_CASE => PDO::CASE_LOWER, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, + ); + + /** + * 数据库链接 + * @param $dbhost 链接地址 + * @param $dbuser 用户账号 + * @param $dbpw 用户名 + * @param $dbname 密码 + * @param $charset 编码 + */ + public function connect($dbhost, $dbuser, $dbpw, $dbname = '', $charset = '') + { + $dsn = "mysql:dbname=$dbname;host=$dbhost"; + + try { + $this->pdo = new PDO($dsn, $dbuser, $dbpw,$this->options); + $this->execute('SET NAMES '.$charset); + } catch (PDOException $e) { + $this->error = 'Connection failed: ' . $e->getMessage(); + E::sys($this->error); + return false; + } + return $this->pdo; + } + + /** + * INSERT\UPDATE\DELETE + * @param $sql + * @return mixed + */ + public function execute($sql ) + { + try { + return $this->pdo->exec($sql); + } catch (PDOException $e) { + $this->error = 'Connection failed: ' . $e->getMessage(); + $this->error .= "($sql)"; + E::sys($this->error); + return false; + } + } + + /** + * 释放查询结果 + * @access public + */ + public function free() { + $this->PDOStatement = null; + } + + /** + * 查询方式 + * @param $sql + * @param $type 0:单条数据,1:多条数据,2:上次影响的行数 + * @return array + */ + protected function _fetch($sql, $type) { + $result = array (); + $query = $this->query($sql); + if(!$query){ + return $result; + } + $this->PDOStatement->setFetchMode(PDO::FETCH_ASSOC); + switch ($type) { + case '0' : + $result = $this->PDOStatement->fetch(); + break; + case '1' : + $result = $this->PDOStatement->fetchAll (); + break; + case '2' : + $result = $this->PDOStatement->rowCount(); + break; + case '3' : + $result = $this->PDOStatement->fetchColumn(); + break; + } + $this->free(); + return $result; + } + + /** + * 查询记录 + * @param $str + * @return bool + */ + public function query($str) + { + $this->queryStr = $str; + //释放前次的查询结果 + if ( !empty($this->PDOStatement) ) $this->free(); + $this->queryTimes++; + $this->PDOStatement = $this->pdo->prepare($str); + try { + $result = $this->PDOStatement->execute(); + return $result; + } catch (PDOException $e) { + $this->error = 'Connection failed: ' . $e->getMessage(); + $this->error .= "($str)"; + E::sys($this->error); + return false; + } + } + + /** + * 获取单条数据 + * @param $sql + * @param bool $lock 启用事务后可以用该参数设为事务锁 + * @return array + */ + public function getOne($sql,$lock=false) + { + if($lock){ + $sql .= ' for update'; + } + return $this->_fetch($sql,0); + } + + /** + * 获取多条数据 + * @param $sql + * @return array + */ + function select($sql) + { + return $this->_fetch($sql,1); + } + + /** + * 获取统计数据 + * @param $sql + * @return array + */ + function count($sql) + { + return $this->_fetch($sql,3); + } + + /** + * 插入数据 + * @param $tablename + * @param $array + * @return int + */ + function insert($tablename, $array) + { + $tablename = table($tablename); + $r = $this->execute("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); + if($r){ + return $this->pdo->lastInsertId(); + }else{ + return false; + } + } + + /** + * 更新数据 + * @param $tablename + * @param $array + * @param string $where + * @return mixed + */ + function update($tablename, $array, $where = '') + { + $tablename = table($tablename); + //$array = $this->escape($array); + $sql = ''; + foreach($array as $k=>$v) + { + $sql .= ", `$k`='$v'"; + } + $sql = substr($sql, 1); + if($where){ + $sql = "UPDATE `$tablename` SET $sql WHERE $where"; + }else{ + $sql = "UPDATE `$tablename` SET $sql"; + } + + /* + if($where) + { + $sql = ''; + foreach($array as $k=>$v) + { + $sql .= ", `$k`='$v'"; + } + $sql = substr($sql, 1); + $sql = "UPDATE `$tablename` SET $sql WHERE $where"; + }*/ + /* + else + { + $sql = "REPLACE INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"; + } + */ + return $this->execute($sql); + } + + /** + * 删除数据 + * @param $tablename + * @param $where + * @return mixed + */ + public function delete($tablename,$where){ + $tablename = table($tablename); + $sql = "DELETE FROM $tablename WHERE $where"; + return $this->execute($sql); + } + + /** + * 启动事务 + */ + public function startTrans() { + $this->pdo->beginTransaction(); + $this->trans = true; + } + + /** + * 用于非自动提交状态下面的查询提交 + */ + public function commit() { + $this->pdo->commit(); + $this->trans = false; + } + + /** + * 事务回滚 + */ + public function rollback() { + $this->pdo->rollback(); + $this->trans = false; + } + + /** + * 检查事务是否开启 + * */ + public function isTrans() + { + if(!$this->trans){ + E::sys("请开启事务"); + } + } + + /** + * 关闭数据库 + */ + function close() + { + $this->pdo = null; + } +} +?> \ No newline at end of file diff --git a/ewomail-admin/core/class/E.class.php b/ewomail-admin/core/class/E.class.php new file mode 100644 index 0000000..e737c91 --- /dev/null +++ b/ewomail-admin/core/class/E.class.php @@ -0,0 +1,83 @@ + +// +---------------------------------------------------------------------- +/** + * 异常/跳转类 + * */ +class E extends Exception +{ + public $data; + //跳转的URL + public $url; + + public function __construct($message, $code = 0,$data=null,$url='') { + $this->data = $data; + $this->url = $url; + parent::__construct($message, $code); + } + + /** + * 系统级异常,通常用于程序初始化阶段的致命错误 + * @param $message + * @throws E + */ + public static function sys($message) + { + $message = self::getMsg($message); + throw new E($message,-100); + } + + /** + * 成功跳转,若是ajax请求将会输出json数据 + * @param $message 信息,也可以是语言包的key(例如是1001) + * @param string $url 跳转链接 + * @param null $data 数据,ajax专用 + * @throws E + */ + public static function success($message,$url='',$data=null) + { + $message = self::getMsg($message); + if(!$url){ + $url = iget('_forward')?iget('_forward'):ipost('_forward'); + $url = urldecode($url); + } + throw new E($message,1,$data,$url); + } + + /** + * 错误跳转,若是ajax请求将会输出json数据 + * @param $message 信息,也可以是语言包的key(例如是1001) + * @param string $url 跳转链接 + * @param null $data 数据,ajax专用 + * @throws E + */ + public static function error($message,$url='',$data=null) + { + $message = self::getMsg($message); + throw new E($message,0,$data,$url); + } + + /** + * 获取信息 + * @param $msg 如果是数字则从语言包提取 + * @return array|mixed + */ + public static function getMsg($msg) + { + if(is_int($msg)){ + return L($msg); + }else{ + return $msg; + } + + } + +} +?> \ No newline at end of file diff --git a/ewomail-admin/core/class/GIF.class.php b/ewomail-admin/core/class/GIF.class.php new file mode 100644 index 0000000..f4ace19 --- /dev/null +++ b/ewomail-admin/core/class/GIF.class.php @@ -0,0 +1,559 @@ +frames = $de->GIFGetFrames(); + $this->delays = $de->GIFGetDelays(); + } catch(\Exception $e){ + E::error("解码GIF图片出错"); + } + } + } + + /** + * 设置或获取当前帧的数据 + * @param string $stream 二进制数据流 + * @return boolean 获取到的数据 + */ + public function image($stream = null){ + if(is_null($stream)){ + $current = current($this->frames); + return false === $current ? reset($this->frames) : $current; + } else { + $this->frames[key($this->frames)] = $stream; + } + } + + /** + * 将当前帧移动到下一帧 + * @return string 当前帧数据 + */ + public function nextImage(){ + return next($this->frames); + } + + /** + * 编码并保存当前GIF图片 + * @param string $gifname 图片名称 + */ + public function save($gifname){ + $gif = new GIFEncoder($this->frames, $this->delays, 0, 2, 0, 0, 0, 'bin'); + file_put_contents($gifname, $gif->GetAnimation()); + } + +} + + +/* +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: GIFEncoder Version 2.0 by László Zsidi, http://gifs.hu +:: +:: This class is a rewritten 'GifMerge.class.php' version. +:: +:: Modification: +:: - Simplified and easy code, +:: - Ultra fast encoding, +:: - Built-in errors, +:: - Stable working +:: +:: +:: Updated at 2007. 02. 13. '00.05.AM' +:: +:: +:: +:: Try on-line GIFBuilder Form demo based on GIFEncoder. +:: +:: http://gifs.hu/phpclasses/demos/GifBuilder/ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +*/ + +Class GIFEncoder { + private $GIF = "GIF89a"; /* GIF header 6 bytes */ + private $VER = "GIFEncoder V2.05"; /* Encoder version */ + + private $BUF = Array ( ); + private $LOP = 0; + private $DIS = 2; + private $COL = -1; + private $IMG = -1; + + private $ERR = Array ( + 'ERR00' => "Does not supported function for only one image!", + 'ERR01' => "Source is not a GIF image!", + 'ERR02' => "Unintelligible flag ", + 'ERR03' => "Does not make animation from animated GIF source", + ); + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFEncoder... + :: + */ + public function __construct($GIF_src, $GIF_dly, $GIF_lop, $GIF_dis,$GIF_red, $GIF_grn, $GIF_blu, $GIF_mod) { + if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_dly ) ) { + printf ( "%s: %s", $this->VER, $this->ERR [ 'ERR00' ] ); + exit ( 0 ); + } + $this->LOP = ( $GIF_lop > -1 ) ? $GIF_lop : 0; + $this->DIS = ( $GIF_dis > -1 ) ? ( ( $GIF_dis < 3 ) ? $GIF_dis : 3 ) : 2; + $this->COL = ( $GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1 ) ? + ( $GIF_red | ( $GIF_grn << 8 ) | ( $GIF_blu << 16 ) ) : -1; + + for ( $i = 0; $i < count ( $GIF_src ); $i++ ) { + if ( strToLower ( $GIF_mod ) == "url" ) { + $this->BUF [ ] = fread ( fopen ( $GIF_src [ $i ], "rb" ), filesize ( $GIF_src [ $i ] ) ); + } + else if ( strToLower ( $GIF_mod ) == "bin" ) { + $this->BUF [ ] = $GIF_src [ $i ]; + } + else { + printf ( "%s: %s ( %s )!", $this->VER, $this->ERR [ 'ERR02' ], $GIF_mod ); + exit ( 0 ); + } + if ( substr ( $this->BUF [ $i ], 0, 6 ) != "GIF87a" && substr ( $this->BUF [ $i ], 0, 6 ) != "GIF89a" ) { + printf ( "%s: %d %s", $this->VER, $i, $this->ERR [ 'ERR01' ] ); + exit ( 0 ); + } + for ( $j = ( 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) ), $k = TRUE; $k; $j++ ) { + switch ( $this->BUF [ $i ] { $j } ) { + case "!": + if ( ( substr ( $this->BUF [ $i ], ( $j + 3 ), 8 ) ) == "NETSCAPE" ) { + printf ( "%s: %s ( %s source )!", $this->VER, $this->ERR [ 'ERR03' ], ( $i + 1 ) ); + exit ( 0 ); + } + break; + case ";": + $k = FALSE; + break; + } + } + } + $this->GIFAddHeader ( ); + for ( $i = 0; $i < count ( $this->BUF ); $i++ ) { + $this->GIFAddFrames ( $i, $GIF_dly [ $i ] ); + } + $this->GIFAddFooter ( ); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddHeader... + :: + */ + private function GIFAddHeader ( ) { + $cmap = 0; + + if ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x80 ) { + $cmap = 3 * ( 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ) ); + + $this->GIF .= substr ( $this->BUF [ 0 ], 6, 7 ); + $this->GIF .= substr ( $this->BUF [ 0 ], 13, $cmap ); + $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . $this->GIFWord ( $this->LOP ) . "\0"; + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddFrames... + :: + */ + private function GIFAddFrames ( $i, $d ) { + + $Locals_str = 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ); + + $Locals_end = strlen ( $this->BUF [ $i ] ) - $Locals_str - 1; + $Locals_tmp = substr ( $this->BUF [ $i ], $Locals_str, $Locals_end ); + + $Global_len = 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ); + $Locals_len = 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ); + + $Global_rgb = substr ( $this->BUF [ 0 ], 13, + 3 * ( 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ) ) ); + $Locals_rgb = substr ( $this->BUF [ $i ], 13, + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) ); + + $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 0 ) . + chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . "\x0\x0"; + + if ( $this->COL > -1 && ord ( $this->BUF [ $i ] { 10 } ) & 0x80 ) { + for ( $j = 0; $j < ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ); $j++ ) { + if ( + ord ( $Locals_rgb { 3 * $j + 0 } ) == ( ( $this->COL >> 16 ) & 0xFF ) && + ord ( $Locals_rgb { 3 * $j + 1 } ) == ( ( $this->COL >> 8 ) & 0xFF ) && + ord ( $Locals_rgb { 3 * $j + 2 } ) == ( ( $this->COL >> 0 ) & 0xFF ) + ) { + $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 1 ) . + chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . chr ( $j ) . "\x0"; + break; + } + } + } + switch ( $Locals_tmp { 0 } ) { + case "!": + $Locals_img = substr ( $Locals_tmp, 8, 10 ); + $Locals_tmp = substr ( $Locals_tmp, 18, strlen ( $Locals_tmp ) - 18 ); + break; + case ",": + $Locals_img = substr ( $Locals_tmp, 0, 10 ); + $Locals_tmp = substr ( $Locals_tmp, 10, strlen ( $Locals_tmp ) - 10 ); + break; + } + if ( ord ( $this->BUF [ $i ] { 10 } ) & 0x80 && $this->IMG > -1 ) { + if ( $Global_len == $Locals_len ) { + if ( $this->GIFBlockCompare ( $Global_rgb, $Locals_rgb, $Global_len ) ) { + $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp ); + } + else { + $byte = ord ( $Locals_img { 9 } ); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ); + $Locals_img { 9 } = chr ( $byte ); + $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp ); + } + } + else { + $byte = ord ( $Locals_img { 9 } ); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ); + $Locals_img { 9 } = chr ( $byte ); + $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp ); + } + } + else { + $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp ); + } + $this->IMG = 1; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddFooter... + :: + */ + private function GIFAddFooter ( ) { + $this->GIF .= ";"; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFBlockCompare... + :: + */ + private function GIFBlockCompare ( $GlobalBlock, $LocalBlock, $Len ) { + + for ( $i = 0; $i < $Len; $i++ ) { + if ( + $GlobalBlock { 3 * $i + 0 } != $LocalBlock { 3 * $i + 0 } || + $GlobalBlock { 3 * $i + 1 } != $LocalBlock { 3 * $i + 1 } || + $GlobalBlock { 3 * $i + 2 } != $LocalBlock { 3 * $i + 2 } + ) { + return ( 0 ); + } + } + + return ( 1 ); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFWord... + :: + */ + private function GIFWord ( $int ) { + + return ( chr ( $int & 0xFF ) . chr ( ( $int >> 8 ) & 0xFF ) ); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GetAnimation... + :: + */ + public function GetAnimation ( ) { + return ( $this->GIF ); + } +} + + +/* +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: GIFDecoder Version 2.0 by László Zsidi, http://gifs.hu +:: +:: Created at 2007. 02. 01. '07.47.AM' +:: +:: +:: +:: +:: Try on-line GIFBuilder Form demo based on GIFDecoder. +:: +:: http://gifs.hu/phpclasses/demos/GifBuilder/ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +*/ + +Class GIFDecoder { + private $GIF_buffer = Array ( ); + private $GIF_arrays = Array ( ); + private $GIF_delays = Array ( ); + private $GIF_stream = ""; + private $GIF_string = ""; + private $GIF_bfseek = 0; + + private $GIF_screen = Array ( ); + private $GIF_global = Array ( ); + private $GIF_sorted; + private $GIF_colorS; + private $GIF_colorC; + private $GIF_colorF; + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFDecoder ( $GIF_pointer ) + :: + */ + public function __construct ( $GIF_pointer ) { + $this->GIF_stream = $GIF_pointer; + + $this->GIFGetByte ( 6 ); // GIF89a + $this->GIFGetByte ( 7 ); // Logical Screen Descriptor + + $this->GIF_screen = $this->GIF_buffer; + $this->GIF_colorF = $this->GIF_buffer [ 4 ] & 0x80 ? 1 : 0; + $this->GIF_sorted = $this->GIF_buffer [ 4 ] & 0x08 ? 1 : 0; + $this->GIF_colorC = $this->GIF_buffer [ 4 ] & 0x07; + $this->GIF_colorS = 2 << $this->GIF_colorC; + + if ( $this->GIF_colorF == 1 ) { + $this->GIFGetByte ( 3 * $this->GIF_colorS ); + $this->GIF_global = $this->GIF_buffer; + } + /* + * + * 05.06.2007. + * Made a little modification + * + * + - for ( $cycle = 1; $cycle; ) { + + if ( GIFDecoder::GIFGetByte ( 1 ) ) { + - switch ( $this->GIF_buffer [ 0 ] ) { + - case 0x21: + - GIFDecoder::GIFReadExtensions ( ); + - break; + - case 0x2C: + - GIFDecoder::GIFReadDescriptor ( ); + - break; + - case 0x3B: + - $cycle = 0; + - break; + - } + - } + + else { + + $cycle = 0; + + } + - } + */ + for ( $cycle = 1; $cycle; ) { + if ( $this->GIFGetByte ( 1 ) ) { + switch ( $this->GIF_buffer [ 0 ] ) { + case 0x21: + $this->GIFReadExtensions ( ); + break; + case 0x2C: + $this->GIFReadDescriptor ( ); + break; + case 0x3B: + $cycle = 0; + break; + } + } + else { + $cycle = 0; + } + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFReadExtension ( ) + :: + */ + private function GIFReadExtensions ( ) { + $this->GIFGetByte ( 1 ); + for ( ; ; ) { + $this->GIFGetByte ( 1 ); + if ( ( $u = $this->GIF_buffer [ 0 ] ) == 0x00 ) { + break; + } + $this->GIFGetByte ( $u ); + /* + * 07.05.2007. + * Implemented a new line for a new function + * to determine the originaly delays between + * frames. + * + */ + if ( $u == 4 ) { + $this->GIF_delays [ ] = ( $this->GIF_buffer [ 1 ] | $this->GIF_buffer [ 2 ] << 8 ); + } + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFReadExtension ( ) + :: + */ + private function GIFReadDescriptor ( ) { + $GIF_screen = Array ( ); + + $this->GIFGetByte ( 9 ); + $GIF_screen = $this->GIF_buffer; + $GIF_colorF = $this->GIF_buffer [ 8 ] & 0x80 ? 1 : 0; + if ( $GIF_colorF ) { + $GIF_code = $this->GIF_buffer [ 8 ] & 0x07; + $GIF_sort = $this->GIF_buffer [ 8 ] & 0x20 ? 1 : 0; + } + else { + $GIF_code = $this->GIF_colorC; + $GIF_sort = $this->GIF_sorted; + } + $GIF_size = 2 << $GIF_code; + $this->GIF_screen [ 4 ] &= 0x70; + $this->GIF_screen [ 4 ] |= 0x80; + $this->GIF_screen [ 4 ] |= $GIF_code; + if ( $GIF_sort ) { + $this->GIF_screen [ 4 ] |= 0x08; + } + $this->GIF_string = "GIF87a"; + $this->GIFPutByte ( $this->GIF_screen ); + if ( $GIF_colorF == 1 ) { + $this->GIFGetByte ( 3 * $GIF_size ); + $this->GIFPutByte ( $this->GIF_buffer ); + } + else { + $this->GIFPutByte ( $this->GIF_global ); + } + $this->GIF_string .= chr ( 0x2C ); + $GIF_screen [ 8 ] &= 0x40; + $this->GIFPutByte ( $GIF_screen ); + $this->GIFGetByte ( 1 ); + $this->GIFPutByte ( $this->GIF_buffer ); + for ( ; ; ) { + $this->GIFGetByte ( 1 ); + $this->GIFPutByte ( $this->GIF_buffer ); + if ( ( $u = $this->GIF_buffer [ 0 ] ) == 0x00 ) { + break; + } + $this->GIFGetByte ( $u ); + $this->GIFPutByte ( $this->GIF_buffer ); + } + $this->GIF_string .= chr ( 0x3B ); + /* + Add frames into $GIF_stream array... + */ + $this->GIF_arrays [ ] = $this->GIF_string; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFGetByte ( $len ) + :: + */ + + /* + * + * 05.06.2007. + * Made a little modification + * + * + - function GIFGetByte ( $len ) { + - $this->GIF_buffer = Array ( ); + - + - for ( $i = 0; $i < $len; $i++ ) { + + if ( $this->GIF_bfseek > strlen ( $this->GIF_stream ) ) { + + return 0; + + } + - $this->GIF_buffer [ ] = ord ( $this->GIF_stream { $this->GIF_bfseek++ } ); + - } + + return 1; + - } + */ + private function GIFGetByte ( $len ) { + $this->GIF_buffer = Array ( ); + + for ( $i = 0; $i < $len; $i++ ) { + if ( $this->GIF_bfseek > strlen ( $this->GIF_stream ) ) { + return 0; + } + $this->GIF_buffer [ ] = ord ( $this->GIF_stream { $this->GIF_bfseek++ } ); + } + return 1; + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFPutByte ( $bytes ) + :: + */ + private function GIFPutByte ( $bytes ) { + for ( $i = 0; $i < count ( $bytes ); $i++ ) { + $this->GIF_string .= chr ( $bytes [ $i ] ); + } + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: PUBLIC FUNCTIONS + :: + :: + :: GIFGetFrames ( ) + :: + */ + public function GIFGetFrames ( ) { + return ( $this->GIF_arrays ); + } + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFGetDelays ( ) + :: + */ + public function GIFGetDelays ( ) { + return ( $this->GIF_delays ); + } +} diff --git a/ewomail-admin/core/class/Gd.class.php b/ewomail-admin/core/class/Gd.class.php new file mode 100644 index 0000000..2f44a1e --- /dev/null +++ b/ewomail-admin/core/class/Gd.class.php @@ -0,0 +1,531 @@ +open($imgname); + } + + /** + * 打开一张图像 + * @param string $imgname 图像路径 + */ + public function open($imgname){ + //检测图像文件 + if(!is_file($imgname)) E::error('不存在的图像文件'); + + //获取图像信息 + $info = getimagesize($imgname); + + //检测图像合法性 + if(false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))){ + E::error('非法图像文件'); + } + + //设置图像信息 + $this->info = array( + 'width' => $info[0], + 'height' => $info[1], + 'type' => image_type_to_extension($info[2], false), + 'mime' => $info['mime'], + ); + + //销毁已存在的图像 + empty($this->img) || imagedestroy($this->img); + + //打开图像 + if('gif' == $this->info['type']){ + $this->gif = new GIF($imgname); + $this->img = imagecreatefromstring($this->gif->image()); + } else { + $fun = "imagecreatefrom{$this->info['type']}"; + $this->img = $fun($imgname); + } + } + + /** + * 保存图像 + * @param string $imgname 图像保存名称 + * @param string $type 图像类型 + * @param integer $quality 图像质量 + * @param boolean $interlace 是否对JPEG类型图像设置隔行扫描 + */ + public function save($imgname, $type = null, $quality=80,$interlace = true){ + if(empty($this->img)) E::error('没有可以被保存的图像资源'); + + //自动获取图像类型 + if(is_null($type)){ + $type = $this->info['type']; + } else { + $type = strtolower($type); + } + //保存图像 + if('jpeg' == $type || 'jpg' == $type){ + //JPEG图像设置隔行扫描 + imageinterlace($this->img, $interlace); + imagejpeg($this->img, $imgname,$quality); + }elseif('gif' == $type && !empty($this->gif)){ + $this->gif->save($imgname); + }else{ + $fun = 'image'.$type; + $fun($this->img, $imgname); + } + } + + /** + * 返回图像宽度 + * @return integer 图像宽度 + */ + public function width(){ + if(empty($this->img)) E::error('没有指定图像资源'); + return $this->info['width']; + } + + /** + * 返回图像高度 + * @return integer 图像高度 + */ + public function height(){ + if(empty($this->img)) E::error('没有指定图像资源'); + return $this->info['height']; + } + + /** + * 返回图像类型 + * @return string 图像类型 + */ + public function type(){ + if(empty($this->img)) E::error('没有指定图像资源'); + return $this->info['type']; + } + + /** + * 返回图像MIME类型 + * @return string 图像MIME类型 + */ + public function mime(){ + if(empty($this->img)) E::error('没有指定图像资源'); + return $this->info['mime']; + } + + /** + * 返回图像尺寸数组 0 - 图像宽度,1 - 图像高度 + * @return array 图像尺寸 + */ + public function size(){ + if(empty($this->img)) E::error('没有指定图像资源'); + return array($this->info['width'], $this->info['height']); + } + + /** + * 裁剪图像 + * @param integer $w 裁剪区域宽度 + * @param integer $h 裁剪区域高度 + * @param integer $x 裁剪区域x坐标 + * @param integer $y 裁剪区域y坐标 + * @param integer $width 图像保存宽度 + * @param integer $height 图像保存高度 + */ + public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ + if(empty($this->img)) E::error('没有可以被裁剪的图像资源'); + + //设置保存尺寸 + empty($width) && $width = $w; + empty($height) && $height = $h; + + do { + //创建新图像 + $img = imagecreatetruecolor($width, $height); + // 调整默认颜色 + $color = imagecolorallocate($img, 255, 255, 255); + imagefill($img, 0, 0, $color); + + //裁剪 + imagecopyresampled($img, $this->img, 0, 0, $x, $y, $width, $height, $w, $h); + imagedestroy($this->img); //销毁原图 + + //设置新图像 + $this->img = $img; + } while(!empty($this->gif) && $this->gifNext()); + + $this->info['width'] = $width; + $this->info['height'] = $height; + } + + /** + * 生成缩略图 + * @param integer $width 缩略图最大宽度 + * @param integer $height 缩略图最大高度 + * @param integer $type 缩略图裁剪类型 + */ + public function thumb($width, $height, $type = Image::IMAGE_THUMB_SCALE){ + if(empty($this->img)) E::error('没有可以被缩略的图像资源'); + + //原图宽度和高度 + $w = $this->info['width']; + $h = $this->info['height']; + + /* 计算缩略图生成的必要参数 */ + switch ($type) { + /* 等比例缩放 */ + case Image::IMAGE_THUMB_SCALE: + //原图尺寸小于缩略图尺寸则不进行缩略 + if($w < $width && $h < $height) return; + + //计算缩放比例 + $scale = min($width/$w, $height/$h); + + //设置缩略图的坐标及宽度和高度 + $x = $y = 0; + $width = $w * $scale; + $height = $h * $scale; + break; + + /* 居中裁剪 */ + case Image::IMAGE_THUMB_CENTER: + //计算缩放比例 + $scale = max($width/$w, $height/$h); + + //设置缩略图的坐标及宽度和高度 + $w = $width/$scale; + $h = $height/$scale; + $x = ($this->info['width'] - $w)/2; + $y = ($this->info['height'] - $h)/2; + break; + + /* 左上角裁剪 */ + case Image::IMAGE_THUMB_NORTHWEST: + //计算缩放比例 + $scale = max($width/$w, $height/$h); + + //设置缩略图的坐标及宽度和高度 + $x = $y = 0; + $w = $width/$scale; + $h = $height/$scale; + break; + + /* 右下角裁剪 */ + case Image::IMAGE_THUMB_SOUTHEAST: + //计算缩放比例 + $scale = max($width/$w, $height/$h); + + //设置缩略图的坐标及宽度和高度 + $w = $width/$scale; + $h = $height/$scale; + $x = $this->info['width'] - $w; + $y = $this->info['height'] - $h; + break; + + /* 填充 */ + case Image::IMAGE_THUMB_FILLED: + //计算缩放比例 + if($w < $width && $h < $height){ + $scale = 1; + } else { + $scale = min($width/$w, $height/$h); + } + + //设置缩略图的坐标及宽度和高度 + $neww = $w * $scale; + $newh = $h * $scale; + $posx = ($width - $w * $scale)/2; + $posy = ($height - $h * $scale)/2; + + do{ + //创建新图像 + $img = imagecreatetruecolor($width, $height); + // 调整默认颜色 + $color = imagecolorallocate($img, 255, 255, 255); + imagefill($img, 0, 0, $color); + + //裁剪 + imagecopyresampled($img, $this->img, $posx, $posy, $x, $y, $neww, $newh, $w, $h); + imagedestroy($this->img); //销毁原图 + $this->img = $img; + } while(!empty($this->gif) && $this->gifNext()); + + $this->info['width'] = $width; + $this->info['height'] = $height; + return; + + /* 固定 */ + case Image::IMAGE_THUMB_FIXED: + $x = $y = 0; + break; + + default: + E::error('不支持的缩略图裁剪类型'); + } + + /* 裁剪图像 */ + $this->crop($w, $h, $x, $y, $width, $height); + } + + /** + * 添加水印 + * @param string $source 水印图片路径 + * @param integer $locate 水印位置 + * @param integer $alpha 水印透明度 + */ + public function water($source, $locate = Image::IMAGE_WATER_SOUTHEAST,$alpha=80){ + //资源检测 + if(empty($this->img)) E::error('没有可以被添加水印的图像资源'); + if(!is_file($source)) E::error('水印图像不存在'); + + //获取水印图像信息 + $info = getimagesize($source); + if(false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))){ + E::error('非法水印文件'); + } + + //创建水印图像资源 + $fun = 'imagecreatefrom' . image_type_to_extension($info[2], false); + $water = $fun($source); + + //设定水印图像的混色模式 + imagealphablending($water, true); + + /* 设定水印位置 */ + switch ($locate) { + /* 右下角水印 */ + case Image::IMAGE_WATER_SOUTHEAST: + $x = $this->info['width'] - $info[0]; + $y = $this->info['height'] - $info[1]; + break; + + /* 左下角水印 */ + case Image::IMAGE_WATER_SOUTHWEST: + $x = 0; + $y = $this->info['height'] - $info[1]; + break; + + /* 左上角水印 */ + case Image::IMAGE_WATER_NORTHWEST: + $x = $y = 0; + break; + + /* 右上角水印 */ + case Image::IMAGE_WATER_NORTHEAST: + $x = $this->info['width'] - $info[0]; + $y = 0; + break; + + /* 居中水印 */ + case Image::IMAGE_WATER_CENTER: + $x = ($this->info['width'] - $info[0])/2; + $y = ($this->info['height'] - $info[1])/2; + break; + + /* 下居中水印 */ + case Image::IMAGE_WATER_SOUTH: + $x = ($this->info['width'] - $info[0])/2; + $y = $this->info['height'] - $info[1]; + break; + + /* 右居中水印 */ + case Image::IMAGE_WATER_EAST: + $x = $this->info['width'] - $info[0]; + $y = ($this->info['height'] - $info[1])/2; + break; + + /* 上居中水印 */ + case Image::IMAGE_WATER_NORTH: + $x = ($this->info['width'] - $info[0])/2; + $y = 0; + break; + + /* 左居中水印 */ + case Image::IMAGE_WATER_WEST: + $x = 0; + $y = ($this->info['height'] - $info[1])/2; + break; + + default: + /* 自定义水印坐标 */ + if(is_array($locate)){ + list($x, $y) = $locate; + } else { + E::error('不支持的水印位置类型'); + } + } + + do{ + //添加水印 + $src = imagecreatetruecolor($info[0], $info[1]); + // 调整默认颜色 + $color = imagecolorallocate($src, 255, 255, 255); + imagefill($src, 0, 0, $color); + + imagecopy($src, $this->img, 0, 0, $x, $y, $info[0], $info[1]); + imagecopy($src, $water, 0, 0, 0, 0, $info[0], $info[1]); + imagecopymerge($this->img, $src, $x, $y, 0, 0, $info[0], $info[1], $alpha); + + //销毁零时图片资源 + imagedestroy($src); + } while(!empty($this->gif) && $this->gifNext()); + + //销毁水印资源 + imagedestroy($water); + } + + /** + * 图像添加文字 + * @param string $text 添加的文字 + * @param string $font 字体路径 + * @param integer $size 字号 + * @param string $color 文字颜色 + * @param integer $locate 文字写入位置 + * @param integer $offset 文字相对当前位置的偏移量 + * @param integer $angle 文字倾斜角度 + */ + public function text($text, $font, $size, $color = '#00000000', + $locate = Image::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0){ + //资源检测 + if(empty($this->img)) E::error('没有可以被写入文字的图像资源'); + if(!is_file($font)) E::error("不存在的字体文件:{$font}"); + + //获取文字信息 + $info = imagettfbbox($size, $angle, $font, $text); + $minx = min($info[0], $info[2], $info[4], $info[6]); + $maxx = max($info[0], $info[2], $info[4], $info[6]); + $miny = min($info[1], $info[3], $info[5], $info[7]); + $maxy = max($info[1], $info[3], $info[5], $info[7]); + + /* 计算文字初始坐标和尺寸 */ + $x = $minx; + $y = abs($miny); + $w = $maxx - $minx; + $h = $maxy - $miny; + + /* 设定文字位置 */ + switch ($locate) { + /* 右下角文字 */ + case Image::IMAGE_WATER_SOUTHEAST: + $x += $this->info['width'] - $w; + $y += $this->info['height'] - $h; + break; + + /* 左下角文字 */ + case Image::IMAGE_WATER_SOUTHWEST: + $y += $this->info['height'] - $h; + break; + + /* 左上角文字 */ + case Image::IMAGE_WATER_NORTHWEST: + // 起始坐标即为左上角坐标,无需调整 + break; + + /* 右上角文字 */ + case Image::IMAGE_WATER_NORTHEAST: + $x += $this->info['width'] - $w; + break; + + /* 居中文字 */ + case Image::IMAGE_WATER_CENTER: + $x += ($this->info['width'] - $w)/2; + $y += ($this->info['height'] - $h)/2; + break; + + /* 下居中文字 */ + case Image::IMAGE_WATER_SOUTH: + $x += ($this->info['width'] - $w)/2; + $y += $this->info['height'] - $h; + break; + + /* 右居中文字 */ + case Image::IMAGE_WATER_EAST: + $x += $this->info['width'] - $w; + $y += ($this->info['height'] - $h)/2; + break; + + /* 上居中文字 */ + case Image::IMAGE_WATER_NORTH: + $x += ($this->info['width'] - $w)/2; + break; + + /* 左居中文字 */ + case Image::IMAGE_WATER_WEST: + $y += ($this->info['height'] - $h)/2; + break; + + default: + /* 自定义文字坐标 */ + if(is_array($locate)){ + list($posx, $posy) = $locate; + $x += $posx; + $y += $posy; + } else { + E::error('不支持的文字位置类型'); + } + } + + /* 设置偏移量 */ + if(is_array($offset)){ + $offset = array_map('intval', $offset); + list($ox, $oy) = $offset; + } else{ + $offset = intval($offset); + $ox = $oy = $offset; + } + + /* 设置颜色 */ + if(is_string($color) && 0 === strpos($color, '#')){ + $color = str_split(substr($color, 1), 2); + $color = array_map('hexdec', $color); + if(empty($color[3]) || $color[3] > 127){ + $color[3] = 0; + } + } elseif (!is_array($color)) { + E::error('错误的颜色值'); + } + + do{ + /* 写入文字 */ + $col = imagecolorallocatealpha($this->img, $color[0], $color[1], $color[2], $color[3]); + imagettftext($this->img, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text); + } while(!empty($this->gif) && $this->gifNext()); + } + + /* 切换到GIF的下一帧并保存当前帧,内部使用 */ + private function gifNext(){ + ob_start(); + ob_implicit_flush(0); + imagegif($this->img); + $img = ob_get_clean(); + + $this->gif->image($img); + $next = $this->gif->nextImage(); + + if($next){ + $this->img = imagecreatefromstring($next); + return $next; + } else { + $this->img = imagecreatefromstring($this->gif->image()); + return false; + } + } + + /** + * 析构方法,用于销毁图像资源 + */ + public function __destruct() { + empty($this->img) || imagedestroy($this->img); + } +} \ No newline at end of file diff --git a/ewomail-admin/core/class/Image.class.php b/ewomail-admin/core/class/Image.class.php new file mode 100644 index 0000000..5a972cf --- /dev/null +++ b/ewomail-admin/core/class/Image.class.php @@ -0,0 +1,162 @@ +img = new Gd($imgname); + } + + /** + * 打开一幅图像 + * @param string $imgname 图片路径 + * @return Object 当前图片处理库对象 + */ + public function open($imgname){ + $this->img->open($imgname); + return $this; + } + + /** + * 保存图片 + * @param string $imgname 图片保存名称 + * @param string $type 图片类型 + * @param integer $quality 图像质量 + * @param boolean $interlace 是否对JPEG类型图片设置隔行扫描 + * @return Object 当前图片处理库对象 + */ + public function save($imgname, $type = null, $quality=80,$interlace = true){ + $this->img->save($imgname, $type, $quality,$interlace); + return $this; + } + + /** + * 返回图片宽度 + * @return integer 图片宽度 + */ + public function width(){ + return $this->img->width(); + } + + /** + * 返回图片高度 + * @return integer 图片高度 + */ + public function height(){ + return $this->img->height(); + } + + /** + * 返回图像类型 + * @return string 图片类型 + */ + public function type(){ + return $this->img->type(); + } + + /** + * 返回图像MIME类型 + * @return string 图像MIME类型 + */ + public function mime(){ + return $this->img->mime(); + } + + /** + * 返回图像尺寸数组 0 - 图片宽度,1 - 图片高度 + * @return array 图片尺寸 + */ + public function size(){ + return $this->img->size(); + } + + /** + * 裁剪图片 + * @param integer $w 裁剪区域宽度 + * @param integer $h 裁剪区域高度 + * @param integer $x 裁剪区域x坐标 + * @param integer $y 裁剪区域y坐标 + * @param integer $width 图片保存宽度 + * @param integer $height 图片保存高度 + * @return Object 当前图片处理库对象 + */ + public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null){ + $this->img->crop($w, $h, $x, $y, $width, $height); + return $this; + } + + /** + * 生成缩略图 + * @param integer $width 缩略图最大宽度 + * @param integer $height 缩略图最大高度 + * @param integer $type 缩略图裁剪类型 + * @return Object 当前图片处理库对象 + */ + public function thumb($width, $height, $type = self::IMAGE_THUMB_SCALE){ + $this->img->thumb($width, $height, $type); + return $this; + } + + /** + * 添加水印 + * @param string $source 水印图片路径 + * @param integer $locate 水印位置 + * @param integer $alpha 水印透明度 + * @return Object 当前图片处理库对象 + */ + public function water($source, $locate = self::IMAGE_WATER_SOUTHEAST,$alpha=80){ + $this->img->water($source, $locate,$alpha); + return $this; + } + + /** + * 图像添加文字 + * @param string $text 添加的文字 + * @param string $font 字体路径 + * @param integer $size 字号 + * @param string $color 文字颜色 + * @param integer $locate 文字写入位置 + * @param integer $offset 文字相对当前位置的偏移量 + * @param integer $angle 文字倾斜角度 + * @return Object 当前图片处理库对象 + */ + public function text($text, $font, $size, $color = '#00000000', + $locate = self::IMAGE_WATER_SOUTHEAST, $offset = 0, $angle = 0){ + $this->img->text($text, $font, $size, $color, $locate, $offset, $angle); + return $this; + } +} \ No newline at end of file diff --git a/ewomail-admin/core/class/Local.class.php b/ewomail-admin/core/class/Local.class.php new file mode 100644 index 0000000..1600105 --- /dev/null +++ b/ewomail-admin/core/class/Local.class.php @@ -0,0 +1,111 @@ +error = '上传根目录不存在!请尝试手动创建:'.$rootpath; + return false; + } + $this->rootPath = $rootpath; + return true; + } + + /** + * 检测上传目录 + * @param string $savepath 上传目录 + * @return boolean 检测结果,true-通过,false-失败 + */ + public function checkSavePath($savepath){ + /* 检测并创建目录 */ + if (!$this->mkdir($savepath)) { + return false; + } else { + /* 检测目录是否可写 */ + if (!is_writable($this->rootPath . $savepath)) { + $this->error = '上传目录 ' . $savepath . ' 不可写!'; + return false; + } else { + return true; + } + } + } + + /** + * 保存指定文件 + * @param array $file 保存的文件信息 + * @param boolean $replace 同名文件是否覆盖 + * @return boolean 保存状态,true-成功,false-失败 + */ + public function save($file, $replace=true) { + $filename = $this->rootPath . $file['savepath'] . $file['savename']; + + /* 不覆盖同名文件 */ + if (!$replace && is_file($filename)) { + $this->error = '存在同名文件' . $file['savename']; + return false; + } + + /* 移动文件 */ + if (!move_uploaded_file($file['tmp_name'], $filename)) { + $this->error = '文件上传保存错误!'; + return false; + } + + return true; + } + + /** + * 创建目录 + * @param string $savepath 要创建的穆里 + * @return boolean 创建状态,true-成功,false-失败 + */ + public function mkdir($savepath){ + $dir = $this->rootPath . $savepath; + if(is_dir($dir)){ + return true; + } + + if(mkdir($dir, 0777, true)){ + return true; + } else { + $this->error = "目录 {$savepath} 创建失败!"; + return false; + } + } + + /** + * 获取最后一次上传错误信息 + * @return string 错误信息 + */ + public function getError(){ + return $this->error; + } + +} diff --git a/ewomail-admin/core/class/Page.class.php b/ewomail-admin/core/class/Page.class.php new file mode 100644 index 0000000..0ab4abf --- /dev/null +++ b/ewomail-admin/core/class/Page.class.php @@ -0,0 +1,155 @@ + '共%TOTAL_ROW%条记录', + 'prev' => '<<', + 'next' => '>>', + 'first' => '1...', + 'last' => '...%TOTAL_PAGE%', + 'theme' => '%HEADER% %FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%', + ); + + /** + * 架构函数 + * @param array $totalRows 总的记录数 + * @param array $listRows 每页显示记录数 + * @param array $parameter 分页跳转的参数 + */ + public function __construct($totalRows, $listRows=20, $parameter = array()) { + //C('VAR_PAGE') && $this->p = C('VAR_PAGE'); //设置分页参数名称 + /* 基础设置 */ + $this->totalRows = $totalRows; //设置总记录数 + $this->listRows = $listRows; //设置每页显示行数 + $this->parameter = empty($parameter) ? $_GET : $parameter; + $this->nowPage = empty($_GET[$this->p]) ? 1 : intval($_GET[$this->p]); + $this->nowPage = $this->nowPage>0 ? $this->nowPage : 1; + $this->firstRow = $this->listRows * ($this->nowPage - 1); + $this->limit = 'limit '.$this->firstRow.','.$this->listRows; + } + + /** + * 定制分页链接设置 + * @param string $name 设置名称 + * @param string $value 设置值 + */ + public function setConfig($name,$value) { + if(isset($this->config[$name])) { + $this->config[$name] = $value; + } + } + + /** + * 生成链接URL + * @param integer $page 页码 + * @return string + */ + private function url($page){ + return str_replace(urlencode('[PAGE]'), $page, $this->url); + } + + /** + * 组装分页链接 + * @return string + */ + public function show() { + if(0 == $this->totalRows) return ''; + + /* 生成URL */ + $url = $_SERVER['REQUEST_URI']; + $parse = parse_url($url); + if(isset($parse['query'])) { + parse_str($parse['query'],$params); + } + $this->parameter = $params; + $this->parameter[$this->p] = '[PAGE]'; + $url = $parse['path'].'?'.http_build_query($this->parameter); + $this->url = $url; + /* 计算分页信息 */ + $this->totalPages = ceil($this->totalRows / $this->listRows); //总页数 + if(!empty($this->totalPages) && $this->nowPage > $this->totalPages) { + $this->nowPage = $this->totalPages; + } + + /* 计算分页临时变量 */ + $now_cool_page = $this->rollPage/2; + $now_cool_page_ceil = ceil($now_cool_page); + $this->lastSuffix && $this->config['last'] = $this->totalPages; + + //上一页 + $up_row = $this->nowPage - 1; + //$up_page = $up_row > 0 ? '' : ''; + $up_page = ''; + + //下一页 + $down_row = $this->nowPage + 1; + //$down_page = ($down_row <= $this->totalPages) ? '' : ''; + $_n = ($down_row <= $this->totalPages) ? $down_row:$this->totalPages; + $down_page = '' ; + + //第一页 + $the_first = ''; + if($this->totalPages > $this->rollPage && ($this->nowPage - $now_cool_page) >= 1){ + $the_first = '' . $this->config['first'] . ''; + } + + //最后一页 + $the_end = ''; + if($this->totalPages > $this->rollPage && ($this->nowPage + $now_cool_page) < $this->totalPages){ + $the_end = '' . $this->config['last'] . ''; + } + + //数字连接 + $link_page = ""; + for($i = 1; $i <= $this->rollPage; $i++){ + if(($this->nowPage - $now_cool_page) <= 0 ){ + $page = $i; + }elseif(($this->nowPage + $now_cool_page - 1) >= $this->totalPages){ + $page = $this->totalPages - $this->rollPage + $i; + }else{ + $page = $this->nowPage - $now_cool_page_ceil + $i; + } + if($page > 0 && $page != $this->nowPage){ + + if($page <= $this->totalPages){ + $link_page .= '' . $page . ''; + }else{ + break; + } + }else{ + /* + if($page > 0 && $this->totalPages != 1){ + $link_page .= '' . $page . ''; + }else{ + $link_page = "dsadsa"; + } + */ + $link_page .= '' . $page . ''; + } + } + + //替换分页内容 + $page_str = str_replace( + array('%HEADER%', '%NOW_PAGE%', '%UP_PAGE%', '%DOWN_PAGE%', '%FIRST%', '%LINK_PAGE%', '%END%', '%TOTAL_ROW%', '%TOTAL_PAGE%'), + array($this->config['header'], $this->nowPage, $up_page, $down_page, $the_first, $link_page, $the_end, $this->totalRows, $this->totalPages), + $this->config['theme']); + return "
{$page_str}
"; + } +} diff --git a/ewomail-admin/core/class/Rout.class.php b/ewomail-admin/core/class/Rout.class.php new file mode 100644 index 0000000..a64c9bc --- /dev/null +++ b/ewomail-admin/core/class/Rout.class.php @@ -0,0 +1,142 @@ + +// +---------------------------------------------------------------------- +/** + * 路由操作类 + * */ +class Rout +{ + private static $core = []; + + private static $action = []; + + private static $init = []; + + public static $method = ''; + + /** + * 核心运行 + * */ + public static function core(callable $fun) + { + self::$core[] = $fun; + } + + private static function key() + { + return HOME.'_'.MODULE; + } + + /** + * 运行action init + * */ + public static function init(callable $fun) + { + self::$init[self::key()][] = $fun; + } + + private static function add($act,callable $fun,$method) + { + self::$action[self::key()][$act][$method] = $fun; + } + + + /** + * 运行action get + * */ + public static function get($act,callable $fun) + { + self::add($act,$fun,'get'); + } + + /** + * 运行action put + * */ + public static function put($act,callable $fun) + { + self::add($act,$fun,'put'); + } + + /** + * 运行action delete + * */ + public static function delete($act,callable $fun) + { + self::add($act,$fun,'delete'); + } + + /** + * 运行路由 + */ + public static function run() + { + try + { + foreach(self::$core as $fun){ + $fun(); + } + $init = self::$init[self::key()]; + foreach($init as $fun){ + $fun(); + } + $method = ipost('_method'); + if(!$method){ + $method = 'get'; + } + self::$method = $method; + $action = self::$action[self::key()]; + $actFun = $action[ACTION][$method]; + + if($actFun){ + $actFun(); + }else{ + E::sys(ACTION."--action不存在"); + } + } + catch(E $e) + { + $code = $e->getCode(); + if(App::$db && App::$db->trans){ + App::$db->rollback(); + } + if($code==-100){ + //系统错误 + header('Content-Type:application/json; charset=utf-8'); + $arr = [ + 'status'=>-100, + 'msg'=>'系统错误:'.$e->getMessage() + ]; + if(IS_AJAX || defined("IS_API")){ + echo json_encode($arr); + }else{ + echo $arr['msg']; + } + + }else{ + $arr = [ + 'status'=>$code, + 'msg'=>$e->getMessage(), + 'url'=>$e->url, + 'data'=>$e->data + ]; + if(IS_AJAX || defined("IS_API")){ + header('Content-Type:application/json; charset=utf-8'); + echo json_encode($arr); + exit; + } + Tp::assign($arr); + Tp::jump(); + } + exit; + } + + } +} +?> \ No newline at end of file diff --git a/ewomail-admin/core/class/Session.class.php b/ewomail-admin/core/class/Session.class.php new file mode 100644 index 0000000..941a911 --- /dev/null +++ b/ewomail-admin/core/class/Session.class.php @@ -0,0 +1,48 @@ + +// +---------------------------------------------------------------------- +/** + * session类 + * */ +class Session{ + + /** + * 输入 + * @param $key + * @param $value + */ + public static function set($key,$value) + { + $key = C('prefix').$key; + $_SESSION[$key] = $value; + } + + /** + * 读取 + * @param $key + * @return mixed + */ + public static function get($key) + { + $key = C('prefix').$key; + return $_SESSION[$key]; + } + + /** + * 清除所有 + */ + public static function clear() + { + $_SESSION = null; + session_destroy(); + } + + +} \ No newline at end of file diff --git a/ewomail-admin/core/class/SimpleCaptcha.class.php b/ewomail-admin/core/class/SimpleCaptcha.class.php new file mode 100644 index 0000000..7f8670e --- /dev/null +++ b/ewomail-admin/core/class/SimpleCaptcha.class.php @@ -0,0 +1,319 @@ + array('spacing' => -3, 'minSize' => 27, 'maxSize' => 30, 'font' => 'AntykwaBold.ttf'), + ); + + /** Wave configuracion in X and Y axes */ + public $Yperiod = 12; + public $Yamplitude = 14; + public $Xperiod = 11; + public $Xamplitude = 5; + + /** letter rotation clockwise */ + public $maxRotation = 8; + + /** + * Internal image size factor (for better image quality) + * 1: low, 2: medium, 3: high + */ + public $scale = 2; + + /** + * Blur effect for better image quality (but slower image processing). + * Better image results with scale=3 + */ + public $blur = false; + + /** Debug? */ + public $debug = false; + + /** Image format: jpeg or png */ + public $imageFormat = 'png'; + + + /** GD image */ + public $im; + + + public function __construct($config = array()) { + } + + public function CreateImage() { + $ini = microtime(true); + + /** Initialization */ + $this->ImageAllocate(); + + /** Text insertion */ + $text = $this->GetCaptchaText(); + $fontcfg = $this->fonts[array_rand($this->fonts)]; + $this->WriteText($text, $fontcfg); + + //$_SESSION[$this->session_var] = $text; + Session::set($this->session_var,$text); + + /** Transformations */ + $this->WaveImage(); + if ($this->blur && function_exists('imagefilter')) { + imagefilter($this->im, IMG_FILTER_GAUSSIAN_BLUR); + } + $this->ReduceImage(); + + + if ($this->debug) { + imagestring($this->im, 1, 1, $this->height-8, + "$text {$fontcfg['font']} ".round((microtime(true)-$ini)*1000)."ms", + $this->GdFgColor + ); + } + + + /** Output */ + $this->WriteImage(); + $this->Cleanup(); + } + + + + + + + + + + /** + * Creates the image resources + */ + protected function ImageAllocate() { + // Cleanup + if (!empty($this->im)) { + imagedestroy($this->im); + } + + $this->im = imagecreatetruecolor($this->width*$this->scale, $this->height*$this->scale); + + // Background color + $this->GdBgColor = imagecolorallocate($this->im, + $this->backgroundColor[0], + $this->backgroundColor[1], + $this->backgroundColor[2] + ); + imagefilledrectangle($this->im, 0, 0, $this->width*$this->scale, $this->height*$this->scale, $this->GdBgColor); + + // Foreground color + $color = $this->colors[mt_rand(0, sizeof($this->colors)-1)]; + $this->GdFgColor = imagecolorallocate($this->im, $color[0], $color[1], $color[2]); + + // Shadow color + if (!empty($this->shadowColor) && is_array($this->shadowColor) && sizeof($this->shadowColor) >= 3) { + $this->GdShadowColor = imagecolorallocate($this->im, + $this->shadowColor[0], + $this->shadowColor[1], + $this->shadowColor[2] + ); + } + } + + + + + + /** + * Text generation + * + * @return string Text + */ + protected function GetCaptchaText() { + $text = $this->GetDictionaryCaptchaText(); + return $text; + } + + /** + * Random dictionary word generation + * + * @param boolean $extended Add extended "fake" words + * @return string Word + */ + function GetDictionaryCaptchaText($length=4) { + $str = null; + //$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + $strPol = "0123456789"; + $max = strlen($strPol)-1; + + for($i=0;$i<$length;$i++){ + $str.=$strPol[rand(0,$max)]; + } + return $str; + } + + /** + * Text insertion + */ + protected function WriteText($text, $fontcfg = array()) { + if (empty($fontcfg)) { + // Select the font configuration + $fontcfg = $this->fonts[array_rand($this->fonts)]; + } + + // Full path of font file + $fontfile = PATH.'/public/fonts/'.$fontcfg['font']; + + + /** Increase font-size for shortest words: 9% for each glyp missing */ + $lettersMissing = $this->maxWordLength-strlen($text); + $fontSizefactor = 1+($lettersMissing*0.09); + + // Text generation (char by char) + $x = 20*$this->scale; + $y = round(($this->height*27/40)*$this->scale); + $length = strlen($text); + for ($i=0; $i<$length; $i++) { + $degree = rand($this->maxRotation*-1, $this->maxRotation); + $fontsize = rand($fontcfg['minSize'], $fontcfg['maxSize'])*$this->scale*$fontSizefactor; + $letter = substr($text, $i, 1); + + if ($this->shadowColor) { + $coords = imagettftext($this->im, $fontsize, $degree, + $x+$this->scale, $y+$this->scale, + $this->GdShadowColor, $fontfile, $letter); + } + $coords = imagettftext($this->im, $fontsize, $degree, + $x, $y, + $this->GdFgColor, $fontfile, $letter); + $x += ($coords[2]-$x) + ($fontcfg['spacing']*$this->scale); + } + } + + + + /** + * Wave filter + */ + protected function WaveImage() { + // X-axis wave generation + $xp = $this->scale*$this->Xperiod*rand(1,3); + $k = rand(0, 100); + for ($i = 0; $i < ($this->width*$this->scale); $i++) { + imagecopy($this->im, $this->im, + $i-1, sin($k+$i/$xp) * ($this->scale*$this->Xamplitude), + $i, 0, 1, $this->height*$this->scale); + } + + // Y-axis wave generation + $k = rand(0, 100); + $yp = $this->scale*$this->Yperiod*rand(1,2); + for ($i = 0; $i < ($this->height*$this->scale); $i++) { + imagecopy($this->im, $this->im, + sin($k+$i/$yp) * ($this->scale*$this->Yamplitude), $i-1, + 0, $i, $this->width*$this->scale, 1); + } + } + + + + + /** + * Reduce the image to the final size + */ + protected function ReduceImage() { + // Reduzco el tama駉 de la imagen + $imResampled = imagecreatetruecolor($this->width, $this->height); + imagecopyresampled($imResampled, $this->im, + 0, 0, 0, 0, + $this->width, $this->height, + $this->width*$this->scale, $this->height*$this->scale + ); + imagedestroy($this->im); + $this->im = $imResampled; + } + + + + + + + + + /** + * File generation + */ + protected function WriteImage() { + if ($this->imageFormat == 'png' && function_exists('imagepng')) { + header("Content-type: image/png"); + imagepng($this->im); + } else { + header("Content-type: image/jpeg"); + imagejpeg($this->im, null, 80); + } + } + + + + + + + + /** + * Cleanup + */ + protected function Cleanup() { + imagedestroy($this->im); + } + + public function isCode($var) + { + $cur_var = strtolower(Session::get($this->session_var)); + $new_var = strtolower($var); + if($new_var==$cur_var){ + return true; + } + Session::set($this->session_var,''); + return false; + } +} diff --git a/ewomail-admin/core/class/String.class.php b/ewomail-admin/core/class/String.class.php new file mode 100644 index 0000000..8ff1624 --- /dev/null +++ b/ewomail-admin/core/class/String.class.php @@ -0,0 +1,243 @@ + 128){ + if(($c >= 254)) return false; + elseif($c >= 252) $bits=6; + elseif($c >= 248) $bits=5; + elseif($c >= 240) $bits=4; + elseif($c >= 224) $bits=3; + elseif($c >= 192) $bits=2; + else return false; + if(($i+$bits) > $len) return false; + while($bits > 1){ + $i++; + $b=ord($str[$i]); + if($b < 128 || $b > 191) return false; + $bits--; + } + } + } + return true; + } + + /** + * 字符串截取,支持中文和其他编码 + * @static + * @access public + * @param string $str 需要转换的字符串 + * @param string $start 开始位置 + * @param string $length 截取长度 + * @param string $charset 编码格式 + * @param string $suffix 截断显示字符 + * @return string + */ + static public function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) { + if(function_exists("mb_substr")) + $slice = mb_substr($str, $start, $length, $charset); + elseif(function_exists('iconv_substr')) { + $slice = iconv_substr($str,$start,$length,$charset); + }else{ + $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; + $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; + $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; + $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; + preg_match_all($re[$charset], $str, $match); + $slice = join("",array_slice($match[0], $start, $length)); + } + return $suffix ? $slice.'...' : $slice; + } + + /** + * 产生随机字串,可用来自动生成密码 + * 默认长度6位 字母和数字混合 支持中文 + * @param string $len 长度 + * @param string $type 字串类型 + * 0 字母 1 数字 其它 混合 + * @param string $addChars 额外字符 + * @return string + */ + static public function randString($len=6,$type='',$addChars='') { + $str =''; + switch($type) { + case 0: + $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.$addChars; + break; + case 1: + $chars= str_repeat('0123456789',3); + break; + case 2: + $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.$addChars; + break; + case 3: + $chars='abcdefghijklmnopqrstuvwxyz'.$addChars; + break; + case 4: + $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借".$addChars; + break; + default : + // 默认去掉了容易混淆的字符oOLl和数字01,要添加请使用addChars参数 + $chars='ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'.$addChars; + break; + } + if($len>10 ) {//位数过长重复字符串一定次数 + $chars= $type==1? str_repeat($chars,$len) : str_repeat($chars,5); + } + if($type!=4) { + $chars = str_shuffle($chars); + $str = substr($chars,0,$len); + }else{ + // 中文随机字 + for($i=0;$i<$len;$i++){ + $str.= self::msubstr($chars, floor(mt_rand(0,mb_strlen($chars,'utf-8')-1)),1,'utf-8',false); + } + } + return $str; + } + + /** + * 生成一定数量的随机数,并且不重复 + * @param integer $number 数量 + * @param string $len 长度 + * @param string $type 字串类型 + * 0 字母 1 数字 其它 混合 + * @return string + */ + static public function buildCountRand ($number,$length=4,$mode=1) { + if($mode==1 && $length $val) { + $_key = self::autoCharset($key, $from, $to); + $string[$_key] = self::autoCharset($val, $from, $to); + if ($key != $_key) + unset($string[$key]); + } + return $string; + } + else { + return $string; + } + } +} \ No newline at end of file diff --git a/ewomail-admin/core/class/Tp.class.php b/ewomail-admin/core/class/Tp.class.php new file mode 100644 index 0000000..ce67393 --- /dev/null +++ b/ewomail-admin/core/class/Tp.class.php @@ -0,0 +1,127 @@ + +// +---------------------------------------------------------------------- +/** + * 模板操作类 + * */ +class Tp +{ + //smarty模板引擎对象 + public static $smarty; + //当前目录 + public static $curDir; + + /** + * 初始化 + */ + public static function init() + { + $template = "/templates"; + self::$smarty = new Smarty(); + self::$smarty->setTemplateDir(PATH.$template); + self::$smarty->setCompileDir(PATH."/cache/templates/c"); + self::$smarty->setCaching(false); + + self::$curDir = HOME.'/'.MODULE; + $arr = [ + 'HOME'=>HOME, + 'PUBLIC'=>$template.'/'.HOME.'/public' + ]; + + self::assign($arr); + } + + /** + * 输出模板 + * @param string $file 指定模板文件,为空则是当前动作模板 + */ + public static function display($file='') + { + $path = self::getPath($file); + self::isFile($path); + self::$smarty->display($path); + } + + /** + * 读取模板 + * @param string $file + */ + public static function fetch($file='') + { + $path = self::getPath($file); + self::isFile($path); + self::$smarty->fetch($path); + } + + /** + * 注入变量 + * $array 数组 + * */ + public static function assign($array) + { + foreach($array as $key=>$value){ + self::$smarty->assign($key,$value); + } + } + + /** + * 获取模板变量 + * @param string $key + * @return mixed + */ + public static function get($key='') + { + return self::$smarty->getTemplateVars($key); + } + + /** + * 获取模板路径 + * @param string $file 指定模板文件 + * @return string + */ + public static function getPath($file='') + { + if(!$file){ + $path = self::$curDir.'/'.ACTION.'.html'; + }else{ + if($file[0]=='/'){ + $path = $file.'.html'; + }else{ + $path = self::$curDir.'/'.$file.'.html'; + } + } + return $path; + } + + /** + * 检查模板文件是否存在 + * @param $file + */ + public static function isFile($file) + { + $file = self::$smarty->getTemplateDir()[0].$file; + if(!file_exists($file)){ + E::sys('模板文件不存在:'.$file); + } + } + + /** + * 跳转输出模板 + * */ + public static function jump() + { + $path = HOME.'/jump.html'; + self::isFile($path); + self::$smarty->display($path); + } + +} + +?> \ No newline at end of file diff --git a/ewomail-admin/core/class/Upload.class.php b/ewomail-admin/core/class/Upload.class.php new file mode 100644 index 0000000..348a082 --- /dev/null +++ b/ewomail-admin/core/class/Upload.class.php @@ -0,0 +1,428 @@ + array(), //允许上传的文件MiMe类型 + 'maxSize' => 0, //上传的文件大小限制 (0-不做限制) + 'exts' => array(), //允许上传的文件后缀 + 'autoSub' => true, //自动子目录保存文件 + 'subName' => array('date', 'Y-m-d'), //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 + 'rootPath' => '', //保存根路径 + 'savePath' => '', //保存路径 + 'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 + 'saveExt' => '', //文件保存后缀,空则使用原后缀 + 'replace' => false, //存在同名是否覆盖 + 'hash' => true, //是否生成hash编码 + 'callback' => false, //检测文件是否存在回调,如果存在返回文件信息数组 + 'driver' => '', // 文件上传驱动 + 'driverConfig' => array(), // 上传驱动配置 + ); + + /** + * 上传错误信息 + * @var string + */ + private $error = ''; //上传错误信息 + + /** + * 上传驱动实例 + * @var Object + */ + private $uploader; + + /** + * 构造方法,用于构造上传实例 + * @param array $config 配置 + * @param string $driver 要使用的上传驱动 LOCAL-本地上传驱动,FTP-FTP上传驱动 + */ + public function __construct($config = array(), $driver = '', $driverConfig = null){ + /* 获取配置 */ + $this->config = array_merge($this->config, $config); + + /* 设置上传驱动 */ + $this->setDriver($driver, $driverConfig); + + /* 调整配置,把字符串配置参数转换为数组 */ + if(!empty($this->config['mimes'])){ + if(is_string($this->mimes)) { + $this->config['mimes'] = explode(',', $this->mimes); + } + $this->config['mimes'] = array_map('strtolower', $this->mimes); + } + if(!empty($this->config['exts'])){ + if (is_string($this->exts)){ + $this->config['exts'] = explode(',', $this->exts); + } + $this->config['exts'] = array_map('strtolower', $this->exts); + } + } + + /** + * 使用 $this->name 获取配置 + * @param string $name 配置名称 + * @return multitype 配置值 + */ + public function __get($name) { + return $this->config[$name]; + } + + public function __set($name,$value){ + if(isset($this->config[$name])) { + $this->config[$name] = $value; + if($name == 'driverConfig'){ + //改变驱动配置后重置上传驱动 + //注意:必须选改变驱动然后再改变驱动配置 + $this->setDriver(); + } + } + } + + public function __isset($name){ + return isset($this->config[$name]); + } + + /** + * 获取最后一次上传错误信息 + * @return string 错误信息 + */ + public function getError(){ + return $this->error; + } + + /** + * 上传单个文件 + * @param array $file 文件数组 + * @return array 上传成功后的文件信息 + */ + public function uploadOne($file){ + $info = $this->upload(array($file)); + return $info ? $info[0] : $info; + } + + /** + * 上传文件 + * @param 文件信息数组 $files ,通常是 $_FILES数组 + */ + public function upload($files='') { + if('' === $files){ + $files = $_FILES; + } + if(empty($files)){ + $this->error = '没有上传的文件!'; + return false; + } + + /* 检测上传根目录 */ + if(!$this->uploader->checkRootPath(PATH.$this->rootPath)){ + $this->error = $this->uploader->getError(); + return false; + } + + /* 检查上传目录 */ + if(!$this->uploader->checkSavePath($this->savePath)){ + $this->error = $this->uploader->getError(); + return false; + } + + /* 逐个检测并上传文件 */ + $info = array(); + if(function_exists('finfo_open')){ + $finfo = finfo_open ( FILEINFO_MIME_TYPE ); + } + // 对上传文件数组信息处理 + $files = $this->dealFiles($files); + foreach ($files as $key => $file) { + $file['name'] = strip_tags($file['name']); + if(!isset($file['key'])) $file['key'] = $key; + /* 通过扩展获取文件类型,可解决FLASH上传$FILES数组返回文件类型错误的问题 */ + if(isset($finfo)){ + $file['type'] = finfo_file ( $finfo , $file['tmp_name'] ); + } + + /* 获取上传文件后缀,允许上传无后缀文件 */ + $file['ext'] = pathinfo($file['name'], PATHINFO_EXTENSION); + + /* 文件上传检测 */ + if (!$this->check($file)){ + continue; + } + + /* 获取文件hash */ + if($this->hash){ + $file['md5'] = md5_file($file['tmp_name']); + $file['sha1'] = sha1_file($file['tmp_name']); + } + + /* 调用回调函数检测文件是否存在 */ + if($this->callback){ + $data = call_user_func($this->callback, $file); + if( $this->callback && $data ){ + if ( file_exists('.'.$data['path']) ) { + $info[$key] = $data; + continue; + }elseif($this->removeTrash){ + call_user_func($this->removeTrash,$data);//删除垃圾据 + } + } + } + + + /* 生成保存文件名 */ + $savename = $this->getSaveName($file); + if(false == $savename){ + continue; + } else { + $file['savename'] = $savename; + } + + /* 检测并创建子目录 */ + $subpath = $this->getSubPath($file['name']); + if(false === $subpath){ + continue; + } else { + $file['savepath'] = $this->savePath . $subpath; + } + + /* 对图像文件进行严格检测 */ + $ext = strtolower($file['ext']); + if(in_array($ext, array('gif','jpg','jpeg','bmp','png','swf'))) { + $imginfo = getimagesize($file['tmp_name']); + if(empty($imginfo) || ($ext == 'gif' && empty($imginfo['bits']))){ + $this->error = '非法图像文件!'; + continue; + } + } + + /* 保存文件 并记录保存成功的文件 */ + if ($this->uploader->save($file,$this->replace)) { + unset($file['error'], $file['tmp_name']); + $info[$key] = $file; + } else { + $this->error = $this->uploader->getError(); + } + } + if(isset($finfo)){ + finfo_close($finfo); + } + return empty($info) ? false : $info; + } + + /** + * 转换上传文件数组变量为正确的方式 + * @access private + * @param array $files 上传的文件变量 + * @return array + */ + private function dealFiles($files) { + $fileArray = array(); + $n = 0; + foreach ($files as $key=>$file){ + if(is_array($file['name'])) { + $keys = array_keys($file); + $count = count($file['name']); + for ($i=0; $i<$count; $i++) { + $fileArray[$n]['key'] = $key; + foreach ($keys as $_key){ + $fileArray[$n][$_key] = $file[$_key][$i]; + } + $n++; + } + }else{ + $fileArray = $files; + break; + } + } + return $fileArray; + } + + /** + * 设置上传驱动 + * @param string $driver 驱动名称 + * @param array $config 驱动配置 + */ + private function setDriver($driver = null, $config = null){ + //$driver = $driver ? : ($this->driver ? : C('FILE_UPLOAD_TYPE')); + //$config = $config ? : ($this->driverConfig ? : C('UPLOAD_TYPE_CONFIG')); + //$class = strpos($driver,'\\')? $driver : 'Think\\Upload\\Driver\\'.ucfirst(strtolower($driver)); + $this->uploader = new Local($config); + //$this->uploader = new Ftp(array()); + if(!$this->uploader){ + E::error("不存在上传驱动"); + } + } + + /** + * 检查上传的文件 + * @param array $file 文件信息 + */ + private function check($file) { + /* 文件上传失败,捕获错误代码 */ + if ($file['error']) { + $this->error($file['error']); + return false; + } + + /* 无效上传 */ + if (empty($file['name'])){ + $this->error = '未知上传错误!'; + } + + /* 检查是否合法上传 */ + if (!is_uploaded_file($file['tmp_name'])) { + $this->error = '非法上传文件!'; + return false; + } + + /* 检查文件大小 */ + if (!$this->checkSize($file['size'])) { + $this->error = '上传文件大小不符!'; + return false; + } + + /* 检查文件Mime类型 */ + //TODO:FLASH上传的文件获取到的mime类型都为application/octet-stream + if (!$this->checkMime($file['type'])) { + $this->error = '上传文件MIME类型不允许!'; + return false; + } + + /* 检查文件后缀 */ + if (!$this->checkExt($file['ext'])) { + $this->error = '上传文件后缀不允许'; + return false; + } + + /* 通过检测 */ + return true; + } + + + /** + * 获取错误代码信息 + * @param string $errorNo 错误号 + */ + private function error($errorNo) { + switch ($errorNo) { + case 1: + $this->error = '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值!'; + break; + case 2: + $this->error = '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值!'; + break; + case 3: + $this->error = '文件只有部分被上传!'; + break; + case 4: + $this->error = '没有文件被上传!'; + break; + case 6: + $this->error = '找不到临时文件夹!'; + break; + case 7: + $this->error = '文件写入失败!'; + break; + default: + $this->error = '未知上传错误!'; + } + } + + /** + * 检查文件大小是否合法 + * @param integer $size 数据 + */ + private function checkSize($size) { + return !($size > $this->maxSize) || (0 == $this->maxSize); + } + + /** + * 检查上传的文件MIME类型是否合法 + * @param string $mime 数据 + */ + private function checkMime($mime) { + return empty($this->config['mimes']) ? true : in_array(strtolower($mime), $this->mimes); + } + + /** + * 检查上传的文件后缀是否合法 + * @param string $ext 后缀 + */ + private function checkExt($ext) { + return empty($this->config['exts']) ? true : in_array(strtolower($ext), $this->exts); + } + + /** + * 根据上传文件命名规则取得保存文件名 + * @param string $file 文件信息 + */ + private function getSaveName($file) { + $rule = $this->saveName; + if (empty($rule)) { //保持文件名不变 + /* 解决pathinfo中文文件名BUG */ + $filename = substr(pathinfo("_{$file['name']}", PATHINFO_FILENAME), 1); + $savename = $filename; + } else { + $savename = $this->getName($rule, $file['name']); + if(empty($savename)){ + $this->error = '文件命名规则错误!'; + return false; + } + } + + /* 文件保存后缀,支持强制更改文件后缀 */ + $ext = empty($this->config['saveExt']) ? $file['ext'] : $this->saveExt; + + return $savename . '.' . $ext; + } + + /** + * 获取子目录的名称 + * @param array $file 上传的文件信息 + */ + private function getSubPath($filename) { + $subpath = ''; + $rule = $this->subName; + if ($this->autoSub && !empty($rule)) { + $subpath = $this->getName($rule, $filename) . '/'; + + if(!empty($subpath) && !$this->uploader->mkdir($this->savePath . $subpath)){ + $this->error = $this->uploader->getError(); + return false; + } + } + return $subpath; + } + + /** + * 根据指定的规则获取文件或目录名称 + * @param array $rule 规则 + * @param string $filename 原文件名 + * @return string 文件或目录名称 + */ + private function getName($rule, $filename){ + $name = ''; + if(is_array($rule)){ //数组规则 + $func = $rule[0]; + $param = (array)$rule[1]; + foreach ($param as &$value) { + $value = str_replace('__FILE__', $filename, $value); + } + $name = call_user_func_array($func, $param); + } elseif (is_string($rule)){ //字符串规则 + if(function_exists($rule)){ + $name = call_user_func($rule); + } else { + $name = $rule; + } + } + return $name; + } + +} diff --git a/ewomail-admin/core/config.php b/ewomail-admin/core/config.php new file mode 100644 index 0000000..778cd37 --- /dev/null +++ b/ewomail-admin/core/config.php @@ -0,0 +1,20 @@ + 'localhost',//数据库连接地址 + 'dbuser' => 'ewomail',//数据库账号 + 'dbpw' => 'ewomail',//数据库密码 + 'dbname' => 'ewomail',//数据库名称 + 'dbcharset' => 'utf8',//数据库编码 + 'dbprefix'=> 'i_',//数据库表的前缀 + 'code_key'=>'',//加密钥匙 + 'url'=>'',//网站链接,后面不要加/线 + 'webmail_url'=>'',//邮件系统链接,后面不要加/线 + 'maildir'=>'/ewomail/mail',//邮件存放目录,邮件安装后请不要修改 + 'home_default' =>'Center',//默认项目 + 'home_allow' => ['Center','Api'],//允许项目 + 'module_default' =>'Index',//默认模块 + 'action_default' =>'index',//默认控制器 + 'prefix'=>'ewomail_',//网站通用前缀,包括session,cookie + +]; diff --git a/ewomail-admin/core/functions.php b/ewomail-admin/core/functions.php new file mode 100644 index 0000000..b60d810 --- /dev/null +++ b/ewomail-admin/core/functions.php @@ -0,0 +1,459 @@ + +// +---------------------------------------------------------------------- +/** + * 全局函数库,自动加载 + */ + +/** + * 获取系统文件配置 + * */ +function C($key){ + static $config; + if($config){ + return $config[$key]; + } + $config = include(PATH.'/core/config.php'); + return $config[$key]; +} + +/** + * 设置或获取一个get/post静态参数,设置参数后将会覆盖get/post传递的参数 + * 一般应用在数据保存 + * @param null $arr 空为获取,存值设置 + * @return array|null + */ +function istatic($arr=null) +{ + static $newArr = []; + + if(is_array($arr)){ + $newArr = $arr; + } + + return $newArr; +} + +/** + * 获取post/get参数 + * @param $key + * @return array|mixed|string + */ +function iany($key) +{ + if(!$key){ + return ''; + } + $data = iget($key); + if(!$data){ + $data = ipost($key); + } + return $data; +} + +/** + * 获取get参数 + * @param string $key + * @return array|mixed|string + */ +function iget($key=''){ + if($key){ + $static = istatic(); + if(isset($static[$key])){ + $data = $static[$key]; + }else{ + $data = $_GET[$key]; + } + }else{ + $data = $_GET; + } + return iFilter($data); +} + +/** + * 获取post参数 + * @param string $key + * @return array|mixed|string + */ +function ipost($key=''){ + if($key){ + $static = istatic(); + if(isset($static[$key])){ + $data = $static[$key]; + }else{ + $data = $_POST[$key]; + } + + }else{ + $data = $_POST; + } + return iFilter($data); +} + +/** + * 参数过滤 + * */ +function iFilter($var) +{ + if(is_array($var)){ + foreach($var as $key=>$v){ + $var[$key] = iFilter($v); + } + }else{ + $var = trim(htmlspecialchars($var)); + $var = str_replace(array('\n', '\r'), array(chr(10), chr(13)), addslashes($var)); + } + return $var; + +} + +/** + * 设置/获取语言包 + * @param $value + * @param string $file 留空获取,存值设置 + * @return array|mixed + */ +function L($value,$file=''){ + static $lang = []; + if($file){ + $r = include $file; + foreach($r as $key=>$v){ + $lang[$key] = $v; + } + return $lang; + } + + if(!$lang[$value]){ + return $value; + } + return $lang[$value]; + +} + +/** + * 获取字符串长度(包含中文) + * @param $str + * @return int + */ +function str_len($str){ + $length = strlen(preg_replace('/[\x00-\x7F]/', '', $str)); + if ($length){ + return strlen($str) - $length + intval($length / 3); + }else{ + return strlen($str); + } +} + +/** + * 获取数据表的前缀 + * @param $tablename 表名 + * @return string 返回表的前缀和表明 + */ +function table($tablename) +{ + return C('dbprefix').$tablename; +} + +/** + * 设置url + * @param $path 定义 模块/控制器/动作 (如不填写模块,函数自动加入当前模块) + * @param null $p ?后面的参数(数组或字符串) + * @return string + */ +function U($path,$p=null) +{ + $path = trim($path,'/'); + $paths = explode('/',$path,3); + if(count($paths)<3){ + if(HOME!=C('home_default')){ + array_unshift($paths,HOME); + } + $path = implode("/",$paths); + } + + if($path){ + $path = '/'.$path; + }else{ + $path = '/'; + } + + if($p){ + if(is_array($p)){ + $var = http_build_query($p); + $path .= '?'.$var; + }else{ + $path .= '?'.$p; + } + } + + return $path; + +} + +/** + * 开启事务 + * */ +function trans(callable $fun) +{ + App::$db->startTrans(); + $r = $fun(); + App::$db->commit(); + return $r; +} + +/** + * 捕获异常 + * @param callable $fun 执行流程的函数 + * @param null $e 需要传递引用变量,出现异常后将会把异常对象变量赋值到该变量 + * @return bool 如果出现异常将会返回false + */ +function E(callable $fun,&$e=null) +{ + try{ + $r = $fun(); + return $r; + }catch(E $_e){ + $e = $_e; + return false; + } +} + +/** + * 邮箱格式验证 + * inAddress 邮箱 + * return 0 格式错误 1 格式正确 + */ +function check_email($inAddress){ + return preg_match("/^[a-zA-Z0-9_\\.-]+@[a-zA-Z0-9_-]+\\..+$/",$inAddress); + +} + +/** + * 域名格式验证 + * $str 邮箱 + * return 0 格式错误 1 格式正确 + */ +function check_domain($str) +{ + return preg_match("/^[_a-zA-Z0-9-]+(\.[a-zA-Z0-9]+)+$/",$str); +} + + +/** + * 格式化数字,以标准MONEY格式输出 + * @param $money + * @return string + */ +function money($money) +{ + $money = number_format($money, 2); + $money = floatval($money); + return $money; +} + +/** + * 指定或获取上一页地址 + * @param $bool true获取上一页地址,false将用U函数获取$path地址 + * @param $path + * @param string $p + * @return string + */ +function asForward($bool,$path,$p='') +{ + if($bool){ + $url = $_SERVER['HTTP_REFERER']; + }else{ + $url = U($path,$p); + } + return urlencode($url); +} + + +/** + * 获取客户端IP地址 + * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 + * @param boolean $adv 是否进行高级模式获取(有可能被伪装) + * @return mixed + */ +function get_client_ip($type = 0,$adv=true) { + $type = $type ? 1 : 0; + static $ip = NULL; + if ($ip !== NULL) return $ip[$type]; + if($adv){ + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + $pos = array_search('unknown',$arr); + if(false !== $pos) unset($arr[$pos]); + $ip = trim($arr[0]); + }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + }elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; + } + }elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; + } + // IP地址合法验证 + $long = sprintf("%u",ip2long($ip)); + $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); + return $ip[$type]; +} + + +/** + * 字符串加密以及解密函数 + * + * @param string $string 原文或者密文 + * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE + * @param string $key 密钥 + * @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效 + * @return string 处理后的 原文或者 经过 base64_encode 处理后的密文 + * + * @example + * + * $a = authcode('abc', 'ENCODE', 'key'); + * $b = authcode($a, 'DECODE', 'key'); // $b(abc) + * + * $a = authcode('abc', 'ENCODE', 'key', 3600); + * $b = authcode('abc', 'DECODE', 'key'); // 在一个小时内,$b(abc),否则 $b 为空 + */ +function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { + + $ckey_length = 4; //note 随机密钥长度 取值 0-32; + //note 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。 + //note 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方 + //note 当此值为 0 时,则不产生随机密钥 + + $key = md5($key ? $key : C('code_key')); + $keya = md5(substr($key, 0, 16)); + $keyb = md5(substr($key, 16, 16)); + $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; + + $cryptkey = $keya.md5($keya.$keyc); + $key_length = strlen($cryptkey); + + $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; + $string_length = strlen($string); + + $result = ''; + $box = range(0, 255); + + $rndkey = array(); + for($i = 0; $i <= 255; $i++) { + $rndkey[$i] = ord($cryptkey[$i % $key_length]); + } + + for($j = $i = 0; $i < 256; $i++) { + $j = ($j + $box[$i] + $rndkey[$i]) % 256; + $tmp = $box[$i]; + $box[$i] = $box[$j]; + $box[$j] = $tmp; + } + + for($a = $j = $i = 0; $i < $string_length; $i++) { + $a = ($a + 1) % 256; + $j = ($j + $box[$a]) % 256; + $tmp = $box[$a]; + $box[$a] = $box[$j]; + $box[$j] = $tmp; + $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); + } + + if($operation == 'DECODE') { + if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { + return substr($result, 26); + } else { + return ''; + } + } else { + return $keyc.str_replace('=', '', base64_encode($result)); + } +} + +/** + * 类似于var_dump,以HTML形式输出 + * @param $var + * @param bool $echo + * @param null $label + * @param bool $strict + * @return mixed|null|string + */ +function dump($var, $echo=true, $label=null, $strict=true) { + $label = ($label === null) ? '' : rtrim($label) . ' '; + if (!$strict) { + if (ini_get('html_errors')) { + $output = print_r($var, true); + $output = '
' . $label . htmlspecialchars($output, ENT_QUOTES) . '
'; + } else { + $output = $label . print_r($var, true); + } + } else { + ob_start(); + var_dump($var); + $output = ob_get_clean(); + if (!extension_loaded('xdebug')) { + $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output); + $output = '
' . $label . htmlspecialchars($output, ENT_QUOTES) . '
'; + } + } + if ($echo) { + echo($output); + return null; + }else + return $output; +} + +function getMailUrl() +{ + $url = C('webmail_url'); + if(substr($url,0,1)=='*'){ + $arr = explode(":",$url); + if($arr[1]){ + $url = 'http://'.$_SERVER['SERVER_ADDR'].':'.$arr[1]; + }else{ + $url = 'http://'.$_SERVER['SERVER_ADDR']; + } + return $url; + } + return $url; +} + +/** + * 字节转换 + * @param $bytes 字节 + * @param string $unit 转换成MB/GB + * @param int $decimals 小数点后保留几位,默认2位 + * @return string + */ +function byteFormat($bytes, $unit = "", $decimals = 2) { + $units = array('B' => 0, 'KB' => 1, 'MB' => 2, 'GB' => 3, 'TB' => 4, 'PB' => 5, 'EB' => 6, 'ZB' => 7, 'YB' => 8); + + $value = 0; + if ($bytes > 0) { + // Generate automatic prefix by bytes + // If wrong prefix given + if (!array_key_exists($unit, $units)) { + $pow = floor(log($bytes)/log(1024)); + $unit = array_search($pow, $units); + } + + // Calculate byte value by prefix + $value = ($bytes/pow(1024,floor($units[$unit]))); + } + + // If decimals is not numeric or decimals is less than 0 + // then set default value + if (!is_numeric($decimals) || $decimals < 0) { + $decimals = 2; + } + + // Format output + return sprintf('%.' . $decimals . 'f', $value); +} diff --git a/ewomail-admin/core/run.php b/ewomail-admin/core/run.php new file mode 100644 index 0000000..77ad695 --- /dev/null +++ b/ewomail-admin/core/run.php @@ -0,0 +1,107 @@ + +// +---------------------------------------------------------------------- +/** + * 主程序运行 + */ + +if(!defined("PATH")) exit; +error_reporting(E_ALL & ~E_NOTICE); +header("Content-type: text/html; charset=utf-8"); +include PATH.'/core/functions.php'; +include PATH.'/lib/smarty-3.1.24/libs/Smarty.class.php'; + +//注册类 +spl_autoload_register(function($class_name){ + static $class_arr; + $dir_arr = [ + PATH.'/api/', + PATH.'/core/class/', + ]; + foreach($dir_arr as $key=>$value){ + if(!$class_arr[$class_name]){ + $file = $dir_arr[$key].$class_name.'.class.php'; + if(file_exists($file)){ + include $file; + $class_arr[$class_name] = true; + break; + } + } + } +}); + +//url映射 +Rout::core(function(){ + //nginx + if(isset($_SERVER['DOCUMENT_URI'])){ + $DOCUMENT_URI = trim($_SERVER['DOCUMENT_URI'],'/'); + $paths = explode('/',$DOCUMENT_URI); + unset($paths[0]); + $_SERVER['REDIRECT_URL'] = '/'.implode("/",$paths); + $paths = null; + } + //apache + if(isset($_SERVER['REDIRECT_URL'])){ + $REDIRECT_URL = trim($_SERVER['REDIRECT_URL'],'/'); + $paths = explode('/',$REDIRECT_URL); + if(count($paths)<3){ + if($paths[0]!=C('home_default') && !in_array($paths[0],C('home_allow'))){ + array_unshift($paths,C('home_default')); + } + } + $home = $paths[0]; + $module = $paths[1]?$paths[1]:C('module_default'); + $action = $paths[2]?$paths[2]:C('action_default'); + }else{ + $home = C('home_default'); + $module = C('module_default'); + $action = C('action_default'); + } + + define("HOME",$home);//当前模块 + define("MODULE",$module);//当前控制器 + define("ACTION",$action);//当前动作 + if(!in_array(HOME,C('home_allow'))){ + E::sys($home.'模块不存在'); + } + define('REQUEST_METHOD',$_SERVER['REQUEST_METHOD']); + define('IS_GET', REQUEST_METHOD =='GET' ? true : false); + define('IS_POST', REQUEST_METHOD =='POST' ? true : false); + define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')) ? true : false); +}); + + +//初始化 +Rout::core(function(){ + $session_id = iget('session_id')?iget('session_id'):ipost('session_id'); + if($session_id){ + session_id($session_id); + } + session_start(); + + Tp::init(); + $file = PATH.'/module/'.HOME.'/'.MODULE.'.php'; + $initFile = PATH.'/module/'.HOME.'/'.'_init.php'; + + if(file_exists($initFile)){ + include $initFile; + }else{ + E::sys(HOME.'模块的_init文件不存在'); + } + if(file_exists($file)){ + include $file; + }else{ + E::sys(MODULE.'控制器不存在'); + } + +}); + +Rout::run(); + diff --git a/ewomail-admin/core/version b/ewomail-admin/core/version new file mode 100644 index 0000000..ef2d578 --- /dev/null +++ b/ewomail-admin/core/version @@ -0,0 +1 @@ +1.05 \ No newline at end of file diff --git a/ewomail-admin/index.php b/ewomail-admin/index.php new file mode 100644 index 0000000..e5735a5 --- /dev/null +++ b/ewomail-admin/index.php @@ -0,0 +1,17 @@ + +// +---------------------------------------------------------------------- +/** + * PHP版本不能低于5.4 + */ +if(version_compare(PHP_VERSION,'5.4.0','<')) die('require PHP > 5.4.0 !'); +define("PATH",dirname(__FILE__)); +require './core/run.php'; + diff --git a/ewomail-admin/lang/config.php b/ewomail-admin/lang/config.php new file mode 100644 index 0000000..9deb7f2 --- /dev/null +++ b/ewomail-admin/lang/config.php @@ -0,0 +1,7 @@ +'中文', + 'zh-hk'=>'繁体', + 'en-us'=>'English', +]; diff --git a/ewomail-admin/lang/en-us.js b/ewomail-admin/lang/en-us.js new file mode 100644 index 0000000..5db915f --- /dev/null +++ b/ewomail-admin/lang/en-us.js @@ -0,0 +1,15 @@ +$L = { + 1001:'The network timed out, please try again', + 1002:'Please select the data to be operated', + 1003:'Are you sure you want to batch delete?', + 1004:'Please select the deleted data', + 1005:'Are you sure to delete?', + 1006:'Data parsing failed. Please try again', + 1007:'Error message:', + 1008:'Turn off after 5 seconds', + 1009:'2 seconds after the closure', + 1010:'confirm', + 1011:'Prompt message', + 1012:'cancel', + 1013:'Data list' +}; \ No newline at end of file diff --git a/ewomail-admin/lang/en-us.php b/ewomail-admin/lang/en-us.php new file mode 100644 index 0000000..425dc98 --- /dev/null +++ b/ewomail-admin/lang/en-us.php @@ -0,0 +1,200 @@ + +// +---------------------------------------------------------------------- +/** + * 中文语言包 + */ +return [ + '100'=>'Background Management System', + + //系统语言 + '1001'=>'Save successfully', + '1002'=>'Save failed', + '1003'=>'Delete Data Successfully', + '1004'=>'You do not have permission to view or manipulate', + '1005'=>'Data not present', + '1006'=>'DELETE FAILED', + '1100'=>'Add', + '1101'=>'Table of Contents', + '1102'=>'Select All', + '1103'=>'Modifications', + '1104'=>'Delete', + '1105'=>'View', + '1106'=>'Operation', + '1107'=>'Please fill in', + '1108'=>'Save', + '1109'=>'None', + '1110'=>'No', + '1111'=>'Yes', + '1112'=>'Menu column data does not exist', + '1113'=>'Enable', + '1114'=>'Creation Time', + '1115'=>'Modification Time', + '1116'=>'Tip', + '1117'=>'Data Inquiry', + '1118'=>'Inquiry', + '1119'=>'Date', + '1200'=>'Empty', + '1201'=>'Sorting', + '1202'=>'Default', + '1203'=>'Unlimited', + '1204'=>'Basic Configuration', + '1205'=>'Advanced Configuration', + '1206'=>'Correct', + '1207'=>'Error', + '1208'=>'State', + '1209'=>'Website Title', + '1210'=>'Language', + '1211'=>'Verify Code', + + + //菜单语言包 + '90100'=>'Mailbox Management', + '90101'=>'Mailing List', + '90102'=>'Mailbox Add', + '90103'=>'Mailbox Domain', + '90105'=>'Mailbox System Settings', + '90200'=>'System Management', + '90201'=>'List of Administrators', + '90202'=>'Admin Add', + '90203'=>'Role List', + '90204'=>'Roles Add', + '90205'=>'System Settings', + '90206'=>'Operation Log', + + //系统管理 + '2001'=>'Roles', + '2002'=>'Role Name', + '2003'=>'Please fill in the role name', + '2004'=>'Permission settings', + '2005'=>'Menu Name', + '2006'=>'Authority', + '2007'=>'Add / Modify', + '2008'=>'Administrator', + '2009'=>'English letters, numbers, or underscores, between 3 and 20 characters, case insensitive', + '2010'=>'Name', + '2011'=>'Administrator Type', + '2012'=>'General Manager', + '2013'=>'Super Admin', + '2014'=>'Admin (Roles)', + '2015'=>'Change Password', + '2016'=>'Password', + '2017'=>'Length 8-20 characters, please set the password more complex, it is best to include numbers and letters', + '2018'=>'Confirm Password', + '2019'=>'Administrator Account Format Error', + '2020'=>'Password character length is incorrect', + '2021'=>'2 passwords do not match', + '2022'=>'Administrator account already exists, please change account', + '2023'=>'Sign In', + '2024'=>'The administrator account does not exist', + '2025'=>'Password is incorrect', + '2026'=>'landing successful', + '2027'=>'Original Password', + '2028'=>'New password', + '2029'=>'Confirm New Password', + '2030'=>'original password is incorrect', + '2031'=>'System default language', + '2032'=>'The language you have selected does not exist', + '2033'=>'Note', + '2034'=>'Back to previous page', + '2035'=>'Mailbox Management Background', + '2036'=>'This is the default administrator account, can not be deleted', + '2037'=>'You are using the system default password, please modify as soon as possible', + '2038'=>'You can use the current account login web mail system control panel for management', + '2039'=>'Click to login', + '2040'=>'Password must contain both letters and numbers', + '2041'=>'This account has been disabled', + '2042'=>'You log on to the account more than 5 times the number of failures, please try to log an hour', + '2043'=>'Clear Log', + '2044'=>'Operations Manager', + '2045'=>'IP', + '2046'=>'Operation Record', + '2047'=>'Make sure to clear all logs? ', + + + //邮箱管理 + '3001'=>'Restrictions are restricted to the mailbox address under the domain name, only for external mailboxes. ', + '3002'=>'Restricted Transmission', + '3003'=>'This parameter can be set to limit the number of single-day delivery per mailbox, 0 for no limit, the default 0', + '3004'=>'Restricted Received', + '3005'=>'This parameter can be set to limit the number of mailboxes received per domain under the domain name, 0 is not restricted, the default 0', + '3006'=>'Limit IP receive amount', + '3007'=>'Set this parameter to limit the number of mailboxes sent to this domain by the other IP, 0 is unrestricted, default 0', + '3008'=>'Limited Capacity', + '3009'=>'Unit G, only integers, 0 for no limit, 0 by default', + '3010'=>'Mailbox domain name format error', + '3011'=>'Mailbox domain already exists', + '3012'=>'E-mail address', + '3013'=>'Number of transceivers', + '3014'=>'TX / RX Limit', + '3015'=>'Capacity limit', + '3016'=>'Mailbox suffix domain does not exist', + '3017'=>'E-mail address already exists', + '3018'=>'Start Date', + '3019'=>'End Date', + '3020'=>'Number of Items to Send', + '3021'=>'Number of Receipts', + '3022'=>'Is Clear Empty? ', + '3023'=>'Name', + '3024'=>'Contact Us', + '3025'=>'E-mail Address or Domain Name', + '3026'=>'List Types', + '3027'=>'Blacklist', + '3028'=>'White List', + '3029'=>'E-mail address can not be empty', + '3030'=>'E-mail address writing
single e-mail address: test@test.com.cn
the entire domain: test.com', + '3031'=>'Black / White List', + '3032'=>'List Types', + '3033'=>'Occupied Capacity (Ascending)', + '3034'=>'Occupied Capacity (Descending Direction)', + '3035'=>'Occupied Capacity (GB)', + '3036'=>'Host Name', + '3037'=>'Main Domain Name', + '3038'=>'imap', + '3039'=>'smtp', + '3040'=>'Example:', + '3041'=>'webmail', + '3042'=>'Capacity Boundaries (Percentage)', + '3043'=>'When the capacity reaches the border will send a message to inform the user, 0 is not sent a notice', + '3044'=>'Mailbox Notification Name', + '3045'=>'is responsible for informing the user\'s e-mail address name, do not need to fill in the mailbox suffix, the default postmaster', + '3046'=>'This configuration will modify the system files, please do not modify frequently', + '3047'=>'dkim data', + '3048'=>'Recording Type', + '3049'=>'Host Records', + '3050'=>'Record Value', + '3051'=>'dkim validation', + '3052'=>'Validation Value', + '3053'=>'Home', + '3054'=>'Profile', + '3055'=>'webmail', + '3056'=>'Exit', + '3057'=>'Welcome back', + '3058'=>'Mailbox Queue', + '3059'=>'the number of items sent', + '3060'=>'NUMBER OF RECIPES', + '3061'=>'System Information', + '3062'=>'Hostname', + '3063'=>'server ip', + '3064'=>'Operating System', + '3065'=>'web server', + '3066'=>'Upload file limit', + '3067'=>'post limit', + '3068'=>'Authorization Information', + '3069'=>'ewomail version', + '3070'=>'Authorization Status', + '3071'=>'Official Website', + '3072'=>'Contact Us', + '3073'=>'dkim View', + '3074'=>'E-mail address @ the front of the characters can not be less than three words', + '3075'=>'Mailbox User', + '3076'=>'Mailbox Usage', + '3077'=>'Web Mail Control Panel Permissions', +]; diff --git a/ewomail-admin/lang/zh-cn.js b/ewomail-admin/lang/zh-cn.js new file mode 100644 index 0000000..ba6159b --- /dev/null +++ b/ewomail-admin/lang/zh-cn.js @@ -0,0 +1,15 @@ +$L = { + 1001:'网络超时,请重试', + 1002:'请选择要操作的数据', + 1003:'确认进行批量删除吗?', + 1004:'请选择删除的数据', + 1005:'确认进行删除吗?', + 1006:'数据解析失败,请重试', + 1007:'错误提示:', + 1008:'5秒后关闭', + 1009:'2秒后关闭', + 1010:'确认', + 1011:'提示信息', + 1012:'取消', + 1013:'数据列表' +}; \ No newline at end of file diff --git a/ewomail-admin/lang/zh-cn.php b/ewomail-admin/lang/zh-cn.php new file mode 100644 index 0000000..1074d81 --- /dev/null +++ b/ewomail-admin/lang/zh-cn.php @@ -0,0 +1,200 @@ + +// +---------------------------------------------------------------------- +/** + * 中文语言包 + */ +return [ + '100'=>'后台管理系统', + + //系统语言 + '1001'=>'保存成功', + '1002'=>'保存失败', + '1003'=>'成功删除数据', + '1004'=>'你没有权限查看或操作', + '1005'=>'数据不存在', + '1006'=>'删除失败', + '1100'=>'添加', + '1101'=>'内容列表', + '1102'=>'全选', + '1103'=>'修改', + '1104'=>'删除', + '1105'=>'查看', + '1106'=>'操作', + '1107'=>'请填写', + '1108'=>'保存', + '1109'=>'无', + '1110'=>'否', + '1111'=>'是', + '1112'=>'菜单栏目数据不存在', + '1113'=>'启用', + '1114'=>'创建时间', + '1115'=>'修改时间', + '1116'=>'提示', + '1117'=>'数据查询', + '1118'=>'查询', + '1119'=>'日期', + '1200'=>'清空', + '1201'=>'排序', + '1202'=>'默认', + '1203'=>'无限制', + '1204'=>'基本配置', + '1205'=>'高级配置', + '1206'=>'正确', + '1207'=>'错误', + '1208'=>'状态', + '1209'=>'网站标题', + '1210'=>'语言', + '1211'=>'验证码', + + + //菜单语言包 + '90100'=>'邮箱管理', + '90101'=>'邮箱列表', + '90102'=>'邮箱添加', + '90103'=>'邮箱域名', + '90105'=>'邮箱系统设置', + '90200'=>'系统管理', + '90201'=>'管理员列表', + '90202'=>'管理员添加', + '90203'=>'角色列表', + '90204'=>'角色添加', + '90205'=>'系统设置', + '90206'=>'操作日志', + + //系统管理 + '2001'=>'角色', + '2002'=>'角色名称', + '2003'=>'请填写角色名称', + '2004'=>'权限设置', + '2005'=>'菜单名称', + '2006'=>'权限', + '2007'=>'添加/修改', + '2008'=>'管理员账号', + '2009'=>'英文字母,数字或下划线,在3-20个字符之间,不区分大小写', + '2010'=>'名称', + '2011'=>'管理员类型', + '2012'=>'普通管理员', + '2013'=>'超级管理员', + '2014'=>'管理组(角色)', + '2015'=>'修改密码', + '2016'=>'密码', + '2017'=>'长度8-20个字符,请将密码设置复杂些,最好包含数字和字母', + '2018'=>'确认密码', + '2019'=>'管理员账号格式错误', + '2020'=>'密码字符长度不正确', + '2021'=>'2个密码不一致', + '2022'=>'管理员账号已存在,请更换账号', + '2023'=>'立即登录', + '2024'=>'管理员账号不存在', + '2025'=>'密码不正确', + '2026'=>'登陆成功', + '2027'=>'原始密码', + '2028'=>'新密码', + '2029'=>'确认新密码', + '2030'=>'原始密码不正确', + '2031'=>'系统默认语言', + '2032'=>'你选择的语言不存在', + '2033'=>'提示信息', + '2034'=>'返回上一页', + '2035'=>'邮箱管理后台', + '2036'=>'这是默认管理员账号,不能删除', + '2037'=>'你使用的是系统默认密码,请尽快修改', + '2038'=>'你可以使用现在的账号登陆web邮件系统控制面板进行管理,', + '2039'=>'点击登陆', + '2040'=>'密码必须同时包含字母和数字', + '2041'=>'该账号已被禁用', + '2042'=>'你登录该账号的失败次数连续超过5次,请一个小时后再尝试登录', + '2043'=>'清空日志', + '2044'=>'操作管理员', + '2045'=>'IP', + '2046'=>'操作记录', + '2047'=>'确认清空所有日志吗?', + + + //邮箱管理 + '3001'=>'限制是针对域名下的邮箱地址,只针对外部邮箱进行限制。', + '3002'=>'限制发送量', + '3003'=>'设置该参数可以限制域名下每个邮箱单天发送量,0为不限制,默认0', + '3004'=>'限制接收量', + '3005'=>'设置该参数可以限制域名下每个邮箱单天接收量,0为不限制,默认0', + '3006'=>'限制IP接收量', + '3007'=>'设置该参数可以限制对方IP发送到本域的邮箱数量,0为不限制,默认0', + '3008'=>'限制容量', + '3009'=>'单位G,只可输入整数,0为不限制,默认0', + '3010'=>'邮箱域名格式错误', + '3011'=>'邮箱域名已存在', + '3012'=>'邮箱地址', + '3013'=>'收发数量', + '3014'=>'收发限制', + '3015'=>'容量限制', + '3016'=>'邮箱的后缀域名不存在', + '3017'=>'邮箱地址已存在', + '3018'=>'开始日期', + '3019'=>'结束日期', + '3020'=>'发件数量', + '3021'=>'收件数量', + '3022'=>'确认清空吗?', + '3023'=>'姓名', + '3024'=>'联系电话', + '3025'=>'邮箱地址或域名', + '3026'=>'名单类型', + '3027'=>'黑名单', + '3028'=>'白名单', + '3029'=>'邮箱地址不能为空', + '3030'=>'邮箱地址的写法
单个邮箱地址:test@test.com.cn
整个域:test.com', + '3031'=>'黑/白名单列表', + '3032'=>'名单类型', + '3033'=>'占用容量(升序)', + '3034'=>'占用容量(降序)', + '3035'=>'占用容量(GB)', + '3036'=>'主机名称', + '3037'=>'邮箱主域名', + '3038'=>'imap', + '3039'=>'smtp', + '3040'=>'例子:', + '3041'=>'webmail', + '3042'=>'容量边界(百分比)', + '3043'=>'当容量达到边界后将发送邮件通知用户,0为不发送通知', + '3044'=>'邮箱通知名称', + '3045'=>'负责通知用户的邮箱地址名称,不需要填写邮箱后缀,默认postmaster', + '3046'=>'该配置将会修改系统文件,请不要频繁修改', + '3047'=>'dkim数据', + '3048'=>'记录类型', + '3049'=>'主机记录', + '3050'=>'记录值', + '3051'=>'dkim验证', + '3052'=>'验证值', + '3053'=>'首页', + '3054'=>'个人资料', + '3055'=>'web邮件系统', + '3056'=>'退出', + '3057'=>'欢迎你回来', + '3058'=>'邮箱队列', + '3059'=>'当天发件数量', + '3060'=>'当天收件数量', + '3061'=>'系统信息', + '3062'=>'主机名', + '3063'=>'服务器ip', + '3064'=>'操作系统', + '3065'=>'web服务器', + '3066'=>'上传文件限制', + '3067'=>'post限制', + '3068'=>'授权信息', + '3069'=>'ewomail版本', + '3070'=>'授权状态', + '3071'=>'官方网站', + '3072'=>'联系电话', + '3073'=>'dkim查看', + '3074'=>'邮箱地址@前面的字符不能少于3个字数', + '3075'=>'邮箱用户', + '3076'=>'邮箱占用', + '3077'=>'web邮件控制面板权限', +]; diff --git a/ewomail-admin/lang/zh-hk.js b/ewomail-admin/lang/zh-hk.js new file mode 100644 index 0000000..66ae802 --- /dev/null +++ b/ewomail-admin/lang/zh-hk.js @@ -0,0 +1,15 @@ +$L = { + 1001:'網絡超時,請重試', + 1002:'請選擇要操作的數據', + 1003:'確認進行批量刪除嗎?', + 1004:'請選擇刪除的數據', + 1005:'確認進行刪除嗎?', + 1006:'數據解析失敗,請重試', + 1007:'錯誤提示:', + 1008:'5秒後關閉', + 1009:'2秒後關閉', + 1010:'確認', + 1011:'提示信息', + 1012:'取消', + 1013:'數據列表' +}; \ No newline at end of file diff --git a/ewomail-admin/lang/zh-hk.php b/ewomail-admin/lang/zh-hk.php new file mode 100644 index 0000000..0679341 --- /dev/null +++ b/ewomail-admin/lang/zh-hk.php @@ -0,0 +1,200 @@ + +// +---------------------------------------------------------------------- +/** + * 中文语言包 + */ +return [ + '100'=>'後台管理系統', + + //系统语言 + '1001'=>'保存成功', + '1002'=>'保存失敗', + '1003'=>'成功刪除數據', + '1004'=>'你沒有權限查看或操作', + '1005'=>'數據不存在', + '1006'=>'刪除失敗', + '1100'=>'添加', + '1101'=>'內容列表', + '1102'=>'全選', + '1103'=>'修改', + '1104'=>'刪除', + '1105'=>'查看', + '1106'=>'操作', + '1107'=>'請填寫', + '1108'=>'保存', + '1109'=>'無', + '1110'=>'否', + '1111'=>'是', + '1112'=>'菜單欄目數據不存在', + '1113'=>'啟用', + '1114'=>'創建時間', + '1115'=>'修改時間', + '1116'=>'提示', + '1117'=>'數據查詢', + '1118'=>'查詢', + '1119'=>'日期', + '1200'=>'清空', + '1201'=>'排序', + '1202'=>'默認', + '1203'=>'無限制', + '1204'=>'基本配置', + '1205'=>'高級配置', + '1206'=>'正確', + '1207'=>'錯誤', + '1208'=>'狀態', + '1209'=>'網站標題', + '1210'=>'語言', + '1211'=>'驗證碼', + + + //菜单语言包 + '90100'=>'郵箱管理', + '90101'=>'郵箱列表', + '90102'=>'郵箱添加', + '90103'=>'郵箱域名', + '90105'=>'郵箱系統設置', + '90200'=>'系統管理', + '90201'=>'管理員列表', + '90202'=>'管理員添加', + '90203'=>'角色列表', + '90204'=>'角色添加', + '90205'=>'系統設置', + '90206'=>'操作日誌', + + //系统管理 + '2001'=>'角色', + '2002'=>'角色名稱', + '2003'=>'請填寫角色名稱', + '2004'=>'權限設置', + '2005'=>'菜單名稱', + '2006'=>'權限', + '2007'=>'添加/修改', + '2008'=>'管理員賬號', + '2009'=>'英文字母,數字或下劃線,在3-20個字符之間,不區分大小寫', + '2010'=>'名稱', + '2011'=>'管理員類型', + '2012'=>'普通管理員', + '2013'=>'超級管理員', + '2014'=>'管理組(角色)', + '2015'=>'修改密碼', + '2016'=>'密碼', + '2017'=>'長度8-20個字符,請將密碼設置複雜些,最好包含數字和字母', + '2018'=>'確認密碼', + '2019'=>'管理員賬號格式錯誤', + '2020'=>'密碼字符長度不正確', + '2021'=>'2個密碼不一致', + '2022'=>'管理員賬號已存在,請更換賬號', + '2023'=>'立即登錄', + '2024'=>'管理員賬號不存在', + '2025'=>'密碼不正確', + '2026'=>'登陸成功', + '2027'=>'原始密碼', + '2028'=>'新密碼', + '2029'=>'確認新密碼', + '2030'=>'原始密碼不正確', + '2031'=>'系統默認語言', + '2032'=>'你選擇的語言不存在', + '2033'=>'提示信息', + '2034'=>'返回上一頁', + '2035'=>'郵箱管理後台', + '2036'=>'這是默認管理員賬號,不能刪除', + '2037'=>'你使用的是系統默認密碼,請盡快修改', + '2038'=>'你可以使用現在的賬號登陸web郵件系統控制面板進行管理,', + '2039'=>'點擊登陸', + '2040'=>'密碼必須同時包含字母和數字', + '2041'=>'該賬號已被禁用', + '2042'=>'你登錄該賬號的失敗次數連續超過5次,請一個小時後再嘗試登錄', + '2043'=>'清空日誌', + '2044'=>'操作管理員', + '2045'=>'IP', + '2046'=>'操作記錄', + '2047'=>'確認清空所有日誌嗎? ', + + + //邮箱管理 + '3001'=>'限制是針對域名下的郵箱地址,只針對外部郵箱進行限制。 ', + '3002'=>'限制發送量', + '3003'=>'設置該參數可以限制域名下每個郵箱單天發送量,0為不限制,默認0', + '3004'=>'限制接收量', + '3005'=>'設置該參數可以限制域名下每個郵箱單天接收量,0為不限制,默認0', + '3006'=>'限制IP接收量', + '3007'=>'設置該參數可以限制對方IP發送到本域的郵箱數量,0為不限制,默認0', + '3008'=>'限制容量', + '3009'=>'單位G,只可輸入整數,0為不限制,默認0', + '3010'=>'郵箱域名格式錯誤', + '3011'=>'郵箱域名已存在', + '3012'=>'郵箱地址', + '3013'=>'收發數量', + '3014'=>'收發限制', + '3015'=>'容量限制', + '3016'=>'郵箱的後綴域名不存在', + '3017'=>'郵箱地址已存在', + '3018'=>'開始日期', + '3019'=>'結束日期', + '3020'=>'發件數量', + '3021'=>'收件數量', + '3022'=>'確認清空嗎? ', + '3023'=>'姓名', + '3024'=>'聯繫電話', + '3025'=>'郵箱地址或域名', + '3026'=>'名單類型', + '3027'=>'黑名單', + '3028'=>'白名單', + '3029'=>'郵箱地址不能為空', + '3030'=>'郵箱地址的寫法
單個郵箱地址:test@test.com.cn
整個域:test.com', + '3031'=>'黑/白名單列表', + '3032'=>'名單類型', + '3033'=>'佔用容量(升序)', + '3034'=>'佔用容量(降序)', + '3035'=>'佔用容量(GB)', + '3036'=>'主機名稱', + '3037'=>'郵箱主域名', + '3038'=>'imap', + '3039'=>'smtp', + '3040'=>'例子:', + '3041'=>'webmail', + '3042'=>'容量邊界(百分比)', + '3043'=>'當容量達到邊界後將發送郵件通知用戶,0為不發送通知', + '3044'=>'郵箱通知名稱', + '3045'=>'負責通知用戶的郵箱地址名稱,不需要填寫郵箱後綴,默認postmaster', + '3046'=>'該配置將會修改系統文件,請不要頻繁修改', + '3047'=>'dkim數據', + '3048'=>'記錄類型', + '3049'=>'主機記錄', + '3050'=>'記錄值', + '3051'=>'dkim驗證', + '3052'=>'驗證值', + '3053'=>'首頁', + '3054'=>'個人資料', + '3055'=>'web郵件系統', + '3056'=>'退出', + '3057'=>'歡迎你回來', + '3058'=>'郵箱隊列', + '3059'=>'當天發件數量', + '3060'=>'當天收件數量', + '3061'=>'系統信息', + '3062'=>'主機名', + '3063'=>'服務器ip', + '3064'=>'操作系統', + '3065'=>'web服務器', + '3066'=>'上傳文件限制', + '3067'=>'post限制', + '3068'=>'授權信息', + '3069'=>'ewomail版本', + '3070'=>'授權狀態', + '3071'=>'官方網站', + '3072'=>'聯繫電話', + '3073'=>'dkim查看', + '3074'=>'郵箱地址@前面的字符不能少於3個字數', + '3075'=>'郵箱用戶', + '3076'=>'郵箱佔用', + '3077'=>'web郵件控制面板權限', +]; diff --git a/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_configfilelexer.plex b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_configfilelexer.plex new file mode 100644 index 0000000..94196be --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_configfilelexer.plex @@ -0,0 +1,318 @@ + 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE'); + + /** + * storage for assembled token patterns + * + * @var sring + */ + private $yy_global_pattern1 = null; + private $yy_global_pattern2 = null; + private $yy_global_pattern3 = null; + private $yy_global_pattern4 = null; + private $yy_global_pattern5 = null; + private $yy_global_pattern6 = null; + + /** + * token names + * + * @var array + */ + public $smarty_token_names = array( // Text for parser error messages + ); + + /** + * constructor + * + * @param string $data template source + * @param Smarty_Internal_Config_File_Compiler $compiler + */ + function __construct($data, Smarty_Internal_Config_File_Compiler $compiler) + { + // set instance object + self::instance($this); + $this->data = $data . "\n"; //now all lines are \n-terminated + $this->counter = 0; + if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) { + $this->counter += strlen($match[0]); + } + $this->line = 1; + $this->compiler = $compiler; + $this->smarty = $compiler->smarty; + $this->configBooleanize = $this->smarty->config_booleanize; + } + + public static function &instance($new_instance = null) + { + static $instance = null; + if (isset($new_instance) && is_object($new_instance)) { + $instance = $new_instance; + } + return $instance; + } + + public function PrintTrace() + { + $this->yyTraceFILE = fopen('php://output', 'w'); + $this->yyTracePrompt = '
'; + } + + +/*!lex2php +%input $this->data +%counter $this->counter +%token $this->token +%value $this->value +%line $this->line +commentstart = /#|;/ +openB = /\[/ +closeB = /\]/ +section = /.*?(?=[\.=\[\]\r\n])/ +equal = /=/ +whitespace = /[ \t\r]+/ +dot = /\./ +id = /[0-9]*[a-zA-Z_]\w*/ +newline = /\n/ +single_quoted_string = /'[^'\\]*(?:\\.[^'\\]*)*'(?=[ \t\r]*[\n#;])/ +double_quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"(?=[ \t\r]*[\n#;])/ +tripple_quotes = /"""/ +tripple_quotes_end = /"""(?=[ \t\r]*[\n#;])/ +text = /[\S\s]/ +float = /\d+\.\d+(?=[ \t\r]*[\n#;])/ +int = /\d+(?=[ \t\r]*[\n#;])/ +maybe_bool = /[a-zA-Z]+(?=[ \t\r]*[\n#;])/ +naked_string = /[^\n]+?(?=[ \t\r]*\n)/ +*/ + +/*!lex2php +%statename START + +commentstart { + $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART; + $this->yypushstate(self::COMMENT); +} +openB { + $this->token = Smarty_Internal_Configfileparser::TPC_OPENB; + $this->yypushstate(self::SECTION); +} +closeB { + $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB; +} +equal { + $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL; + $this->yypushstate(self::VALUE); +} +whitespace { + return false; +} +newline { + $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE; +} +id { + $this->token = Smarty_Internal_Configfileparser::TPC_ID; +} +text { + $this->token = Smarty_Internal_Configfileparser::TPC_OTHER; +} + +*/ + +/*!lex2php +%statename VALUE + +whitespace { + return false; +} +float { + $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT; + $this->yypopstate(); +} +int { + $this->token = Smarty_Internal_Configfileparser::TPC_INT; + $this->yypopstate(); +} +tripple_quotes { + $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES; + $this->yypushstate(self::TRIPPLE); +} +single_quoted_string { + $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING; + $this->yypopstate(); +} +double_quoted_string { + $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING; + $this->yypopstate(); +} +maybe_bool { + if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) { + $this->yypopstate(); + $this->yypushstate(self::NAKED_STRING_VALUE); + return true; //reprocess in new state + } else { + $this->token = Smarty_Internal_Configfileparser::TPC_BOOL; + $this->yypopstate(); + } +} +naked_string { + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + $this->yypopstate(); +} +newline { + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + $this->value = ""; + $this->yypopstate(); +} + +*/ + +/*!lex2php +%statename NAKED_STRING_VALUE + +naked_string { + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + $this->yypopstate(); +} + +*/ + +/*!lex2php +%statename COMMENT + +whitespace { + return false; +} +naked_string { + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; +} +newline { + $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE; + $this->yypopstate(); +} + +*/ + +/*!lex2php +%statename SECTION + +dot { + $this->token = Smarty_Internal_Configfileparser::TPC_DOT; +} +section { + $this->token = Smarty_Internal_Configfileparser::TPC_SECTION; + $this->yypopstate(); +} + +*/ +/*!lex2php +%statename TRIPPLE + +tripple_quotes_end { + $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END; + $this->yypopstate(); + $this->yypushstate(self::START); +} +text { + $to = strlen($this->data); + preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } else { + $this->compiler->trigger_template_error ("missing or misspelled literal closing tag"); + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT; +} +*/ + +} diff --git a/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_configfileparser.y b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_configfileparser.y new file mode 100644 index 0000000..ac96177 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_configfileparser.y @@ -0,0 +1,362 @@ +/** +* Smarty Internal Plugin Configfileparser +* +* This is the config file parser +* +* +* @package Smarty +* @subpackage Config +* @author Uwe Tews +*/ +%name TPC_ +%declare_class { +/** +* Smarty Internal Plugin Configfileparse +* +* This is the config file parser. +* It is generated from the smarty_internal_configfileparser.y file +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ +class Smarty_Internal_Configfileparser +} +%include_class +{ + /** + * result status + * + * @var bool + */ + public $successful = true; + /** + * return value + * + * @var mixed + */ + public $retvalue = 0; + /** + * @var + */ + public $yymajor; + /** + * lexer object + * + * @var Smarty_Internal_Configfilelexer + */ + private $lex; + /** + * internal error flag + * + * @var bool + */ + private $internalError = false; + /** + * compiler object + * + * @var Smarty_Internal_Config_File_Compiler + */ + public $compiler = null; + /** + * smarty object + * + * @var Smarty + */ + public $smarty = null; + /** + * copy of config_overwrite property + * + * @var bool + */ + private $configOverwrite = false; + /** + * copy of config_read_hidden property + * + * @var bool + */ + private $configReadHidden = false; + /** + * helper map + * + * @var array + */ + private static $escapes_single = Array('\\' => '\\', + '\'' => '\''); + + /** + * constructor + * + * @param Smarty_Internal_Configfilelexer $lex + * @param Smarty_Internal_Config_File_Compiler $compiler + */ + function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler) + { + // set instance object + self::instance($this); + $this->lex = $lex; + $this->smarty = $compiler->smarty; + $this->compiler = $compiler; + $this->configOverwrite = $this->smarty->config_overwrite; + $this->configReadHidden = $this->smarty->config_read_hidden; + } + + /** + * @param null $new_instance + * + * @return null + */ + public static function &instance($new_instance = null) + { + static $instance = null; + if (isset($new_instance) && is_object($new_instance)) { + $instance = $new_instance; + } + return $instance; + } + + /** + * parse optional boolean keywords + * + * @param string $str + * + * @return bool + */ + private function parse_bool($str) + { + $str = strtolower($str); + if (in_array($str, array('on', 'yes', 'true'))) { + $res = true; + } else { + $res = false; + } + return $res; + } + + /** + * parse single quoted string + * remove outer quotes + * unescape inner quotes + * + * @param string $qstr + * + * @return string + */ + private static function parse_single_quoted_string($qstr) + { + $escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes + + $ss = preg_split('/(\\\\.)/', $escaped_string, - 1, PREG_SPLIT_DELIM_CAPTURE); + + $str = ""; + foreach ($ss as $s) { + if (strlen($s) === 2 && $s[0] === '\\') { + if (isset(self::$escapes_single[$s[1]])) { + $s = self::$escapes_single[$s[1]]; + } + } + $str .= $s; + } + return $str; + } + + /** + * parse double quoted string + * + * @param string $qstr + * + * @return string + */ + private static function parse_double_quoted_string($qstr) + { + $inner_str = substr($qstr, 1, strlen($qstr) - 2); + return stripcslashes($inner_str); + } + + /** + * parse triple quoted string + * + * @param string $qstr + * + * @return string + */ + private static function parse_tripple_double_quoted_string($qstr) + { + return stripcslashes($qstr); + } + + /** + * set a config variable in target array + * + * @param array $var + * @param array $target_array + */ + private function set_var(Array $var, Array &$target_array) + { + $key = $var["key"]; + $value = $var["value"]; + + if ($this->configOverwrite || !isset($target_array['vars'][$key])) { + $target_array['vars'][$key] = $value; + } else { + settype($target_array['vars'][$key], 'array'); + $target_array['vars'][$key][] = $value; + } + } + + /** + * add config variable to global vars + * + * @param array $vars + */ + private function add_global_vars(Array $vars) + { + if (!isset($this->compiler->config_data['vars'])) { + $this->compiler->config_data['vars'] = Array(); + } + foreach ($vars as $var) { + $this->set_var($var, $this->compiler->config_data); + } + } + + /** + * add config variable to section + * + * @param string $section_name + * @param array $vars + */ + private function add_section_vars($section_name, Array $vars) + { + if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) { + $this->compiler->config_data['sections'][$section_name]['vars'] = Array(); + } + foreach ($vars as $var) { + $this->set_var($var, $this->compiler->config_data['sections'][$section_name]); + } + } +} + +%token_prefix TPC_ + +%parse_accept +{ + $this->successful = !$this->internalError; + $this->internalError = false; + $this->retvalue = $this->_retvalue; +} + +%syntax_error +{ + $this->internalError = true; + $this->yymajor = $yymajor; + $this->compiler->trigger_config_file_error(); +} + +%stack_overflow +{ + $this->internalError = true; + $this->compiler->trigger_config_file_error("Stack overflow in configfile parser"); +} + +// Complete config file +start(res) ::= global_vars sections. { + res = null; +} + +// Global vars +global_vars(res) ::= var_list(vl). { + $this->add_global_vars(vl); + res = null; +} + +// Sections +sections(res) ::= sections section. { + res = null; +} + +sections(res) ::= . { + res = null; +} + +section(res) ::= OPENB SECTION(i) CLOSEB newline var_list(vars). { + $this->add_section_vars(i, vars); + res = null; +} + +section(res) ::= OPENB DOT SECTION(i) CLOSEB newline var_list(vars). { + if ($this->configReadHidden) { + $this->add_section_vars(i, vars); + } + res = null; +} + +// Var list +var_list(res) ::= var_list(vl) newline. { + res = vl; +} + +var_list(res) ::= var_list(vl) var(v). { + res = array_merge(vl, Array(v)); +} + +var_list(res) ::= . { + res = Array(); +} + + +// Var +var(res) ::= ID(id) EQUAL value(v). { + res = Array("key" => id, "value" => v); +} + + +value(res) ::= FLOAT(i). { + res = (float) i; +} + +value(res) ::= INT(i). { + res = (int) i; +} + +value(res) ::= BOOL(i). { + res = $this->parse_bool(i); +} + +value(res) ::= SINGLE_QUOTED_STRING(i). { + res = self::parse_single_quoted_string(i); +} + +value(res) ::= DOUBLE_QUOTED_STRING(i). { + res = self::parse_double_quoted_string(i); +} + +value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_TEXT(c) TRIPPLE_QUOTES_END(ii). { + res = self::parse_tripple_double_quoted_string(c); +} + +value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_QUOTES_END(ii). { + res = ''; +} + +value(res) ::= NAKED_STRING(i). { + res = i; +} + +// NOTE: this is not a valid rule +// It is added hier to produce a usefull error message on a missing '='; +value(res) ::= OTHER(i). { + res = i; +} + + +// Newline and comments +newline(res) ::= NEWLINE. { + res = null; +} + +newline(res) ::= COMMENTSTART NEWLINE. { + res = null; +} + +newline(res) ::= COMMENTSTART NAKED_STRING NEWLINE. { + res = null; +} diff --git a/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_templatelexer.plex b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_templatelexer.plex new file mode 100644 index 0000000..bd9b7a9 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_templatelexer.plex @@ -0,0 +1,758 @@ + 'TEXT', 2 => 'TAG', 3 => 'TAGBODY', 4 => 'LITERAL', 5 => 'DOUBLEQUOTEDSTRING', + 6 => 'CHILDBODY', 7 => 'CHILDBLOCK', 8 => 'CHILDLITERAL'); + + /** + * storage for assembled token patterns + * + * @var string + */ + private $yy_global_pattern1 = null; + + private $yy_global_pattern2 = null; + + private $yy_global_pattern3 = null; + + private $yy_global_pattern4 = null; + + private $yy_global_pattern5 = null; + + private $yy_global_pattern6 = null; + + private $yy_global_pattern7 = null; + + private $yy_global_pattern8 = null; + + /** + * token names + * + * @var array + */ + public $smarty_token_names = array( // Text for parser error messages + 'NOT' => '(!,not)', + 'OPENP' => '(', + 'CLOSEP' => ')', + 'OPENB' => '[', + 'CLOSEB' => ']', + 'PTR' => '->', + 'APTR' => '=>', + 'EQUAL' => '=', + 'NUMBER' => 'number', + 'UNIMATH' => '+" , "-', + 'MATH' => '*" , "/" , "%', + 'INCDEC' => '++" , "--', + 'SPACE' => ' ', + 'DOLLAR' => '$', + 'SEMICOLON' => ';', + 'COLON' => ':', + 'DOUBLECOLON' => '::', + 'AT' => '@', + 'HATCH' => '#', + 'QUOTE' => '"', + 'BACKTICK' => '`', + 'VERT' => '"|" modifier', + 'DOT' => '.', + 'COMMA' => '","', + 'QMARK' => '"?"', + 'ID' => 'id, name', + 'TEXT' => 'text', + 'LDELSLASH' => '{/..} closing tag', + 'LDEL' => '{...} Smarty tag', + 'COMMENT' => 'comment', + 'AS' => 'as', + 'TO' => 'to', + 'PHP' => '" '"<", "==" ... logical operator', + 'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition', + 'SCOND' => '"is even" ... if condition', + ); + + /** + * constructor + * + * @param string $data template source + * @param Smarty_Internal_TemplateCompilerBase $compiler + */ + function __construct($data, Smarty_Internal_TemplateCompilerBase $compiler) + { + $this->data = $data; + $this->counter = 0; + if (preg_match('~^\xEF\xBB\xBF~i', $this->data, $match)) { + $this->counter += strlen($match[0]); + } + $this->line = 1; + $this->smarty = $compiler->smarty; + $this->compiler = $compiler; + $this->ldel = preg_quote($this->smarty->left_delimiter, '~'); + $this->ldel_length = strlen($this->smarty->left_delimiter); + $this->rdel = preg_quote($this->smarty->right_delimiter, '~'); + $this->rdel_length = strlen($this->smarty->right_delimiter); + $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter; + $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter; + } + + public function PrintTrace() + { + $this->yyTraceFILE = fopen('php://output', 'w'); + $this->yyTracePrompt = '
'; + } + + /* + * Check if this tag is autoliteral + */ + public function isAutoLiteral () + { + return $this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false; + } + + /*!lex2php + %input $this->data + %counter $this->counter + %token $this->token + %value $this->value + %line $this->line + linebreak = ~[\t ]*[\r\n]+[\t ]*~ + text = ~[\S\s]~ + textdoublequoted = ~([^"\\]*?)((?:\\.[^"\\]*?)*?)(?=(SMARTYldel|\$|`\$|"))~ + namespace = ~([0-9]*[a-zA-Z_]\w*)?(\\[0-9]*[a-zA-Z_]\w*)+~ + all = ~[\S\s]+~ + emptyjava = ~[{][}]~ + phpstart = ~(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|()|([?][>])|([%][>])|(SMARTYldel\s*php(.*?)SMARTYrdel)|(SMARTYldel\s*[/]phpSMARTYrdel)~ + slash = ~[/]~ + ldel = ~SMARTYldel\s*~ + rdel = ~\s*SMARTYrdel~ + nocacherdel = ~(\s+nocache)?\s*SMARTYrdel~ + notblockid = ~(?:(?!block)[0-9]*[a-zA-Z_]\w*)~ + smartyblockchildparent = ~[\$]smarty\.block\.(child|parent)~ + integer = ~\d+~ + hex = ~0[xX][0-9a-fA-F]+~ + math = ~\s*([*]{1,2}|[%/^&]|[<>]{2})\s*~ + comment = ~SMARTYldel[*]~ + incdec = ~([+]|[-]){2}~ + unimath = ~\s*([+]|[-])\s*~ + openP = ~\s*[(]\s*~ + closeP = ~\s*[)]~ + openB = ~\[\s*~ + closeB = ~\s*\]~ + dollar = ~[$]~ + dot = ~[.]~ + comma = ~\s*[,]\s*~ + doublecolon = ~[:]{2}~ + colon = ~\s*[:]\s*~ + at = ~[@]~ + hatch = ~[#]~ + semicolon = ~\s*[;]\s*~ + equal = ~\s*[=]\s*~ + space = ~\s+~ + ptr = ~\s*[-][>]\s*~ + aptr = ~\s*[=][>]\s*~ + singlequotestring = ~'[^'\\]*(?:\\.[^'\\]*)*'~ + backtick = ~[`]~ + vert = ~[|]~ + qmark = ~\s*[?]\s*~ + constant = ~([_]+[A-Z0-9][0-9A-Z_]*|[A-Z][0-9A-Z_]*)(?![0-9A-Z_]*[a-z])~ + attr = ~\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\s*[=]\s*~ + id = ~[0-9]*[a-zA-Z_]\w*~ + literal = ~literal~ + strip = ~strip~ + lop = ~\s*(([!=][=]{1,2})|([<][=>]?)|([>][=]?)|[&|]{2})\s*~ + tlop = ~\s+(eq|ne|neg|gt|ge|gte|lt|le|lte|mod|and|or|xor|(is\s+(not\s+)?(odd|even|div)\s+by))\s+~ + scond = ~\s+is\s+(not\s+)?(odd|even)~ + isin = ~\s+is\s+in\s+~ + as = ~\s+as\s+~ + to = ~\s+to\s+~ + step = ~\s+step\s+~ + block = ~block~ + if = ~(if|elseif|else if|while)\s+~ + for = ~for\s+~ + foreach = ~foreach(?![^\s])~ + setfilter = ~setfilter\s+~ + instanceof = ~\s+instanceof\s+~ + not = ~([!]\s*)|(not\s+)~ + typecast = ~[(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\s*~ + double_quote = ~["]~ + single_quote = ~[']~ + */ + /*!lex2php + %statename TEXT + emptyjava { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + comment { + preg_match("~[*]{$this->rdel}~",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1] + strlen($match[0][0]); + } else { + $this->compiler->trigger_template_error ("missing or misspelled comment closing tag '*{$this->smarty->right_delimiter}'"); + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + return false; + } + phpstart { + $obj = new Smarty_Internal_Compile_Private_Php(); + $obj->parsePhp($this); + $this->token = Smarty_Internal_Templateparser::TP_PHP; + } + ldel literal rdel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART; + $this->yypushstate(self::LITERAL); + } + } + ldel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->yypushstate(self::TAG); + return true; + } + } + rdel { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + text { + $to = strlen($this->data); + preg_match("~($this->ldel)|([<]script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*[>])|([<][?])|([<][%])|([?][>])|([%][>])~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + */ + /*!lex2php + %statename TAG + ldel if { + $this->token = Smarty_Internal_Templateparser::TP_LDELIF; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel for { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOR; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel foreach { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel setfilter { + $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel id nocacherdel { + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG; + $this->taglineno = $this->line; + } + ldel slash notblockid rdel { + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_CLOSETAG; + $this->taglineno = $this->line; + } + ldel dollar id nocacherdel { + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_SIMPELOUTPUT; + $this->taglineno = $this->line; + } + ldel slash { + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + */ + /*!lex2php + %statename TAGBODY + rdel { + $this->token = Smarty_Internal_Templateparser::TP_RDEL; + $this->yypopstate(); + } + double_quote { + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; + $this->yypushstate(self::DOUBLEQUOTEDSTRING); + } + singlequotestring { + $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING; + } + smartyblockchildparent { + $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT; + $this->taglineno = $this->line; + } + dollar id { + $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; + } + dollar { + $this->token = Smarty_Internal_Templateparser::TP_DOLLAR; + } + isin { + $this->token = Smarty_Internal_Templateparser::TP_ISIN; + } + as { + $this->token = Smarty_Internal_Templateparser::TP_AS; + } + to { + $this->token = Smarty_Internal_Templateparser::TP_TO; + } + step { + $this->token = Smarty_Internal_Templateparser::TP_STEP; + } + instanceof { + $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF; + } + lop { + $this->token = Smarty_Internal_Templateparser::TP_LOGOP; + } + tlop { + $this->token = Smarty_Internal_Templateparser::TP_TLOGOP; + } + scond { + $this->token = Smarty_Internal_Templateparser::TP_SINGLECOND; + } + not{ + $this->token = Smarty_Internal_Templateparser::TP_NOT; + } + typecast { + $this->token = Smarty_Internal_Templateparser::TP_TYPECAST; + } + openP { + $this->token = Smarty_Internal_Templateparser::TP_OPENP; + } + closeP { + $this->token = Smarty_Internal_Templateparser::TP_CLOSEP; + } + openB { + $this->token = Smarty_Internal_Templateparser::TP_OPENB; + } + closeB { + $this->token = Smarty_Internal_Templateparser::TP_CLOSEB; + } + ptr { + $this->token = Smarty_Internal_Templateparser::TP_PTR; + } + aptr { + $this->token = Smarty_Internal_Templateparser::TP_APTR; + } + equal { + $this->token = Smarty_Internal_Templateparser::TP_EQUAL; + } + incdec { + $this->token = Smarty_Internal_Templateparser::TP_INCDEC; + } + unimath { + $this->token = Smarty_Internal_Templateparser::TP_UNIMATH; + } + math { + $this->token = Smarty_Internal_Templateparser::TP_MATH; + } + at { + $this->token = Smarty_Internal_Templateparser::TP_AT; + } + hatch { + $this->token = Smarty_Internal_Templateparser::TP_HATCH; + } + attr { + // resolve conflicts with shorttag and right_delimiter starting with '=' + if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) { + preg_match("~\s+~",$this->value,$match); + $this->value = $match[0]; + $this->token = Smarty_Internal_Templateparser::TP_SPACE; + } else { + $this->token = Smarty_Internal_Templateparser::TP_ATTR; + } + } + namespace { + $this->token = Smarty_Internal_Templateparser::TP_NAMESPACE; + } + id { + $this->token = Smarty_Internal_Templateparser::TP_ID; + } + integer { + $this->token = Smarty_Internal_Templateparser::TP_INTEGER; + } + backtick { + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; + $this->yypopstate(); + } + vert { + $this->token = Smarty_Internal_Templateparser::TP_VERT; + } + dot { + $this->token = Smarty_Internal_Templateparser::TP_DOT; + } + comma { + $this->token = Smarty_Internal_Templateparser::TP_COMMA; + } + semicolon { + $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON; + } + doublecolon { + $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON; + } + colon { + $this->token = Smarty_Internal_Templateparser::TP_COLON; + } + qmark { + $this->token = Smarty_Internal_Templateparser::TP_QMARK; + } + hex { + $this->token = Smarty_Internal_Templateparser::TP_HEX; + } + space { + $this->token = Smarty_Internal_Templateparser::TP_SPACE; + } + ldel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->yypushstate(self::TAG); + return true; + } + } + text { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + */ + + /*!lex2php + %statename LITERAL + ldel literal rdel { + $this->literal_cnt++; + $this->token = Smarty_Internal_Templateparser::TP_LITERAL; + } + ldel slash literal rdel { + if ($this->literal_cnt) { + $this->literal_cnt--; + $this->token = Smarty_Internal_Templateparser::TP_LITERAL; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LITERALEND; + $this->yypopstate(); + } + } + text { + $to = strlen($this->data); + preg_match("~{$this->ldel}[/]?literal{$this->rdel}~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } else { + $this->compiler->trigger_template_error ("missing or misspelled literal closing tag"); + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_LITERAL; + } + */ + /*!lex2php + %statename DOUBLEQUOTEDSTRING + ldel literal rdel { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + ldel slash literal rdel { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + ldel slash { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->yypushstate(self::TAG); + return true; + } + } + ldel id { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->yypushstate(self::TAG); + return true; + } + } + ldel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->taglineno = $this->line; + $this->yypushstate(self::TAGBODY); + } + } + double_quote { + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; + $this->yypopstate(); + } + backtick dollar { + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; + $this->value = substr($this->value,0,-1); + $this->yypushstate(self::TAGBODY); + $this->taglineno = $this->line; + } + dollar id { + $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; + } + dollar { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + textdoublequoted { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + text { + $to = strlen($this->data); + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + */ + /*!lex2php + %statename CHILDBODY + ldel strip rdel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + return false; + } else { + $this->token = Smarty_Internal_Templateparser::TP_STRIPON; + } + } + ldel slash strip rdel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + return false; + } else { + $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF; + } + } + ldel block { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + return false; + } else { + $this->yypopstate(); + return true; + } + } + text { + $to = strlen($this->data); + preg_match("~SMARTYldel\s*(([/])?strip\s*SMARTYrdel|block\s+)~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + return false; + } + + */ + /*!lex2php + %statename CHILDBLOCK + ldel literal rdel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } else { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + $this->yypushstate(self::CHILDLITERAL); + } + } + ldel block { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } else { + $this->yypopstate(); + return true; + } + } + ldel slash block { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } else { + $this->yypopstate(); + return true; + } + } + ldel smartyblockchildparent { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } else { + $this->yypopstate(); + return true; + } + } + text { + $to = strlen($this->data); + preg_match("~SMARTYldel\s*(literal\s*SMARTYrdel|([/])?block(\s|SMARTYrdel)|[\$]smarty\.block\.(child|parent))~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } + */ + /*!lex2php + %statename CHILDLITERAL + ldel literal rdel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } else { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + $this->yypushstate(self::CHILDLITERAL); + } + } + ldel slash literal rdel { + if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } else { + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + $this->yypopstate(); + } + } + text { + $to = strlen($this->data); + preg_match("~{$this->ldel}[/]?literal\s*{$this->rdel}~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } else { + $this->compiler->trigger_template_error ("missing or misspelled literal closing tag"); + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE; + } + */ + } + + \ No newline at end of file diff --git a/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_templateparser.y b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_templateparser.y new file mode 100644 index 0000000..78bf90a --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/lexer/smarty_internal_templateparser.y @@ -0,0 +1,1335 @@ +/** +* Smarty Internal Plugin Templateparser +* +* This is the template parser +* +* +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ +%stack_size 500 +%name TP_ +%declare_class { +/** +* Smarty Internal Plugin Templateparser +* +* This is the template parser. +* It is generated from the smarty_internal_templateparser.y file +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ +class Smarty_Internal_Templateparser +} +%include_class +{ + const Err1 = "Security error: Call to private object member not allowed"; + const Err2 = "Security error: Call to dynamic object member not allowed"; + const Err3 = "PHP in template not allowed. Use SmartyBC to enable it"; + + /** + * result status + * + * @var bool + */ + public $successful = true; + /** + * return value + * + * @var mixed + */ + public $retvalue = 0; + /** + * counter for prefix code + * + * @var int + */ + public static $prefix_number = 0; + /** + * @var + */ + public $yymajor; + /** + * last index of array variable + * + * @var mixed + */ + public $last_index; + /** + * last variable name + * + * @var string + */ + public $last_variable; + /** + * root parse tree buffer + * + * @var Smarty_Internal_ParseTree + */ + public $root_buffer; + /** + * current parse tree object + * + * @var Smarty_Internal_ParseTree + */ + public $current_buffer; + /** + * lexer object + * + * @var Smarty_Internal_Templatelexer + */ + private $lex; + /** + * internal error flag + * + * @var bool + */ + private $internalError = false; + /** + * {strip} status + * + * @var bool + */ + public $strip = false; + /** + * compiler object + * + * @var Smarty_Internal_TemplateCompilerBase + */ + public $compiler = null; + /** + * smarty object + * + * @var Smarty + */ + public $smarty = null; + /** + * template object + * + * @var Smarty_Internal_Template + */ + public $template = null; + /** + * block nesting level + * + * @var int + */ + public $block_nesting_level = 0; + + /** + * security object + * + * @var Smarty_Security + */ + private $security = null; + + /** + * constructor + * + * @param Smarty_Internal_Templatelexer $lex + * @param Smarty_Internal_TemplateCompilerBase $compiler + */ + function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_TemplateCompilerBase $compiler) + { + $this->lex = $lex; + $this->compiler = $compiler; + $this->template = $this->compiler->template; + $this->smarty = $this->template->smarty; + $this->security = isset($this->smarty->security_policy) ? $this->smarty->security_policy : false; + $this->current_buffer = $this->root_buffer = new Smarty_Internal_ParseTree_Template($this); + } + + /** + * insert PHP code in current buffer + * + * @param string $code + */ + public function insertPhpCode($code) + { + $this->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($this, $code)); + } + + /** + * merge PHP code with prefix code and return parse tree tag object + * + * @param string $code + * + * @return Smarty_Internal_ParseTree_Tag + */ + public function mergePrefixCode($code) + { + $tmp =''; + foreach ($this->compiler->prefix_code as $preCode) { + $tmp = empty($tmp) ? $preCode : $this->compiler->appendCode($tmp, $preCode); + } + $this->compiler->prefix_code=array(); + $tmp = empty($tmp) ? $code : $this->compiler->appendCode($tmp, $code); + return new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp,true)); + } + +} + +%token_prefix TP_ + +%parse_accept +{ + $this->successful = !$this->internalError; + $this->internalError = false; + $this->retvalue = $this->_retvalue; +} + +%syntax_error +{ + $this->internalError = true; + $this->yymajor = $yymajor; + $this->compiler->trigger_template_error(); +} + +%stack_overflow +{ + $this->internalError = true; + $this->compiler->trigger_template_error("Stack overflow in template parser"); +} + +%left VERT. +%left COLON. + + // + // complete template + // +start(res) ::= template. { + res = $this->root_buffer->to_smarty_php(); +} + + // + // loop over template elements + // + // single template element +template ::= template_element(e). { + if (e != null) { + $this->current_buffer->append_subtree(e); + } +} + + // loop of elements +template ::= template template_element(e). { + if (e != null) { + // because of possible code injection + $this->current_buffer->append_subtree(e); + } +} + + // empty template +template ::= . + +// +// template elements +// + // Smarty tag +template_element(res)::= smartytag(st). { + if ($this->compiler->has_code) { + res = $this->mergePrefixCode(st); + } else { + res = null; + } + $this->compiler->has_variable_string = false; + $this->block_nesting_level = count($this->compiler->_tag_stack); +} + + // Literal +template_element(res) ::= literal(l). { + res = new Smarty_Internal_ParseTree_Text($this, l); +} + // php tags +template_element(res)::= PHP(o). { + $code = $this->compiler->compileTag('private_php',array(array('code' => o), array('type' => $this->lex->phpType )),array()); + if ($this->compiler->has_code && !empty($code)) { + $tmp =''; foreach ($this->compiler->prefix_code as $code) {$tmp.=$code;} $this->compiler->prefix_code=array(); + res = new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp.$code,true)); + } else { + res = null; + } +} + + // template text +template_element(res)::= text_content(t). { + res = $this->compiler->processText(t); +} + +text_content(res) ::= TEXT(o). { + res = o; +} + +text_content(res) ::= text_content(t) TEXT(o). { + res = t . o; +} + + // strip on +template_element ::= STRIPON(d). { + $this->strip = true; +} + // strip off +template_element ::= STRIPOFF(d). { + $this->strip = false; +} + // process source of inheritance child block +template_element ::= BLOCKSOURCE(s). { + if ($this->strip) { + SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', s)); + } else { + SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, s); + } +} + + // Litteral +literal(res) ::= LITERALSTART LITERALEND. { + res = ''; +} + +literal(res) ::= LITERALSTART literal_elements(l) LITERALEND. { + res = l; +} + +literal_elements(res) ::= literal_elements(l1) literal_element(l2). { + res = l1.l2; +} + +literal_elements(res) ::= . { + res = ''; +} + +literal_element(res) ::= literal(l). { + res = l; +} + +literal_element(res) ::= LITERAL(l). { + res = l; +} + +smartytag(res) ::= tag(t) RDEL. { + res = t; +} +// +// output tags start here +// +smartytag(res) ::= SIMPELOUTPUT(i). { + $var = trim(substr(i, $this->lex->ldel_length, -$this->lex->rdel_length), ' $'); + if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) { + res = $this->compiler->compileTag('private_print_expression',array('nocache'),array('value'=>$this->compiler->compileVariable('\''.$match[1].'\''))); + } else { + res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->compiler->compileVariable('\''.$var.'\''))); + } +} + + // output with optional attributes +tag(res) ::= LDEL variable(e). { + res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>e)); +} + +tag(res) ::= LDEL variable(e) modifierlist(l) attributes(a). { + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e, 'modifierlist'=>l)); +} + +tag(res) ::= LDEL variable(e) attributes(a). { + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e)); +} +tag(res) ::= LDEL value(e). { + res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>e)); +} +tag(res) ::= LDEL value(e) modifierlist(l) attributes(a). { + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e, 'modifierlist'=>l)); +} + +tag(res) ::= LDEL value(e) attributes(a). { + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e)); +} + +tag(res) ::= LDEL expr(e) modifierlist(l) attributes(a). { + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e,'modifierlist'=>l)); +} + +tag(res) ::= LDEL expr(e) attributes(a). { + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e)); +} + +// +// Smarty tags start here +// + + // assign new style +tag(res) ::= LDEL DOLLARID(i) EQUAL value(e). { + res = $this->compiler->compileTag('assign',array(array('value'=>e),array('var'=>'\''.substr(i,1).'\''))); +} + +tag(res) ::= LDEL DOLLARID(i) EQUAL expr(e). { + res = $this->compiler->compileTag('assign',array(array('value'=>e),array('var'=>'\''.substr(i,1).'\''))); +} + +tag(res) ::= LDEL DOLLARID(i) EQUAL expr(e) attributes(a). { + res = $this->compiler->compileTag('assign',array_merge(array(array('value'=>e),array('var'=>'\''.substr(i,1).'\'')),a)); +} + +tag(res) ::= LDEL varindexed(vi) EQUAL expr(e) attributes(a). { + res = $this->compiler->compileTag('assign',array_merge(array(array('value'=>e),array('var'=>vi['var'])),a),array('smarty_internal_index'=>vi['smarty_internal_index'])); +} + +// simple tag like {name} +smartytag(res)::= SIMPLETAG(t). { + $tag = trim(substr(t, $this->lex->ldel_length, -$this->lex->rdel_length)); + if ($tag == 'strip') { + $this->strip = true; + res = null;; + } else { + if (defined($tag)) { + if ($this->security) { + $this->security->isTrustedConstant($tag, $this->compiler); + } + res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$tag)); + } else { + if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) { + res = $this->compiler->compileTag($match[1],array('nocache')); + } else { + res = $this->compiler->compileTag($tag,array()); + } + } + } +} + + // tag with optional Smarty2 style attributes +tag(res) ::= LDEL ID(i) attributes(a). { + if (defined(i)) { + if ($this->security) { + $this->security->isTrustedConstant(i, $this->compiler); + } + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i)); + } else { + res = $this->compiler->compileTag(i,a); + } +} +tag(res) ::= LDEL ID(i). { + if (defined(i)) { + if ($this->security) { + $this->security->isTrustedConstant(i, $this->compiler); + } + res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>i)); + } else { + res = $this->compiler->compileTag(i,array()); + } +} + + + // tag with modifier and optional Smarty2 style attributes +tag(res) ::= LDEL ID(i) modifierlist(l)attributes(a). { + if (defined(i)) { + if ($this->security) { + $this->security->isTrustedConstant(i, $this->compiler); + } + res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i, 'modifierlist'=>l)); + } else { + res = ''.$this->compiler->compileTag(i,a).'compiler->compileTag('private_modifier',array(),array('modifierlist'=>l,'value'=>'ob_get_clean()')).';?>'; + } +} + + // registered object tag +tag(res) ::= LDEL ID(i) PTR ID(m) attributes(a). { + res = $this->compiler->compileTag(i,a,array('object_method'=>m)); +} + + // registered object tag with modifiers +tag(res) ::= LDEL ID(i) PTR ID(me) modifierlist(l) attributes(a). { + res = ''.$this->compiler->compileTag(i,a,array('object_method'=>me)).'compiler->compileTag('private_modifier',array(),array('modifierlist'=>l,'value'=>'ob_get_clean()')).';?>'; +} + + // {if}, {elseif} and {while} tag +tag(res) ::= LDELIF(i) expr(ie). { + $tag = trim(substr(i,$this->lex->ldel_length)); + res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie)); +} + +tag(res) ::= LDELIF(i) expr(ie) attributes(a). { + $tag = trim(substr(i,$this->lex->ldel_length)); + res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,a,array('if condition'=>ie)); +} + +tag(res) ::= LDELIF(i) statement(ie). { + $tag = trim(substr(i,$this->lex->ldel_length)); + res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie)); +} + +tag(res) ::= LDELIF(i) statement(ie) attributes(a). { + $tag = trim(substr(i,$this->lex->ldel_length)); + res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,a,array('if condition'=>ie)); +} + + // {for} tag +tag(res) ::= LDELFOR statements(st) SEMICOLON expr(ie) SEMICOLON varindexed(v2) foraction(e2) attributes(a). { + res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('ifexp'=>ie),array('var'=>v2),array('step'=>e2))),1); +} + + foraction(res) ::= EQUAL expr(e). { + res = '='.e; +} + + foraction(res) ::= INCDEC(e). { + res = e; +} + +tag(res) ::= LDELFOR statement(st) TO expr(v) attributes(a). { + res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v))),0); +} + +tag(res) ::= LDELFOR statement(st) TO expr(v) STEP expr(v2) attributes(a). { + res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v),array('step'=>v2))),0); +} + + // {foreach} tag +tag(res) ::= LDELFOREACH attributes(a). { + res = $this->compiler->compileTag('foreach',a); +} + + // {foreach $array as $var} tag +tag(res) ::= LDELFOREACH SPACE value(v1) AS varvar(v0) attributes(a). { + res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>v1),array('item'=>v0)))); +} + +tag(res) ::= LDELFOREACH SPACE value(v1) AS varvar(v2) APTR varvar(v0) attributes(a). { + res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>v1),array('item'=>v0),array('key'=>v2)))); +} + +tag(res) ::= LDELFOREACH SPACE expr(e) AS varvar(v0) attributes(a). { + res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0)))); +} + +tag(res) ::= LDELFOREACH SPACE expr(e) AS varvar(v1) APTR varvar(v0) attributes(a). { + res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0),array('key'=>v1)))); +} + + // {setfilter} +tag(res) ::= LDELSETFILTER ID(m) modparameters(p). { + res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array(m),p)))); +} + +tag(res) ::= LDELSETFILTER ID(m) modparameters(p) modifierlist(l). { + res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array(m),p)),l))); +} + + // {$smarty.block.child} or {$smarty.block.parent} +tag(res) ::= LDEL SMARTYBLOCKCHILDPARENT(i). { + $j = strrpos(i,'.'); + if (i[$j+1] == 'c') { + // {$smarty.block.child} + res = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler); + } else { + // {$smarty.block.parent} + res = SMARTY_INTERNAL_COMPILE_BLOCK::compileParentBlock($this->compiler); + } +} + + + // end of block tag {/....} +smartytag(res)::= CLOSETAG(t). { + $tag = trim(substr(t, $this->lex->ldel_length, -$this->lex->rdel_length), ' /'); + if ($tag == 'strip') { + $this->strip = false; + res = null; + } else { + res = $this->compiler->compileTag($tag.'close',array()); + } + } +tag(res) ::= LDELSLASH ID(i). { + res = $this->compiler->compileTag(i.'close',array()); +} + +tag(res) ::= LDELSLASH ID(i) modifierlist(l). { + res = $this->compiler->compileTag(i.'close',array(),array('modifier_list'=>l)); +} + + // end of block object tag {/....} +tag(res) ::= LDELSLASH ID(i) PTR ID(m). { + res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m)); +} + +tag(res) ::= LDELSLASH ID(i) PTR ID(m) modifierlist(l). { + res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m, 'modifier_list'=>l)); +} + +// +//Attributes of Smarty tags +// + // list of attributes +attributes(res) ::= attributes(a1) attribute(a2). { + res = a1; + res[] = a2; +} + + // single attribute +attributes(res) ::= attribute(a). { + res = array(a); +} + + // no attributes +attributes(res) ::= . { + res = array(); +} + + // attribute +attribute(res) ::= SPACE ID(v) EQUAL ID(id). { + if (defined(id)) { + if ($this->security) { + $this->security->isTrustedConstant(id, $this->compiler); + } + res = array(v=>id); + } else { + res = array(v=>'\''.id.'\''); + } +} + +attribute(res) ::= ATTR(v) expr(e). { + res = array(trim(v," =\n\r\t")=>e); +} + +attribute(res) ::= ATTR(v) value(e). { + res = array(trim(v," =\n\r\t")=>e); +} + +attribute(res) ::= SPACE ID(v). { + res = '\''.v.'\''; +} + +attribute(res) ::= SPACE expr(e). { + res = e; +} + +attribute(res) ::= SPACE value(v). { + res = v; +} + +attribute(res) ::= SPACE INTEGER(i) EQUAL expr(e). { + res = array(i=>e); +} + + + +// +// statement +// +statements(res) ::= statement(s). { + res = array(s); +} + +statements(res) ::= statements(s1) COMMA statement(s). { + s1[]=s; + res = s1; +} + +statement(res) ::= DOLLARID(i) EQUAL INTEGER(e). { + res = array('var' => '\''.substr(i,1).'\'', 'value'=>e); +} +statement(res) ::= DOLLARID(i) EQUAL expr(e). { + res = array('var' => '\''.substr(i,1).'\'', 'value'=>e); +} + +statement(res) ::= varindexed(vi) EQUAL expr(e). { + res = array('var' => vi, 'value'=>e); +} + +statement(res) ::= OPENP statement(st) CLOSEP. { + res = st; +} + + +// +// expressions +// + + // single value +expr(res) ::= value(v). { + res = v; +} + + // ternary +expr(res) ::= ternary(v). { + res = v; +} + + // resources/streams +expr(res) ::= DOLLARID(i) COLON ID(i2). { + res = '$_smarty_tpl->getStreamVariable(\''.substr(i,1).'://' . i2 . '\')'; +} + + // arithmetic expression +expr(res) ::= expr(e) MATH(m) value(v). { + res = e . trim(m) . v; +} + +expr(res) ::= expr(e) UNIMATH(m) value(v). { + res = e . trim(m) . v; +} + + // array +expr(res) ::= array(a). { + res = a; +} + + // modifier +expr(res) ::= expr(e) modifierlist(l). { + res = $this->compiler->compileTag('private_modifier',array(),array('value'=>e,'modifierlist'=>l)); +} + +// if expression + // simple expression +expr(res) ::= expr(e1) lop(c) expr(e2). { + res = (isset(c['pre']) ? c['pre'] : '') . e1.c['op'].e2 . (isset(c['pre']) ? ')' : ''); +} +expr(res) ::= expr(e1) scond(c). { + res = c . e1 . ')'; +} + +expr(res) ::= expr(e1) ISIN array(a). { + res = 'in_array('.e1.','.a.')'; +} + +expr(res) ::= expr(e1) ISIN value(v). { + res = 'in_array('.e1.',(array)'.v.')'; +} + +expr(res) ::= variable(v1) INSTANCEOF(i) ns1(v2). { + res = v1.i.v2; +} + + +// +// ternary +// +ternary(res) ::= OPENP expr(v) CLOSEP QMARK DOLLARID(e1) COLON expr(e2). { + res = v.' ? '. $this->compiler->compileVariable('\''.substr(e1,1).'\'') . ' : '.e2; +} + +ternary(res) ::= OPENP expr(v) CLOSEP QMARK expr(e1) COLON expr(e2). { + res = v.' ? '.e1.' : '.e2; +} + + // value +value(res) ::= variable(v). { + res = v; +} + + // +/- value +value(res) ::= UNIMATH(m) value(v). { + res = m.v; +} + + // logical negation +value(res) ::= NOT value(v). { + res = '!'.v; +} + +value(res) ::= TYPECAST(t) value(v). { + res = t.v; +} + +value(res) ::= variable(v) INCDEC(o). { + res = v.o; +} + + // numeric +value(res) ::= HEX(n). { + res = n; +} + +value(res) ::= INTEGER(n). { + res = n; +} + +value(res) ::= INTEGER(n1) DOT INTEGER(n2). { + res = n1.'.'.n2; +} + +value(res) ::= INTEGER(n1) DOT. { + res = n1.'.'; +} + +value(res) ::= DOT INTEGER(n1). { + res = '.'.n1; +} + + // ID, true, false, null +value(res) ::= ID(id). { + if (defined(id)) { + if ($this->security) { + $this->security->isTrustedConstant(id, $this->compiler); + } + res = id; + } else { + res = '\''.id.'\''; + } +} + + // function call +value(res) ::= function(f). { + res = f; +} + + // expression +value(res) ::= OPENP expr(e) CLOSEP. { + res = "(". e .")"; +} + + // singele quoted string +value(res) ::= SINGLEQUOTESTRING(t). { + res = t; +} + + // double quoted string +value(res) ::= doublequoted_with_quotes(s). { + res = s; +} + + +value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). { + self::$prefix_number++; + if (vi['var'] == '\'smarty\'') { + $this->compiler->prefix_code[] = 'compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>'; + } else { + $this->compiler->prefix_code[] = 'compiler->compileVariable(vi['var']).vi['smarty_internal_index'].';?>'; + } + res = '$_tmp'.self::$prefix_number.'::'.r[0].r[1]; +} + + // Smarty tag +value(res) ::= smartytag(st). { + self::$prefix_number++; + $tmp = $this->compiler->appendCode('', st); + $this->compiler->prefix_code[] = $this->compiler->appendCode($tmp, ''); + res = '$_tmp'.self::$prefix_number; +} + +value(res) ::= value(v) modifierlist(l). { + res = $this->compiler->compileTag('private_modifier',array(),array('value'=>v,'modifierlist'=>l)); +} + // name space constant +value(res) ::= NAMESPACE(c). { + res = c; +} + + + // static class access +value(res) ::= ns1(c)DOUBLECOLON static_class_access(s). { + if (!in_array(strtolower(c), array('self', 'parent')) && (!$this->security || $this->security->isTrustedStaticClassAccess(c, s, $this->compiler))) { + if (isset($this->smarty->registered_classes[c])) { + res = $this->smarty->registered_classes[c].'::'.s[0].s[1]; + } else { + res = c.'::'.s[0].s[1]; + } + } else { + $this->compiler->trigger_template_error ("static class '".c."' is undefined or not allowed by security setting"); + } +} +// +// namespace stuff +// + +ns1(res) ::= ID(i). { + res = i; +} + +ns1(res) ::= NAMESPACE(i). { + res = i; +} + +//ns1(res) ::= variable(v). { +// res = v; +//} + + + + +// +// variables +// + // Smarty variable (optional array) +variable(res) ::= DOLLARID(i). { + res = $this->compiler->compileVariable('\''.substr(i,1).'\''); +} +variable(res) ::= varindexed(vi). { + if (vi['var'] == '\'smarty\'') { + $smarty_var = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']); + res = $smarty_var; + } else { + // used for array reset,next,prev,end,current + $this->last_variable = vi['var']; + $this->last_index = vi['smarty_internal_index']; + res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index']; + } +} + + // variable with property +variable(res) ::= varvar(v) AT ID(p). { + res = '$_smarty_tpl->tpl_vars['. v .']->'.p; +} + + // object +variable(res) ::= object(o). { + res = o; +} + + // config variable +variable(res) ::= HATCH ID(i) HATCH. { + res = '$_smarty_tpl->getConfigVariable( \''. i .'\')'; +} + +variable(res) ::= HATCH ID(i) HATCH arrayindex(a). { + res = '(is_array($tmp = $_smarty_tpl->getConfigVariable( \''. i .'\')) ? $tmp'.a.' :null)'; +} + +variable(res) ::= HATCH variable(v) HATCH. { + res = '$_smarty_tpl->getConfigVariable( '. v .')'; +} + +variable(res) ::= HATCH variable(v) HATCH arrayindex(a). { + res = '(is_array($tmp = $_smarty_tpl->getConfigVariable( '. v .')) ? $tmp'.a.' : null)'; +} + +varindexed(res) ::= DOLLARID(i) arrayindex(a). { + res = array('var'=>'\''.substr(i,1).'\'', 'smarty_internal_index'=>a); +} +varindexed(res) ::= varvar(v) arrayindex(a). { + res = array('var'=>v, 'smarty_internal_index'=>a); +} + +// +// array index +// + // multiple array index +arrayindex(res) ::= arrayindex(a1) indexdef(a2). { + res = a1.a2; +} + + // no array index +arrayindex ::= . { + return; +} + +// single index definition + // Smarty2 style index +indexdef(res) ::= DOT DOLLARID(i). { + res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']'; +} +indexdef(res) ::= DOT varvar(v). { + res = '['.$this->compiler->compileVariable(v).']'; +} + +indexdef(res) ::= DOT varvar(v) AT ID(p). { + res = '['.$this->compiler->compileVariable(v).'->'.p.']'; +} + +indexdef(res) ::= DOT ID(i). { + if (defined(i)) { + if ($this->security) { + $this->security->isTrustedConstant(i, $this->compiler); + } + res = '['. i .']'; + } else { + res = "['". i ."']"; + } +} + +indexdef(res) ::= DOT INTEGER(n). { + res = '['. n .']'; +} + + +indexdef(res) ::= DOT LDEL expr(e) RDEL. { + res = '['. e .']'; +} + + // section tag index +indexdef(res) ::= OPENB ID(i)CLOSEB. { + res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\'index\']').']'; +} + +indexdef(res) ::= OPENB ID(i) DOT ID(i2) CLOSEB. { + res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\''.i2.'\']').']'; +} +indexdef(res) ::= OPENB SINGLEQUOTESTRING(s) CLOSEB. { + res = '['.s.']'; +} +indexdef(res) ::= OPENB INTEGER(n) CLOSEB. { + res = '['.n.']'; +} +indexdef(res) ::= OPENB DOLLARID(i) CLOSEB. { + res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']';; +} +indexdef(res) ::= OPENB variable(v) CLOSEB. { + res = '['.v.']'; +} +indexdef(res) ::= OPENB value(v) CLOSEB. { + res = '['.v.']'; +} + + // PHP style index +indexdef(res) ::= OPENB expr(e) CLOSEB. { + res = '['. e .']'; +} + + // for assign append array +indexdef(res) ::= OPENB CLOSEB. { + res = '[]'; +} + + +// +// variable variable names +// + + // singel identifier element +varvar(res) ::= DOLLARID(i). { + res = '\''.substr(i,1).'\''; +} + // single $ +varvar(res) ::= DOLLAR. { + res = "''"; +} + + // sequence of identifier elements +varvar(res) ::= varvar(v1) varvarele(v2). { + res = v1.'.'.v2; +} + + // fix sections of element +varvarele(res) ::= ID(s). { + res = '\''.s.'\''; +} +varvarele(res) ::= SIMPELOUTPUT(i). { + $var = trim(substr(i, $this->lex->ldel_length, -$this->lex->rdel_length), ' $'); + res = $this->compiler->compileVariable('\''.$var.'\''); +} + + // variable sections of element +varvarele(res) ::= LDEL expr(e) RDEL. { + res = '('.e.')'; +} + +// +// objects +// +object(res) ::= varindexed(vi) objectchain(oc). { + if (vi['var'] == '\'smarty\'') { + res = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).oc; + } else { + res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].oc; + } +} + + // single element +objectchain(res) ::= objectelement(oe). { + res = oe; +} + + // chain of elements +objectchain(res) ::= objectchain(oc) objectelement(oe). { + res = oc.oe; +} + + // variable +objectelement(res)::= PTR ID(i) arrayindex(a). { + if ($this->security && substr(i,0,1) == '_') { + $this->compiler->trigger_template_error (self::Err1); + } + res = '->'.i.a; +} + +objectelement(res)::= PTR varvar(v) arrayindex(a). { + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + res = '->{'.$this->compiler->compileVariable(v).a.'}'; +} + +objectelement(res)::= PTR LDEL expr(e) RDEL arrayindex(a). { + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + res = '->{'.e.a.'}'; +} + +objectelement(res)::= PTR ID(ii) LDEL expr(e) RDEL arrayindex(a). { + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + res = '->{\''.ii.'\'.'.e.a.'}'; +} + + // method +objectelement(res)::= PTR method(f). { + res = '->'.f; +} + + +// +// function +// +function(res) ::= ns1(f) OPENP params(p) CLOSEP. { + if (!$this->security || $this->security->isTrustedPhpFunction(f, $this->compiler)) { + if (strcasecmp(f,'isset') === 0 || strcasecmp(f,'empty') === 0 || strcasecmp(f,'array') === 0 || is_callable(f)) { + $func_name = strtolower(f); + if ($func_name == 'isset') { + if (count(p) == 0) { + $this->compiler->trigger_template_error ('Illegal number of paramer in "isset()"'); + } + $par = implode(',',p); + if (strncasecmp($par,'$_smarty_tpl->getConfigVariable',strlen('$_smarty_tpl->getConfigVariable')) === 0) { + self::$prefix_number++; + $this->compiler->prefix_code[] = ''; + $isset_par = '$_tmp'.self::$prefix_number; + } else { + $isset_par=str_replace("')->value","',null,true,false)->value",$par); + } + res = f . "(". $isset_par .")"; + } elseif (in_array($func_name,array('empty','reset','current','end','prev','next'))){ + if (count(p) != 1) { + $this->compiler->trigger_template_error ('Illegal number of paramer in "empty()"'); + } + if ($func_name == 'empty') { + res = $func_name.'('.str_replace("')->value","',null,true,false)->value",p[0]).')'; + } else { + res = $func_name.'('.p[0].')'; + } + } else { + res = f . "(". implode(',',p) .")"; + } + } else { + $this->compiler->trigger_template_error ("unknown function \"" . f . "\""); + } + } +} + + +// +// method +// +method(res) ::= ID(f) OPENP params(p) CLOSEP. { + if ($this->security && substr(f,0,1) == '_') { + $this->compiler->trigger_template_error (self::Err1); + } + res = f . "(". implode(',',p) .")"; +} + +method(res) ::= DOLLARID(f) OPENP params(p) CLOSEP. { + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + self::$prefix_number++; + $this->compiler->prefix_code[] = 'compiler->compileVariable('\''.substr(f,1).'\'').';?>'; + res = '$_tmp'.self::$prefix_number.'('. implode(',',p) .')'; +} + +// function/method parameter + // multiple parameters +params(res) ::= params(p) COMMA expr(e). { + res = array_merge(p,array(e)); +} + + // single parameter +params(res) ::= expr(e). { + res = array(e); +} + + // kein parameter +params(res) ::= . { + res = array(); +} + +// +// modifier +// +modifierlist(res) ::= modifierlist(l) modifier(m) modparameters(p). { + res = array_merge(l,array(array_merge(m,p))); +} + +modifierlist(res) ::= modifier(m) modparameters(p). { + res = array(array_merge(m,p)); +} + +modifier(res) ::= VERT AT ID(m). { + res = array(m); +} + +modifier(res) ::= VERT ID(m). { + res = array(m); +} + +// +// modifier parameter +// + // multiple parameter +modparameters(res) ::= modparameters(mps) modparameter(mp). { + res = array_merge(mps,mp); +} + + // no parameter +modparameters(res) ::= . { + res = array(); +} + + // parameter expression +modparameter(res) ::= COLON value(mp). { + res = array(mp); +} + +modparameter(res) ::= COLON array(mp). { + res = array(mp); +} + + // static class methode call +static_class_access(res) ::= method(m). { + res = array(m, '', 'method'); +} + + // static class methode call with object chainig +static_class_access(res) ::= method(m) objectchain(oc). { + res = array(m, oc, 'method'); +} + + // static class constant +static_class_access(res) ::= ID(v). { + res = array(v, ''); +} + + // static class variables +static_class_access(res) ::= DOLLARID(v) arrayindex(a). { + res = array(v, a, 'property'); +} + + // static class variables with object chain +static_class_access(res) ::= DOLLARID(v) arrayindex(a) objectchain(oc). { + res = array(v, a.oc, 'property'); +} + + +// if conditions and operators +lop(res) ::= LOGOP(o). { + res['op'] = ' '. trim(o) . ' '; +} + +lop(res) ::= TLOGOP(o). { + static $lops = array( + 'eq' => array('op' => ' == ', 'pre' => null), + 'ne' => array('op' => ' != ', 'pre' => null), + 'neq' => array('op' => ' != ', 'pre' => null), + 'gt' => array('op' => ' > ', 'pre' => null), + 'ge' => array('op' => ' >= ', 'pre' => null), + 'gte' => array('op' => ' >= ', 'pre' => null), + 'lt' => array('op' => ' < ', 'pre' => null), + 'le' => array('op' => ' <= ', 'pre' => null), + 'lte' => array('op' => ' <= ', 'pre' => null), + 'mod' => array('op' => ' % ', 'pre' => null), + 'and' => array('op' => ' && ', 'pre' => null), + 'or' => array('op' => ' || ', 'pre' => null), + 'xor' => array('op' => ' xor ', 'pre' => null), + 'isdivby' => array('op' => ' % ', 'pre' => '!('), + 'isnotdivby' => array('op' => ' % ', 'pre' => '('), + 'isevenby' => array('op' => ' / ', 'pre' => '!(1 & '), + 'isnotevenby' => array('op' => ' / ', 'pre' => '(1 & '), + 'isoddby' => array('op' => ' / ', 'pre' => '(1 & '), + 'isnotoddby' => array('op' => ' / ', 'pre' => '!(1 & '), + ); + $op = strtolower(str_replace(' ', '', o)); + res = $lops[$op]; +} + +scond(res) ::= SINGLECOND(o). { + static $scond = array ( + 'iseven' => '!(1 & ', + 'isnoteven' => '(1 & ', + 'isodd' => '(1 & ', + 'isnotodd' => '!(1 & ', + ); + $op = strtolower(str_replace(' ', '', o)); + res = $scond[$op]; +} + +// +// ARRAY element assignment +// +array(res) ::= OPENB arrayelements(a) CLOSEB. { + res = 'array('.a.')'; +} + +arrayelements(res) ::= arrayelement(a). { + res = a; +} + +arrayelements(res) ::= arrayelements(a1) COMMA arrayelement(a). { + res = a1.','.a; +} + +arrayelements ::= . { + return; +} + +arrayelement(res) ::= value(e1) APTR expr(e2). { + res = e1.'=>'.e2; +} + +arrayelement(res) ::= ID(i) APTR expr(e2). { + res = '\''.i.'\'=>'.e2; +} + +arrayelement(res) ::= expr(e). { + res = e; +} + + +// +// double qouted strings +// +doublequoted_with_quotes(res) ::= QUOTE QUOTE. { + res = "''"; +} + +doublequoted_with_quotes(res) ::= QUOTE doublequoted(s) QUOTE. { + res = s->to_smarty_php(); +} + + +doublequoted(res) ::= doublequoted(o1) doublequotedcontent(o2). { + o1->append_subtree(o2); + res = o1; +} + +doublequoted(res) ::= doublequotedcontent(o). { + res = new Smarty_Internal_ParseTree_Dq($this, o); +} + +doublequotedcontent(res) ::= BACKTICK variable(v) BACKTICK. { + res = new Smarty_Internal_ParseTree_Code($this, '(string)'.v); +} + +doublequotedcontent(res) ::= BACKTICK expr(e) BACKTICK. { + res = new Smarty_Internal_ParseTree_Code($this, '(string)'.e); +} + +doublequotedcontent(res) ::= DOLLARID(i). { + res = new Smarty_Internal_ParseTree_Code($this, '(string)$_smarty_tpl->tpl_vars[\''. substr(i,1) .'\']->value'); +} + +doublequotedcontent(res) ::= LDEL variable(v) RDEL. { + res = new Smarty_Internal_ParseTree_Code($this, '(string)'.v); +} + +doublequotedcontent(res) ::= LDEL expr(e) RDEL. { + res = new Smarty_Internal_ParseTree_Code($this, '(string)('.e.')'); +} + +doublequotedcontent(res) ::= smartytag(st). { + res = new Smarty_Internal_ParseTree_Tag($this, st); +} + +doublequotedcontent(res) ::= TEXT(o). { + res = new Smarty_Internal_ParseTree_DqContent($this, o); +} + diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/Autoloader.php b/ewomail-admin/lib/smarty-3.1.24/libs/Autoloader.php new file mode 100644 index 0000000..a24cad6 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/Autoloader.php @@ -0,0 +1,158 @@ + 'Smarty.class.php', + 'SmartyBC' => 'SmartyBC.class.php', + ); + + private static $syspluginsClasses = array( + 'smarty_config_source' => true, + 'smarty_security' => true, + 'smarty_cacheresource' => true, + 'smarty_compiledresource' => true, + 'smarty_cacheresource_custom' => true, + 'smarty_cacheresource_keyvaluestore' => true, + 'smarty_resource' => true, + 'smarty_resource_custom' => true, + 'smarty_resource_uncompiled' => true, + 'smarty_resource_recompiled' => true, + 'smarty_template_source' => true, + 'smarty_template_compiled' => true, + 'smarty_template_cached' => true, + 'smarty_template_config' => true, + 'smarty_data' => true, + 'smarty_variable' => true, + 'smarty_undefined_variable' => true, + 'smartyexception' => true, + 'smartycompilerexception' => true, + 'smarty_internal_data' => true, + 'smarty_internal_template' => true, + 'smarty_internal_templatebase' => true, + 'smarty_internal_resource_file' => true, + 'smarty_internal_resource_extends' => true, + 'smarty_internal_resource_eval' => true, + 'smarty_internal_resource_string' => true, + 'smarty_internal_resource_registered' => true, + 'smarty_internal_extension_codeframe' => true, + 'smarty_internal_extension_config' => true, + 'smarty_internal_filter_handler' => true, + 'smarty_internal_function_call_handler' => true, + 'smarty_internal_cacheresource_file' => true, + 'smarty_internal_write_file' => true, + ); + + /** + * Registers Smarty_Autoloader backward compatible to older installations. + * + * @param bool $prepend Whether to prepend the autoloader or not. + */ + public static function registerBC($prepend = false) + { + /** + * register the class autoloader + */ + if (!defined('SMARTY_SPL_AUTOLOAD')) { + define('SMARTY_SPL_AUTOLOAD', 0); + } + if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) { + $registeredAutoLoadFunctions = spl_autoload_functions(); + if (!isset($registeredAutoLoadFunctions['spl_autoload'])) { + spl_autoload_register(); + } + } else { + self::register($prepend); + } + } + + /** + * Registers Smarty_Autoloader as an SPL autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not. + */ + public static function register($prepend = false) + { + self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . '/'; + self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR : self::$SMARTY_DIR . 'sysplugins/'; + if (version_compare(phpversion(), '5.3.0', '>=')) { + spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend); + } else { + spl_autoload_register(array(__CLASS__, 'autoload')); + } + } + + /** + * Handles autoloading of classes. + * + * @param string $class A class name. + */ + public static function autoload($class) + { + // Request for Smarty or already unknown class + if (isset(self::$unknown[$class])) { + return; + } + $_class = strtolower($class); + if (isset(self::$syspluginsClasses[$_class])) { + $_class = (self::$syspluginsClasses[$_class] === true) ? $_class : self::$syspluginsClasses[$_class]; + $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + require_once $file; + return; + } elseif (0 !== strpos($_class, 'smarty_internal_')) { + if (isset(self::$rootClasses[$class])) { + $file = self::$SMARTY_DIR . self::$rootClasses[$class]; + require_once $file; + return; + } + self::$unknown[$class] = true; + return; + } + $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + if (is_file($file)) { + require_once $file; + return; + } + self::$unknown[$class] = true; + return; + } +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/Smarty.class.php b/ewomail-admin/lib/smarty-3.1.24/libs/Smarty.class.php new file mode 100644 index 0000000..0a72076 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/Smarty.class.php @@ -0,0 +1,1815 @@ + + * @author Uwe Tews + * @author Rodney Rehm + * @package Smarty + * @version 3.1-DEV + */ + +/** + * define shorthand directory separator constant + */ +if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); +} + +/** + * set SMARTY_DIR to absolute path to Smarty library files. + * Sets SMARTY_DIR only if user application has not already defined it. + */ +if (!defined('SMARTY_DIR')) { + define('SMARTY_DIR', dirname(__FILE__) . DS); +} + +/** + * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. + * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. + */ +if (!defined('SMARTY_SYSPLUGINS_DIR')) { + define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS); +} +if (!defined('SMARTY_PLUGINS_DIR')) { + define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); +} +if (!defined('SMARTY_MBSTRING')) { + define('SMARTY_MBSTRING', function_exists('mb_get_info')); +} +if (!defined('SMARTY_RESOURCE_CHAR_SET')) { + // UTF-8 can only be done properly when mbstring is available! + /** + * @deprecated in favor of Smarty::$_CHARSET + */ + define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); +} +if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { + /** + * @deprecated in favor of Smarty::$_DATE_FORMAT + */ + define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y'); +} + +/** + * Try loading the Smmarty_Internal_Data class + * If we fail we must load Smarty's autoloader. + * Otherwise we may have a global autoloader like Composer + */ +if (!class_exists('Smarty_Autoloader', false)) { + if (!class_exists('Smarty_Internal_Data', true)) { + require_once 'Autoloader.php'; + Smarty_Autoloader::registerBC(); + } +} + +/** + * Load always needed external class files + */ + +if (!class_exists('Smarty_Internal_Data', false)) { + require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php'; +} +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php'; + +/** + * This is the main Smarty class + * + * @package Smarty + */ +class Smarty extends Smarty_Internal_TemplateBase +{ + /**#@+ + * constant definitions + */ + + /** + * smarty version + */ + const SMARTY_VERSION = '3.1.24'; + + /** + * define variable scopes + */ + const SCOPE_LOCAL = 0; + + const SCOPE_PARENT = 1; + + const SCOPE_ROOT = 2; + + const SCOPE_GLOBAL = 3; + + /** + * define caching modes + */ + const CACHING_OFF = 0; + + const CACHING_LIFETIME_CURRENT = 1; + + const CACHING_LIFETIME_SAVED = 2; + + /** + * define constant for clearing cache files be saved expiration datees + */ + const CLEAR_EXPIRED = - 1; + + /** + * define compile check modes + */ + const COMPILECHECK_OFF = 0; + + const COMPILECHECK_ON = 1; + + const COMPILECHECK_CACHEMISS = 2; + + /** + * define debug modes + */ + const DEBUG_OFF = 0; + + const DEBUG_ON = 1; + + const DEBUG_INDIVIDUAL = 2; + + /** + * modes for handling of "" tags in templates. + */ + const PHP_PASSTHRU = 0; //-> print tags as plain text + + const PHP_QUOTE = 1; //-> escape tags as entities + + const PHP_REMOVE = 2; //-> escape tags as entities + + const PHP_ALLOW = 3; //-> escape tags as entities + + /** + * filter types + */ + const FILTER_POST = 'post'; + + const FILTER_PRE = 'pre'; + + const FILTER_OUTPUT = 'output'; + + const FILTER_VARIABLE = 'variable'; + + /** + * plugin types + */ + const PLUGIN_FUNCTION = 'function'; + + const PLUGIN_BLOCK = 'block'; + + const PLUGIN_COMPILER = 'compiler'; + + const PLUGIN_MODIFIER = 'modifier'; + + const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler'; + + /**#@-*/ + + /** + * assigned global tpl vars + */ + public static $global_tpl_vars = array(); + + /** + * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors() + */ + public static $_previous_error_handler = null; + + /** + * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors() + */ + public static $_muted_directories = array('./templates_c/' => null, + './cache/' => null); + + /** + * Flag denoting if Multibyte String functions are available + */ + public static $_MBSTRING = SMARTY_MBSTRING; + + /** + * The character set to adhere to (e.g. "UTF-8") + */ + public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET; + + /** + * The date format to be used internally + * (accepts date() and strftime()) + */ + public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT; + + /** + * Flag denoting if PCRE should run in UTF-8 mode + */ + public static $_UTF8_MODIFIER = 'u'; + + /** + * Flag denoting if operating system is windows + */ + public static $_IS_WINDOWS = false; + + /**#@+ + * variables + */ + + /** + * auto literal on delimiters with whitspace + * + * @var boolean + */ + public $auto_literal = true; + + /** + * display error on not assigned variables + * + * @var boolean + */ + public $error_unassigned = false; + + /** + * look up relative filepaths in include_path + * + * @var boolean + */ + public $use_include_path = false; + + /** + * template directory + * + * @var array + */ + private $template_dir = array('./templates/'); + + /** + * joined template directory string used in cache keys + * + * @var string + */ + public $joined_template_dir = './templates/'; + + /** + * joined config directory string used in cache keys + * + * @var string + */ + public $joined_config_dir = './configs/'; + + /** + * default template handler + * + * @var callable + */ + public $default_template_handler_func = null; + + /** + * default config handler + * + * @var callable + */ + public $default_config_handler_func = null; + + /** + * default plugin handler + * + * @var callable + */ + public $default_plugin_handler_func = null; + + /** + * compile directory + * + * @var string + */ + private $compile_dir = './templates_c/'; + + /** + * plugins directory + * + * @var array + */ + private $plugins_dir = null; + + /** + * cache directory + * + * @var string + */ + private $cache_dir = './cache/'; + + /** + * config directory + * + * @var array + */ + private $config_dir = array('./configs/'); + + /** + * force template compiling? + * + * @var boolean + */ + public $force_compile = false; + + /** + * check template for modifications? + * + * @var boolean + */ + public $compile_check = true; + + /** + * use sub dirs for compiled/cached files? + * + * @var boolean + */ + public $use_sub_dirs = false; + + /** + * allow ambiguous resources (that are made unique by the resource handler) + * + * @var boolean + */ + public $allow_ambiguous_resources = false; + + /** + * merge compiled includes + * + * @var boolean + */ + public $merge_compiled_includes = false; + + /** + * template inheritance merge compiled includes + * + * @var boolean + */ + public $inheritance_merge_compiled_includes = true; + + /** + * force cache file creation + * + * @var boolean + */ + public $force_cache = false; + + /** + * template left-delimiter + * + * @var string + */ + public $left_delimiter = "{"; + + /** + * template right-delimiter + * + * @var string + */ + public $right_delimiter = "}"; + + /**#@+ + * security + */ + /** + * class name + * This should be instance of Smarty_Security. + * + * @var string + * @see Smarty_Security + */ + public $security_class = 'Smarty_Security'; + + /** + * implementation of security class + * + * @var Smarty_Security + */ + public $security_policy = null; + + /** + * controls handling of PHP-blocks + * + * @var integer + */ + public $php_handling = self::PHP_PASSTHRU; + + /** + * controls if the php template file resource is allowed + * + * @var bool + */ + public $allow_php_templates = false; + + /** + * Should compiled-templates be prevented from being called directly? + * {@internal + * Currently used by Smarty_Internal_Template only. + * }} + * + * @var boolean + */ + public $direct_access_security = true; + + /**#@-*/ + /** + * debug mode + * Setting this to true enables the debug-console. + * + * @var boolean + */ + public $debugging = false; + + /** + * This determines if debugging is enable-able from the browser. + *
    + *
  • NONE => no debugging control allowed
  • + *
  • URL => enable debugging when SMARTY_DEBUG is found in the URL.
  • + *
+ * + * @var string + */ + public $debugging_ctrl = 'NONE'; + + /** + * Name of debugging URL-param. + * Only used when $debugging_ctrl is set to 'URL'. + * The name of the URL-parameter that activates debugging. + * + * @var string + */ + public $smarty_debug_id = 'SMARTY_DEBUG'; + + /** + * Path of debug template. + * + * @var string + */ + public $debug_tpl = null; + + /** + * When set, smarty uses this value as error_reporting-level. + * + * @var int + */ + public $error_reporting = null; + + /** + * Internal flag for getTags() + * + * @var boolean + */ + public $get_used_tags = false; + + /**#@+ + * config var settings + */ + + /** + * Controls whether variables with the same name overwrite each other. + * + * @var boolean + */ + public $config_overwrite = true; + + /** + * Controls whether config values of on/true/yes and off/false/no get converted to boolean. + * + * @var boolean + */ + public $config_booleanize = true; + + /** + * Controls whether hidden config sections/vars are read from the file. + * + * @var boolean + */ + public $config_read_hidden = false; + + /**#@-*/ + + /**#@+ + * resource locking + */ + + /** + * locking concurrent compiles + * + * @var boolean + */ + public $compile_locking = true; + + /** + * Controls whether cache resources should emply locking mechanism + * + * @var boolean + */ + public $cache_locking = false; + + /** + * seconds to wait for acquiring a lock before ignoring the write lock + * + * @var float + */ + public $locking_timeout = 10; + + /**#@-*/ + + /** + * resource type used if none given + * Must be an valid key of $registered_resources. + * + * @var string + */ + public $default_resource_type = 'file'; + + /** + * caching type + * Must be an element of $cache_resource_types. + * + * @var string + */ + public $caching_type = 'file'; + + /** + * internal config properties + * + * @var array + */ + public $properties = array(); + + /** + * config type + * + * @var string + */ + public $default_config_type = 'file'; + + /** + * cached template objects + * + * @var array + */ + public $source_objects = array(); + + /** + * cached template objects + * + * @var array + */ + public $template_objects = array(); + + /** + * enable resource caching + * + * @var bool + */ + public $resource_caching = false; + + /** + * enable template resource caching + * + * @var bool + */ + public $template_resource_caching = true; + + /** + * check If-Modified-Since headers + * + * @var boolean + */ + public $cache_modified_check = false; + + /** + * registered plugins + * + * @var array + */ + public $registered_plugins = array(); + + /** + * plugin search order + * + * @var array + */ + public $plugin_search_order = array('function', + 'block', + 'compiler', + 'class'); + + /** + * registered objects + * + * @var array + */ + public $registered_objects = array(); + + /** + * registered classes + * + * @var array + */ + public $registered_classes = array(); + + /** + * registered filters + * + * @var array + */ + public $registered_filters = array(); + + /** + * registered resources + * + * @var array + */ + public $registered_resources = array(); + + /** + * resource handler cache + * + * @var array + */ + public $_resource_handlers = array(); + + /** + * registered cache resources + * + * @var array + */ + public $registered_cache_resources = array(); + + /** + * cache resource handler cache + * + * @var array + */ + public $_cacheresource_handlers = array(); + + /** + * autoload filter + * + * @var array + */ + public $autoload_filters = array(); + + /** + * default modifier + * + * @var array + */ + public $default_modifiers = array(); + + /** + * autoescape variable output + * + * @var boolean + */ + public $escape_html = false; + + /** + * global internal smarty vars + * + * @var array + */ + public static $_smarty_vars = array(); + + /** + * start time for execution time calculation + * + * @var int + */ + public $start_time = 0; + + /** + * default file permissions + * + * @var int + */ + public $_file_perms = 0644; + + /** + * default dir permissions + * + * @var int + */ + public $_dir_perms = 0771; + + /** + * block tag hierarchy + * + * @var array + */ + public $_tag_stack = array(); + + /** + * required by the compiler for BC + * + * @var string + */ + public $_current_file = null; + + /** + * internal flag to enable parser debugging + * + * @var bool + */ + public $_parserdebug = false; + + /** + * Cache of is_file results of loadPlugin() + * + * @var array + */ + public $_is_file_cache = array(); + + /**#@-*/ + + /** + * Initialize new Smarty object + */ + public function __construct() + { + if (is_callable('mb_internal_encoding')) { + mb_internal_encoding(Smarty::$_CHARSET); + } + $this->start_time = microtime(true); + // check default dirs for overloading + if ($this->template_dir[0] !== './templates/' || isset($this->template_dir[1])) { + $this->setTemplateDir($this->template_dir); + } + if ($this->config_dir[0] !== './configs/' || isset($this->config_dir[1])) { + $this->setConfigDir($this->config_dir); + } + if ($this->compile_dir !== './templates_c/') { + unset(self::$_muted_directories['./templates_c/']); + $this->setCompileDir($this->compile_dir); + } + if ($this->cache_dir !== './cache/') { + unset(self::$_muted_directories['./cache/']); + $this->setCacheDir($this->cache_dir); + } + if (isset($this->plugins_dir)) { + $this->setPluginsDir($this->plugins_dir); + } else { + $this->setPluginsDir(SMARTY_PLUGINS_DIR); + } + if (isset($_SERVER['SCRIPT_NAME'])) { + Smarty::$global_tpl_vars['SCRIPT_NAME'] = new Smarty_Variable($_SERVER['SCRIPT_NAME']); + } + + // Check if we're running on windows + Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + + // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 + if (Smarty::$_CHARSET !== 'UTF-8') { + Smarty::$_UTF8_MODIFIER = ''; + } + } + + /** + * fetches a rendered Smarty template + * + * @param string $template the resource handle of the template file or template object + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param object $parent next higher level of Smarty variables + * @param bool $display true: display, false: fetch + * @param bool $merge_tpl_vars not used - left for BC + * @param bool $no_output_filter not used - left for BC + * + * @throws Exception + * @throws SmartyException + * @return string rendered template output + */ + public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) + { + if ($cache_id !== null && is_object($cache_id)) { + $parent = $cache_id; + $cache_id = null; + } + if ($parent === null) { + $parent = $this; + } + // get template object + $_template = is_object($template) ? $template : $this->createTemplate($template, $cache_id, $compile_id, $parent, false); + // set caching in template object + $_template->caching = $this->caching; + // fetch template content + return $_template->render(true, false, $display); + } + + /** + * displays a Smarty template + * + * @param string $template the resource handle of the template file or template object + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param object $parent next higher level of Smarty variables + */ + public function display($template = null, $cache_id = null, $compile_id = null, $parent = null) + { + // display template + $this->fetch($template, $cache_id, $compile_id, $parent, true); + } + + /** + * Check if a template resource exists + * + * @param string $resource_name template name + * + * @return boolean status + */ + public function templateExists($resource_name) + { + // create template object + $save = $this->template_objects; + $tpl = new $this->template_class($resource_name, $this); + // check if it does exists + $result = $tpl->source->exists; + $this->template_objects = $save; + + return $result; + } + + /** + * Returns a single or all global variables + * + * @param string $varname variable name or null + * + * @return string variable value or or array of variables + */ + public function getGlobal($varname = null) + { + if (isset($varname)) { + if (isset(self::$global_tpl_vars[$varname])) { + return self::$global_tpl_vars[$varname]->value; + } else { + return ''; + } + } else { + $_result = array(); + foreach (self::$global_tpl_vars AS $key => $var) { + $_result[$key] = $var->value; + } + + return $_result; + } + } + + /** + * Empty cache folder + * + * @param integer $exp_time expiration time + * @param string $type resource type + * + * @return integer number of cache files deleted + */ + public function clearAllCache($exp_time = null, $type = null) + { + // load cache resource and call clearAll + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + + return $_cache_resource->clearAll($this, $exp_time); + } + + /** + * Empty cache for a specific template + * + * @param string $template_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @param string $type resource type + * + * @return integer number of cache files deleted + */ + public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) + { + // load cache resource and call clear + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + + return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); + } + + /** + * Loads security class and enables security + * + * @param string|Smarty_Security $security_class if a string is used, it must be class-name + * + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when an invalid class name is provided + */ + public function enableSecurity($security_class = null) + { + if ($security_class instanceof Smarty_Security) { + $this->security_policy = $security_class; + + return $this; + } elseif (is_object($security_class)) { + throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security."); + } + if ($security_class == null) { + $security_class = $this->security_class; + } + if (!class_exists($security_class)) { + throw new SmartyException("Security class '$security_class' is not defined"); + } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) { + throw new SmartyException("Class '$security_class' must extend Smarty_Security."); + } else { + $this->security_policy = new $security_class($this); + } + + return $this; + } + + /** + * Disable security + * + * @return Smarty current Smarty instance for chaining + */ + public function disableSecurity() + { + $this->security_policy = null; + + return $this; + } + + /** + * Set template directory + * + * @param string|array $template_dir directory(s) of template sources + * + * @return Smarty current Smarty instance for chaining + */ + public function setTemplateDir($template_dir) + { + $this->template_dir = array(); + foreach ((array) $template_dir as $k => $v) { + $this->template_dir[$k] = rtrim(strtr($v, '\\', '/'), '/') . '/'; + } + $this->joined_template_dir = join(' # ', $this->template_dir); + return $this; + } + + /** + * Add template directory(s) + * + * @param string|array $template_dir directory(s) of template sources + * @param string $key of the array element to assign the template dir to + * + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when the given template directory is not valid + */ + public function addTemplateDir($template_dir, $key = null) + { + $this->_addDir('template_dir', $template_dir, $key); + $this->joined_template_dir = join(' # ', $this->template_dir); + return $this; + } + + /** + * Get template directories + * + * @param mixed $index index of directory to get, null to get all + * + * @return array|string list of template directories, or directory of $index + */ + public function getTemplateDir($index = null) + { + if ($index !== null) { + return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; + } + return (array) $this->template_dir; + } + + /** + * Set config directory + * + * @param $config_dir + * + * @return Smarty current Smarty instance for chaining + */ + public function setConfigDir($config_dir) + { + $this->config_dir = array(); + foreach ((array) $config_dir as $k => $v) { + $this->config_dir[$k] = rtrim(strtr($v, '\\', '/'), '/') . '/'; + } + $this->joined_config_dir = join(' # ', $this->config_dir); + return $this; + } + + /** + * Add config directory(s) + * + * @param string|array $config_dir directory(s) of config sources + * @param mixed $key key of the array element to assign the config dir to + * + * @return Smarty current Smarty instance for chaining + */ + public function addConfigDir($config_dir, $key = null) + { + $this->_addDir('config_dir', $config_dir, $key); + $this->joined_config_dir = join(' # ', $this->config_dir); + return $this; + } + + /** + * Get config directory + * + * @param mixed $index index of directory to get, null to get all + * + * @return array|string configuration directory + */ + public function getConfigDir($index = null) + { + if ($index !== null) { + return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null; + } + return (array) $this->config_dir; + } + + /** + * Set plugins directory + * + * @param string|array $plugins_dir directory(s) of plugins + * + * @return Smarty current Smarty instance for chaining + */ + public function setPluginsDir($plugins_dir) + { + $this->plugins_dir = array(); + foreach ((array) $plugins_dir as $k => $v) { + $this->plugins_dir[$k] = rtrim(strtr($v, '\\', '/'), '/') . '/'; + } + $this->_is_file_cache = array(); + return $this; + } + + /** + * Adds directory of plugin files + * + * @param $plugins_dir + * + * @return Smarty current Smarty instance for chaining + */ + public function addPluginsDir($plugins_dir) + { + $this->_addDir('plugins_dir', $plugins_dir); + $this->plugins_dir = array_unique($this->plugins_dir); + $this->_is_file_cache = array(); + return $this; + } + + /** + * Get plugin directories + * + * @return array list of plugin directories + */ + public function getPluginsDir() + { + return (array) $this->plugins_dir; + } + + /** + * Set compile directory + * + * @param string $compile_dir directory to store compiled templates in + * + * @return Smarty current Smarty instance for chaining + */ + public function setCompileDir($compile_dir) + { + $this->compile_dir = rtrim(strtr($compile_dir, '\\', '/'), '/') . '/'; + if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { + Smarty::$_muted_directories[$this->compile_dir] = null; + } + + return $this; + } + + /** + * Get compiled directory + * + * @return string path to compiled templates + */ + public function getCompileDir() + { + return $this->compile_dir; + } + + /** + * Set cache directory + * + * @param string $cache_dir directory to store cached templates in + * + * @return Smarty current Smarty instance for chaining + */ + public function setCacheDir($cache_dir) + { + $this->cache_dir = rtrim(strtr($cache_dir, '\\', '/'), '/') . '/'; + if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { + Smarty::$_muted_directories[$this->cache_dir] = null; + } + + return $this; + } + + /** + * Get cache directory + * + * @return string path of cache directory + */ + public function getCacheDir() + { + return $this->cache_dir; + } + + /** + * add directories to given property name + * + * @param string $dirName directory property name + * @param string|array $dir directory string or array of strings + * @param mixed $key optional key + */ + private function _addDir($dirName, $dir, $key = null) + { + // make sure we're dealing with an array + $this->$dirName = (array) $this->$dirName; + + if (is_array($dir)) { + foreach ($dir as $k => $v) { + $v = rtrim(strtr($v, '\\', '/'), '/') . '/'; + if (is_int($k)) { + // indexes are not merged but appended + $this->{$dirName}[] = $v; + } else { + // string indexes are overridden + $this->{$dirName}[$k] = $v; + } + } + } else { + $v = rtrim(strtr($dir, '\\', '/'), '/') . '/'; + if ($key !== null) { + // override directory at specified index + $this->{$dirName}[$key] = $v; + } else { + // append new directory + $this->{$dirName}[] = $v; + } + } + } + + /** + * Set default modifiers + * + * @param array|string $modifiers modifier or list of modifiers to set + * + * @return Smarty current Smarty instance for chaining + */ + public function setDefaultModifiers($modifiers) + { + $this->default_modifiers = (array) $modifiers; + + return $this; + } + + /** + * Add default modifiers + * + * @param array|string $modifiers modifier or list of modifiers to add + * + * @return Smarty current Smarty instance for chaining + */ + public function addDefaultModifiers($modifiers) + { + if (is_array($modifiers)) { + $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); + } else { + $this->default_modifiers[] = $modifiers; + } + + return $this; + } + + /** + * Get default modifiers + * + * @return array list of default modifiers + */ + public function getDefaultModifiers() + { + return $this->default_modifiers; + } + + /** + * Set autoload filters + * + * @param array $filters filters to load automatically + * @param string $type "pre", "output", ?specify the filter type to set. Defaults to none treating $filters' + * keys as the appropriate types + * + * @return Smarty current Smarty instance for chaining + */ + public function setAutoloadFilters($filters, $type = null) + { + if ($type !== null) { + $this->autoload_filters[$type] = (array) $filters; + } else { + $this->autoload_filters = (array) $filters; + } + + return $this; + } + + /** + * Add autoload filters + * + * @param array $filters filters to load automatically + * @param string $type "pre", "output", ?specify the filter type to set. Defaults to none treating $filters' + * keys as the appropriate types + * + * @return Smarty current Smarty instance for chaining + */ + public function addAutoloadFilters($filters, $type = null) + { + if ($type !== null) { + if (!empty($this->autoload_filters[$type])) { + $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters); + } else { + $this->autoload_filters[$type] = (array) $filters; + } + } else { + foreach ((array) $filters as $key => $value) { + if (!empty($this->autoload_filters[$key])) { + $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value); + } else { + $this->autoload_filters[$key] = (array) $value; + } + } + } + + return $this; + } + + /** + * Get autoload filters + * + * @param string $type type of filter to get autoloads for. Defaults to all autoload filters + * + * @return array array( 'type1' => array( 'filter1', 'filter2', ?) ) or array( 'filter1', 'filter2', ? if $type + * was specified + */ + public function getAutoloadFilters($type = null) + { + if ($type !== null) { + return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); + } + + return $this->autoload_filters; + } + + /** + * return name of debugging template + * + * @return string + */ + public function getDebugTemplate() + { + return $this->debug_tpl; + } + + /** + * set the debug template + * + * @param string $tpl_name + * + * @return Smarty current Smarty instance for chaining + * @throws SmartyException if file is not readable + */ + public function setDebugTemplate($tpl_name) + { + if (!is_readable($tpl_name)) { + throw new SmartyException("Unknown file '{$tpl_name}'"); + } + $this->debug_tpl = $tpl_name; + + return $this; + } + + /** + * creates a template object + * + * @param string $template the resource handle of the template file + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param object $parent next higher level of Smarty variables + * @param boolean $do_clone flag is Smarty object shall be cloned + * + * @return object template object + */ + public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) + { + if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) { + $parent = $cache_id; + $cache_id = null; + } + if ($parent !== null && is_array($parent)) { + $data = $parent; + $parent = null; + } else { + $data = null; + } + $_templateId = $this->getTemplateId($template, $cache_id, $compile_id); + if (isset($this->template_objects[$_templateId])) { + if ($do_clone) { + $tpl = clone $this->template_objects[$_templateId]; + $tpl->smarty = clone $tpl->smarty; + } else { + $tpl = $this->template_objects[$_templateId]; + } + $tpl->parent = $parent; + $tpl->tpl_vars = array(); + $tpl->config_vars = array(); + } else { + $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id); + if ($do_clone) { + $tpl->smarty = clone $tpl->smarty; + } + $tpl->templateId = $_templateId; + } + // fill data if present + if (!empty($data) && is_array($data)) { + // set up variable values + foreach ($data as $_key => $_val) { + $tpl->tpl_vars[$_key] = new Smarty_Variable($_val); + } + } + if ($this->debugging) { + Smarty_Internal_Debug::register_template($tpl); + } + return $tpl; + } + + /** + * Takes unknown classes and loads plugin files for them + * class name format: Smarty_PluginType_PluginName + * plugin filename format: plugintype.pluginname.php + * + * @param string $plugin_name class plugin name to load + * @param bool $check check if already loaded + * + * @throws SmartyException + * @return string |boolean filepath of loaded file or false + */ + public function loadPlugin($plugin_name, $check = true) + { + // if function or class exists, exit silently (already loaded) + if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { + return true; + } + // Plugin name is expected to be: Smarty_[Type]_[Name] + $_name_parts = explode('_', $plugin_name, 3); + // class name must have three parts to be valid plugin + // count($_name_parts) < 3 === !isset($_name_parts[2]) + if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') { + throw new SmartyException("plugin {$plugin_name} is not a valid name format"); + } + // if type is "internal", get plugin from sysplugins + if (strtolower($_name_parts[1]) == 'internal') { + $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php'; + if (isset($this->_is_file_cache[$file]) ? $this->_is_file_cache[$file] : $this->_is_file_cache[$file] = is_file($file)) { + require_once($file); + return $file; + } else { + return false; + } + } + // plugin filename is expected to be: [type].[name].php + $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; + + $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); + + // loop through plugin dirs and find the plugin + foreach ($this->getPluginsDir() as $_plugin_dir) { + $names = array($_plugin_dir . $_plugin_filename, + $_plugin_dir . strtolower($_plugin_filename),); + foreach ($names as $file) { + if (isset($this->_is_file_cache[$file]) ? $this->_is_file_cache[$file] : $this->_is_file_cache[$file] = is_file($file)) { + require_once($file); + return $file; + } + if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $file = stream_resolve_include_path($file); + } else { + $file = Smarty_Internal_Get_Include_Path::getIncludePath($file); + } + + if ($file !== false) { + require_once($file); + + return $file; + } + } + } + } + // no plugin loaded + return false; + } + + /** + * Compile all template files + * + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * + * @return integer number of template files recompiled + */ + public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) + { + return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this); + } + + /** + * Compile all config files + * + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * + * @return integer number of template files recompiled + */ + public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) + { + return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this); + } + + /** + * Delete compiled template file + * + * @param string $resource_name template name + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * + * @return integer number of template files deleted + */ + public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) + { + return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this); + } + + /** + * Return array of tag/attributes of all tags used by an template + * + * @param Smarty_Internal_Template $template + * + * @return array of tag/attributes + */ + public function getTags(Smarty_Internal_Template $template) + { + return Smarty_Internal_Utility::getTags($template); + } + + /** + * Run installation test + * + * @param array $errors Array to write errors into, rather than outputting them + * + * @return boolean true if setup is fine, false if something is wrong + */ + public function testInstall(&$errors = null) + { + return Smarty_Internal_TestInstall::testInstall($this, $errors); + } + + /** + * @param boolean $compile_check + */ + public function setCompileCheck($compile_check) + { + $this->compile_check = $compile_check; + } + + /** + * @param boolean $use_sub_dirs + */ + public function setUseSubDirs($use_sub_dirs) + { + $this->use_sub_dirs = $use_sub_dirs; + } + + /** + * @param boolean $caching + */ + public function setCaching($caching) + { + $this->caching = $caching; + } + + /** + * @param int $cache_lifetime + */ + public function setCacheLifetime($cache_lifetime) + { + $this->cache_lifetime = $cache_lifetime; + } + + /** + * @param string $compile_id + */ + public function setCompileId($compile_id) + { + $this->compile_id = $compile_id; + } + + /** + * @param string $cache_id + */ + public function setCacheId($cache_id) + { + $this->cache_id = $cache_id; + } + + /** + * @param int $error_reporting + */ + public function setErrorReporting($error_reporting) + { + $this->error_reporting = $error_reporting; + } + + /** + * @param boolean $escape_html + */ + public function setEscapeHtml($escape_html) + { + $this->escape_html = $escape_html; + } + + /** + * @param boolean $auto_literal + */ + public function setAutoLiteral($auto_literal) + { + $this->auto_literal = $auto_literal; + } + + /** + * @param boolean $force_compile + */ + public function setForceCompile($force_compile) + { + $this->force_compile = $force_compile; + } + + /** + * @param boolean $merge_compiled_includes + */ + public function setMergeCompiledIncludes($merge_compiled_includes) + { + $this->merge_compiled_includes = $merge_compiled_includes; + } + + /** + * @param string $left_delimiter + */ + public function setLeftDelimiter($left_delimiter) + { + $this->left_delimiter = $left_delimiter; + } + + /** + * @param string $right_delimiter + */ + public function setRightDelimiter($right_delimiter) + { + $this->right_delimiter = $right_delimiter; + } + + /** + * @param boolean $debugging + */ + public function setDebugging($debugging) + { + $this->debugging = $debugging; + } + + /** + * @param boolean $config_overwrite + */ + public function setConfigOverwrite($config_overwrite) + { + $this->config_overwrite = $config_overwrite; + } + + /** + * @param boolean $config_booleanize + */ + public function setConfigBooleanize($config_booleanize) + { + $this->config_booleanize = $config_booleanize; + } + + /** + * @param boolean $config_read_hidden + */ + public function setConfigReadHidden($config_read_hidden) + { + $this->config_read_hidden = $config_read_hidden; + } + + /** + * @param boolean $compile_locking + */ + public function setCompileLocking($compile_locking) + { + $this->compile_locking = $compile_locking; + } + + /** + * Class destructor + */ + public function __destruct() + { + // intentionally left blank + } + + /** + * <> Generic getter. + * Calls the appropriate getter function. + * Issues an E_USER_NOTICE if no valid getter is found. + * + * @param string $name property name + * + * @return mixed + */ + public function __get($name) + { + $allowed = array('template_dir' => 'getTemplateDir', + 'config_dir' => 'getConfigDir', + 'plugins_dir' => 'getPluginsDir', + 'compile_dir' => 'getCompileDir', + 'cache_dir' => 'getCacheDir',); + + if (isset($allowed[$name])) { + return $this->{$allowed[$name]}(); + } else { + trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); + } + } + + /** + * <> Generic setter. + * Calls the appropriate setter function. + * Issues an E_USER_NOTICE if no valid setter is found. + * + * @param string $name property name + * @param mixed $value parameter passed to setter + */ + public function __set($name, $value) + { + $allowed = array('template_dir' => 'setTemplateDir', + 'config_dir' => 'setConfigDir', + 'plugins_dir' => 'setPluginsDir', + 'compile_dir' => 'setCompileDir', + 'cache_dir' => 'setCacheDir',); + + if (isset($allowed[$name])) { + $this->{$allowed[$name]}($value); + } else { + trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); + } + } + + /** + * Error Handler to mute expected messages + * + * @link http://php.net/set_error_handler + * + * @param integer $errno Error level + * @param $errstr + * @param $errfile + * @param $errline + * @param $errcontext + * + * @return boolean + */ + public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) + { + $_is_muted_directory = false; + + // add the SMARTY_DIR to the list of muted directories + if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { + $smarty_dir = realpath(SMARTY_DIR); + if ($smarty_dir !== false) { + Smarty::$_muted_directories[SMARTY_DIR] = array('file' => $smarty_dir, + 'length' => strlen($smarty_dir),); + } + } + + // walk the muted directories and test against $errfile + foreach (Smarty::$_muted_directories as $key => &$dir) { + if (!$dir) { + // resolve directory and length for speedy comparisons + $file = realpath($key); + if ($file === false) { + // this directory does not exist, remove and skip it + unset(Smarty::$_muted_directories[$key]); + continue; + } + $dir = array('file' => $file, + 'length' => strlen($file),); + } + if (!strncmp($errfile, $dir['file'], $dir['length'])) { + $_is_muted_directory = true; + break; + } + } + + // pass to next error handler if this error did not occur inside SMARTY_DIR + // or the error was within smarty but masked to be ignored + if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { + if (Smarty::$_previous_error_handler) { + return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext); + } else { + return false; + } + } + } + + /** + * Enable error handler to mute expected messages + * + * @return void + */ + public static function muteExpectedErrors() + { + /* + error muting is done because some people implemented custom error_handlers using + http://php.net/set_error_handler and for some reason did not understand the following paragraph: + + It is important to remember that the standard PHP error handler is completely bypassed for the + error types specified by error_types unless the callback function returns FALSE. + error_reporting() settings will have no effect and your error handler will be called regardless - + however you are still able to read the current value of error_reporting and act appropriately. + Of particular note is that this value will be 0 if the statement that caused the error was + prepended by the @ error-control operator. + + Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include + - @filemtime() is almost twice as fast as using an additional file_exists() + - between file_exists() and filemtime() a possible race condition is opened, + which does not exist using the simple @filemtime() approach. + */ + $error_handler = array('Smarty', + 'mutingErrorHandler'); + $previous = set_error_handler($error_handler); + + // avoid dead loops + if ($previous !== $error_handler) { + Smarty::$_previous_error_handler = $previous; + } + } + + /** + * Disable error handler muting expected messages + * + * @return void + */ + public static function unmuteExpectedErrors() + { + restore_error_handler(); + } +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/SmartyBC.class.php b/ewomail-admin/lib/smarty-3.1.24/libs/SmartyBC.class.php new file mode 100644 index 0000000..76dd8bd --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/SmartyBC.class.php @@ -0,0 +1,448 @@ + + * @author Uwe Tews + * @author Rodney Rehm + * @package Smarty + */ +/** + * @ignore + */ +require_once(dirname(__FILE__) . '/Smarty.class.php'); + +/** + * Smarty Backward Compatability Wrapper Class + * + * @package Smarty + */ +class SmartyBC extends Smarty +{ + /** + * Smarty 2 BC + * + * @var string + */ + public $_version = self::SMARTY_VERSION; + + /** + * Initialize new SmartyBC object + * + * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false ) + */ + public function __construct(array $options = array()) + { + parent::__construct($options); + } + + /** + * wrapper for assign_by_ref + * + * @param string $tpl_var the template variable name + * @param mixed &$value the referenced value to assign + */ + public function assign_by_ref($tpl_var, &$value) + { + $this->assignByRef($tpl_var, $value); + } + + /** + * wrapper for append_by_ref + * + * @param string $tpl_var the template variable name + * @param mixed &$value the referenced value to append + * @param boolean $merge flag if array elements shall be merged + */ + public function append_by_ref($tpl_var, &$value, $merge = false) + { + $this->appendByRef($tpl_var, $value, $merge); + } + + /** + * clear the given assigned template variable. + * + * @param string $tpl_var the template variable to clear + */ + public function clear_assign($tpl_var) + { + $this->clearAssign($tpl_var); + } + + /** + * Registers custom function to be used in templates + * + * @param string $function the name of the template function + * @param string $function_impl the name of the PHP function to register + * @param bool $cacheable + * @param mixed $cache_attrs + */ + public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null) + { + $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs); + } + + /** + * Unregisters custom function + * + * @param string $function name of template function + */ + public function unregister_function($function) + { + $this->unregisterPlugin('function', $function); + } + + /** + * Registers object to be used in templates + * + * @param string $object name of template object + * @param object $object_impl the referenced PHP object to register + * @param array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param array $block_methods list of methods that are block format + * + * @throws SmartyException + * @internal param array $block_functs list of methods that are block format + */ + public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + { + settype($allowed, 'array'); + settype($smarty_args, 'boolean'); + $this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods); + } + + /** + * Unregisters object + * + * @param string $object name of template object + */ + public function unregister_object($object) + { + $this->unregisterObject($object); + } + + /** + * Registers block function to be used in templates + * + * @param string $block name of template block + * @param string $block_impl PHP function to register + * @param bool $cacheable + * @param mixed $cache_attrs + */ + public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null) + { + $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs); + } + + /** + * Unregisters block function + * + * @param string $block name of template function + */ + public function unregister_block($block) + { + $this->unregisterPlugin('block', $block); + } + + /** + * Registers compiler function + * + * @param string $function name of template function + * @param string $function_impl name of PHP function to register + * @param bool $cacheable + */ + public function register_compiler_function($function, $function_impl, $cacheable = true) + { + $this->registerPlugin('compiler', $function, $function_impl, $cacheable); + } + + /** + * Unregisters compiler function + * + * @param string $function name of template function + */ + public function unregister_compiler_function($function) + { + $this->unregisterPlugin('compiler', $function); + } + + /** + * Registers modifier to be used in templates + * + * @param string $modifier name of template modifier + * @param string $modifier_impl name of PHP function to register + */ + public function register_modifier($modifier, $modifier_impl) + { + $this->registerPlugin('modifier', $modifier, $modifier_impl); + } + + /** + * Unregisters modifier + * + * @param string $modifier name of template modifier + */ + public function unregister_modifier($modifier) + { + $this->unregisterPlugin('modifier', $modifier); + } + + /** + * Registers a resource to fetch a template + * + * @param string $type name of resource + * @param array $functions array of functions to handle resource + */ + public function register_resource($type, $functions) + { + $this->registerResource($type, $functions); + } + + /** + * Unregisters a resource + * + * @param string $type name of resource + */ + public function unregister_resource($type) + { + $this->unregisterResource($type); + } + + /** + * Registers a prefilter function to apply + * to a template before compiling + * + * @param callable $function + */ + public function register_prefilter($function) + { + $this->registerFilter('pre', $function); + } + + /** + * Unregisters a prefilter function + * + * @param callable $function + */ + public function unregister_prefilter($function) + { + $this->unregisterFilter('pre', $function); + } + + /** + * Registers a postfilter function to apply + * to a compiled template after compilation + * + * @param callable $function + */ + public function register_postfilter($function) + { + $this->registerFilter('post', $function); + } + + /** + * Unregisters a postfilter function + * + * @param callable $function + */ + public function unregister_postfilter($function) + { + $this->unregisterFilter('post', $function); + } + + /** + * Registers an output filter function to apply + * to a template output + * + * @param callable $function + */ + public function register_outputfilter($function) + { + $this->registerFilter('output', $function); + } + + /** + * Unregisters an outputfilter function + * + * @param callable $function + */ + public function unregister_outputfilter($function) + { + $this->unregisterFilter('output', $function); + } + + /** + * load a filter of specified type and name + * + * @param string $type filter type + * @param string $name filter name + */ + public function load_filter($type, $name) + { + $this->loadFilter($type, $name); + } + + /** + * clear cached content for the given template and cache id + * + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * + * @return boolean + */ + public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + { + return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time); + } + + /** + * clear the entire contents of cache (all templates) + * + * @param string $exp_time expire time + * + * @return boolean + */ + public function clear_all_cache($exp_time = null) + { + return $this->clearCache(null, null, null, $exp_time); + } + + /** + * test to see if valid cache exists for this template + * + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * + * @return boolean + */ + public function is_cached($tpl_file, $cache_id = null, $compile_id = null) + { + return $this->isCached($tpl_file, $cache_id, $compile_id); + } + + /** + * clear all the assigned template variables. + */ + public function clear_all_assign() + { + $this->clearAllAssign(); + } + + /** + * clears compiled version of specified template resource, + * or all compiled template files if one is not specified. + * This function is for advanced use only, not normally needed. + * + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * + * @return boolean results of {@link smarty_core_rm_auto()} + */ + public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + { + return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time); + } + + /** + * Checks whether requested template exists. + * + * @param string $tpl_file + * + * @return boolean + */ + public function template_exists($tpl_file) + { + return $this->templateExists($tpl_file); + } + + /** + * Returns an array containing template variables + * + * @param string $name + * + * @return array + */ + public function get_template_vars($name = null) + { + return $this->getTemplateVars($name); + } + + /** + * Returns an array containing config variables + * + * @param string $name + * + * @return array + */ + public function get_config_vars($name = null) + { + return $this->getConfigVars($name); + } + + /** + * load configuration values + * + * @param string $file + * @param string $section + * @param string $scope + */ + public function config_load($file, $section = null, $scope = 'global') + { + $this->ConfigLoad($file, $section, $scope); + } + + /** + * return a reference to a registered object + * + * @param string $name + * + * @return object + */ + public function get_registered_object($name) + { + return $this->getRegisteredObject($name); + } + + /** + * clear configuration values + * + * @param string $var + */ + public function clear_config($var = null) + { + $this->clearConfig($var); + } + + /** + * trigger Smarty error + * + * @param string $error_msg + * @param integer $error_type + */ + public function trigger_error($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Smarty error: $error_msg", $error_type); + } +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/debug.tpl b/ewomail-admin/lib/smarty-3.1.24/libs/debug.tpl new file mode 100644 index 0000000..5b09c5b --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/debug.tpl @@ -0,0 +1,160 @@ +{capture name='_smarty_debug' assign=debug_output} + + + + Smarty Debug Console + + + + +

Smarty {Smarty::SMARTY_VERSION} Debug Console + - {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}

+ + {if !empty($template_data)} +

included templates & config files (load time in seconds)

+
+ {foreach $template_data as $template} + {$template.name} +
   + (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}) + +
+ {/foreach} +
+ {/if} + +

assigned template variables

+ + + {foreach $assigned_vars as $vars} + + + + + {/foreach} +

${$vars@key}

+ {if isset($vars['nocache'])}Nocache
{/if} + {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var:10:80 nofilter}{/if} +

Value

{$vars['value']|debug_print_var:10:80 nofilter}
{if isset($vars['attributes'])}

Attributes

{$vars['attributes']|debug_print_var nofilter} {/if}
+ +

assigned config file variables

+ + + {foreach $config_vars as $vars} + + + + + {/foreach} + +

#{$vars@key}#

+ {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var:10:80 nofilter}{/if} +
{$vars['value']|debug_print_var:10:80 nofilter}
+ + +{/capture} + diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/plugins/block.textformat.php b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/block.textformat.php new file mode 100644 index 0000000..abf5449 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/block.textformat.php @@ -0,0 +1,110 @@ + + * Name: textformat
+ * Purpose: format text a certain way with preset styles + * or custom wrap/indent settings
+ * Params: + *
+ * - style         - string (email)
+ * - indent        - integer (0)
+ * - wrap          - integer (80)
+ * - wrap_char     - string ("\n")
+ * - indent_char   - string (" ")
+ * - wrap_boundary - boolean (true)
+ * 
+ * + * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * + * @param array $params parameters + * @param string $content contents of the block + * @param Smarty_Internal_Template $template template object + * @param boolean &$repeat repeat flag + * + * @return string content re-formatted + * @author Monte Ohrt + */ +function smarty_block_textformat($params, $content, $template, &$repeat) +{ + if (is_null($content)) { + return; + } + + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string) $_val; + break; + + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int) $_val; + break; + + case 'wrap_cut': + $$_key = (bool) $_val; + break; + + default: + trigger_error("textformat: unknown attribute '$_key'"); + } + } + + if ($style == 'email') { + $wrap = 72; + } + // split into paragraphs + $_paragraphs = preg_split('![\r\n]{2}!', $content); + + foreach ($_paragraphs as &$_paragraph) { + if (!$_paragraph) { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph); + // indent first line + if ($indent_first > 0) { + $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph; + } + // wordwrap sentences + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'); + $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } else { + $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } + // indent lines + if ($indent > 0) { + $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + + if ($assign) { + $template->assign($assign, $_output); + } else { + return $_output; + } +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.counter.php b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.counter.php new file mode 100644 index 0000000..4da85a1 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.counter.php @@ -0,0 +1,78 @@ + + * Name: counter
+ * Purpose: print out a counter value + * + * @author Monte Ohrt + * @link http://www.smarty.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @return string|null + */ +function smarty_function_counter($params, $template) +{ + static $counters = array(); + + $name = (isset($params['name'])) ? $params['name'] : 'default'; + if (!isset($counters[$name])) { + $counters[$name] = array( + 'start' => 1, + 'skip' => 1, + 'direction' => 'up', + 'count' => 1 + ); + } + $counter =& $counters[$name]; + + if (isset($params['start'])) { + $counter['start'] = $counter['count'] = (int) $params['start']; + } + + if (!empty($params['assign'])) { + $counter['assign'] = $params['assign']; + } + + if (isset($counter['assign'])) { + $template->assign($counter['assign'], $counter['count']); + } + + if (isset($params['print'])) { + $print = (bool) $params['print']; + } else { + $print = empty($counter['assign']); + } + + if ($print) { + $retval = $counter['count']; + } else { + $retval = null; + } + + if (isset($params['skip'])) { + $counter['skip'] = $params['skip']; + } + + if (isset($params['direction'])) { + $counter['direction'] = $params['direction']; + } + + if ($counter['direction'] == "down") { + $counter['count'] -= $counter['skip']; + } else { + $counter['count'] += $counter['skip']; + } + + return $retval; +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.cycle.php b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.cycle.php new file mode 100644 index 0000000..8dc5cd9 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.cycle.php @@ -0,0 +1,107 @@ + + * Name: cycle
+ * Date: May 3, 2002
+ * Purpose: cycle through given values
+ * Params: + *
+ * - name      - name of cycle (optional)
+ * - values    - comma separated list of values to cycle, or an array of values to cycle
+ *               (this can be left out for subsequent calls)
+ * - reset     - boolean - resets given var to true
+ * - print     - boolean - print var or not. default is true
+ * - advance   - boolean - whether or not to advance the cycle
+ * - delimiter - the value delimiter, default is ","
+ * - assign    - boolean, assigns to template var instead of printed.
+ * 
+ * Examples:
+ *
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * 
+ * + * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle} + * (Smarty online manual) + * @author Monte Ohrt + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat + * @version 1.3 + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @return string|null + */ + +function smarty_function_cycle($params, $template) +{ + static $cycle_vars; + + $name = (empty($params['name'])) ? 'default' : $params['name']; + $print = (isset($params['print'])) ? (bool) $params['print'] : true; + $advance = (isset($params['advance'])) ? (bool) $params['advance'] : true; + $reset = (isset($params['reset'])) ? (bool) $params['reset'] : false; + + if (!isset($params['values'])) { + if (!isset($cycle_vars[$name]['values'])) { + trigger_error("cycle: missing 'values' parameter"); + + return; + } + } else { + if (isset($cycle_vars[$name]['values']) + && $cycle_vars[$name]['values'] != $params['values'] + ) { + $cycle_vars[$name]['index'] = 0; + } + $cycle_vars[$name]['values'] = $params['values']; + } + + if (isset($params['delimiter'])) { + $cycle_vars[$name]['delimiter'] = $params['delimiter']; + } elseif (!isset($cycle_vars[$name]['delimiter'])) { + $cycle_vars[$name]['delimiter'] = ','; + } + + if (is_array($cycle_vars[$name]['values'])) { + $cycle_array = $cycle_vars[$name]['values']; + } else { + $cycle_array = explode($cycle_vars[$name]['delimiter'], $cycle_vars[$name]['values']); + } + + if (!isset($cycle_vars[$name]['index']) || $reset) { + $cycle_vars[$name]['index'] = 0; + } + + if (isset($params['assign'])) { + $print = false; + $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); + } + + if ($print) { + $retval = $cycle_array[$cycle_vars[$name]['index']]; + } else { + $retval = null; + } + + if ($advance) { + if ($cycle_vars[$name]['index'] >= count($cycle_array) - 1) { + $cycle_vars[$name]['index'] = 0; + } else { + $cycle_vars[$name]['index'] ++; + } + } + + return $retval; +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.fetch.php b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.fetch.php new file mode 100644 index 0000000..3506d4a --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.fetch.php @@ -0,0 +1,221 @@ + + * Name: fetch
+ * Purpose: fetch file, web or ftp data and display results + * + * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch} + * (Smarty online manual) + * @author Monte Ohrt + * + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * + * @throws SmartyException + * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable + */ +function smarty_function_fetch($params, $template) +{ + if (empty($params['file'])) { + trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE); + + return; + } + + // strip file protocol + if (stripos($params['file'], 'file://') === 0) { + $params['file'] = substr($params['file'], 7); + } + + $protocol = strpos($params['file'], '://'); + if ($protocol !== false) { + $protocol = strtolower(substr($params['file'], 0, $protocol)); + } + + if (isset($template->smarty->security_policy)) { + if ($protocol) { + // remote resource (or php stream, …) + if (!$template->smarty->security_policy->isTrustedUri($params['file'])) { + return; + } + } else { + // local file + if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) { + return; + } + } + } + + $content = ''; + if ($protocol == 'http') { + // http fetch + if ($uri_parts = parse_url($params['file'])) { + // set defaults + $host = $server_name = $uri_parts['host']; + $timeout = 30; + $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + $agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION; + $referer = ""; + $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; + $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $_is_proxy = false; + if (empty($uri_parts['port'])) { + $port = 80; + } else { + $port = $uri_parts['port']; + } + if (!empty($uri_parts['user'])) { + $user = $uri_parts['user']; + } + if (!empty($uri_parts['pass'])) { + $pass = $uri_parts['pass']; + } + // loop through parameters, setup headers + foreach ($params as $param_key => $param_value) { + switch ($param_key) { + case "file": + case "assign": + case "assign_headers": + break; + case "user": + if (!empty($param_value)) { + $user = $param_value; + } + break; + case "pass": + if (!empty($param_value)) { + $pass = $param_value; + } + break; + case "accept": + if (!empty($param_value)) { + $accept = $param_value; + } + break; + case "header": + if (!empty($param_value)) { + if (!preg_match('![\w\d-]+: .+!', $param_value)) { + trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE); + + return; + } else { + $extra_headers[] = $param_value; + } + } + break; + case "proxy_host": + if (!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case "proxy_port": + if (!preg_match('!\D!', $param_value)) { + $proxy_port = (int) $param_value; + } else { + trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE); + + return; + } + break; + case "agent": + if (!empty($param_value)) { + $agent = $param_value; + } + break; + case "referer": + if (!empty($param_value)) { + $referer = $param_value; + } + break; + case "timeout": + if (!preg_match('!\D!', $param_value)) { + $timeout = (int) $param_value; + } else { + trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE); + + return; + } + break; + default: + trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE); + + return; + } + } + if (!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout); + } else { + $fp = fsockopen($server_name, $port, $errno, $errstr, $timeout); + } + + if (!$fp) { + trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE); + + return; + } else { + if ($_is_proxy) { + fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); + } else { + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if (!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if (!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if (!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if (!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if (isset($extra_headers) && is_array($extra_headers)) { + foreach ($extra_headers as $curr_header) { + fputs($fp, $curr_header . "\r\n"); + } + } + if (!empty($user) && !empty($pass)) { + fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n"); + } + + fputs($fp, "\r\n"); + while (!feof($fp)) { + $content .= fgets($fp, 4096); + } + fclose($fp); + $csplit = preg_split("!\r\n\r\n!", $content, 2); + + $content = $csplit[1]; + + if (!empty($params['assign_headers'])) { + $template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0])); + } + } + } else { + trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE); + + return; + } + } else { + $content = @file_get_contents($params['file']); + if ($content === false) { + throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'"); + } + } + + if (!empty($params['assign'])) { + $template->assign($params['assign'], $content); + } else { + return $content; + } +} diff --git a/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.html_checkboxes.php b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.html_checkboxes.php new file mode 100644 index 0000000..d786803 --- /dev/null +++ b/ewomail-admin/lib/smarty-3.1.24/libs/plugins/function.html_checkboxes.php @@ -0,0 +1,237 @@ + + * Type: function
+ * Name: html_checkboxes
+ * Date: 24.Feb.2003
+ * Purpose: Prints out a list of checkbox input types
+ * Examples: + *
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='
' output=$names} + * {html_checkboxes values=$ids checked=$checked separator='
' output=$names} + *
+ * Params: + *
+ * - name       (optional) - string default "checkbox"
+ * - values     (required) - array
+ * - options    (optional) - associative array
+ * - checked    (optional) - array default not set
+ * - separator  (optional) - ie 
or   + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * - escape (optional) - escape the content (not value), defaults to true + *
+ * + * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt + * @version 1.0 + * + * @param array $params parameters + * @param object $template template object + * + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_checkboxes($params, $template) +{ + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + + $name = 'checkbox'; + $values = null; + $options = null; + $selected = array(); + $separator = ''; + $escape = true; + $labels = true; + $label_ids = false; + $output = null; + + $extra = ''; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'name': + case 'separator': + $$_key = (string) $_val; + break; + + case 'escape': + case 'labels': + case 'label_ids': + $$_key = (bool) $_val; + break; + + case 'options': + $$_key = (array) $_val; + break; + + case 'values': + case 'output': + $$_key = array_values((array) $_val); + break; + + case 'checked': + case 'selected': + if (is_array($_val)) { + $selected = array(); + foreach ($_val as $_sel) { + if (is_object($_sel)) { + if (method_exists($_sel, "__toString")) { + $_sel = smarty_function_escape_special_chars((string) $_sel->__toString()); + } else { + trigger_error("html_checkboxes: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE); + continue; + } + } else { + $_sel = smarty_function_escape_special_chars((string) $_sel); + } + $selected[$_sel] = true; + } + } elseif (is_object($_val)) { + if (method_exists($_val, "__toString")) { + $selected = smarty_function_escape_special_chars((string) $_val->__toString()); + } else { + trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE); + } + } else { + $selected = smarty_function_escape_special_chars((string) $_val); + } + break; + + case 'checkboxes': + trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); + $options = (array) $_val; + break; + + case 'assign': + break; + + case 'strict': + break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + + default: + if (!is_array($_val)) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; + } else { + trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (!isset($options) && !isset($values)) { + return ''; + } /* raise error here? */ + + $_html_result = array(); + + if (isset($options)) { + foreach ($options as $_key => $_val) { + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } + } else { + foreach ($values as $_i => $_key) { + $_val = isset($output[$_i]) ? $output[$_i] : ''; + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } + } + + if (!empty($params['assign'])) { + $template->assign($params['assign'], $_html_result); + } else { + return implode("\n", $_html_result); + } +} + +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true) +{ + $_output = ''; + + if (is_object($value)) { + if (method_exists($value, "__toString")) { + $value = (string) $value->__toString(); + } else { + trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE); + + return ''; + } + } else { + $value = (string) $value; + } + + if (is_object($output)) { + if (method_exists($output, "__toString")) { + $output = (string) $output->__toString(); + } else { + trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE); + + return ''; + } + } else { + $output = (string) $output; + } + + if ($labels) { + if ($label_ids) { + $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value)); + $_output .= '