]> git.andy128k.dev Git - ipf.git/commitdiff
rework auth and admin apps. try to separate from legacy orm. WIP
authorAndrey Kutejko <andy128k@gmail.com>
Sun, 24 Aug 2014 17:10:43 +0000 (20:10 +0300)
committerAndrey Kutejko <andy128k@gmail.com>
Sun, 24 Aug 2014 17:10:43 +0000 (20:10 +0300)
37 files changed:
ipf/admin/app.php
ipf/admin/commands/syncperms.php
ipf/admin/form.php [deleted file]
ipf/admin/formlayout.php [new file with mode: 0644]
ipf/admin/forms/changepassword.php [new file with mode: 0644]
ipf/admin/forms/login.php [new file with mode: 0644]
ipf/admin/legacymodel.php [new file with mode: 0644]
ipf/admin/model.php
ipf/admin/modelinline.php
ipf/admin/models/AdminLog.php
ipf/admin/templates/admin/change.html
ipf/admin/templates/admin/changepassword.html
ipf/admin/templates/admin/delete.html
ipf/admin/templates/admin/index.html
ipf/admin/templates/admin/items.html
ipf/admin/views.php
ipf/application.php
ipf/auth/admin.php [new file with mode: 0644]
ipf/auth/app.php
ipf/auth/forms/changepassword.php [deleted file]
ipf/auth/forms/login.php [deleted file]
ipf/auth/middleware.php
ipf/auth/migrations/20140102000000_create_auth_tables.php [new file with mode: 0644]
ipf/auth/models.php
ipf/auth/models.yml [deleted file]
ipf/auth/models/Permission.php [deleted file]
ipf/auth/models/Role.php [deleted file]
ipf/auth/models/RolePermission.php [deleted file]
ipf/auth/models/User.php [deleted file]
ipf/auth/models/UserPermission.php [deleted file]
ipf/auth/models/UserRole.php [deleted file]
ipf/auth/models/_generated/BasePermission.php [deleted file]
ipf/auth/models/_generated/BaseRole.php [deleted file]
ipf/auth/models/_generated/BaseRolePermission.php [deleted file]
ipf/auth/models/_generated/BaseUser.php [deleted file]
ipf/auth/models/_generated/BaseUserPermission.php [deleted file]
ipf/auth/models/_generated/BaseUserRole.php [deleted file]

index 5221a33eb5d6c1786d69ba4b557d2d1a7524437d..30a6365a3ba6237111fb9e8c458c590ee78d9390 100644 (file)
@@ -38,26 +38,72 @@ class IPF_Admin_App extends IPF_Application
         return new IPF_HTTP_Response($html);
     }
 
-    public static function loadAllModels()
+    private static $appComponents = array();
+
+    public static function applicationComponents($app)
     {
-        foreach (IPF_Project::getInstance()->appList() as $appname => $app)
-            foreach (IPF_Legacy_ORM_App::appModelList($app) as $modelName)
-                new $modelName;
+        if (!array_key_exists($app->slug(), self::$appComponents)) {
+            $components = array();
+
+            if (is_file($app->getPath().'/admin.php')) {
+                $list = require_once $app->getPath().'/admin.php';
+                foreach ($list as $c) {
+                    $component = is_string($c) ? new $c : $c;
+                    $component->app = $app;
+                    $components[] = $component;
+                }
+            }
+
+            // legacy ORM
+            foreach (IPF_Legacy_ORM_App::appModelList($app) as $m) {
+                new $m; // autoload
+                $ma = IPF_Admin_Model::getModelAdmin($m);
+                if ($ma) {
+                    $ma->app = $app;
+                    $components[] = $ma;
+                }
+            }
+
+            self::$appComponents[$app->slug()] = $components;
+        }
+        return self::$appComponents[$app->slug()];
     }
 
-    static function checkAdminAuth($request)
+    public static function ensureUserIsStaff($request)
     {
-        $ok = true;
         if ($request->user->isAnonymous())
-            $ok = false;
-        elseif ( (!$request->user->is_staff) && (!$request->user->is_superuser) )
-            $ok = false;
+            throw new IPF_Admin_LoginRequired;
+
+        if (!$request->user->is_staff && !$request->user->is_superuser)
+            throw new IPF_Admin_LoginRequired;
+    }
+
+    public static function isAccessible($request, $component, $requiredPermissions)
+    {
+        if (count(array_diff($requiredPermissions, $component->getPerms($request))))
+            return false;
+
+        if ($request->user->is_superuser || !self::ArePermissionsEnabled())
+            return true;
+
+        $authPermissions = \PFF\Arr($requiredPermissions)
+            ->map('sprintf', '%s|%s|%s', get_class($component->app), $component->slug(), \PFF\Symbol::_())
+            ->arr();
+
+        return $request->user->can($authPermissions);
+    }
+
+    public static function getComponent($request, $requiredPermissions)
+    {
+        self::ensureUserIsStaff($request);
+
+        $component = self::getComponentBySlugs($request->params[1], $request->params[2]);
 
-        if (!$ok)
-            return new IPF_HTTP_Response_Redirect(IPF_HTTP_URL::urlForView('IPF_Admin_Views_Login'));
+        if (!IPF_Admin_App::isAccessible($request, $component, $requiredPermissions))
+            throw new IPF_Admin_AccessDenied;
 
-        self::loadAllModels();
-        return true;
+        $component->request = $request;
+        return $component;
     }
 
     static function appByModel($model)
@@ -69,45 +115,22 @@ class IPF_Admin_App extends IPF_Application
         return null;
     }
 
-    static function GetAppModelFromSlugs($lapp, $lmodel)
+    public static function getApplicationBySlug($slug)
     {
-        foreach (IPF_Project::getInstance()->appList() as $app) {
-            if ($app->getSlug() == $lapp) {
-                foreach (IPF_Legacy_ORM_App::appModelList($app) as $m) {
-                    if (strtolower($m) == $lmodel)
-                        return array('app' => $app, 'modelname' => $m);
-                }
-            }
-        }
-        return null;
+        foreach (IPF_Project::getInstance()->appList() as $app)
+            if ($app->slug() == $slug)
+                return $app;
+        throw new IPF_HTTP_Error404;
     }
 
-    static function GetAdminModelPermissions($adminModel, $request, $lapp, $lmodel)
+    public static function getComponentBySlugs($appSlug, $componentSlug)
     {
-        $adminPerms = $adminModel->getPerms($request);
-    
-        if (!count($adminPerms))
-            return false;
-
-        $am = self::GetAppModelFromSlugs($lapp, $lmodel);
-        
-        if ($am === null)
-            return false;
-            
-        $app = $am['app'];
-        $m   = $am['modelname'];
-
-        if ($m !== $adminModel->modelName)
-            return false;
-            
-        $perms = array();
-        
-        foreach (IPF_Auth_App::checkPermissions($request, $app, $m, $adminPerms) as $permName=>$permValue) {
-            if ($permValue)
-                $perms[] = $permName;
+        $app = self::getApplicationBySlug($appSlug);
+        foreach (self::applicationComponents($app) as $component) {
+            if ($component->slug() == $componentSlug)
+                return $component;
         }
-        
-        return $perms;
+        throw new IPF_HTTP_Error404;
     }
 
     public function commands()
@@ -118,3 +141,19 @@ class IPF_Admin_App extends IPF_Application
     }
 }
 
