Access Control Library for Codeigniter

先检讨。比较浮躁,先前帖的Codeigniter ACL library 有较大的bug。配置和使用方法也没有说太多。今天正好用到,调试了一下。重新发布。嗯,这个也是淡水在ci在官网论坛上挖到的。还有个autoacl的,也是基于这个修改的。不过淡水觉得太耦合了,而且繁琐了。还是没有采用。

先来library:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * MX_ACL - Access Control Library PHP5
 *
 * Notes:
 * $config['cache_path'] must be set
 *
 * Install this file as application/libraries/MX_ACL.php
 *
 *
@copyright    Copyright (c) Wiredesignz & Maxximus 2009-11-03
 *
@version     1.1
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

class MX_ACL
{   
    
private $_config, $_cache_path;
    
    
public function __construct() {
        
        
$this->load->helper('url');
        
$this->load->library('session');
        
$this->load->config('mx_acl', TRUE);
        
        
$this->_config = $this->config->item('mx_acl');
        
#$this->_cache_path = $this->config->item('cache_path');
        
$this->_cache_path = $this->config->item('cache_path', 'mx_acl');
        
        
/* previous flashdata is available to views */
        
$this->load->vars($this->_config['error_var'], $this->session->flashdata($this->_config['error_var']));
        
        
/* run the access control check now */
        
($this->_config['check_uri']) AND $this->check_uri();
    
}
    
    
/**
     * Check the current uri and user privileges against the cached ACL array
     * Redirect if access is denied
     *
     *
@return void
     */

    
public function check_uri() {
        
        
/* Load the cached access control list or show error */
        
(is_file($cached_acl = $this->_cache_path.'mx_acl'.EXT)) OR show_error($this->_config['error_msg']);
        
        
$acl = include $cached_acl;
 
        
/* Match current url to access list */
        
#if (is_array($acl) AND $acl = $this->match_uri($this->current_uri(), $acl)) {
        
if (is_array($acl) AND $acl = $this->match_uri(strtolower($this->current_uri()), $acl)) {
            
            
/* Check session group against access level group */
            
$allow_access = (bool)(in_array($this->session->userdata($this->_config['session_var']), $acl['allowed']));
                
            
/* Additional check to allow IP addresses in range */
            
if ($allow_access AND isset($acl['ipl']))
            
{
                
if (is_array($acl['ipl']))
                
{
                    
$allow_access = $this->check_ip($acl['ipl']);
                
}
            
}
            
            
if ($allow_access == FALSE)    {
                
                
/* Set a return url into the session */
                
$this->session->set_userdata('return_url', $this->uri->uri_string());
                
                
/* set the error message... */
                
$error_msg = (isset($acl['error_msg'])) ? $acl['error_msg'] : $this->_config['error_msg'];
                    
                
/* set a flash message... */
                
$this->session->set_flashdata($this->_config['error_var'], $error_msg);       
                    
                
/* redirect to absolute url */
                
die(header("Location: ".$acl['error_uri'], TRUE, 302));
            
}
        
}
    
}
    
    
/**
     * Return the access control profile for a given url
     *
     *
@return string
     *
@param string $current_uri
     *
@param array  $acl
     */

    
private function match_uri($current_uri, $acl) {
        
if (array_key_exists($current_uri, $acl)) {
            
return $acl[$current_uri];           
        
} else {
            
if ($pos = strripos($current_uri, '/')) {
                
return $this->match_uri(substr($current_uri, 0, $pos), $acl);
            
}
        
}
    
}
 
    
/**
     * Returns the current uri string from segments
     *
     *
@return string
     */

    
private function current_uri() {
        
return implode('/', $this->uri->rsegments);
    
}
 
    
/**
     * Checks the remote IP address against the specified $ipl array
     *
     *
@return bool
     *
@param array $ipl
     *
@param string $remote_ip[optional]
     */
   
    
private function check_ip($ipl, $remote_ip = NULL) {
        
        
/* Convert ip address into a double (for lousy OSes)*/
        
$remote_ip = floatval(ip2long(($this->session->userdata('ip_address'))));
        
        
/* Loop through the ip list array */
        
foreach ($ipl as $allowed_ip) {
            
            
/* Replace '*' (for IP ranges) with a suitable range number */
            
$min = str_replace("*", "0", $allowed_ip);       
            
$max = str_replace("*", "255", $allowed_ip);
 
            
/* Check for a match */
            
if (($remote_ip >= floatval(ip2long($min))) AND ($remote_ip <= floatval(ip2long($max)))) {
                
return TRUE;
            
}
        
}
    
}
    
    
public function __get($var)    {
        
static $CI;
        
(is_object($CI)) OR $CI = get_instance();
        
return $CI->$var;
    
}
}
/* End of file MX_ACL.php */
/* Location: ./application/libraries/MX_ACL.php */