+class IPF_Admin_LoginRequired extends IPF_Router_Shortcut
+{
+    public function response($request)
+    {
+        return new IPF_HTTP_Response_Redirect(IPF_HTTP_URL::urlForView('IPF_Admin_Views_Login'));
+    }
+}
+
+class IPF_Admin_AccessDenied extends IPF_Router_Shortcut
+{
+    public function response($request)
+    {
+        return new IPF_HTTP_Response_NotFound($request);
+    }
+}
+
index 7940096b2a7be439d36301165e9301455fb62f04..45f44137418db98f3198b7499a8d833a4694830e 100644 (file)
@@ -9,19 +9,14 @@ class IPF_Admin_Command_SyncPerms
     {
         print "Create/Update permissions from model classes\n";
 
-        IPF_Admin_App::loadAllModels();
-
         print "COLLECTED PERMISSIONS:\n";
         $permissions = array();
         foreach (IPF_Project::getInstance()->appList() as $appname => $app) {
-            foreach (IPF_Legacy_ORM_App::appModelList($app) as $modelName) {
-                $adminModel = IPF_Admin_Model::getModelAdmin($modelName);
-                if ($adminModel) {
-                    foreach ($adminModel->getPerms(null) as $permName) {
-                        $name = get_class($app).'|'.$modelName.'|'.$permName;
-                        $permissions[$name] = array($app, $modelName, $permName);
-                        print '  '.$name."\n";
-                    }
+            foreach (IPF_Admin_App::applicationComponents($app) as $component) {
+                foreach ($component->getPerms(null) as $permName) {
+                    $name = get_class($app).'|'.$component->slug().'|'.$permName;
+                    $permissions[$name] = array($app, $component, $permName);
+                    print '  '.$name."\n";
                 }
             }
         }
@@ -50,13 +45,13 @@ class IPF_Admin_Command_SyncPerms
 
             foreach ($toAdd as $name) {
                 $app = $permissions[$name][0];
-                $admin = IPF_Admin_Model::getModelAdmin($permissions[$name][1]);
+                $component = $permissions[$name][1];
 
                 \PFF\Container::databaseQuery()
                     ->insertInto('auth_permission')
                     ->values(array(
                         'name' => $name,
-                        'title' => $app->getTitle().' | '.$admin->verbose_name().' | '.ucfirst($permissions[$name][2]),
+                        'title' => $app->getTitle().' | '.$component->slug().' | '.ucfirst($permissions[$name][2]),
                     ))->execute();
             }
         }
diff --git a/ipf/admin/form.php b/ipf/admin/form.php
deleted file mode 100644 (file)
index 3f7330a..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-use \PFF\HtmlBuilder\Tag as Tag;
-
-
-class IFP_Admin_ModelForm extends IPF_Form_Model
-{
-    public function unescape($html)
-    {
-        return new IPF_Template_SafeString($html, true);
-    }
-
-    public function render()
-    {
-        return $this->renderLayout(new IPF_Admin_Form_Layout, false);
-    }
-
-    public static function GetFormForModel($model, $data=null, $extra=array(), $label_suffix=null)
-    {
-        $extra['model'] = $model;
-        return new self($data, $extra, $label_suffix);
-    }
-}
-
-
-class IPF_Admin_Form_Layout extends IPF_Form_LayoutAdapter
-{
-    public function startForm($form)
-    {
-        $errors = $this->commonErrors($form);
-        return $this->errors($errors) .
-            $this->hiddenWidgets($form);
-    }
-
-    public function startGroup($label)
-    {
-        if ($label)
-            return Tag::div(array('class' => 'form-group-title'), $label)->html();
-        else
-            return '';
-    }
-
-    public function field($boundField)
-    {
-        if ($boundField->help_text) {
-            $help_text = Tag::p(array('class' => 'help'))
-                ->raw($boundField->help_text);
-        } else {
-            $help_text = '';
-        }
-
-        return $this->errors($boundField->errors) .
-            Tag::div(array('class' => 'form-row'),
-                Tag::div()
-                    ->raw($boundField->renderLabel())
-                    ->raw(' ')
-                    ->raw($boundField->renderWidget())
-                    ->append($help_text));
-    }
-
-    private function errors($errors)
-    {
-        if (!count($errors))
-            return '';
-
-        $ul = Tag::ul(array('class' => 'errorlist'));
-        foreach ($errors as $err)
-            $ul->append(Tag::li(null, $err));
-        return Tag::div(array('class' => 'form-row'), $ul);
-    }
-}
-
diff --git a/ipf/admin/formlayout.php b/ipf/admin/formlayout.php
new file mode 100644 (file)
index 0000000..47690e6
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+use \PFF\HtmlBuilder\Tag as Tag;
+
+class IPF_Admin_Form_Layout extends IPF_Form_LayoutAdapter
+{
+    public function startForm($form)
+    {
+        $errors = $this->commonErrors($form);
+        return $this->errors($errors) .
+            $this->hiddenWidgets($form);
+    }
+
+    public function startGroup($label)
+    {
+        if ($label)
+            return Tag::div(array('class' => 'form-group-title'), $label)->html();
+        else
+            return '';
+    }
+
+    public function field($boundField)
+    {
+        if ($boundField->help_text) {
+            $help_text = Tag::p(array('class' => 'help'))
+                ->raw($boundField->help_text);
+        } else {
+            $help_text = '';
+        }
+
+        return $this->errors($boundField->errors) .
+            Tag::div(array('class' => 'form-row'),
+                Tag::div()
+                    ->raw($boundField->renderLabel())
+                    ->raw(' ')
+                    ->raw($boundField->renderWidget())
+                    ->append($help_text));
+    }
+
+    private function errors($errors)
+    {
+        if (!count($errors))
+            return '';
+
+        $ul = Tag::ul(array('class' => 'errorlist'));
+        foreach ($errors as $err)
+            $ul->append(Tag::li(null, $err));
+        return Tag::div(array('class' => 'form-row'), $ul);
+    }
+}
+
diff --git a/ipf/admin/forms/changepassword.php b/ipf/admin/forms/changepassword.php
new file mode 100644 (file)
index 0000000..bff9094
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+class IPF_Admin_Forms_ChangePassword extends IPF_Form
+{
+    function initFields($extra=array())
+    {
+        $this->fields['password1'] = new IPF_Form_Field_Varchar(array(
+            'required'  => true,
+            'widget'    =>'IPF_Form_Widget_PasswordInput',
+        ));
+        $this->fields['password2'] = new IPF_Form_Field_Varchar(array(
+            'required'  => true,
+            'widget'    => 'IPF_Form_Widget_PasswordInput',
+            'help_text' => __('Enter the same password as above, for verification.'),
+        ));
+    }
+
+    public function clean()
+    {
+        $data = parent::clean();
+
+        if ($data['password1'] != $data['password2'])
+            $this->errors['password2'][] = __('The two password fields didn\'t match.');
+
+        return $data;
+    }
+
+    public function render()
+    {
+        return $this->renderLayout(new IPF_Admin_Form_Layout, false);
+    }
+
+    public function unescape($html)
+    {
+        return new IPF_Template_SafeString($html, true);
+    }
+}
+
diff --git a/ipf/admin/forms/login.php b/ipf/admin/forms/login.php
new file mode 100644 (file)
index 0000000..37a4ea8
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+class IPF_Admin_Forms_Login extends IPF_Form
+{
+    public $message = null;
+    public $user = null;
+
+    protected function initFields($extra=array())
+    {
+        $this->fields['username'] = new IPF_Form_Field_Varchar(array('required'=>true));
+        $this->fields['password'] = new IPF_Form_Field_Varchar(array('required'=>true,'widget'=>'IPF_Form_Widget_PasswordInput'));
+        $this->fields['next'] = new IPF_Form_Field_Varchar(array('required'=>false,'widget'=>'IPF_Form_Widget_HiddenInput'));
+    }
+
+    public function clean()
+    {
+        $data = parent::clean();
+
+        $this->user = User::checkCreditentials($data['username'], $data['password']);
+        if (!$this->user)
+            throw new IPF_Exception_Form(__('The login or the password is not valid. The login and the password are case sensitive.'));
+
+        return $data;
+    }
+
+    public function render()
+    {
+        return $this->renderLayout(new IPF_Admin_Form_Layout, false);
+    }
+
+    public function unescape($html)
+    {
+        return new IPF_Template_SafeString($html, true);
+    }
+}
+
diff --git a/ipf/admin/legacymodel.php b/ipf/admin/legacymodel.php
new file mode 100644 (file)
index 0000000..aaad49f
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+
+class IPF_Admin_Model extends IPF_Admin_Component
+{
+    static $models = array();
+
+    public static function register($classModel, $classAdmin)
+    {
+        self::$models[$classModel] = new $classAdmin($classModel);
+    }
+
+    public static function getModelAdmin($classModel)
+    {
+        if (array_key_exists($classModel, self::$models)) {
+            return self::$models[$classModel];
+        }
+        return null;
+    }
+
+    public $modelName;
+
+    public function __construct($modelName)
+    {
+        $this->modelName = $modelName;
+    }
+
+    public function slug()
+    {
+        return strtolower($this->modelName);
+    }
+
+    private function table()
+    {
+        return IPF_ORM::getTable($this->modelName);
+    }
+
+    private function query($searchValue)
+    {
+        if (method_exists($this->modelName, 'ordering')) {
+            $m = new $this->modelName;
+            $ord = $m->ordering();
+        } elseif ($this->table()->getOrdering()) {
+            $ord = implode(', ', $this->table()->getOrdering());
+        } elseif ($this->table()->hasTemplate('IPF_ORM_Template_Orderable')) {
+            $ord = $this->table()->getTemplate('IPF_ORM_Template_Orderable')->getColumnName();
+        } else {
+            $ord = '1 desc';
+        }
+
+        $q = IPF_ORM_Query::create()->from($this->modelName)->orderby($ord);
+
+        if ($searchValue) {
+            $wh = array();
+            $whv = array();
+            foreach ($this->_searchFields() as $f) {
+                $wh[] = $f.' like ?';
+                $whv[] = '%'.$searchValue.'%';
+            }
+            $q->addWhere($wh, $whv);
+        }
+
+        return $q;
+    }
+
+    public function ListItemsQuery($searchValue, $page, $pageSize)
+    {
+        $idColumn = $this->table()->getIdentifier();
+
+        $result = array();
+        foreach ($this->query($searchValue)->limit($pageSize)->offset(($page - 1) * $pageSize)->execute() as $o) {
+            $id = $o->__get($idColumn);
+            $result[$id] = $o;
+        }
+        return $result;
+    }
+
+    public function ListItemsQueryCount($searchValue)
+    {
+        return $this->query($searchValue)->count();
+    }
+
+    public function getObjectByID($id)
+    {
+        return $this->table()->find($id);
+    }
+
+    public function searcheable()
+    {
+        return count($this->_searchFields()) > 0;
+    }
+
+    protected function _searchFields()
+    {
+        return array();
+    }
+
+    public function list_display()
+    {
+        return $this->table()->getColumnNames();
+    }
+
+    public function renderCell($object, $column)
+    {
+        $value = $object->$column;
+        switch ($object->getTable()->getTypeOf($column)) {
+            case 'boolean':
+                if ($value)
+                    return '<img src="'.IPF::get('static_url').'admin/img/icon-yes.gif" alt="True" />';
+                else
+                    return '<img src="'.IPF::get('static_url').'admin/img/icon-no.gif" alt="False" />';
+            case 'timestamp':
+                return htmlspecialchars(IPF_Utils::formatDate($value), ENT_COMPAT, 'UTF-8');
+            default:
+                return htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
+        }
+    }
+
+    protected function columnTitle($column)
+    {
+        $columns = $this->table()->getColumns();
+        if (array_key_exists($column, $columns) && array_key_exists('verbose', $columns[$column]))
+            return $columns[$column]['verbose'];
+        else
+            return parent::columnTitle($column);
+    }
+
+    public function _orderable()
+    {
+        return $this->_orderableColumn() !== null;
+    }
+
+    public function _orderableColumn()
+    {
+        if (method_exists($this, 'list_order'))
+            return $this->list_order();
+        elseif ($this->table()->hasTemplate('IPF_ORM_Template_Orderable'))
+            return $this->table()->getTemplate('IPF_ORM_Template_Orderable')->getColumnName();
+        else
+            return null;
+    }
+
+    public function reorder($ids)
+    {
+        if (!$this->_orderable())
+            return false;
+
+        $ord_field = $this->_orderableColumn();
+
+        $table = IPF_ORM::getTable($this->modelName);
+        $conn = $table->getConnection();
+
+        $idColumn = $table->getIdentifier();
+        if (is_array($idColumn))
+            $idColumn = $idColumn[0];
+
+        $questions = str_repeat('?,', count($ids)-1) . '?';
+        $query = 'SELECT ' . $conn->quoteIdentifier($ord_field) .
+            ' FROM ' . $conn->quoteIdentifier($table->getTableName()) .
+            ' WHERE ' . $conn->quoteIdentifier($idColumn) . ' IN (' . $questions . ')' .
+            ' ORDER BY ' . $conn->quoteIdentifier($ord_field);
+        $ords = $conn->fetchColumn($query, $ids);
+
+        $i = 0;
+        foreach ($ids as $id) {
+            $item = $table->find($id);
+            $item[$ord_field] = $ords[$i];
+            $item->save();
+            $i++;
+        }
+
+        return true;
+    }
+
+    /* edit */
+
+    protected function _getForm($model, $data)
+    {
+        if ($model) {
+            // edit
+            if (!$data)
+                $data = $this->getFormData($model);
+        } else {
+            // add
+            $model = new $this->modelName;
+        }
+
+        $extra = array(
+            'user_fields' => $this->fields(),
+            'model' => $model,
+        );
+
+        return new IPF_Form_Model($data, $extra);
+    }
+
+    public function saveObject($form, $model)
+    {
+        $model = $form->save();
+        $idColumn = $this->table()->getIdentifier();
+        return array($model->$idColumn, $model);
+    }
+
+    public function deleteObject($model)
+    {
+        $model->delete();
+    } 
+
+    public function fields()
+    {
+        return null;
+    }
+
+    public function getFormData($o)
+    {
+        $data = $o->getData();
+        foreach ($o->getTable()->getRelations() as $rname => $rel) {
+            $fields = $this->fields();
+            if (!$fields || in_array($rname, $fields)) {
+                if ($rel->getType() == IPF_ORM_Relation::MANY_AGGREGATE) {
+                    $data[$rname] = array();
+                    foreach ($rel->fetchRelatedFor($o) as $ri) {
+                        $data[$rname][] = $ri->pk();
+                    }
+                }
+            }
+        }
+        return $data;
+    }
+}
+
index bd3b1edadf2f88210e305d384a0019e47a330b2d..9a9fba388b8bd2d942b36f6ead448d12bd89a7ad 100644 (file)
@@ -358,106 +358,45 @@ class DateHierarchyListFilter extends BaseListFilter {
     }
 }
 
-class IPF_Admin_ModelListener
+abstract class IPF_Admin_Component
 {
-    public function beforeEdit($o)
-    {
-        $this->beforeChange($o);
-    }
-
-    public function beforeAdd($o)
-    {
-        $this->beforeChange($o);
-    }
-
-    public function beforeChange($o)
-    {
-    }
-
-    public function afterEdit($o)
-    {
-        $this->afterChange($o);
-    }
-
-    public function afterAdd($o)
-    {
-        $this->afterChange($o);
-    }
-
-    public function afterChange($o)
-    {
-    }
-}
-
-class IPF_Admin_Model
-{
-    static $models = array();
-    static $handlers = array();
-
-    public static function register($classModel, $classAdmin)
-    {
-        $ma = new $classAdmin($classModel);
-        self::$models[$classModel] = $ma;
-        foreach (\PFF\Arr::get(self::$handlers, $classModel, array()) as $action) {
-            call_user_func($action, $ma);
-        }
-        unset(self::$handlers[$classModel]);
-    }
-
-    public static function isModelRegister($classModel)
-    {
-        return array_key_exists($classModel, self::$models);
-    }
-
-    public static function getModelAdmin($classModel)
-    {
-        if (array_key_exists($classModel, self::$models)) {
-            $ma = self::$models[$classModel];
-            $ma->setUp();
-            return $ma;
-        }
-        return null;
-    }
-
-    public static function on($classModel, $action)
-    {
-        if (array_key_exists($classModel, self::$models)) {
-            call_user_func($action, self::$models[$classModel]);
-        } else {
-            \PFF\Arr::pushToKey(self::$handlers, $classModel, $action);
-        }
-    }
-
-    var $modelName = null;
-    var $model = null;
     var $inlineInstances = array();
     var $perPage = 50;
-    public $hidden = false;
-    public $modelListeners = array();
 
-    public function __construct($modelName)
-    {
-        $this->modelName = $modelName;
-    }
+    public $app = null, $request = null;
 
     public function verbose_name()
     {
         return IPF_Utils::humanTitle($this->modelName);
     }
 
+    public function slug()
+    {
+        $slug = get_class($this);
+        $slug = preg_replace('/^Admin([A-Z])/', '\1', $slug);
+        $slug = preg_replace('/Admin$/', '', $slug);
+        $slug = preg_replace('/([a-z0-9])([A-Z0-9])/', '\1-\2', $slug);
+        $slug = preg_replace('/\W+/', '-', $slug);
+        return strtolower($slug);
+    }
+
     public function titleList() { return $this->verbose_name().' List'; }
     public function titleAdd() { return 'Add ' . $this->verbose_name(); }
     public function titleEdit() { return 'Edit ' . $this->verbose_name(); }
     public function titleDelete() { return 'Delete ' . $this->verbose_name(); }
 
-    public function setUp()
+    public function getPerms($request)
     {
-        $this->model = new $this->modelName;
+        return array('view', 'add', 'change', 'delete');
     }
 
-    public function getPerms($request)
+    public function isAccessible($what, $request=null)
     {
-        return array('view', 'add', 'change', 'delete');
+        if (!$request)
+            $request = $this->request;
+        if (!$request)
+            throw new IPF_Exception('No request.');
+        return IPF_Admin_App::isAccessible($request, $this, $what);
     }
 
     protected function context($request)
@@ -467,7 +406,13 @@ class IPF_Admin_Model
 
     protected function renderToResponse($template, $context, $request)
     {
-        $context = array_merge($this->context($request), $context);
+        $context = array_merge(
+            array(
+                'component' => $this,
+                'app' => $this->app,
+            ),
+            $this->context($request),
+            $context);
         return IPF_Admin_App::RenderToResponse($template, $context, $request);
     }
 
@@ -507,11 +452,6 @@ class IPF_Admin_Model
     {
     }
 
-    public function fields()
-    {
-        return null;
-    }
-
     public function inlines()
     {
         return null;
@@ -525,49 +465,47 @@ class IPF_Admin_Model
         return true;
     }
 
+    public abstract function list_display();
+
+    protected function columnTitle($column)
+    {
+        return IPF_Utils::humanTitle($column);
+    }
+
     public function ListItemsHeader()
     {
         $this->header = array();
-        if (method_exists($this, 'list_display'))
-            $this->names = $this->list_display();
-        else
-            $this->names = $this->model->getTable()->getColumnNames();
-
-        $columns = $this->model->getTable()->getColumns();
+        $this->names = $this->list_display();
 
         foreach ($this->names as $name) {
             if (is_array($name)) {
                 list($name, $title) = $name;
-            } elseif (array_key_exists($name, $columns) && array_key_exists('verbose', $columns[$name])) {
-                $title = $columns[$name]['verbose'];
             } else {
-                $title = IPF_Utils::humanTitle($name);
+                $title = $this->columnTitle($name);
             }
 
-            $this->header[$name] = new IPF_Template_ContextVars(array(
-                'title'     => $title,
-                'name'      => $name,
-                'sortable'  => null,
-            ));
+            $this->header[$name] = array(
+                'title' => $title,
+                'name' => $name,
+            );
         }
         return $this->header;
     }
 
-    public function ListItemsQuery()
+    public abstract function ListItemsQuery($searchValue, $page, $pageSize);
+    public abstract function ListItemsQueryCount($searchValue);
+    public abstract function getObjectByID($id);
+    public abstract function saveObject($form, $object);
+    public abstract function deleteObject($object);
+
+    public function searcheable()
     {
-        if (method_exists($this->model,'ordering')) {
-            $ord = $this->model->ordering();
-        } elseif ($this->model->getTable()->getOrdering()) {
-            $ord = implode(', ', $this->model->getTable()->getOrdering());
-        } elseif ($this->model->getTable()->hasTemplate('IPF_ORM_Template_Orderable')) {
-            $ord = $this->model->getTable()->getTemplate('IPF_ORM_Template_Orderable')->getColumnName();
-        } else {
-            $ord = '1 desc';
-        }
-        $this->q = IPF_ORM_Query::create()->from($this->modelName)->orderby($ord);
+        return false;
     }
 
-    public function ListRow($o)
+    public abstract function renderCell($object, $column);
+
+    public function ListRow($o, $id)
     {
         $row = array();
 
@@ -576,27 +514,15 @@ class IPF_Admin_Model
             if (method_exists($this,$listMethod)) {
                 $str = $this->$listMethod($o);
             } else {
-                $t = $o->getTable()->getTypeOf($h['name']);
-                $str = $o->$h['name'];
-                switch ($t) {
-                    case 'boolean':
-                        if ($str)
-                            $str = '<img src="'.IPF::get('static_url').'admin/img/icon-yes.gif" alt="True" />';
-                        else
-                            $str = '<img src="'.IPF::get('static_url').'admin/img/icon-no.gif" alt="False" />';
-                        break;
-                    case 'timestamp':
-                        $str = IPF_Utils::formatDate($str);
-                        break;
-                }
+                $str = $this->renderCell($o, $h['name']);
             }
             $row[$h['name']] = $str;
         }
-        $this->linksRow($row, $o);
+        $this->linksRow($row, $o, $id);
         return $row;
     }
 
-    protected function linksRow(&$row, $o)
+    protected function linksRow(&$row, $o, $id)
     {
         if (method_exists($this, 'list_display_links')) {
             $links_display = $this->list_display_links();
@@ -607,33 +533,25 @@ class IPF_Admin_Model
         foreach ($row as $name => &$v) {
             if ($links_display) {
                 if (array_search($name, $links_display) !== false)
-                    $v = '<a href="'.$this->UrlForResult($o).'">'.$v.'</a>';
+                    $v = '<a href="'.$id.'/">'.$v.'</a>';
             } else {
                 if ($i == 1)
-                    $v = '<a href="'.$this->UrlForResult($o).'">'.$v.'</a>';
+                    $v = '<a href="'.$id.'/">'.$v.'</a>';
                 $i++;
             }
         }
     }
 
-    protected function UrlForResult($o)
-    {
-        return  $o->__get($this->model->getTable()->getIdentifier()).'/';
-    }
-
-    protected function _getForm($model_obj, $data, $extra)
-    {
-        return IFP_Admin_ModelForm::GetFormForModel($model_obj, $data, $extra);
-    }
+    protected abstract function _getForm($obj, $data);
 
-    protected function _getEditForm($model_obj, $data, $extra)
+    protected function _getEditForm($model_obj, $data)
     {
-        return $this->_getForm($model_obj, $data, $extra);
+        return $this->_getForm($model_obj, $data);
     }
 
-    protected function _getAddForm($model_obj, $data, $extra)
+    protected function _getAddForm($model_obj, $data)
     {
-        return $this->_getForm($model_obj, $data, $extra);
+        return $this->_getForm($model_obj, $data);
     }
 
     protected function _getListTemplate()
@@ -651,42 +569,6 @@ class IPF_Admin_Model
         return 'admin/change.html';
     }
 
-    protected function _beforeEdit($o)
-    {
-        foreach ($this->modelListeners as $l)
-            $l->beforeEdit($o);
-        $this->_beforeChange($o);
-    }
-
-    protected function _beforeAdd($o)
-    {
-        foreach ($this->modelListeners as $l)
-            $l->beforeAdd($o);
-        $this->_beforeChange($o);
-    }
-
-    protected function _beforeChange($o)
-    {
-    }
-
-    protected function _afterEdit($o)
-    {
-        foreach ($this->modelListeners as $l)
-            $l->afterEdit($o);
-        $this->_afterChange($o);
-    }
-
-    protected function _afterAdd($o)
-    {
-        foreach ($this->modelListeners as $l)
-            $l->afterAdd($o);
-        $this->_afterChange($o);
-    }
-
-    protected function _afterChange($o)
-    {
-    }
-
     protected function extraMedia($form)
     {
         return array(
@@ -701,39 +583,27 @@ class IPF_Admin_Model
     }
 
     // Views Function
-    public function AddItem($request, $lapp, $lmodel)
+    public function AddItem($request)
     {
-        $perms = IPF_Admin_App::GetAdminModelPermissions($this, $request, $lapp, $lmodel);
-        
-        if ($perms === false || !in_array('view', $perms) || !in_array('add', $perms))
-            return new IPF_HTTP_Response_NotFound($request);
-
         $errors = false;
         if ($request->method == 'POST') {
-            $this->_beforeAdd(new $this->model());
-            $data = $request->POST+$request->FILES;
-            $form = $this->_getAddForm($this->model, $data, array('user_fields'=>$this->fields()));
+            $form = $this->_getAddForm(null, $request->POST + $request->FILES);
             $this->_setupAddForm($form);
-            $this->setInlines($this->model, $data);
-
-            $validForm = $form->isValid();
-            $validInlines = $this->isValidInlines();
-            if ($validForm && $validInlines) {
-                $item = $form->save();
-                $this->saveInlines($item);
-                AdminLog::logAction($request, $item, AdminLog::ADDITION);
-                $this->_afterAdd($item);
+
+            if ($form->isValid()) {
+                list($id, $object) = $this->saveObject($form, null);
+
+                AdminLog::logAction($request->user, AdminLog::ADDITION, (string)$object, IPF_HTTP_URL::urlForView('IPF_Admin_Views_EditItem', array($this->app->slug(), $this->slug(), $id)));
+
                 $url = @$request->POST['ipf_referrer'];
-                if ($url=='')
-                    $url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($lapp, $lmodel));
+                if (!$url)
+                    $url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($this->app->slug(), $this->slug()));
                 return new IPF_HTTP_Response_Redirect($url);
             }
             $errors = true;
         } else {
-            $form = $this->_getAddForm($this->model,null,array('user_fields'=>$this->fields()));
+            $form = $this->_getAddForm(null, null);
             $this->_setupAddForm($form);
-            $data = array();
-            $this->setInlines($this->model);
         }
 
         $extraMedia = $this->extraMedia($form);
@@ -743,169 +613,122 @@ class IPF_Admin_Model
             'page_title'=>$this->titleAdd(),
             'classname'=>$this->verbose_name(),
             'form' => $form,
+            'form_html' => $form->renderLayout(new IPF_Admin_Form_Layout),
             'extra_js' => $extraMedia['js'],
             'extra_css' => $extraMedia['css'],
             'inlineInstances'=>$this->inlineInstances,
             'errors' => $errors,
-            'lapp'=>$lapp,
-            'perms'=>$perms,
-            'lmodel'=>$lmodel,
             'objecttools' => array(),
         );
         return $this->renderToResponse($this->_getAddTemplate(), $context, $request);
     }
 