再来配置文件:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * MX_Acl configuration
 *
 * Save this file as application/config/mx_acl.php
 */

$config = array(
    
'check_uri'    => TRUE,
    
'error_var'    => 'error',
    
'error_msg'    => 'You don\'t have sufficient access rights to view this page!',
    
'session_var'  => 'role_id',
    
'cache_path'   => 'application/acl/',
);

具体的acl,没有写入到db,直接放到上面的cache_path中的:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * This is the cached access control list
 *
 * save this file as {cache_path}/mx_acl.php
 */

return array(
    
'setting/update' => array(                       // the "module/controller/method" to protect
        
'allowed'    => array(1),                    // the allowed user role_id array (eg.$this->session->set_userdata('role_id','1'))
        
'ipl'        => array('127.0.0.1'),          // the allowed IP range array or FALSE(allowed all ip)
        
'error_uri'  => site_url('secure/setting')// the url to redirect to on failure
        
'error_msg'  => 'You do not have permission to update this page!',
    
),
    
'page/update'    => array(
        
'allowed'    => array(1, 2, 3),
        
'ipl'        => array('127.0.0.0','127.0.0.*'),
        
'error_uri'  => (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : site_url('secure/page'),
        
'error_msg'  => 'You do not have permission to update this page!',
    
),
);

staticpage的内容,处理未授权显示:

<?php
class Staticpage extends Controller
{
    
    
function error_auth()
    
{
        
show_error($this->session->flashdata('error'),203);
    
}
}

登录时给出相应的角色:

$this->session->set_userdata('role_id','1');

基本就是这样了。role_id使用了ci自带的session;errror用的也是的session的flashdata。嗯,就是这样,没有了。

li水平居中css实现

其实这个是凑数来的。只是好久没动博客了,实在是说不过去了,丫的太懒了。其实是淡水没有时间(好假的借口)。

闲话不多说了。现在一般都是用li做菜单了,淡水也就从了。li的float:left,可以了变成横向的菜单了。但是它们怎么跑到区域里居中显示呢(一般是页脚的链接是居中的)?li的display:inline;就可以了,float:left都不要了,自己跑一行去了。

#main_footer{
list-style:none;
text-align:center;
}
#main_footer li{
display:inline;
}

<ul id=”main_footer”>
<li><a href=”#”>公司介绍</a></li>
<li><a href=”#”>我们的创新</a></li>
<li><a href=”#”>工作理念</a></li>
<li><a href=”#”>价值观</a></li>
<li><a href=”#”>联系我们</a></li>
</ul>

其实淡水还是在用table布局,为啥,方便啊。不过也少了:)

哎,div啊。。。

ShangHai

嗯,新环境……

mysql查询今天、昨天、7天、近30天、本月、上一月 数据

今天
select * from 表名 where to_days(时间字段名) = to_days(now());
昨天
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) – TO_DAYS( 时间字段名) <= 1
7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
近30天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)
本月
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, ‘%Y%m’ ) = DATE_FORMAT( CURDATE( ) , ‘%Y%m’ )
上一月
SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , ‘%Y%m’ ) , date_format( 时间字段名, ‘%Y%m’ ) ) =1
来源:http://blog.163.com/dreamman_yx/blog/static/26526894201053115622827/