-    public function DeleteItem($request, $lapp, $lmodel, $o)
+    public function DeleteItem($request, $id)
     {
-        $perms = IPF_Admin_App::GetAdminModelPermissions($this, $request, $lapp, $lmodel);
-        
-        if ($perms === false || !in_array('view', $perms) || !in_array('delete', $perms))
-            return new IPF_HTTP_Response_NotFound($request);
+        $object = $this->getObjectByID($id);
+        if (!$object)
+            throw new IPF_HTTP_Error404;
+
+        if ($request->method == 'POST') {
+            AdminLog::logAction($request->user, AdminLog::DELETION, (string)$object);
+
+            $this->deleteObject($object);
 
-        if ($request->method == 'POST')
-        {
-            AdminLog::logAction($request, $o, AdminLog::DELETION);
-            $o->delete();
             $url = @$request->POST['ipf_referrer'];
-            if ($url=='')
-                $url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($lapp, $lmodel));
+            if (!$url)
+                $url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($this->app->slug(), $this->slug()));
             return new IPF_HTTP_Response_Redirect($url);
         }
+
         $context = array(
-            'page_title'=>$this->titleDelete(),
-            'classname'=>$this->verbose_name(),
-            'object'=>$o,
-            'lapp'=>$lapp,
-            'lmodel'=>$lmodel,
-            'affected'=>array(),
-            'ipf_referrer'=>@$request->GET['ipf_referrer'],
+            'page_title' => $this->titleDelete(),
+            'classname' => $this->verbose_name(),
+            'object' => $object,
+            'object_id' => $id,
+            'ipf_referrer' => @$request->GET['ipf_referrer'],
         );
         return $this->renderToResponse('admin/delete.html', $context, $request);
     }
 
-    public function EditItem($request, $lapp, $lmodel, $o)
+    public function EditItem($request, $id)
     {
-        $perms = IPF_Admin_App::GetAdminModelPermissions($this, $request, $lapp, $lmodel);
-
-        if ($perms === false || !in_array('view', $perms))
-            return new IPF_HTTP_Response_NotFound($request);
+        $object = $this->getObjectByID($id);
+        if (!$object)
+            throw new IPF_HTTP_Error404;
 
         $errors = false;
         if ($request->method == 'POST') {
-            if (!in_array('change', $perms))
-                return new IPF_HTTP_Response_NotFound($request);
-
-            $this->_beforeEdit($o);
-            $data = $request->POST+$request->FILES;
-            $form = $this->_getEditForm($o, $data, array('user_fields'=>$this->fields()));
+            $form = $this->_getEditForm($object, $request->POST + $request->FILES);
             $this->_setupEditForm($form);
-            $this->setInlines($o, $data);
-            
-            $validForm = $form->isValid();
-            $validInlines = $this->isValidInlines();
-            if ($validForm && $validInlines) {
-                $item = $form->save();
-                $this->saveInlines($item);
-                AdminLog::logAction($request, $item, AdminLog::CHANGE);
-                $this->_afterEdit($item);
+
+            if ($form->isValid()) {
+                list($id, $object) = $this->saveObject($form, $object);
+
+                AdminLog::logAction($request->user, AdminLog::CHANGE, (string)$object, IPF_HTTP_URL::urlForView('IPF_Admin_Views_EditItem', array($this->app->slug(), $this->slug(), $id)));
+
                 $url = @$request->POST['ipf_referrer'];
-                if ($url=='')
-                    $url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($lapp, $lmodel));
+                if (!$url)
+                    $url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($this->app->slug(), $this->slug()));
+
                 return new IPF_HTTP_Response_Redirect($url);
             }
             $errors = true;
         } else {
-            $data = $o->getData();
-            foreach ($o->getTable()->getRelations() as $rname => $rel) {
-                $fields = $this->fields();
-                if (!$fields || in_array($rname, $fields)) {
-                    if ($rel->getType() == IPF_ORM_Relation::MANY_AGGREGATE) {
-                        $data[$rname] = array();
-                        foreach ($rel->fetchRelatedFor($o) as $ri) {
-                            $data[$rname][] = $ri->pk();
-                        }
-                    }
-                }
-            }
-            $form = $this->_getEditForm($o, $data, array('user_fields'=>$this->fields()));
+            $form = $this->_getEditForm($object, null);
             $this->_setupEditForm($form);
-            $this->setInlines($o);
         }
 
-        $objecttools = $this->objectTools($o);
+        $objecttools = $this->objectTools($object);
         $extraMedia = $this->extraMedia($form);
 
         $context = array(
             'mode'=>'change',
             'page_title'=>$this->titleEdit(),
             'classname'=>$this->verbose_name(),
-            'object'=>$o,
+            'object' => $object,
+            'object_id' => $id,
             'form' => $form,
+            'form_html' => $form->renderLayout(new IPF_Admin_Form_Layout),
             'extra_js' => $extraMedia['js'],
             'extra_css' => $extraMedia['css'],
             'inlineInstances'=>$this->inlineInstances,
             'errors' => $errors,
-            'lapp'=>$lapp,
-            'perms'=>$perms,
-            'lmodel'=>$lmodel,
             'objecttools' => $objecttools,
         );
         return $this->renderToResponse($this->_getChangeTemplate(), $context, $request);
     }
 
-    public function ListItems($request, $lapp, $lmodel)
+    public function ListItems($request)
     {
-        $perms = IPF_Admin_App::GetAdminModelPermissions($this, $request, $lapp, $lmodel);
+        $searchValue = @$request->GET['q'];
+        $this->filters = array();
+        // $this->_GetFilters($request);
 
-        if ($perms === false || !in_array('view', $perms))
-            return new IPF_HTTP_Response_NotFound($request);
+        $currentPage = (int)@$request->GET['page'];
+        if (!$currentPage)
+            $currentPage = 1;
 
-        $this->ListItemsQuery();
-        $this->_GetFilters($request);
-        $this->_ListSearchQuery($request);
-        $this->_ListFilterQuery($request);
-        $this->ListItemsHeader();
+        $count = $this->ListItemsQueryCount($searchValue);
+        $objects = $this->ListItemsQuery($searchValue, $currentPage, $this->perPage);
 
-        $currentPage = (int)@$request->GET['page'];
+        $this->ListItemsHeader();
 
-        $url = '';
-        foreach ($request->GET as $k=>$v){
-            if ($k=='page')
-                continue;
-            if ($url=='')
-                $url = '?';
-            else
-                $url .= '&';
-            $url .= $k.'='.$v;
-        }
-        if ($url=='')
-            $pager_url = '?page={%page_number}';
-        else
-            $pager_url = $url.'&page={%page_number}';
-
-        $pager = new IPF_ORM_Pager_LayoutArrows(
-            new IPF_ORM_Pager($this->q, $currentPage, $this->perPage),
-            new IPF_ORM_Pager_Range_Sliding(array('chunk' => 10)),
-            $pager_url
-        );
-        $pager->setTemplate('<a href="{%url}">{%page}</a> ');
-        $pager->setSelectedTemplate('<span class="this-page">{%page}</span> ');
-        $objects = $pager->getPager()->execute();
+        $pagerLayout = new IPF_Pager_Layout;
+        $pages = $pagerLayout->layout($currentPage, ceil($count / $this->perPage));
 
         $context = array(
             'orderable'=>$this->_orderable(),
             'page_title'=>$this->titleList(),
             'header'=>$this->header,
-            'objects'=>$objects,
-            'pager'=>$pager,
+            'objects' => $objects,
+            'count' => $count,
+            'pages' => $pages,
+            'current_page' => $currentPage,
             'classname'=>$this->verbose_name(),
             'title_add'=>$this->titleAdd(),
-            'perms'=>$perms,
             'filters'=>$this->filters,
-            'is_search' => $this->_isSearch(),
-            'search_value' => $this->search_value,
-            'lapp'=>$lapp,
-            'lmodel'=>$lmodel,
+            'is_search' => $this->searcheable(),
+            'search_value' => $searchValue,
         );
         return $this->renderToResponse($this->_getListTemplate(), $context, $request);
     }
@@ -917,30 +740,6 @@ class IPF_Admin_Model
         }
     }
 