Install ‘xdebug’ PHP extension for XAMPP on Ubuntu10.04

  • First you have to install XAMPP development package
    (http://www.apachefriends.org/en/xampp-linux.html) for your XAMPP
    installation. This package provides the necessary source files
    needed to compile the extra stuff

  • Download ‘xdebug’ source from http://www.xdebug.com/ , uncompress it in a
    suitable directory, cd to that directory.

  • Now run phpize

[bruce@bruce-laptop xdebug-2.1.0RC1]$ /opt/lampp/bin/phpize

if had errors:
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable is set correctly and then rerun
this script.

try determining if ‘autoconf’ is installed ,by just running
$autoconf

if it’s not there then you will need to install the tool first, you can do it by,

sudo apt-get install autoconf

  • Configure the extension

[bruce@bruce-laptop xdebug-2.1.0RC1]$ ./configure –enable-xdebug –with-php-config=/opt/lampp/bin/php-config

  • Run ‘make’ to get the compiled xdebug.so

[bruce@bruce-laptop xdebug-2.1.0RC1]$ make

  • Copy the xdebug.so file to PHP’s extensions directory (you may need root privileges for
    this)

    [bruce@bruce-laptop xdebug-2.1.0RC1]$ sudo cp modules/xdebug.so /opt/lampp/lib/php/extensions

  • After that edit php.ini file and add

;xDebug Configuration starts

zend_extension = /opt/lampp/lib/php/extensions/xdebug.so

xdebug.profiler_output_dir = “/tmp/xdebug/”

xdebug.profiler_enable = On

xdebug.remote_enable=On

xdebug.remote_host=”localhost”

xdebug.remote_port=9000

xdebug.remote_handler=”dbgp”

;xDebug Configuration ends

  • Lastly restart XAMPP and check phpinfo for Xdebug extension

    [bruce@bruce-laptop xdebug-2.1.0RC1]$ sudo /opt/lampp/lampp restart

嗯,openoffice用不太习惯,被d版的ms office惯坏了:(

关于ci和zend framework的一些牢骚

首先说明,这是淡水的牢骚,看不惯不要看。

老华仔歌里唱的应景“总逃不开工作表,做完了又来了,怎样也甩不掉……”。淡水手头的项目还没有完全结束,新的项目又要上马。于是前期就框架选择开大会,开小会。

有.net高手就开始在网上搜索合适框架。结果他得出的结论是Zend Framework,理由:官方。
不推荐Codeigniter是因为,一家小公司做的,后期支持跟不上。而且ci是轻量级的,功能不强。
php本身就是草根出身,如果看公司大小,那么为什么不用.net?
ci是轻量级的,但是php能做的,他都能做,没有内置的功能,可以自己加阿?非得一定要和zend framework一样,几乎把所有能想到用到的功能都整合进去变成皇家内裤(类库)?
窃以为,做大型应用时应用框架快速开发是可取的,但是要考虑到代码的执行效率,和开发的灵活度。
zend framework能做到的, ci扩展一下也能做到,麻烦一点了。但是zend framwork有ci灵活么,ci2天可以掌握,zend framework可以么(太NB的天才不算)。
这些主流框架的评比本身没有太大的意义。框架只是工具,各有其特点(Yii高效;ci上手容易,代码优雅;thinkphp代码全中文注释,文档齐全;qee……),人才是重点。

如果理由是:
zend framework是官方出品,支持应该比其他(ci)公司长久。
zend framework是官方出品,使用人数较多,人力资源丰富。
zend framework内置许多类库,扩展类库的时间可以节省不少。
zend framework内置许多类库,规范了代码(尽量使用内置类库)。
还有最具分量的理由:这是高层主管决定的。

这些我可以接受,但是说ci不行,以否定ci来肯定zend framwork,那就有些牵强了。

滔滔不绝的,连绵不断,就是要表明“zend framework是php官方出品,功能强大。ci一家小公司做的,后期支持跟不上。而且ci是轻量级的,功能不强。”。但是,zend framework哪些方面强大,ci又是哪里功能不强,都没有说出个一二三来。

嗯,滔滔不绝但也要言之有物才行吧!

恢复Ubuntu的默认面板

如果不小心将ubuntu的面板弄得一团糟,又不想慢慢找回来。有没有什么方法一键恢复默认状态呢?
答案是:“能恢复是肯定的,但是没有一键!“。

首先重置面板设置

gconftool –recursive-unset /apps/panel

然后删除面板设置文件。

rm -rf ~/.gconf/apps/panel

再杀掉控制面板的进程使其重启即可!

pkill gnome-panel

此时默认的顶部底部两个面板就已经回来了。

如果悲剧到没有办法进入终端,那么建个文件。往里面写入这三条命令,再保存为.sh文件。给执行权限,运行即可。

真的好用。

from:http://blog.okkey.net/1202.html

投入ubuntu,体验中

嗯,体验还不错。推荐。。。
不过wine下ie6太耗资源了,能跑死机器。
两天了,基本上手
开发用XAMPP+PDT,PDT在linux下比windows下的速度快些,但是边框太粗,难看。
:p

SVN小记

名词解释:
修订版(revision):可以认为是某个文件在其生命周期内各个保存的快照,每个快照和一个时间区间对应。
版本库(Repository):存放修订版的数据库
本地工作拷贝(Local working copy):修订版在本地的副本
版本的检入(Check in):本地副本提交到服务器的版本库
检出(Check out):从服务器的版本库中取出修订版成为本地副本
版本号的来源:有两种策略,基于文件的计数和基于仓库的计数,subversion使用后者
标签(Tags):为版本加一个名字,便于检出
分支(Branches):修订版打分支,以后可以平行修改,互不干扰
合并(Merging):将分支的修订版合并为一个新的修订版
锁(Locking):为修订版枷锁
冲突(Conflict):并发版本控制时防止修订版混乱的错误机制

创建版本库
创建服务器端版本库
命令行:
svnadmin create file_path/repo_name

初始导入(import)
通过命令行导入:
svn import -m “init import” http://10.0.0.6/svn/teaching/
该命令可将当前路径下文件导入到版本库中。

检出(checkout)
通过命令行检入:
svn co http://10.0.0.6/svn/teaching/ mysvntest
或者:
svn checkout http://10.0.0.6/svn/teaching/ mysvntest
最后取出来的新目录名,不给定就会用路径的最后一个目录名(如这里的teaching,这里给了就是mysvntest)

保持更新(update)
命令行:
svn update
或者
svn up
多人合作时:
更新要经常频繁的做,尽量让问题及早暴露,便于处理。
提交代码前要更新,否则容易产生版本冲突。
通过第一步import后的那个目录并没有默认建立svn与远程的关系,需要手动从服务器checkout回服务器的版本到本地, 才算正式建立与远程的关系,才能直接 svn up……

添加(add)
命令行:
svn add file_path

告知svn服务器,添加目录和/或文件到服务器上,这个操作类似SQL的insert,但是并没有真的操作,直到commit。

提交改动(commit)
相当于通用概念:检入(checkin)。
命令行:
svn commit
或者:
svn ci
要求:一般要注明修改的原因
svn ci -m “修改bug #224″

要求:提交之前要做更新
svn up
svn ci -m “修改bug #224″

还原改动
对应提交(commit),要有类似回滚(rollback)的操作。
svn revert

“还原”已提交的改动
revert只适合未提交的情况。
如果已经提交,发现问题,要回退到之前的修订版。
首先:
svn up
让本地工作拷贝更新到最新状态。
然后:
svn log your_file_path
查看文件日志,这时候提交时填写的说明信息就派上用场了。
再,查看两个修订版之间的不同:
svn diff -r 旧修订版序号:新修订版序号 your_file_path

决定用哪个旧的修订版号后,用旧的修订版号文件覆盖新的修订版号文件。
svn merge -r 新修订版序号:旧修订版序号 your_file_path
还需要:
svn commit -m “恢复到某修订版(某修订版作废)”

拷贝文件和目录
命令行:
svn copy path/file_name newpath/new_file_name
svn commit -m “xxxx”
或者:
svn cp path/file_name newpath/new_file_name
svn commit -m “xxxx”
svn的copy,是很重要的工具,版本分支和标签等概念都通过它实现。

重命名目录/文件
命令行:
svn move file_name new_file_name
或者:
svn mv file_name new_file_name

处理合并冲突
svn默认不对文件加锁。
如果不同人编辑了同一个文件的不同部分,提交时会自动合并。
如果不同人编辑了同一个文件的同一部分,后提交者会报告合并冲突。
解决方法(人工仲裁):
放弃改动;
坚持你的改动,找到.mine的文件名,恢复为原文件名,然后执行:
svn resolved file_name
注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的相关文件,然后让 PATH 可以再次提交。

删除文件
将本地工作拷贝删除。
命令行:
svn delete file_path
或者:
svn del file_path

版本库创建策略
单一的版本库保存一个项目。
单一的版本库保存多个项目。
多个版本库。

使用标签和分支
在svn中标签和分支都源于copy命令。
3个约定俗成的目录:
trunk:主干
branches:分支
tags:标签

发布分支:
svn cp -m “创建用于实现radio标签的分支” https://easymorse-simpletag.googlecode.com/svn/branches/simpletag_select_1 https://easymorse-simpletag.googlecode.com/svn/branches/simpletag_select_2

切换分支:
svn switch https://easymorse-simpletag.googlecode.com/svn/branches/simpletag_select_2

合并分支需要两个步骤:

合并操作
svn merge -r 33:HEAD https://easymorse-simpletag.googlecode.com/svn/branches/simpletag_select_2
或者:
svn merge https://easymorse-simpletag.googlecode.com/svn/trunk/simpletag@HEAD https://easymorse-simpletag.googlecode.com/svn/branches/simpletag_select_1@HEAD
提交。

socks5 proxy 折腾记

需要在服务器上装sock5 proxy,服务器平台是Redhat enterprise linux5,淡水要在有限的时间里去折腾它。
google之。
找到了socks5-v1.0r11编译报错:(
再google之。。。
又转找到ss5-3.6.4-3, 编译,又报错:(
时间有限,精力有限,关键是能力有限。。
最后google之。。。。。。
找到Antinat。看似很方便的样子。官网:http://antinat.sourceforge.net/
下载:
antinat-0.90-1.i386.rpm
antinat-libs-0.90-1.i386.rpm
先rpm -ivh antinat-libs-0.90-1.i386.rpm
再rpm -ivh antinat-0.90-1.i386.rpm
搞定。
也可以下载:antinat-0.90.tar.bz2 编译安装。
tar jvxf antinat-0.90.tar.bz2
cd antinat-0.90
./configure
make install
cp etc/antinat.xml.allopen /usr/local/etc/antinat.xml
配置端口:

  1. <!-- Port to listen on -->
  2.         <port value='1080'/>

如无需认证,这样就完成了。我要加入认证帐号则,那么如下:

  1. vi  /usr/local/etc/antinat.xml
  2. <!-- <user user='testuser' password='testpass'/> -->

改为

  1. <user user='username' password='userpassword'/>

  1. <select mechanism='anonymous'/>

注销
ok,运行吧:
[root@testserver]antinat
看看是否启动了
[root@testserver]netstat -na|grep 1080
tcp 0 0 0.0.0.0:1080 0.0.0.0:* LISTEN
搞定了。X雷,X讯可以用了,嘿嘿嘿嘿(奸笑中……)

Page 1 of 11 12345...Last »