-    protected function _isSearch()
-    {
-        return method_exists($this,'_searchFields');
-    }
-
-    protected function _ListSearchQuery($request)
-    {
-        $this->search_value = null;
-        if (!$this->_isSearch())
-            return;
-        $fields = $this->_searchFields();
-        $this->search_value = @$request->GET['q'];
-        if ($this->search_value!=''){
-            $wh = '';
-            $whv = array();
-            foreach ($fields as $f){
-                if ($wh!='') $wh.=' or ';
-                $wh.= $f.' like ?';
-                $whv[] = '%'.$this->search_value.'%';
-            }
-            $this->q->addWhere($wh,$whv);
-        }
-    }
-
     protected function _GetFilters($request)
     {
         $this->filters = array();
@@ -991,17 +790,12 @@ class IPF_Admin_Model
 
     public function _orderable()
     {
-        return $this->_orderableColumn() !== null;
+        return false;
     }
 
-    public function _orderableColumn()
+    public function reorder($ids)
     {
-        if (method_exists($this, 'list_order'))
-            return $this->list_order();
-        elseif ($this->model->getTable()->hasTemplate('IPF_ORM_Template_Orderable'))
-            return $this->model->getTable()->getTemplate('IPF_ORM_Template_Orderable')->getColumnName();
-        else
-            return null;
+        throw new IPF_Exception('Reordering is not implemented.');
     }
 }
 
index 42eb5d2f31f162b27af21c3ff6001c873e3f3067..0baf64d571096f662ee1c878e3bfbd5a1b30ba54 100644 (file)
@@ -21,7 +21,11 @@ abstract class IPF_Admin_ModelInline
 
     public function getApplication()
     {
-        return IPF_Admin_App::appByModel($this->getModelName());
+        foreach (IPF_Project::getInstance()->appList() as $app)
+            foreach (IPF_Legacy_ORM_App::appModelList($app) as $model)
+                if ($model == $this->getModelName())
+                    return $app;
+        return null;
     }
 
     function getAddNum()
@@ -81,9 +85,10 @@ abstract class IPF_Admin_ModelInline
         return true;
     }
 
-    protected function _getForm($model_obj, $data, $extra)
+    protected function _getForm($model, $data, $extra)
     {
-        return IFP_Admin_ModelForm::GetFormForModel($model_obj, $data, $extra);
+        $extra['model'] = $model;
+        return new IPF_Form_Model($data, $extra);
     }
 
     function getFkName()
index c2c0adc7ab54e9a49c99471c1641303da5543dc3..3f8fa00c606928fa51b8c7dca19ee90e0444b763 100644 (file)
@@ -6,27 +6,14 @@ class AdminLog extends BaseAdminLog
     const CHANGE    = 2;
     const DELETION  = 3;
 
-    public static function logAction($request, $object, $action_flag, $object_url=null, $message='')
+    public static function logAction($who, $action, $repr, $url=null)
     {
         $log = new AdminLog;
-        $log->username  = $request->user->username;
-        $log->user_id   = $request->user->id;
-
-        $log->object_id       = (int)$object[$object->getTable()->getIdentifier()];
-        $log->object_class    = get_class($object);
-        $log->object_repr     = (string)$object;
-
-        if (!$object_url) {
-            $app = IPF_Admin_App::appByModel($log->object_class);
-            if ($app)
-                $object_url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_EditItem', array($app->getSlug(), strtolower($log->object_class), $log->object_id));
-        }
-
-        $log->object_url      = $object_url;
-
-        $log->action_flag     = $action_flag;
-        $log->change_message  = $message;
-
+        $log->username    = $who->username;
+        $log->user_id     = $who->id;
+        $log->object_repr = $repr;
+        $log->object_url  = $url;
+        $log->action_flag = $action;
         $log->save();
     }
 
index 992992585b5ba2573216193a62e02936b371573a..05938cffc09bf355d0e5dc7bef31f7c07c05c14d 100644 (file)
 
 {block bodyclass}change-form{/block}
 
-{block breadcrumbs}<div class="breadcrumbs"><a href="{url 'IPF_Admin_Views_Index'}">{trans 'Home'}</a> &raquo; <a href="{url 'IPF_Admin_Views_ListItems', array($lapp, $lmodel)}">{$classname}</a> &raquo; {$page_title}</div>{/block}
+{block breadcrumbs}
+<div class="breadcrumbs">
+  <a href="{url 'IPF_Admin_Views_Index'}">{trans 'Home'}</a> &raquo;
+  <a href="{url 'IPF_Admin_Views_ListItems', array($app->slug(), $component->slug())}">{$classname}</a> &raquo;
+  {$page_title}
+</div>
+{/block}
 
 {block content}
 <div id="content" class="colM">
@@ -31,7 +37,7 @@
             {/if}
             <fieldset class="module aligned">
               {block form}
-                {$form->render()}
+                {$form_html|safe}
               {/block}
             </fieldset>
             {if $inlineInstances}
@@ -40,7 +46,7 @@
                 <div class="tabular inline-related">
                     <fieldset class="module">
                     <h2>{$inline->getLegend()}</h2>
-                    <table{if $inline->_orderable()} class="orderable-inlne" data-url="{url 'IPF_Admin_Views_ListItems', array($inline->getApplication()->getSlug(), strtolower($inline->getModelName()))}"{/if}>
+                    <table{if $inline->_orderable()} class="orderable-inlne" data-url="{url 'IPF_Admin_Views_ListItems', array($inline->getApplication()->slug(), strtolower($inline->getModelName()))}"{/if}>
                         <thead>
                         <tr class="nodrop">
                             {foreach $inline->listColumns() as $column}
@@ -72,9 +78,9 @@
             {/foreach}
             {/if}
             <div class="submit-row">
-                {if ($mode=='change') && (array_search('delete',$perms)!==false)}<p class="float-left"><a id="id_a_delete" href="{url 'IPF_Admin_Views_DeleteItem', array($lapp, $lmodel, $object.pk())}" class="deletelink">{trans 'Delete'}</a></p>{/if}
-                {if ($mode=='change') && (array_search('change',$perms)!==false)}<input type="submit" value="{trans 'Save'}" class="default" />{/if}
-                {if ($mode=='add') && (array_search('add',$perms)!==false)}<input type="submit" value="{trans 'Add'}" class="default" />{/if}
+                {if ($mode=='change') && $component->isAccessible(array('delete'))}<p class="float-left"><a id="id_a_delete" href="{url 'IPF_Admin_Views_DeleteItem', array($app->slug(), $component->slug(), $object_id)}" class="deletelink">{trans 'Delete'}</a></p>{/if}
+                {if ($mode=='change') && $component->isAccessible(array('change'))}<input type="submit" value="{trans 'Save'}" class="default" />{/if}
+                {if ($mode=='add') && $component->isAccessible(array('add'))}<input type="submit" value="{trans 'Add'}" class="default" />{/if}
                 <input type="button" value="{trans 'Cancel'}" onclick="javascript:history.back();" />
             </div>
         </div>
index e43341fcbb4aadb5f595b47a6f0d0733642bdf21..8386b446fbf13e9ae2e7eb440accc0567c5144d3 100644 (file)
@@ -7,7 +7,14 @@
 
 {block bodyclass}change-form{/block}
 
-{block breadcrumbs}<div class="breadcrumbs"><a href="{url 'IPF_Admin_Views_Index'}">{trans 'Home'}</a> &raquo; <a href="{url 'IPF_Admin_Views_ListItems', array($lapp, $lmodel)}">{$classname}</a> &raquo; <a href="{url 'IPF_Admin_Views_EditItem', array($lapp, $lmodel, $object.id)}">{$object}</a> &raquo; Change Password</div>{/block}
+{block breadcrumbs}
+<div class="breadcrumbs">
+  <a href="{url 'IPF_Admin_Views_Index'}">{trans 'Home'}</a> &raquo;
+  <a href="{url 'IPF_Admin_Views_ListItems', array($app->slug(), $component->slug())}">{$classname}</a> &raquo;
+  <a href="{url 'IPF_Admin_Views_EditItem', array($app->slug(), $component->slug(), $object.id)}">{$object}</a> &raquo;
+  Change Password
+</div>
+{/block}
 
 {block content}
 <div id="content" class="colM">
index 15ade535566d5eef2c351ae91c48eb445d59c0f3..00267902b58aaa28f52a2d0e5f841826961472e3 100644 (file)
@@ -1,24 +1,23 @@
 {extends "admin/base.html"}
 
-{block breadcrumbs}<div class="breadcrumbs"><a href="{url 'IPF_Admin_Views_Index'}">{trans 'Home'}</a> &raquo; <a href="{url 'IPF_Admin_Views_ListItems', array($lapp, $lmodel)}">{$classname}</a> &raquo; <a href="{url 'IPF_Admin_Views_EditItem', array($lapp, $lmodel, $object.id)}">{$object}</a> &raquo; {$page_title}</div>{/block}
+{block breadcrumbs}
+<div class="breadcrumbs">
+  <a href="{url 'IPF_Admin_Views_Index'}">{trans 'Home'}</a> &raquo;
+  <a href="{url 'IPF_Admin_Views_ListItems', array($app->slug(), $component->slug())}">{$classname}</a> &raquo;
+  <a href="{url 'IPF_Admin_Views_EditItem', array($app->slug(), $component->slug(), $object_id)}">{$object}</a> &raquo;
+  {$page_title}
+</div>
+{/block}
 
 {block content}
 <div id="content" class="colM">
-    <h1>{$page_title}</h1>
-    <form method="post">
-       <input type="hidden" name="ipf_referrer" id="id_ipf_referrer" value="{$ipf_referrer}" />
-    <p>Are you sure you want to delete <em>{$object}</em>?
-    </p>
-    {if count($affected) > 0}
-    <p>It will also delete the following linked elements:</p>
-    <ul>
-    {foreach $affected as $aff}<li>{$aff}</li>{/foreach}
-    </ul>
-    {/if}
+  <h1>{$page_title}</h1>
+  <form method="post">
+    <input type="hidden" name="ipf_referrer" id="id_ipf_referrer" value="{$ipf_referrer}" />
+    <p>Are you sure you want to delete <em>{$object}</em>?</p>
     <input type="submit" value="Yes, delete it!" class="default" />
     <input type="button" value="Cancel" onclick="javascript:history.back();" />
-    </form>    
+  </form>    
 </div>
-
 {/block}
 
index da366e4df07b6d0b34eca4ad4db2359ff93111ec..9236fe3c20aa861d75c50007fd87894e82ad1b1a 100644 (file)
         <table summary="">
         <caption>{$app.name|escxml}</caption>
                <tbody>
-        {foreach $app.models as $model}
+        {foreach $app.components as $component}
         <tr>
-            <th scope="row"><a href="{url 'IPF_Admin_Views_ListItems', array($app.path, $model.path)}">{$model.name}</a></th>
-            <td>{if array_search('add',$model['perms'])!==false}<a class="addlink" href="{url 'IPF_Admin_Views_AddItem', array($app.path, $model.path)}">{trans 'Add'}</a>{/if}</td>
-            <td>{if array_search('change',$model['perms'])!==false}<a class="changelink" href="{url 'IPF_Admin_Views_ListItems', array($app.path, $model.path)}">{trans 'Change'}</a>{/if}</td>
+            <th scope="row"><a href="{url 'IPF_Admin_Views_ListItems', array($app.path, $component->slug())}">{$component->verbose_name()}</a></th>
+            <td>{if $component->isAccessible(array('add'))}<a class="addlink" href="{url 'IPF_Admin_Views_AddItem', array($app.path, $component->slug())}">{trans 'Add'}</a>{/if}</td>
+            <td><a class="changelink" href="{url 'IPF_Admin_Views_ListItems', array($app.path, $component->slug())}">{trans 'Change'}</a></td>
         </tr>
         {/foreach}
         {foreach $app.additions as $item}
index e6d8e6a00535ce612c7298e2b1c5ec64fe168e6a..26dbd321b732297366e268ff5b66b238d1d87262 100644 (file)
@@ -15,7 +15,7 @@
   <div id="content-main">
     <ul class="object-tools">
       {block objecttools}
-      {if array_search('add',$perms)!==false}<li><a href="add/">{$title_add}</a></li>{/if}
+      {if $component->isAccessible(array('add'))}<li><a href="add/">{$title_add}</a></li>{/if}
       <li><a href="javascript:print();">{trans 'Print'}</a></li>
       {/block}
     </ul>
@@ -35,7 +35,7 @@
             <input id="searchbar" type="text" value="{$search_value}" name="q" size="40"/>
             <input type="submit" value="Go"/>
             {if $search_value}
-            <span class="small quiet">{$pager->getPager()->getNumResults()} results (<a href="?{params $request->GET, 'q', null}">reset</a>)</span>
+            <span class="small quiet">{$count} results (<a href="?{params $request->GET, 'q', null}">reset</a>)</span>
             {/if}
           </div>
         </form>
           <thead>
             <tr class="nodrop">
               {foreach $header as $h}
-              <th>{$h.title}</th>
+              <th>{$h['title']}</th>
               {/foreach}
             </tr>
           </thead>
           <tbody>
-            {foreach $objects as $o}
-            <tr class="trsort" id="{$o.pk()}">
-              {foreach $o.ModelAdmin().ListRow($o) as $v}
+            {foreach $objects as $id => $o}
+            <tr class="trsort" id="{$id}">
+              {foreach $component->ListRow($o, $id) as $v}
               <td>{$v|safe}</td>
               {/foreach}
             </tr>
         </table>
         {/block}
         <p class="paginator">
-          {$pager->display()|safe}{$pager->getPager()->getNumResults()} record(s) of {$classname}
+          {foreach $pages as $p}
+            {if $p}
+              {if $p == $current_page}
+                <span class="this-page">{$p}</span>
+              {else}
+                <a href="?{params $request->GET, 'page', $p}">{$p}</a>
+              {/if}
+            {else}
+              &hellip;
+            {/if}
+          {/foreach}
+          {$count} record(s) of {$classname}
         </p>
       </div>
 
index 43d2be0bf4bbc3f7d47b73c8693d86845de38908..8a42707cddd559983dc90577f4e4bb5b704587ee 100644 (file)
@@ -2,43 +2,26 @@
 
 function IPF_Admin_Views_Index($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
+    IPF_Admin_App::ensureUserIsStaff($request);
 
     $apps = array();
     $app_list = new IPF_Template_ContextVars();
     foreach (IPF_Project::getInstance()->appList() as $app) {
-        $appModels = IPF_Legacy_ORM_App::appModelList($app);
-        if (!$appModels)
-            continue;
-
-        $models = new IPF_Template_ContextVars();
-        $models_found = false;
-        foreach ($appModels as $m) {
-            $ma = IPF_Admin_Model::getModelAdmin($m);
-            if ($ma!==null && !$ma->hidden){
-                $perms = $ma->getPerms($request);
-                if (array_search('view', $perms)!==false){
-                    $user_perms = IPF_Auth_App::checkPermissions($request, $app, $m, array('view'));
-                    if ($user_perms['view'])
-                    {
-                        $models[] = new IPF_Template_ContextVars(array(
-                            'name'=>$ma->verbose_name(),
-                            'path'=>strtolower($m),
-                            'perms'=>$perms,
-                        ));
-                        $models_found = true;
-                    }
-                }
+        $components = array();
+        foreach (IPF_Admin_App::applicationComponents($app) as $component) {
+            if ($component->isAccessible(array('view'), $request)) {
+                $component->request = $request;
+                $components[] = $component;
             }
         }
-        if ($models_found){
-            $app_list[$app->getName()] = new IPF_Template_ContextVars(array(
+
+        if ($components) {
+            $app_list[] = (object)array(
                 'name' => $app->getTitle(),
-                'path' => $app->getSlug(),
+                'path' => $app->slug(),
                 'additions' => $app->getAdditions(),
-                'models' => $models,
-            ));
+                'components' => $components,
+            );
         }
     }
 
@@ -59,215 +42,69 @@ function IPF_Admin_Views_Index($request, $match)
 
 function IPF_Admin_Views_ListItems($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
-
-    $lapp = $match[1];
-    $lmodel = $match[2];
-    
-    $am = IPF_Admin_App::GetAppModelFromSlugs($lapp, $lmodel);
-    
-    if ($am !== null)
-    {    
-        $app = $am['app'];
-        $m   = $am['modelname'];
-    
-        $ma = IPF_Admin_Model::getModelAdmin($m);
-    
-        if ($ma !== null)
-            return $ma->ListItems($request, $lapp, $lmodel);
-    }
-    
-    return new IPF_HTTP_Response_NotFound($request);
+    $component = IPF_Admin_App::getComponent($request, array('view'));
+    return $component->ListItems($request);
 }
 
 function IPF_Admin_Views_AddItem($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
-
-    $lapp = $match[1];
-    $lmodel = $match[2];
-    
-    $am = IPF_Admin_App::GetAppModelFromSlugs($lapp, $lmodel);
-    
-    if ($am !== null)
-    {    
-        $app = $am['app'];
-        $m   = $am['modelname'];
-
-        $ma = IPF_Admin_Model::getModelAdmin($m);
-        
-        if ($ma !== null)
-            return $ma->AddItem($request, $lapp, $lmodel);
-    }
-    
-    return new IPF_HTTP_Response_NotFound($request);
+    $component = IPF_Admin_App::getComponent($request, array('view', 'add'));
+    return $component->AddItem($request);
 }
 
 function IPF_Admin_Views_EditItem($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
-
-    $lapp = $match[1];
-    $lmodel = $match[2];
-    $id = $match[3];
-
-    $am = IPF_Admin_App::GetAppModelFromSlugs($lapp, $lmodel);
-
-    if ($am !== null) {
-        $m = $am['modelname'];
-        $ma = IPF_Admin_Model::getModelAdmin($m);
-        if ($ma !== null) {
-            $item = IPF_ORM::getTable($m)->find($id);
-            if (!$item)
-                throw new IPF_HTTP_Error404();
-            return $ma->EditItem($request, $lapp, $lmodel, $item);
-        }
-    }
-
-    return new IPF_HTTP_Response_NotFound($request);
+    $component = IPF_Admin_App::getComponent($request, array('view', 'change'));
+    return $component->EditItem($request, $request->params[3]);
 }
 
 function IPF_Admin_Views_DeleteItem($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
-
-    $lapp = $match[1];
-    $lmodel = $match[2];
-    $id = $match[3];
-    
-    $am = IPF_Admin_App::GetAppModelFromSlugs($lapp, $lmodel);
-    
-    if ($am !== null)
-    {    
-        $app = $am['app'];
-        $m   = $am['modelname'];
-
-        $ma = IPF_Admin_Model::getModelAdmin($m);
-        
-        if ($ma !== null)
-        {
-            $o = new $m();
-            $item = $o->getTable()->find($id);
-            if (!$item)
-                throw new IPF_HTTP_Error404();
-            
-            return $ma->DeleteItem($request, $lapp, $lmodel, $item);
-        }
-    }
-    
-    return new IPF_HTTP_Response_NotFound($request);
+    $component = IPF_Admin_App::getComponent($request, array('view', 'delete'));
+    return $component->DeleteItem($request, $request->params[3]);
 }
 
 function IPF_Admin_Views_Reorder($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
+    $component = IPF_Admin_App::getComponent($request, array('view', 'change'));
 
     if ($request->method != 'POST' || !isset($request->POST['ids']) || !is_array($request->POST['ids']))
         return new IPF_HTTP_Response_NotFound($request);
 
-    $lapp = $match[1];
-    $lmodel = $match[2];
-    
-    $am = IPF_Admin_App::GetAppModelFromSlugs($lapp, $lmodel);
-
-    if ($am !== null) {
-        $app = $am['app'];
-        $m   = $am['modelname'];
-
-        $user_perms = IPF_Auth_App::checkPermissions($request, $app, $m, array('view', 'change'));
-        $ma = ($user_perms['view'] && $user_perms['change']) ? IPF_Admin_Model::getModelAdmin($m) : null;
-        
-        if ($ma !==null && $ma->_orderable()) {
-            $ord_field = $ma->_orderableColumn();
-
-            $ids = $request->POST['ids'];
-
-            $table = IPF_ORM::getTable($m);
-            $conn = $table->getConnection();
-
-            $idColumn = $table->getIdentifier();
-            if (is_array($idColumn))
-                $idColumn = $idColumn[0];
-
-            $questions = str_repeat('?,', count($ids)-1) . '?';
-            $query = 'SELECT ' . $conn->quoteIdentifier($ord_field) .
-                ' FROM ' . $conn->quoteIdentifier($table->getTableName()) .
-                ' WHERE ' . $conn->quoteIdentifier($idColumn) . ' IN (' . $questions . ')' .
-                ' ORDER BY ' . $conn->quoteIdentifier($ord_field);
-            $ords = $conn->fetchColumn($query, $ids);
-
-            $i = 0;
-            foreach ($ids as $id) {
-                $item = $table->find($id);
-                $item[$ord_field] = $ords[$i];
-                $item->save();
-                $i++;
-            }
-
-            return new IPF_HTTP_Response_Json("Ok");
-         }
-    }
-
-    return new IPF_HTTP_Response_Json("Cannot find model");
+    if ($component->reorder($request->POST['ids']))
+        return new IPF_HTTP_Response_Json("Ok");
+    else
+        return new IPF_HTTP_Response_Json('Cannot find model');
 }
 
 function IPF_Admin_Views_ChangePassword($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
+    $component = IPF_Admin_App::getComponent($request, array('view', 'change'));
 
-    $lapp = 'auth';
-    $lmodel = 'user';
-    $id = $match[1];
-    
-    $am = IPF_Admin_App::GetAppModelFromSlugs($lapp, $lmodel);
-    
-    if ($am !== null)
-    {    
-        $app = $am['app'];
-        $m   = $am['modelname'];
-        
-        $ma = IPF_Admin_Model::getModelAdmin($m);
-        
-        if ($ma !== null)
-        {
-            $o = new $m();
-            $user = $o->getTable()->find($id);
-
-            if ($request->method == 'POST')
-            {
-                $form = new IPF_Auth_Forms_ChangePassword($request->POST);
-                
-                if ($form->isValid())
-                {
-                    $user->setPassword($form->cleaned_data['password1']);
-                    $user->save();
-                   
-                    return new IPF_HTTP_Response_Redirect(IPF_HTTP_URL::urlForView('IPF_Admin_Views_ListItems', array($lapp, $lmodel)));
-                }
-            }
-            else $form = new IPF_Auth_Forms_ChangePassword();
-            
-            $context = array(
-                'page_title'=>'Change Password: '.$user->username,
-                'classname'=>'User',
-                'object'=>$user,
-                'form' => $form,
-                'extra_js' => array(),
-                'lapp'=>$lapp,
-                'lmodel'=>$lmodel,
-            );
-                
-            return IPF_Admin_App::RenderToResponse('admin/changepassword.html', $context, $request);
+    $user = User::table()->find($match[1]);
+
+    if ($request->method == 'POST') {
+        $form = new IPF_Admin_Forms_ChangePassword($request->POST);
+        if ($form->isValid()) {
+            $user->setPassword($form->cleaned_data['password1']);
+            $user->save();
+            return new IPF_HTTP_Response_Redirect('../');
         }
+    } else {
+        $form = new IPF_Admin_Forms_ChangePassword();
     }
-    
-    return new IPF_HTTP_Response_NotFound($request);
+
+    $context = array(
+        'component' => $this,
+        'app' => $app,
+        'page_title'=>'Change Password: '.$user->username,
+        'classname'=>'User',
+        'object'=>$user,
+        'form' => $form,
+        'extra_js' => array(),
+    );
+        
+    return IPF_Admin_App::RenderToResponse('admin/changepassword.html', $context, $request);
 }
 
 function IPF_Admin_Views_Login($request, $match)
@@ -279,13 +116,13 @@ function IPF_Admin_Views_Login($request, $match)
         $success_url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_Index');
 
     if ($request->method == 'POST') {
-        $form = new IPF_Auth_Forms_Login($request->POST);
+        $form = new IPF_Admin_Forms_Login($request->POST);
         if ($form->isValid()) {
             IPF_Auth_App::login($request, $form->user);
             return new IPF_HTTP_Response_Redirect($success_url);
         }
     } else {
-        $form = new IPF_Auth_Forms_Login(array('next'=>$success_url));
+        $form = new IPF_Admin_Forms_Login(array('next'=>$success_url));
     }
 
     $context = array(
@@ -355,8 +192,7 @@ function dir_recursive($dir, $path=DIRECTORY_SEPARATOR, $level='')
 
 function IPF_Admin_Views_FileBrowser($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
+    IPF_Admin_App::ensureUserIsStaff($request);
 
     $curr_dir = urldecode(substr($match[1],1));
     if (substr($curr_dir, -1) == '/')
@@ -459,8 +295,7 @@ function IPF_Admin_Views_FileBrowser($request, $match)
 
 function IPF_Admin_Views_FileBrowserRename($request, $match)
 {
-    $ca = IPF_Admin_App::checkAdminAuth($request);
-    if ($ca!==true) return $ca;
+    IPF_Admin_App::ensureUserIsStaff($request);
     
     $old_name = @$request->POST['old_value'];
     $name = @$request->POST['value'];
index 458a3701b513a08911e0eda1b6d3a76357548dce..fc138f4b846f222e4aa2b11c6377d36a584dcbec 100644 (file)
@@ -37,7 +37,7 @@ abstract class IPF_Application
         return $this->path;
     }
 
-    public function getSlug()
+    public function slug()
     {
         $e = explode('_',$this->name);
         return strtolower($e[count($e)-1]);
diff --git a/ipf/auth/admin.php b/ipf/auth/admin.php
new file mode 100644 (file)
index 0000000..d03d914
--- /dev/null
@@ -0,0 +1,379 @@
+<?php
+
+class IPFAuthAdminUserForm extends IPF_Form
+{
+    private $isAdd;
+
+    function initFields($extra=array())
+    {
+        $this->isAdd = $extra['is_add'];
+
+        $this->fields['username'] = new IPF_Form_Field_Varchar(array(
+            'required'    => true,
+            'max_length'  => 32,
+            'label'       => __('Username'),
+            'help_text'   => __('Required. 32 characters or less. Alphanumeric characters only (letters, digits and underscores).'),
+        ));
+        $this->fields['password'] = new IPF_Form_Field_Varchar(array(
+            'required'    => true,
+            'max_length'  => 128,
+            'label'       => __('Password'),
+        ));
+
+        $this->fields['email'] = new IPF_Form_Field_Email(array(
+            'required'    => true,
+            'max_length'  => 200,
+            'label'       => __('E-mail'),
+        ));
+
+        $this->fields['is_active'] = new IPF_Form_Field_Boolean(array(
+            'label'       => __('Active'),
+            'help_text'   => __('Designates whether this user should be treated as active. Unselect this instead of deleting accounts.'),
+        ));
+        $this->fields['is_staff'] = new IPF_Form_Field_Boolean(array(
+            'label'       => __('Staff status'),
+            'help_text'   => __('Designates whether the user can log into this admin site.'),
+        ));
+        $this->fields['is_superuser'] = new IPF_Form_Field_Boolean(array(
+            'label'       => __('Superuser status'),
+            'help_text'   => __('Designates that this user has all permissions without explicitly assigning them.'),
+        ));
+
+        if ($this->isAdd) {
+            unset($this->fields['password']);
+
+            $this->fields['password1'] = new IPF_Form_Field_Varchar(array(
+                'label'       => __('Password'),
+                'required'    => true,
+                'max_length'  => 32,
+                'widget'      => 'IPF_Form_Widget_PasswordInput'
+            ));
+
+            $this->fields['password2'] = new IPF_Form_Field_Varchar(array(
+                'label'       => __('Password (again)'),
+                'required'    => true,
+                'max_length'  => 32,
+                'widget'      => 'IPF_Form_Widget_PasswordInput',
+                'help_text'   => __('Enter the same password as above, for verification.'),
+            ));
+
+            $account = array('username', 'password1', 'password2', 'email');
+        } else {
+            $this->fields['password']->help_text = __("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."); 
+
+            $account = array('username', 'password', 'email');
+        }
+
+        $permissions = array('is_active', 'is_staff', 'is_superuser');
+        if (IPF_Auth_App::ArePermissionsEnabled()) {
+            $permissions[] = 'permissions';
+            $permissions[] = 'roles';
+
+            $this->fields['permissions'] = new IPF_Form_Field_MultipleChoice(array(
+                'label'     => __('Permissions'),
+                'choices'   => Permission::query()->fetchPairs('title', 'id'),
+                'widget'    => 'IPF_Form_Widget_SelectMultipleInputCheckbox',
+                'widget_attrs' => array('class' => 'checkgroup'),
+            ));
+
+            $this->fields['roles'] = new IPF_Form_Field_MultipleChoice(array(
+                'label'     => __('Groups'),
+                'help_text' => __('In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in.'),
+                'choices'   => Role::query()->fetchPairs('name', 'id'),
+                'widget'    => 'IPF_Form_Widget_SelectMultipleInputCheckbox',
+                'widget_attrs' => array('class' => 'checkgroup'),
+            ));
+        }
+
+        $this->field_groups = array(
+            array('fields' => $account),
+            array('fields' => $permissions, 'label' => __('Permissions')),
+        );
+    }
+
+    function isValid()
+    {
+        $ok = parent::isValid();
+
+        if ($ok===true && $this->isAdd) {
+            if ($this->cleaned_data['password1'] != $this->cleaned_data['password2']) {
+                $this->is_valid = false;
+                $this->errors['password2'][] = "The two password fields didn't match.";
+
+                return false;
+            }
+
+            $this->cleaned_data['password'] = User::SetPassword2($this->cleaned_data['password1']);
+        }
+
+        return $ok;
+    }
+}
+
+class AdminUser extends IPF_Admin_Component
+{
+    public function ListItemsQuery($searchValue, $page, $pageSize)
+    {
+        return User::query()
+            ->limit($pageSize)
+            ->offset(($page - 1) * $pageSize)
+            ->fetchAll('id');
+    }
+
+    public function ListItemsQueryCount($searchValue)
+    {
+        return User::query()
+            ->select(null)->select('COUNT(1)')
+            ->fetchColumn();
+    }
+
+    public function list_display()
+    {
+        $columns = array(
+            'username',
+            'email',
+            'is_active',
+            'is_staff',
+            'is_superuser',
+        );
+        if (IPF_Auth_App::ArePermissionsEnabled()) {
+            $columns[] = 'groups';
+        }
+        return $columns;
+    }
+
+    public function column_groups($obj)
+    {
+        return \PFF\Arr::create($obj->roles())->pluck('name')->join(' / ');
+    }
+
+    function _searchFields()
+    {
+        return array(
+            'username',
+            'email',
+        );
+    }
+
+    public function renderCell($object, $column)
+    {
+        return $object->$column;
+    }
+
+    public function getObjectByID($id)
+    {
+        return User::query()->where('id', $id)->fetch();
+    }
+
+    protected function _getForm($user, $data)
+    {
+        $extra = array();
+        if ($user) {
+            $extra['initial'] = array(
+                'username' => $user->username,
+                'password' => $user->password,
+                'email' => $user->email,
+                'is_active' => $user->is_active,
+                'is_staff' => $user->is_staff,
+                'is_superuser' => $user->is_superuser,
+                'permissions' => \PFF\Arr::create($user->permissions())->pluck('id')->arr(),
+                'roles' => \PFF\Arr::create($user->roles())->pluck('id')->arr(),
+            );
+            $extra['is_add'] = false;
+        } else {
+            $extra['is_add'] = true;
+        }
+        return new IPFAuthAdminUserForm($data, $extra);
+    }
+
+    public function saveObject($form, $user)
+    {
+        if (!$user)
+            $user = new User;
+
+        if ($user->id) {
+        } else {
+        }
+
+/*  
+
+        \PFF\Container::databaseQuery()
+            ->deleteFrom('auth_user_permission')
+            ->where('user_id', $user->id)
+            ->execute();
+
+        $query = \PFF\Container::databaseQuery()
+            ->insertInto('auth_user_permission');
+        foreach ($this->cleaned_data['permissions'] as $pid)
+            $query->values(array('user_id' => $user->id, 'permission_id' => $pid));
+        $query->execute();
+
+
+        \PFF\Container::databaseQuery()
+            ->deleteFrom('auth_user_group')
+            ->where('user_id', $user->id)
+            ->execute();
+
+        $query = \PFF\Container::databaseQuery()
+            ->insertInto('auth_user_role');
+        foreach ($this->cleaned_data['roles'] as $pid)
+            $query->values(array('user_id' => $user->id, 'role_id' => $pid));
+        $query->execute();
+
+
+    */
+        return array($user->id, $user);
+    }
+
+    public function deleteObject($user)
+    {
+        \PFF\Container::databaseQuery()
+            ->deleteFrom('auth_user')
+            ->where('id', $user->id)
+            ->execute();
+    }
+
+    protected function objectTools($user)
+    {
+        return array(
+            'impersonate' => IPF_HTTP_URL::urlForView('IPF_Admin_Views_Impersonate', array($user->id)),
+        );
+    }
+
+    public function verbose_name() { return 'User'; }
+}
+
+class IPFAdminRoleForm extends IPF_Form
+{
+    function initFields($extra=array())
+    {
+        $this->fields['name'] = new IPF_Form_Field_Varchar(array(
+            'required' => true,
+            'label' => __('Name'),
+            'max_length' => 255,
+        ));
+
+        if (IPF_Auth_App::ArePermissionsEnabled()) {
+            $this->fields['permissions'] = new IPF_Form_Field_MultipleChoice(array(
+                'label' => __('Permissions'),
+                'choices' => Permission::query()->fetchPairs('title', 'id'),
+                'widget' => 'IPF_Form_Widget_SelectMultipleInputCheckbox',
+                'widget_attrs' => array('class' => 'checkgroup'),
+            ));
+        }
+    }
+}
+
+class AdminRole extends IPF_Admin_Component
+{
+    public function ListItemsQuery($searchValue, $page, $pageSize)
+    {
+        return Role::query()
+            ->limit($pageSize)
+            ->offset(($page - 1) * $pageSize)
+            ->fetchAll('id');
+    }
+
+    public function ListItemsQueryCount($searchValue)
+    {
+        return Role::query()
+            ->select(null)->select('COUNT(1)')
+            ->fetchColumn();
+    }
+
+    public function list_display()
+    {
+        return array(
+            'name',
+        );
+    }
+
+    public function renderCell($object, $column)
+    {
+        return $object->$column;
+    }
+
+    function _searchFields()
+    {
+        return array(
+            'name',
+        );
+    }
+
+    public function getObjectByID($id)
+    {
+        return Role::query()->where('id', $id)->fetch();
+    }
+
+    protected function _getForm($role, $data)
+    {
+        $extra = array();
+        if ($role) {
+            $extra['initial'] = array(
+                'name' => $role->name,
+                'permissions' => \PFF\Arr::create($role->permissions())->pluck('id')->arr(),
+            );
+        }
+        return new IPFAdminRoleForm($data, $extra);
+    }
+
+    public function saveObject($form, $role)
+    {
+        if (!$role)
+            $role = new Role;
+
+        $role->name = $form->cleaned_data['name'];
+        if ($role->id) {
+            \PFF\Container::databaseQuery()
+                ->update('auth_role')
+                ->set('name', $role->name)
+                ->where('id', $role->id)
+                ->execute();
+
+            \PFF\Container::databaseQuery()
+                ->deleteFrom('auth_role_permission')
+                ->where('role_id', $role->id)
+                ->execute();
+        } else {
+            $role->id = \PFF\Container::databaseQuery()
+                ->insertInto('auth_role')
+                ->values(array('name' => $role->name))
+                ->execute();
+        }
+
+        if ($form->cleaned_data['permissions']) {
+            $data = array_map(function($pid) use($role) { return array('role_id' => $role->id, 'permission_id' => $pid); },
+                $form->cleaned_data['permissions']);
+
+            \PFF\Container::databaseQuery()
+                ->insertInto('auth_role_permission')
+                ->values($data)
+                ->execute();
+        }
+
+        return array($role->id, $role);
+    }
+
+    public function deleteObject($role)
+    {
+        \PFF\Container::databaseQuery()
+            ->deleteFrom('auth_role')
+            ->where('id', $role->id)
+            ->execute();
+    }
+
+    public function page_title()   { return 'Group'; }
+    public function verbose_name() { return 'Group'; }
+}
+
+if (IPF_Auth_App::ArePermissionsEnabled()) {
+    return array(
+        'AdminUser',
+        'AdminRole',
+    );
+} else {
+    return array(
+        'AdminUser',
+    );
+}
+
index 81affddbfd7a4912483ad3f2c83e5a7d60c56acf..f7134df0d53ac25e3cc29afa7c05e24d721e7493 100644 (file)
@@ -2,9 +2,9 @@
 
 class IPF_Auth_App extends IPF_Application
 {
-    public function admin_models_order()
+    public function getTitle()
     {
-        return array('User', 'Role');
+        return 'User Accounts';
     }
 
     static function login($request, $user)
@@ -13,12 +13,6 @@ class IPF_Auth_App extends IPF_Application
         $request->session->data = array(
             'login_time' => gmdate('Y-m-d H:i:s')
         );
-        $user->save();
-    }
-
-    public function getTitle()
-    {
-        return 'User Accounts';
     }
 
     static function logout($request)
@@ -29,64 +23,16 @@ class IPF_Auth_App extends IPF_Application
         );
     }
 
-    static function ArePermissionsEnabled()
-    {
-        try {
-            return IPF_ORM_Query::create()->from('Permission')->count() ? true : false;
-        } catch (IPF_ORM_Exception $e) {
-            return true;
-        }
-    }
+    private static $permissionsEnabled = null;
 
-    static function checkPermissions($request, $app, $modelName, array $perms)
+    static function ArePermissionsEnabled()
     {
-        $count = count($perms);
-
-        if (!$count)
-            return array();
-
-        $permissions = array_combine($perms, array_fill(0, $count, false));
-
-        if ($request->user->isAnonymous() || !($request->user->is_staff || $request->user->is_superuser))
-            return $permissions;
-
-        if ($request->user->is_superuser || !self::ArePermissionsEnabled())
-            return array_combine($perms, array_fill(0, $count, true));
-
-        $user_permissions = array();
-
-        foreach ($request->user->Permissions as $up)
-            $user_permissions[] = $up->name;
-
-        foreach ($request->user->Roles as $role)
-        {
-            foreach ($role->Permissions as $rp)
-            {
-                if (!in_array($rp->name, $user_permissions))
-                    $user_permissions[] = $rp->name;
-            }
-        }
-
-        if (!count($user_permissions))
-            return $permissions;
-
-        $prefix = get_class($app).'|'.$modelName.'|';
-
-        foreach ($permissions as $permName=>&$permValue)
-        {
-            $permissionValue = $prefix.$permName;
-
-            foreach ($user_permissions as $user_permission_value)
-            {
-                if ($permissionValue == $user_permission_value)
-                {
-                    $permValue = true;
-                    break;
-                }
-            }
-        }
-
-        return $permissions;
+        if (self::$permissionsEnabled === null)
+            self::$permissionsEnabled = (bool)\PFF\Container::databaseQuery()
+                ->from('auth_permission')
+                ->select('COUNT(1)')
+                ->fetchColumn();
+        return self::$permissionsEnabled;
     }
 
     public function commands()
diff --git a/ipf/auth/forms/changepassword.php b/ipf/auth/forms/changepassword.php
deleted file mode 100644 (file)
index 5162647..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-class IPF_Auth_Forms_ChangePassword extends IPF_Form
-{
-    function initFields($extra=array())
-    {
-        $this->fields['password1'] = new IPF_Form_Field_Varchar(array(
-            'required'  => true,
-            'widget'    =>'IPF_Form_Widget_PasswordInput',
-        ));
-        $this->fields['password2'] = new IPF_Form_Field_Varchar(array(
-            'required'  => true,
-            'widget'    => 'IPF_Form_Widget_PasswordInput',
-            'help_text' => __('Enter the same password as above, for verification.'),
-        ));
-    }
-
-    public function clean()
-    {
-        $data = parent::clean();
-
-        if ($data['password1'] != $data['password2'])
-            $this->errors['password2'][] = __('The two password fields didn\'t match.');
-
-        return $data;
-    }
-}
-
diff --git a/ipf/auth/forms/login.php b/ipf/auth/forms/login.php
deleted file mode 100644 (file)
index 405e5d0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-class IPF_Auth_Forms_Login extends IPF_Form
-{
-    public $message = null;
-    public $user = null;
-
-    protected function initFields($extra=array())
-    {
-        $this->fields['username'] = new IPF_Form_Field_Varchar(array('required'=>true));
-        $this->fields['password'] = new IPF_Form_Field_Varchar(array('required'=>true,'widget'=>'IPF_Form_Widget_PasswordInput'));
-        $this->fields['next'] = new IPF_Form_Field_Varchar(array('required'=>false,'widget'=>'IPF_Form_Widget_HiddenInput'));
-    }
-
-    public function clean()
-    {
-        $data = parent::clean();
-
-        $this->user = User::checkCreditentials($data['username'], $data['password']);
-        if (!$this->user)
-            throw new IPF_Exception_Form(__('The login or the password is not valid. The login and the password are case sensitive.'));
-
-        return $data;
-    }
-}
-
index 455403c7c6c07e46c2fa331d5f3fa5f1a9801abc..0cf563a118fcb504ccce53fd0fb0e6fe4ec7bdd6 100644 (file)
@@ -10,7 +10,7 @@ class IPF_Auth_Middleware
 
         $user_id = \PFF\Arr::get($request->session->data, self::SessionKey, 0);
         if ($user_id > 0) {
-            $request->user = User::table()->find($user_id);
+            $request->user = User::find($user_id);
             if ($request->user && 43200 < IPF_Utils::dateCompare($request->user->last_login)) {
                 $request->user->last_login = gmdate('Y-m-d H:i:s');
                 $request->user->save();
diff --git a/ipf/auth/migrations/20140102000000_create_auth_tables.php b/ipf/auth/migrations/20140102000000_create_auth_tables.php
new file mode 100644 (file)
index 0000000..e3e953a
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+class Migration_20140102000000 extends \PFF\Migrations\Migration
+{
+    function migrate()
+    {
+        $this->connection->exec('CREATE TABLE auth_user (id BIGINT AUTO_INCREMENT, username VARCHAR(32) NOT NULL UNIQUE, password VARCHAR(128) NOT NULL, email VARCHAR(200) NOT NULL UNIQUE, is_staff TINYINT(1) NOT NULL DEFAULT 0, is_active TINYINT(1) NOT NULL DEFAULT 0, is_superuser TINYINT(1) NOT NULL DEFAULT 0, last_login TIMESTAMP, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB');
+        $this->connection->exec('CREATE TABLE auth_role (id BIGINT AUTO_INCREMENT, name VARCHAR(255) UNIQUE, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB');
+        $this->connection->exec('CREATE TABLE auth_permission (id BIGINT AUTO_INCREMENT, name VARCHAR(255) NOT NULL UNIQUE, title VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB');
+
+        $this->connection->exec('CREATE TABLE auth_user_permission (user_id BIGINT, permission_id BIGINT, PRIMARY KEY(user_id, permission_id)) ENGINE = INNODB');
+        $this->connection->exec('CREATE TABLE auth_user_role (user_id BIGINT, role_id BIGINT, PRIMARY KEY(user_id, role_id)) ENGINE = INNODB');
+        $this->connection->exec('CREATE TABLE auth_role_permission (role_id BIGINT, permission_id BIGINT, PRIMARY KEY(role_id, permission_id)) ENGINE = INNODB');
+
+        $this->connection->exec('ALTER TABLE auth_user_permission ADD FOREIGN KEY (user_id) REFERENCES auth_user(id) ON DELETE CASCADE');
+        $this->connection->exec('ALTER TABLE auth_user_permission ADD FOREIGN KEY (permission_id) REFERENCES auth_permission(id) ON DELETE CASCADE');
+        $this->connection->exec('ALTER TABLE auth_user_role ADD FOREIGN KEY (user_id) REFERENCES auth_user(id) ON DELETE CASCADE');
+        $this->connection->exec('ALTER TABLE auth_user_role ADD FOREIGN KEY (role_id) REFERENCES auth_role(id) ON DELETE CASCADE');
+        $this->connection->exec('ALTER TABLE auth_role_permission ADD FOREIGN KEY (role_id) REFERENCES auth_role(id) ON DELETE CASCADE');
+        $this->connection->exec('ALTER TABLE auth_role_permission ADD FOREIGN KEY (permission_id) REFERENCES auth_permission(id) ON DELETE CASCADE');
+    }
+}
+
index 501288395ec051643931c00324eec4ccfcec5fd4..933cdcbe8ddcfd0a933edb123883b3edfec79c7b 100644 (file)
@@ -1,5 +1,134 @@
 <?php
 
+class User
+{
+    public $id, $username, $password, $email, $is_active, $is_staff, $is_superuser, $last_login;
+
+    public function __toString()
+    {
+        $s = $this->username;
+        if ($s===null)
+            return 'Anonymous';
+        return $s;
+    }
+
+    function setPassword($raw_password)
+    {
+        if ($raw_password)
+            $this->password = IPF_Crypto::hashPassword($raw_password);
+        else
+            $this->password = '';
+    }
+
+    function isAnonymous()
+    {
+        return 0 === (int)$this->id;
+    }
+
+    public static function find($id)
+    {
+        return self::query()->where('id', $id)->fetch();
+    }
+
+    public static function checkCreditentials($username, $password)
+    {
+        $user = self::query()->where('username', $username)->fetch();
+        if ($user && $user->is_active && IPF_Crypto::checkPassword($password, $user->password))
+            return $user;
+        else
+            return false;
+    }
+
+    public static function query()
+    {
+        return \PFF\Container::databaseQuery()
+            ->from('auth_user')
+            ->orderBy('username')
+            ->asObject('User');
+    }
+
+    public function permissions()
+    {
+        return Permission::query()
+            ->innerJoin('auth_user_permission ON permission_id = id')
+            ->where('user_id', $this->id)
+            ->fetchAll();
+    }
+
+    public function roles()
+    {
+        return Role::query()
+            ->innerJoin('auth_user_role ON role_id = id')
+            ->where('user_id', $this->id)
+            ->fetchAll();
+    }
+
+    public function effectivePermissions()
+    {
+        return Permission::query()
+            ->where(
+              'EXISTS(SELECT 1 FROM auth_user_permission AS up ' .
+              ' WHERE up.permission_id = auth_permission.id' .
+              '   AND up.user_id = :user_id)' .
+              ' OR '.
+              'EXISTS(SELECT 1 FROM auth_user_role AS ur, auth_role_permission AS rp'.
+              ' WHERE rp.permission_id = auth_permission.id'.
+              '   AND rp.role_id = ur.role_id' .
+              '   AND ur.user_id = :user_id)', array('user_id' => $this->id));
+    }
+
+    public function can(/* $permission ... */)
+    {
+        $cond = array();
+        $params = array();
+        foreach (func_get_args() as $permission) {
+            if ($permission instanceof Permission) {
+                $cond[] = 'id = ?';
+                $params[] = $permission->id;
+            } elseif (is_int($permission)) {
+                $cond[] = 'id = ?';
+                $params[] = $permission;
+            } elseif (is_string($permission)) {
+                $cond[] = 'name = ?';
+                $params[] = $permission;
+            } else {
+                throw new IPF_Exception('Bad argument');
+            }
+        }
+
+        return $this->effectivePermissions()
+            ->select(null)->select('COUNT(1)')
+            ->where(implode(' OR ', $cond), $params)
+            ->fetchColumn() == count($params);
+    }
+}
+
+class Role
+{
+    public $id, $name;
+
+    public function __toString()
+    {
+        return $this->name;
+    }
+
+    public static function query()
+    {
+        return \PFF\Container::databaseQuery()
+            ->from('auth_role')
+            ->asObject('Role')
+            ->orderBy('name');
+    }
+
+    public function permissions()
+    {
+        return Permission::query()
+            ->innerJoin('auth_role_permission ON permission_id = id')
+            ->where('role_id', $this->id)
+            ->fetchAll();
+    }
+}
+
 class Permission
 {
     public $id, $name, $title;
diff --git a/ipf/auth/models.yml b/ipf/auth/models.yml
deleted file mode 100644 (file)
index 1d1515c..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
----
-User:
-    tableName: auth_user
-    actAs: [Timestampable]
-    columns:
-        username: 
-            type: string(32)
-            notblank: true
-            notnull: true
-            unique: true
-        password: 
-            type: string(128)
-            notblank: true
-            notnull: true
-        first_name: string(32)
-        last_name: string(32)
-        email:
-            type: string(200)
-            email: true
-            notnull: true
-            notblank: true
-            unique: true
-        is_staff: 
-            type: boolean
-            notnull: true
-            default: false
-        is_active: 
-            type: boolean
-            notnull: true
-            default: false
-        is_superuser: 
-            type: boolean
-            notnull: true
-            default: false
-        last_login:
-            type: timestamp
-    relations:
-        Roles:
-            class: Role
-            refClass: UserRole
-            foreignAlias: Users
-        Permissions:
-            class: Permission
-            refClass: UserPermission
-            foreignAlias: Users
-    options:
-        type: INNODB
-        collate: utf8_unicode_ci
-        charset: utf8
----
-Role:
-    tableName: auth_role
-    columns:
-        name:
-            unique: true 
-            type: string(255)
-            notblank: true
-    relations:
-        Permissions:
-            class: Permission
-            refClass: RolePermission
-            foreignAlias: Roles
-    options:
-        type: INNODB
-        collate: utf8_unicode_ci
-        charset: utf8
----
-Permission:
-    tableName: auth_permission
-    columns:
-        name:
-            unique: true 
-            type: string(255)
-            notnull: true
-        title:
-            type: string(255)
-            notnull: true
-    options:
-        type: INNODB
-        collate: utf8_unicode_ci
-        charset: utf8
----
-RolePermission:
-    tableName: auth_role_permission
-    columns:
-        role_id:
-            type: integer
-            primary: true
-        permission_id:
-            type: integer
-            primary: true
-    relations:
-        Role:
-            local: role_id
-            onDelete: CASCADE
-        Permission:
-            local: permission_id
-            onDelete: CASCADE
-    options:
-        type: INNODB
-        collate: utf8_unicode_ci
-        charset: utf8
----
-UserRole:
-    tableName: auth_user_role
-    columns:
-        user_id:
-            type: integer
-            primary: true
-        role_id:
-            type: integer
-            primary: true
-    relations:
-        User:
-            local: user_id
-            onDelete: CASCADE
-        Role:
-            local: role_id
-            onDelete: CASCADE
-    options:
-        type: INNODB
-        collate: utf8_unicode_ci
-        charset: utf8
----
-UserPermission:
-    tableName: auth_user_permission
-    columns:
-        user_id:
-            type: integer
-            primary: true
-        permission_id:
-            type: integer
-            primary: true
-    relations:
-        User:
-            local: user_id
-            onDelete: CASCADE
-        Permission:
-            local: permission_id
-            onDelete: CASCADE
-    options:
-        type: INNODB
-        collate: utf8_unicode_ci
-        charset: utf8
----
-
diff --git a/ipf/auth/models/Permission.php b/ipf/auth/models/Permission.php
deleted file mode 100644 (file)
index 30943f2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-class Permission extends BasePermission
-{
-    public function __toString()
-    {
-        return $this->title;
-    }
-}
-
diff --git a/ipf/auth/models/Role.php b/ipf/auth/models/Role.php
deleted file mode 100644 (file)
index 4281783..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-class Role extends BaseRole
-{
-    public function __toString()
-    {
-        return $this->name;
-    }
-}
-
-class IPFAdminRoleForm extends IFP_Admin_ModelForm
-{
-    public function add__Permissions__field()
-    {
-        if (!IPF_Auth_App::ArePermissionsEnabled())
-            return null;
-
-        $choices = array();
-        foreach (IPF_ORM::getTable('Permission')->findAll() as $o)
-            $choices[$o->__toString()] = $o->id;
-        ksort($choices);
-
-        return new IPF_Form_Field_ModelMultipleChoice(array(
-            'required' => false,
-            'label' => 'Permissions',
-            'help_text' => '',
-            'type' => 'manytomany',
-            'editable' => true,
-            'model' => 'Permission',
-            'widget' => 'IPF_Form_Widget_SelectMultipleInputCheckbox',
-            'choices' => $choices,
-            'widget_attrs' => array('class' => 'checkgroup'),
-        ));
-    }
-}
-
-class AdminRole extends IPF_Admin_Model
-{
-    public function list_display()
-    {
-        return array(
-            'name',
-        );
-    }
-    
-    public function fields()
-    {
-        return array(
-            'name',
-            'Permissions',
-        );
-    }
-
-    function _searchFields()
-    {
-        return array(
-            'name',
-        );
-    }
-
-    protected function _getForm($model_obj, $data, $extra)
-    {
-        $extra['model'] = $model_obj;
-        return new IPFAdminRoleForm($data, $extra);
-    }
-
-    public function page_title()   { return 'Group'; }
-    public function verbose_name() { return 'Group'; }
-}
-
-if (IPF_Auth_App::ArePermissionsEnabled())
-    IPF_Admin_Model::register('Role', 'AdminRole');
-
diff --git a/ipf/auth/models/RolePermission.php b/ipf/auth/models/RolePermission.php
deleted file mode 100644 (file)
index c407a8c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-class RolePermission extends BaseRolePermission
-{
-}
-
diff --git a/ipf/auth/models/User.php b/ipf/auth/models/User.php
deleted file mode 100644 (file)
index bc85456..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-<?php
-
-class IPFAuthAdminUserForm extends IFP_Admin_ModelForm
-{
-    function initFields($extra=array())
-    {
-        \PFF\Arr::pushToKey($extra, 'exclude', 'UserRole');
-        \PFF\Arr::pushToKey($extra, 'exclude', 'UserPermission');
-        parent::initFields($extra);
-
-        $this->fields['email']->label = 'E-mail';
-
-        $this->fields['is_active']->label    = __('Active');
-        $this->fields['is_staff']->label     = __('Staff status');
-        $this->fields['is_superuser']->label = __('Superuser status');
-
-        $this->fields['is_active']->help_text    = __('Designates whether this user should be treated as active. Unselect this instead of deleting accounts.');
-        $this->fields['is_staff']->help_text     = __('Designates whether the user can log into this admin site.');
-        $this->fields['is_superuser']->help_text = __('Designates that this user has all permissions without explicitly assigning them.');
-
-        $this->fields['username']->help_text = __('Required. 32 characters or less. Alphanumeric characters only (letters, digits and underscores).');
-
-        if (!$this->model->id) {
-            unset($this->fields['password']);
-
-            $this->fields['password1'] = new IPF_Form_Field_Varchar(array(
-                'label'       => __('Password'),
-                'required'    => true,
-                'max_length'  => 32,
-                'widget'      => 'IPF_Form_Widget_PasswordInput'
-            ));
-
-            $this->fields['password2'] = new IPF_Form_Field_Varchar(array(
-                'label'       => __('Password (again)'),
-                'required'    => true,
-                'max_length'  => 32,
-                'widget'      => 'IPF_Form_Widget_PasswordInput',
-                'help_text'   => __('Enter the same password as above, for verification.'),
-            ));
-
-            $account = array('username', 'password1', 'password2');
-        } else {
-            $this->fields['password']->help_text = __("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."); 
-
-            $account = array('username', 'password');
-        }
-
-        $permissions = array('is_active', 'is_staff', 'is_superuser');
-        if (IPF_Auth_App::ArePermissionsEnabled()) {
-            $permissions[] = 'Permissions';
-            $permissions[] = 'Roles';
-        }
-
-        $this->field_groups = array(
-            array('fields' => $account),
-            array('fields' => array('email', 'first_name', 'last_name'), 'label' => __('Personal info')),
-            array('fields' => $permissions, 'label' => __('Permissions')),
-        );
-
-        /*
-         * User's profile
-         */
-
-        $profileTable = IPF::get('auth_profile_model');
-        if ($profileTable) {
-            $table = IPF_ORM::getTable($profileTable);
-            $profileFields = self::suggestFields($table);
-
-            $fieldGroup = array();
-            foreach ($profileFields as $field) {
-                list($n, $f) = $field;
-                $this->fields[$n] = $f;
-                $fieldGroup[] = $n;
-            }
-
-            $this->field_groups[] = array('fields' => $fieldGroup, 'label' => __('Profile'));
-        }
-    }
-
-    public function add__Permissions__field()
-    {
-        if (!IPF_Auth_App::ArePermissionsEnabled())
-            return null;
-
-        $choices = array();
-        foreach (IPF_ORM::getTable('Permission')->findAll() as $o)
-            $choices[$o->__toString()] = $o->id;
-        ksort($choices);
-
-        return new IPF_Form_Field_ModelMultipleChoice(array(
-            'required' => false,
-            'label' => 'Permissions',
-            'help_text' => '',
-            'type' => 'manytomany',
-            'editable' => true,
-            'model' => 'Permission',
-            'widget' => 'IPF_Form_Widget_SelectMultipleInputCheckbox',
-            'choices' => $choices,
-            'widget_attrs' => array('class' => 'checkgroup'),
-        ));
-    }
-
-    public function add__Roles__field()
-    {
-        if (!IPF_Auth_App::ArePermissionsEnabled())
-            return null;
-
-        $choices = array();
-        foreach (IPF_ORM::getTable('Role')->findAll() as $o)
-            $choices[$o->__toString()] = $o->id;
-
-        return new IPF_Form_Field_ModelMultipleChoice(array(
-            'required' => false,
-            'label' => 'Groups',
-            'help_text' => 'In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in.',
-            'type' => 'manytomany',
-            'editable' => true,
-            'model' => 'Role',
-            'widget' => 'IPF_Form_Widget_SelectMultipleInputCheckbox',
-            'choices' => $choices,
-            'widget_attrs' => array('class' => 'checkgroup'),
-        ));
-    }
-
-    function isValid()
-    {
-        $ok = parent::isValid();
-        
-        if ($ok===true && !$this->model->id) {
-            if ($this->cleaned_data['password1'] != $this->cleaned_data['password2']) {
-                $this->is_valid = false;
-                $this->errors['password2'][] = "The two password fields didn't match.";
-
-                return false;
-            }
-
-            $this->cleaned_data['password'] = User::SetPassword2($this->cleaned_data['password1']);
-        }
-
-        return $ok;
-    }
-
-    function save($commit=true)
-    {
-        $user = parent::save($commit);
-        $profileTable = IPF::get('auth_profile_model');
-        if ($profileTable) {
-            $profile = $user->getProfile();
-
-            $profile->SetFromFormData($this->cleaned_data);
-            $profile->save();
-        }
-        return $user;
-    }
-}
-
-class AdminUser extends IPF_Admin_Model
-{
-    public function list_display()
-    {
-        $columns = array(
-            'username',
-            'email',
-            'is_active',
-            'is_staff',
-            'is_superuser',
-        );
-        if (IPF_Auth_App::ArePermissionsEnabled()) {
-            $columns[] = 'groups';
-        }
-        $columns[] = 'created_at';
-        return $columns;
-    }
-
-    public function column_groups($obj)
-    {
-        $roles = array();
-        foreach ($obj->Roles as $role) {
-            $roles[] = $role->name;
-        }
-        return implode(' / ', $roles);
-    }
-
-    function _searchFields()
-    {
-        return array(
-            'username',
-            'email',
-        );
-    }
-
-    protected function _getForm($model_obj, $data, $extra)
-    {
-        $extra['model'] = $model_obj;
-        return new IPFAuthAdminUserForm($data, $extra);
-    }
-
-    protected function objectTools($user)
-    {
-        return array(
-            'impersonate' => IPF_HTTP_URL::urlForView('IPF_Admin_Views_Impersonate', array($user->id)),
-        );
-    }
-}
-
-class User extends BaseUser
-{
-    private $profile = null;
-
-    public function __toString()
-    {
-        $s = $this->username;
-        if ($s===null)
-            return 'Anonymous';
-        return $s;
-    }
-
-    function setPassword($raw_password)
-    {
-        if ($raw_password)
-            $this->password = IPF_Crypto::hashPassword($raw_password);
-        else
-            $this->password = '';
-    }
-
-    function isAnonymous()
-    {
-        return 0 === (int)$this->id;
-    }
-
-    public static function checkCreditentials($username, $password)
-    {
-        $user = self::table()->findOneByUsername($username);
-        if ($user && $user->is_active && IPF_Crypto::checkPassword($password, $user->password))
-            return $user;
-        else
-            return false;
-    }
-
-    public function getData()
-    {
-        $data = parent::getData();
-        $profile = $this->getProfile();
-        if ($profile)
-            $data = $data + $profile->getData();
-        return $data;
-    }
-
-    public function getProfile()
-    {
-        if (!$this->id)
-            return null;
-
-        $profileTable = IPF::get('auth_profile_model');
-        if (!$profileTable)
-            return null;
-
-        if (!$this->profile)
-            $this->profile = IPF_ORM::getTable($profileTable)->findOneByUserId($this->id);
-
-        if (!$this->profile) {
-            $this->profile = new $profileTable;
-            $this->profile->user = $this;
-        }
-
-        return $this->profile;
-    }
-}
-
-IPF_Admin_Model::register('User', 'AdminUser');
-
diff --git a/ipf/auth/models/UserPermission.php b/ipf/auth/models/UserPermission.php
deleted file mode 100644 (file)
index 7af37b9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-class UserPermission extends BaseUserPermission
-{
-}
-
diff --git a/ipf/auth/models/UserRole.php b/ipf/auth/models/UserRole.php
deleted file mode 100644 (file)
index 35126dd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-class UserRole extends BaseUserRole
-{
-}
-
diff --git a/ipf/auth/models/_generated/BasePermission.php b/ipf/auth/models/_generated/BasePermission.php
deleted file mode 100644 (file)
index fdc6d18..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-/**
- * This class has been auto-generated by the IPF_ORM Framework.
- * Changes to this file may cause incorrect behavior
- * and will be lost if the code is regenerated.
- */
-
-abstract class BasePermission extends IPF_ORM_Record
-{
-  public static function setTableDefinition(IPF_ORM_Table $table)
-  {
-    $table->setTableName('auth_permission');
-    $table->setColumn('name', 'string', 255, array('unique' => true, 'type' => 'string', 'notnull' => true, 'length' => '255'));
-    $table->setColumn('title', 'string', 255, array('type' => 'string', 'notnull' => true, 'length' => '255'));
-    $table->setOption('type', 'INNODB');
-    $table->setOption('collate', 'utf8_unicode_ci');
-    $table->setOption('charset', 'utf8');
-
-  }
-
-  public static function setUp(IPF_ORM_Table $table)
-  {
-    $table->hasMany('User', 'Users', array('refClass' => 'UserPermission', 'local' => 'permission_id', 'foreign' => 'user_id'));
-    $table->hasMany('Role', 'Roles', array('refClass' => 'RolePermission', 'local' => 'permission_id', 'foreign' => 'role_id'));
-    $table->hasMany('RolePermission', '', array('local' => 'id', 'foreign' => 'permission_id'));
-    $table->hasMany('UserPermission', '', array('local' => 'id', 'foreign' => 'permission_id'));
-  }
-
-  public static function table()
-  {
-    return IPF_ORM::getTable('Permission');
-  }
-
-  public static function query($alias='')
-  {
-    return IPF_ORM::getTable('Permission')->createQuery($alias);
-  }
-}
\ No newline at end of file
diff --git a/ipf/auth/models/_generated/BaseRole.php b/ipf/auth/models/_generated/BaseRole.php
deleted file mode 100644 (file)
index 0099fab..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * This class has been auto-generated by the IPF_ORM Framework.
- * Changes to this file may cause incorrect behavior
- * and will be lost if the code is regenerated.
- */
-
-abstract class BaseRole extends IPF_ORM_Record
-{
-  public static function setTableDefinition(IPF_ORM_Table $table)
-  {
-    $table->setTableName('auth_role');
-    $table->setColumn('name', 'string', 255, array('unique' => true, 'type' => 'string', 'notblank' => true, 'length' => '255'));
-    $table->setOption('type', 'INNODB');
-    $table->setOption('collate', 'utf8_unicode_ci');
-    $table->setOption('charset', 'utf8');
-
-  }
-
-  public static function setUp(IPF_ORM_Table $table)
-  {
-    $table->hasMany('Permission', 'Permissions', array('refClass' => 'RolePermission', 'local' => 'role_id', 'foreign' => 'permission_id'));
-    $table->hasMany('User', 'Users', array('refClass' => 'UserRole', 'local' => 'role_id', 'foreign' => 'user_id'));
-    $table->hasMany('RolePermission', '', array('local' => 'id', 'foreign' => 'role_id'));
-    $table->hasMany('UserRole', '', array('local' => 'id', 'foreign' => 'role_id'));
-  }
-
-  public static function table()
-  {
-    return IPF_ORM::getTable('Role');
-  }
-
-  public static function query($alias='')
-  {
-    return IPF_ORM::getTable('Role')->createQuery($alias);
-  }
-}
\ No newline at end of file
diff --git a/ipf/auth/models/_generated/BaseRolePermission.php b/ipf/auth/models/_generated/BaseRolePermission.php
deleted file mode 100644 (file)
index b4da1a4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * This class has been auto-generated by the IPF_ORM Framework.
- * Changes to this file may cause incorrect behavior
- * and will be lost if the code is regenerated.
- */
-
-abstract class BaseRolePermission extends IPF_ORM_Record
-{
-  public static function setTableDefinition(IPF_ORM_Table $table)
-  {
-    $table->setTableName('auth_role_permission');
-    $table->setColumn('role_id', 'integer', null, array('type' => 'integer', 'primary' => true));
-    $table->setColumn('permission_id', 'integer', null, array('type' => 'integer', 'primary' => true));
-    $table->setOption('type', 'INNODB');
-    $table->setOption('collate', 'utf8_unicode_ci');
-    $table->setOption('charset', 'utf8');
-
-  }
-
-  public static function setUp(IPF_ORM_Table $table)
-  {
-    $table->hasOne('Role', '', array('local' => 'role_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
-    $table->hasOne('Permission', '', array('local' => 'permission_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
-  }
-
-  public static function table()
-  {
-    return IPF_ORM::getTable('RolePermission');
-  }
-
-  public static function query($alias='')
-  {
-    return IPF_ORM::getTable('RolePermission')->createQuery($alias);
-  }
-}
\ No newline at end of file
diff --git a/ipf/auth/models/_generated/BaseUser.php b/ipf/auth/models/_generated/BaseUser.php
deleted file mode 100644 (file)
index 0411e71..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * This class has been auto-generated by the IPF_ORM Framework.
- * Changes to this file may cause incorrect behavior
- * and will be lost if the code is regenerated.
- */
-
-abstract class BaseUser extends IPF_ORM_Record
-{
-  public static function setTableDefinition(IPF_ORM_Table $table)
-  {
-    $table->setTableName('auth_user');
-    $table->setColumn('username', 'string', 32, array('type' => 'string', 'notblank' => true, 'notnull' => true, 'unique' => true, 'length' => '32'));
-    $table->setColumn('password', 'string', 128, array('type' => 'string', 'notblank' => true, 'notnull' => true, 'length' => '128'));
-    $table->setColumn('first_name', 'string', 32, array('type' => 'string', 'length' => '32'));
-    $table->setColumn('last_name', 'string', 32, array('type' => 'string', 'length' => '32'));
-    $table->setColumn('email', 'string', 200, array('type' => 'string', 'email' => true, 'notnull' => true, 'notblank' => true, 'unique' => true, 'length' => '200'));
-    $table->setColumn('is_staff', 'boolean', null, array('type' => 'boolean', 'notnull' => true, 'default' => false));
-    $table->setColumn('is_active', 'boolean', null, array('type' => 'boolean', 'notnull' => true, 'default' => false));
-    $table->setColumn('is_superuser', 'boolean', null, array('type' => 'boolean', 'notnull' => true, 'default' => false));
-    $table->setColumn('last_login', 'timestamp', null, array('type' => 'timestamp'));
-    $table->setOption('type', 'INNODB');
-    $table->setOption('collate', 'utf8_unicode_ci');
-    $table->setOption('charset', 'utf8');
-
-  }
-
-  public static function setUp(IPF_ORM_Table $table)
-  {
-    $table->hasMany('Role', 'Roles', array('refClass' => 'UserRole', 'local' => 'user_id', 'foreign' => 'role_id'));
-    $table->hasMany('Permission', 'Permissions', array('refClass' => 'UserPermission', 'local' => 'user_id', 'foreign' => 'permission_id'));
-    $table->hasMany('UserRole', '', array('local' => 'id', 'foreign' => 'user_id'));
-    $table->hasMany('UserPermission', '', array('local' => 'id', 'foreign' => 'user_id'));
-    $table->addTemplate(new IPF_ORM_Template_Timestampable());
-  }
-
-  public static function table()
-  {
-    return IPF_ORM::getTable('User');
-  }
-
-  public static function query($alias='')
-  {
-    return IPF_ORM::getTable('User')->createQuery($alias);
-  }
-}
\ No newline at end of file
diff --git a/ipf/auth/models/_generated/BaseUserPermission.php b/ipf/auth/models/_generated/BaseUserPermission.php
deleted file mode 100644 (file)
index 198ac96..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * This class has been auto-generated by the IPF_ORM Framework.
- * Changes to this file may cause incorrect behavior
- * and will be lost if the code is regenerated.
- */
-
-abstract class BaseUserPermission extends IPF_ORM_Record
-{
-  public static function setTableDefinition(IPF_ORM_Table $table)
-  {
-    $table->setTableName('auth_user_permission');
-    $table->setColumn('user_id', 'integer', null, array('type' => 'integer', 'primary' => true));
-    $table->setColumn('permission_id', 'integer', null, array('type' => 'integer', 'primary' => true));
-    $table->setOption('type', 'INNODB');
-    $table->setOption('collate', 'utf8_unicode_ci');
-    $table->setOption('charset', 'utf8');
-
-  }
-
-  public static function setUp(IPF_ORM_Table $table)
-  {
-    $table->hasOne('User', '', array('local' => 'user_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
-    $table->hasOne('Permission', '', array('local' => 'permission_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
-  }
-
-  public static function table()
-  {
-    return IPF_ORM::getTable('UserPermission');
-  }
-
-  public static function query($alias='')
-  {
-    return IPF_ORM::getTable('UserPermission')->createQuery($alias);
-  }
-}
\ No newline at end of file
diff --git a/ipf/auth/models/_generated/BaseUserRole.php b/ipf/auth/models/_generated/BaseUserRole.php
deleted file mode 100644 (file)
index 9297d16..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * This class has been auto-generated by the IPF_ORM Framework.
- * Changes to this file may cause incorrect behavior
- * and will be lost if the code is regenerated.
- */
-
-abstract class BaseUserRole extends IPF_ORM_Record
-{
-  public static function setTableDefinition(IPF_ORM_Table $table)
-  {
-    $table->setTableName('auth_user_role');
-    $table->setColumn('user_id', 'integer', null, array('type' => 'integer', 'primary' => true));
-    $table->setColumn('role_id', 'integer', null, array('type' => 'integer', 'primary' => true));
-    $table->setOption('type', 'INNODB');
-    $table->setOption('collate', 'utf8_unicode_ci');
-    $table->setOption('charset', 'utf8');
-
-  }
-
-  public static function setUp(IPF_ORM_Table $table)
-  {
-    $table->hasOne('User', '', array('local' => 'user_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
-    $table->hasOne('Role', '', array('local' => 'role_id', 'foreign' => 'id', 'onDelete' => 'CASCADE'));
-  }
-
-  public static function table()
-  {
-    return IPF_ORM::getTable('UserRole');
-  }
-
-  public static function query($alias='')
-  {
-    return IPF_ORM::getTable('UserRole')->createQuery($alias);
-  }
-}
\ No newline at end of file