<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[GlotPress] [458] trunk:
  Move validator permissions interface to project and add GP_Validator_Permission thing to make working with them easier </title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd>458</dd>
<dt>Author</dt> <dd>nbachiyski</dd>
<dt>Date</dt> <dd>2010-04-05 17:07:27 +0000 (Mon, 05 Apr 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move validator permissions interface to project and add GP_Validator_Permission thing to make working with them easier </pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkcssstylecss">trunk/css/style.css</a></li>
<li><a href="#trunkgpincludesadvancedpermissionsphp">trunk/gp-includes/advanced-permissions.php</a></li>
<li><a href="#trunkgpincludesgpphp">trunk/gp-includes/gp.php</a></li>
<li><a href="#trunkgpincludesroutesprojectphp">trunk/gp-includes/routes/project.php</a></li>
<li><a href="#trunkgpincludesroutestranslationphp">trunk/gp-includes/routes/translation.php</a></li>
<li><a href="#trunkgpincludesroutesphp">trunk/gp-includes/routes.php</a></li>
<li><a href="#trunkgpincludestemplatephp">trunk/gp-includes/template.php</a></li>
<li><a href="#trunkgpincludesthingphp">trunk/gp-includes/thing.php</a></li>
<li><a href="#trunkgpincludesthingspermissionphp">trunk/gp-includes/things/permission.php</a></li>
<li><a href="#trunkgpincludesthingsprojectphp">trunk/gp-includes/things/project.php</a></li>
<li><a href="#trunkgptemplatesprojectphp">trunk/gp-templates/project.php</a></li>
<li><a href="#trunkgptemplatestranslationsphp">trunk/gp-templates/translations.php</a></li>
<li><a href="#trunkttest_permissionsphp">trunk/t/test_permissions.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkgpincludesthingsvalidatorpermissionphp">trunk/gp-includes/things/validator-permission.php</a></li>
<li><a href="#trunkgptemplatesprojectpermissionsphp">trunk/gp-templates/project-permissions.php</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkgptemplatestranslationsetpermissionsphp">trunk/gp-templates/translation-set-permissions.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkcssstylecss"></a>
<div class="modfile"><h4>Modified: trunk/css/style.css (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/css/style.css        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/css/style.css        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -379,10 +379,10 @@
</span><span class="cx"> .actionlist a:active {
</span><span class="cx">     color: red;
</span><span class="cx"> }
</span><del>-#translation-set-permissions .user {
</del><ins>+.permissions .user {
</ins><span class="cx">     font-weight: bold;
</span><span class="cx"> }
</span><del>-#translation-set-permissions .permission-action {
</del><ins>+.permissions .permission-action {
</ins><span class="cx">     font-style: italic;
</span><span class="cx">     color: #999;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkgpincludesadvancedpermissionsphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/advanced-permissions.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/advanced-permissions.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/advanced-permissions.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -15,11 +15,11 @@
</span><span class="cx">         return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function gp_recurse_project_locale_set_slug_permissions( $verdict, $args ) {
-        if ( !( !$verdict &amp;&amp; $args['object_type'] == 'project|locale|set-slug' &amp;&amp; $args['object_id'] &amp;&amp; $args['user'] ) ) {
</del><ins>+function gp_recurse_validator_permission( $verdict, $args ) {
+        if ( !( !$verdict &amp;&amp; $args['object_type'] == GP::$validator_permission-&gt;object_type &amp;&amp; $args['object_id'] &amp;&amp; $args['user'] ) ) {
</ins><span class="cx">                 return $verdict;
</span><span class="cx">         }
</span><del>-        list( $project_id, $locale_slug, $set_slug ) = explode( '|', $args['object_id'] );
</del><ins>+        list( $project_id, $locale_slug, $set_slug ) = GP::$validator_permission-&gt;project_id_locale_slug_set_slug( $args['object_id'] );
</ins><span class="cx">         $project = GP::$project-&gt;get( $project_id );
</span><span class="cx">         if ( $project-&gt;parent_project_id ) {
</span><span class="cx">                 return $args['user']-&gt;can( $args['action'], $args['object_type'], $project-&gt;parent_project_id.'|'.$locale_slug.'|'.$set_slug );
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-function gp_route_translation_set_permissions_to_parent_project( $verdict, $args ) {
</del><ins>+function gp_route_translation_set_permissions_to_validator_permissions( $verdict, $args ) {
</ins><span class="cx">         if ( !( $verdict == 'no-verdict' &amp;&amp; $args['action'] == 'approve' &amp;&amp; $args['object_type'] == 'translation-set'
</span><span class="cx">                         &amp;&amp; $args['object_id'] &amp;&amp; $args['user'] ) ) {
</span><span class="cx">                 return $verdict;
</span><span class="lines">@@ -37,10 +37,11 @@
</span><span class="cx">                 $set = $args['extra']['set'];
</span><span class="cx">         else
</span><span class="cx">                 $set = GP::$translation_set-&gt;get( $args['object_id'] );
</span><del>-        return $args['user']-&gt;can( 'approve', 'project|locale|set-slug', $set-&gt;project_id.'|'.$set-&gt;locale.'|'.$set-&gt;slug );
</del><ins>+        return $args['user']-&gt;can( 'approve', GP::$validator_permission-&gt;object_type,
+                GP::$validator_permission-&gt;object_id( $set-&gt;project_id, $set-&gt;locale, $set-&gt;slug ) );
</ins><span class="cx">         
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> add_filter( 'can_user', 'gp_recurse_project_permissions', 10, 2 );
</span><del>-add_filter( 'can_user', 'gp_recurse_project_locale_set_slug_permissions', 10, 2 );
-add_filter( 'pre_can_user', 'gp_route_translation_set_permissions_to_parent_project', 10, 2 );
</del><ins>+add_filter( 'can_user', 'gp_recurse_validator_permission', 10, 2 );
+add_filter( 'pre_can_user', 'gp_route_translation_set_permissions_to_validator_permissions', 10, 2 );
</ins></span></pre></div>
<a id="trunkgpincludesgpphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/gp.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/gp.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/gp.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -5,6 +5,7 @@
</span><span class="cx">         static $user;
</span><span class="cx">         static $translation_set;
</span><span class="cx">         static $permission;
</span><ins>+        static $validator_permission;
</ins><span class="cx">         static $translation;
</span><span class="cx">         static $original;
</span><span class="cx">         // other singletons
</span></span></pre></div>
<a id="trunkgpincludesroutesprojectphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes/project.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes/project.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/routes/project.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">                 $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
</span><span class="cx"> 
</span><span class="cx">                 $format = gp_array_get( GP::$formats, gp_post( 'format', 'po' ), null );
</span><del>-                if ( !$format ) $this-&gt;redirect_with_error( __('No such format.') );;
</del><ins>+                if ( !$format ) $this-&gt;redirect_with_error( __('No such format.') );
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">                 if ( !is_uploaded_file( $_FILES['import-file']['tmp_name'] ) ) {
</span><span class="lines">@@ -132,4 +132,66 @@
</span><span class="cx">                         gp_redirect( gp_url_project( $project, '_edit' ) );
</span><span class="cx">                 }
</span><span class="cx">         }
</span><ins>+        
+        function permissions_get( $project_path ) {
+                $project = GP::$project-&gt;by_path( $project_path );
+                if ( !$project ) gp_tmpl_404();
+                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
+                $path_to_root = array_slice( $project-&gt;path_to_root(), 1 );
+                $permissions = GP::$validator_permission-&gt;by_project_id( $project-&gt;id );
+                $parent_permissions = array();
+                foreach( $path_to_root as $parent_project ) {
+                        $this_parent_permissions = GP::$validator_permission-&gt;by_project_id( $parent_project-&gt;id );
+                        foreach( $this_parent_permissions as $permission ) {
+                                $permission-&gt;project = $parent_project;
+                        }
+                        $parent_permissions = array_merge( $parent_permissions, (array)$this_parent_permissions );
+                }
+                // we can't join on users table
+                foreach( array_merge( (array)$permissions, (array)$parent_permissions ) as $permission ) {
+                        $permission-&gt;user = GP::$user-&gt;get( $permission-&gt;user_id );
+                }
+                $this-&gt;tmpl( 'project-permissions', get_defined_vars() );
+        }
+
+        function permissions_post( $project_path ) {
+                $project = GP::$project-&gt;by_path( $project_path );
+                if ( !$project ) gp_tmpl_404();
+                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
+                if ( 'add-validator' == gp_post( 'action' ) ) {
+                        $user = GP::$user-&gt;by_login( gp_post( 'user_login' ) );
+                        if ( !$user ) {
+                                $this-&gt;redirect_with_error( __('User wasn&amp;#8217;t found!'), gp_url_current() );
+                        }
+                        $new_permission = new GP_Validator_Permission( array(
+                                'user_id' =&gt; $user-&gt;id,
+                                'action' =&gt; 'approve',
+                                'project_id' =&gt; $project-&gt;id,
+                                'locale_slug' =&gt; gp_post( 'locale' ),
+                                'set_slug' =&gt; gp_post( 'set-slug' ),
+                        ) );
+                        $this-&gt;validate_or_redirect( $new_permission, gp_url_current() );
+                        $permission = GP::$validator_permission-&gt;create( $new_permission );
+                        $permission?
+                                $this-&gt;notices[] = __('Validator was added.') : $this-&gt;errors[] = __('Error in adding validator.');
+                }
+                gp_redirect( gp_url_current() );
+        }
+        
+        function permissions_delete( $project_path, $permission_id ) {
+                $project = GP::$project-&gt;by_path( $project_path );
+                if ( !$project ) gp_tmpl_404();
+                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
+                $permission = GP::$permission-&gt;get( $permission_id );
+                if ( $permission ) {
+                        if ( $permission-&gt;delete() ) {
+                                $this-&gt;notices[] = __('Permission was deleted.');
+                        } else {
+                                $this-&gt;errors[] = __('Error in deleting permission!');
+                        }
+                } else {
+                        $this-&gt;errors[] = __('Permission wasn&amp;#8217;t found!');
+                }
+                gp_redirect( gp_url_project( $project, array( '_permissions' ) ) );
+        }        
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesroutestranslationphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes/translation.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes/translation.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/routes/translation.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -248,66 +248,7 @@
</span><span class="cx">                         $this-&gt;notices[] = sprintf( __('%d fuzzy translation from Google Translate were added.' ), $ok );
</span><span class="cx">                 }
</span><span class="cx">         }
</span><del>-        
-
-        function permissions_post( $project_path, $locale_slug, $translation_set_slug ) {
-                $project = GP::$project-&gt;by_path( $project_path );
-                $locale = GP_Locales::by_slug( $locale_slug );
-                $translation_set = GP::$translation_set-&gt;by_project_id_slug_and_locale( $project-&gt;id, $translation_set_slug, $locale_slug );
-                if ( !$project || !$locale || !$translation_set ) gp_tmpl_404();
-                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
-                if ( 'add-approver' == gp_post( 'action' ) ) {
-                        $user = GP::$user-&gt;by_login( gp_post( 'user_login' ) );
-                        if ( $user ) {
-                                $res = GP::$permission-&gt;create( array(
-                                        'user_id' =&gt; $user-&gt;id,
-                                        'action' =&gt; 'approve',
-                                        'object_type' =&gt; 'translation-set',
-                                        'object_id' =&gt; $translation_set-&gt;id,
-                                ) );
-                                $res?
-                                        $this-&gt;notices[] = 'Validator was added.' :
-                                        $this-&gt;errors[] = 'Error in adding validator.';
-                        } else {
-                                $this-&gt;errors[] = 'User wasn&amp;#8217;t found!';
-                        }
-                }
-                gp_redirect( gp_url_current() );
-        }
-        
-        function permissions_get( $project_path, $locale_slug, $translation_set_slug ) {
-                $project = GP::$project-&gt;by_path( $project_path );
-                $locale = GP_Locales::by_slug( $locale_slug );
-                $translation_set = GP::$translation_set-&gt;by_project_id_slug_and_locale( $project-&gt;id, $translation_set_slug, $locale_slug );
-                if ( !$project || !$locale || !$translation_set ) gp_tmpl_404();
-                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
-                $permissions = GP::$permission-&gt;by_translation_set_id( $translation_set-&gt;id );
-                // we can't join on users table
-                foreach( (array)$permissions as $permission ) {
-                        $permission-&gt;user = GP::$user-&gt;get( $permission-&gt;user_id );
-                }
-                $this-&gt;tmpl( 'translation-set-permissions', get_defined_vars() );
-        }
-        
-        function permissions_delete( $project_path, $locale_slug, $translation_set_slug, $permission_id ) {
-                $project = GP::$project-&gt;by_path( $project_path );
-                $locale = GP_Locales::by_slug( $locale_slug );
-                $translation_set = GP::$translation_set-&gt;by_project_id_slug_and_locale( $project-&gt;id, $translation_set_slug, $locale_slug );
-                if ( !$project || !$locale || !$translation_set ) gp_tmpl_404();
-                $this-&gt;can_or_redirect( 'write', 'project', $project-&gt;id );
-                $permission = GP::$permission-&gt;get( $permission_id );
-                if ( $permission ) {
-                        if ( $permission-&gt;delete() ) {
-                                $this-&gt;notices[] = 'Permissin was deleted.';
-                        } else {
-                                $this-&gt;errors[] = 'Error in deleting permission!';
-                        }
-                } else {
-                        $this-&gt;errors[] = 'Permission wasn&amp;#8217;t found!';
-                }
-                gp_redirect( gp_url_project( $project, array( $locale-&gt;slug, $translation_set-&gt;slug, '_permissions' ) ) );
-        }
-        
</del><ins>+                        
</ins><span class="cx">         function discard_warning( $project_path, $locale_slug, $translation_set_slug ) {
</span><span class="cx">                 $project = GP::$project-&gt;by_path( $project_path );
</span><span class="cx">                 $locale = GP_Locales::by_slug( $locale_slug );
</span></span></pre></div>
<a id="trunkgpincludesroutesphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/routes.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/routes.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/routes.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -53,6 +53,11 @@
</span><span class="cx">                         &quot;post:/$project/_delete&quot; =&gt; array('GP_Route_Project', 'delete_post'),
</span><span class="cx"> 
</span><span class="cx">                         &quot;post:/$project/_personal&quot; =&gt; array('GP_Route_Project', 'personal_options_post'),
</span><ins>+                        
+                        &quot;get:/$project/_permissions&quot; =&gt; array('GP_Route_Project', 'permissions_get'),
+                        &quot;post:/$project/_permissions&quot; =&gt; array('GP_Route_Project', 'permissions_post'),
+                        &quot;get:/$project/_permissions/_delete/$dir&quot; =&gt; array('GP_Route_Project', 'permissions_delete'),
+                        
</ins><span class="cx"> 
</span><span class="cx">                         &quot;get:/$projects&quot; =&gt; array('GP_Route_Project', 'index'),
</span><span class="cx">                         &quot;get:/$projects/_new&quot; =&gt; array('GP_Route_Project', 'new_get'),
</span><span class="lines">@@ -64,9 +69,6 @@
</span><span class="cx">                         &quot;post:/$project/$locale/$dir&quot; =&gt; array('GP_Route_Translation', 'translations_post'),
</span><span class="cx">                         &quot;get:/$project/$locale/$dir/import-translations&quot; =&gt; array('GP_Route_Translation', 'import_translations_get'),
</span><span class="cx">                         &quot;post:/$project/$locale/$dir/import-translations&quot; =&gt; array('GP_Route_Translation', 'import_translations_post'),
</span><del>-                        &quot;get:/$project/$locale/$dir/_permissions&quot; =&gt; array('GP_Route_Translation', 'permissions_get'),
-                        &quot;post:/$project/$locale/$dir/_permissions&quot; =&gt; array('GP_Route_Translation', 'permissions_post'),
-                        &quot;get:/$project/$locale/$dir/_permissions/_delete/$dir&quot; =&gt; array('GP_Route_Translation', 'permissions_delete'),
</del><span class="cx">                         &quot;post:/$project/$locale/$dir/_discard-warning&quot; =&gt; array('GP_Route_Translation', 'discard_warning'),
</span><span class="cx">                         &quot;/$project/$locale/$dir/export-translations&quot; =&gt; array('GP_Route_Translation', 'export_translations_get'),
</span><span class="cx">                         // keep this one at the bottom of the project, because it will catch anything starting with project
</span></span></pre></div>
<a id="trunkgpincludestemplatephp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/template.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/template.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/template.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -163,4 +163,12 @@
</span><span class="cx"> function gp_attrs_add_class( $attrs, $class_name ) {
</span><span class="cx">         $attrs['class'] = isset( $attrs['class'] )? $attrs['class'] . ' ' . $class_name : $class_name;
</span><span class="cx">         return $attrs;
</span><ins>+}
+
+function gp_locales_dropdown( $name_and_id, $selected_slug = '', $attrs = array() ) {
+        $options = array( '' =&gt; '&amp;mdash; Locale &amp;mdash;' );
+        foreach( GP_Locales::locales() as $locale ) {
+                $options[$locale-&gt;slug] = sprintf( '%s &amp;ndash; %s', $locale-&gt;slug, $locale-&gt;english_name );
+        }
+        return gp_select( $name_and_id, $options, $selected_slug, $attrs );
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesthingphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/thing.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/thing.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/thing.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx">         
</span><span class="cx">         var $table = null;
</span><span class="cx">         var $field_names = array();
</span><ins>+        var $non_db_field_names = array();
</ins><span class="cx">         var $errors = array();
</span><span class="cx">         var $validation_rules = null;
</span><span class="cx">         var $per_page = 30;
</span><span class="lines">@@ -24,7 +25,7 @@
</span><span class="cx">                 if ( isset( self::$validation_rules_by_class[$this-&gt;class] ) ) {
</span><span class="cx">                         $this-&gt;validation_rules = &amp;self::$validation_rules_by_class[$this-&gt;class];
</span><span class="cx">                 } else {
</span><del>-                        $this-&gt;validation_rules = new GP_Validation_Rules( $this-&gt;field_names );
</del><ins>+                        $this-&gt;validation_rules = new GP_Validation_Rules( array_merge( $this-&gt;field_names, $this-&gt;non_db_field_names ) );
</ins><span class="cx">                         // we give the rules as a parameter here solely as a syntax sugar
</span><span class="cx">                         $this-&gt;restrict_fields( $this-&gt;validation_rules );
</span><span class="cx">                         self::$validation_rules_by_class[$this-&gt;class] = &amp;$this-&gt;validation_rules;
</span><span class="lines">@@ -186,8 +187,9 @@
</span><span class="cx"> 
</span><span class="cx">         function get( $thing_or_id ) {
</span><span class="cx">                 global $gpdb;
</span><del>-                if ( is_object( $thing_or_id ) ) $thing_or_id = $thing_or_id-&gt;id;
-                return $this-&gt;coerce( $gpdb-&gt;get_row( $gpdb-&gt;prepare( &quot;SELECT * FROM $this-&gt;table WHERE `id` = '%s'&quot;, $thing_or_id ) ) );
</del><ins>+                if ( !$thing_or_id ) return false;
+                $id = is_object( $thing_or_id )? $thing_or_id-&gt;id : $thing_or_id;
+                return $this-&gt;find_one( array( 'id' =&gt; $id ) );
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         function save( $args = null ) {
</span><span class="lines">@@ -305,15 +307,20 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         function sql_from_conditions( $conditions ) {
</span><del>-                $conditions = array_map( array( &amp;$this, 'sql_condition_from_php_value' ), $conditions );
-                $string_conditions = array();
-                foreach( $conditions as $field =&gt; $sql_condition ) {
-                        if ( is_array( $sql_condition ) )
-                                $string_conditions[] = '('. implode( ' OR ', array_map( lambda( '$cond', '&quot;$field $cond&quot;', compact('field') ), $sql_condition ) ) . ')';
-                        else
-                                $string_conditions[] = &quot;$field $sql_condition&quot;;
</del><ins>+                if ( is_string( $conditions ) ) {
+                        $conditions;
+                } elseif ( is_array( $conditions ) ) {
+                        $conditions = array_map( array( &amp;$this, 'sql_condition_from_php_value' ), $conditions );
+                        $string_conditions = array();
+                        foreach( $conditions as $field =&gt; $sql_condition ) {
+                                if ( is_array( $sql_condition ) )
+                                        $string_conditions[] = '('. implode( ' OR ', array_map( lambda( '$cond', '&quot;$field $cond&quot;', compact('field') ), $sql_condition ) ) . ')';
+                                else
+                                        $string_conditions[] = &quot;$field $sql_condition&quot;;
+                        }
+                        $conditions = implode( ' AND ', $string_conditions );
</ins><span class="cx">                 }
</span><del>-                return implode( ' AND ', $string_conditions );
</del><ins>+                return $this-&gt;apply_default_conditions( $conditions );
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         function select_all_from_conditions( $conditions ) {
</span><span class="lines">@@ -359,4 +366,11 @@
</span><span class="cx">         function like_escape_printf( $s ) {
</span><span class="cx">                 return str_replace( '%', '%%', like_escape( $s ) );
</span><span class="cx">         }
</span><ins>+        
+        function apply_default_conditions( $conditions_str ) {
+                $conditions = array();
+                if ( isset( $this-&gt;default_conditions ) )  $conditions[] = $this-&gt;default_conditions;
+                if ( $conditions_str ) $conditions[] = $conditions_str;
+                return implode( ' AND ', $conditions );
+        }
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesthingspermissionphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/things/permission.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/things/permission.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/things/permission.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -15,14 +15,5 @@
</span><span class="cx">                 }
</span><span class="cx">                 return $args;
</span><span class="cx">         }
</span><del>-        
-        function by_translation_set_id( $translation_set_id ) {
-                return $this-&gt;many( &quot;SELECT * FROM $this-&gt;table WHERE object_type='translation-set' AND object_id = %d&quot;, $translation_set_id );
-        }
-        
-        function by_project_id_locale_slug_set_slug( $project_id, $locale_slug, $set_slug = 'default' ) {
-                return $this-&gt;many( &quot;SELECT * FROM $this-&gt;table WHERE object_type='project|locale|set' AND object_id = %s&quot;,
-                        $project_id.'|'.$locale_slug.'|'.$set_slug );
-        }
</del><span class="cx"> }
</span><span class="cx"> GP::$permission = new GP_Permission();
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgpincludesthingsprojectphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-includes/things/project.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/things/project.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-includes/things/project.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx">         function after_create() {
</span><span class="cx">                 // TODO: pass some args to pre/after_create?
</span><span class="cx">                 if ( is_null( $this-&gt;update_path() ) ) return false;
</span><del>-                if ( !$this-&gt;copy_permissions_from_parent() ) return false;
</del><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Field handling
</span><span class="lines">@@ -80,19 +79,6 @@
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        function copy_permissions_from_parent() {
-                if ( !$this-&gt;parent_project_id ) return true;
-                $permissions = GP::$permission-&gt;find( array( 'action' =&gt; 'write', 'object_type' =&gt; 'project',  'object_id' =&gt; $this-&gt;parent_project_id )  );
-                if ( !is_array( $permissions ) ) return false;
-                foreach( $permissions as $permission ) {
-                        if ( !GP::$permission-&gt;create( array( 'user_id' =&gt; $permission-&gt;user_id, 'action' =&gt; 'write',
-                                        'object_type' =&gt; 'project',  'object_id' =&gt; $this-&gt;id ) ) ) {
-                                return false;
-                        }
-                }
-                return true;
-        }
-
</del><span class="cx">         /**
</span><span class="cx">          * Regenrate the paths of all projects from its parents slugs
</span><span class="cx">          */
</span></span></pre></div>
<a id="trunkgpincludesthingsvalidatorpermissionphp"></a>
<div class="addfile"><h4>Added: trunk/gp-includes/things/validator-permission.php (0 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-includes/things/validator-permission.php                                (rev 0)
+++ trunk/gp-includes/things/validator-permission.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+&lt;?php
+class GP_Validator_Permission extends GP_Permission {
+
+        var $table_basename = 'permissions';
+        var $field_names = array( 'id', 'user_id', 'action', 'object_type', 'object_id' );
+        var $non_db_field_names = array( 'project_id', 'locale_slug', 'set_slug' );
+        var $non_updatable_attributes = array( 'id', );
+
+        function restrict_fields( $permission ) {
+                $permission-&gt;project_id_should_not_be('empty');
+                $permission-&gt;locale_slug_should_not_be('empty');
+                $permission-&gt;user_id_should_not_be('empty');
+                $permission-&gt;action_should_not_be('empty');
+                $permission-&gt;set_slug_should_not_be('empty');
+        }
+        
+        function set_fields( $db_object ) {
+                parent::set_fields( $db_object );
+                if ( $this-&gt;object_id ) {
+                        list( $this-&gt;project_id, $this-&gt;locale_slug, $this-&gt;set_slug ) = $this-&gt;project_id_locale_slug_set_slug( $this-&gt;object_id );
+                }
+                $this-&gt;object_type = 'project|locale|set-slug';
+                $this-&gt;default_conditions = &quot;object_type = '&quot;.$this-&gt;object_type.&quot;'&quot;;
+        }
+
+        function prepare_fields_for_save( $args ) {
+                $args = (array)$args;
+                $args['object_type'] = $this-&gt;object_type;                
+                if ( gp_array_get( $args, 'project_id' ) &amp;&amp; gp_array_get( $args, 'locale_slug' )
+                                 &amp;&amp; gp_array_get( $args, 'set_slug' ) &amp;&amp; !gp_array_get( $args, 'object_id' ) ) {
+                        $args['object_id'] = $this-&gt;object_id( $args['project_id'], $args['locale_slug'], $args['set_slug'] );
+                }
+                $args = parent::prepare_fields_for_save( $args );                
+                return $args;
+        }
+        
+        function project_id_locale_slug_set_slug( $object_id ) {
+                return explode( '|', $object_id );
+        }
+        
+        function object_id( $project_id, $locale_slug, $set_slug = 'default' ) {
+                return implode( '|', array( $project_id, $locale_slug, $set_slug ) );
+        }
+        
+        function by_project_id( $project_id ) {
+                $project_id = (int)$project_id;
+                return $this-&gt;find_many( &quot;object_id LIKE '$project_id|%'&quot; );
+        }
+}
+GP::$validator_permission = new GP_Validator_Permission();
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/gp-includes/things/validator-permission.php
</span><span class="cx">___________________________________________________________________
</span><span class="cx">Name: svn:eol-style
</span><span class="cx">   + native
</span></span></pre></div>
<a id="trunkgptemplatesprojectpermissionsphpfromrev454trunkgptemplatestranslationsetpermissionsphp"></a>
<div class="copfile"><h4>Copied: trunk/gp-templates/project-permissions.php (from rev 454, trunk/gp-templates/translation-set-permissions.php) (0 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/project-permissions.php                                (rev 0)
+++ trunk/gp-templates/project-permissions.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+&lt;?php
+gp_title( sprintf( __( 'Permissions &amp;lt; %s &amp;lt; GlotPress' ), $project-&gt;name ) );
+gp_breadcrumb( array(
+        gp_link_project_get( $project, $project-&gt;name ),
+        __('Permissions')
+) );
+gp_tmpl_header();
+?&gt;
+&lt;h2&gt;&lt;?php _e('Permissions'); ?&gt;&lt;/h2&gt;
+&lt;h3 id=&quot;validators&quot;&gt;&lt;?php _e('Validators'); ?&gt;&lt;/h3&gt;
+        &lt;?php if ( $permissions ): ?&gt;
+        &lt;?php if ( $parent_permissions ): ?&gt;
+&lt;h4 id=&quot;validators&quot;&gt;&lt;?php _e('Validators for this project'); ?&gt;&lt;/h4&gt;
+        &lt;?php endif; ?&gt;
+&lt;ul class=&quot;permissions&quot;&gt;
+        &lt;?php foreach( $permissions as $permission ): ?&gt;
+                &lt;li&gt;
+                        &lt;span class=&quot;permission-action&quot;&gt;&lt;?php _e('user'); ?&gt;&lt;/span&gt;
+                        &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;user-&gt;user_login ); ?&gt;&lt;/span&gt;
+                        &lt;span class=&quot;permission-action&quot;&gt;can &lt;?php echo esc_html( $permission-&gt;action ); ?&gt; strings with locale&lt;/span&gt;
+                        &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;locale_slug ); ?&gt;&lt;/span&gt;
+                        &lt;span class=&quot;permission-action&quot;&gt;and slug&lt;/span&gt;
+                        &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;set_slug ); ?&gt;&lt;/span&gt;
+                        &lt;a href=&quot;&lt;?php echo gp_url_join( gp_url_current(), '_delete/'.$permission-&gt;id ); ?&gt;&quot; class=&quot;action delete&quot;&gt;&lt;?php _e('Remove'); ?&gt;&lt;/a&gt;
+                &lt;/li&gt;
+        &lt;? endforeach; ?&gt;
+&lt;/ul&gt;        
+        &lt;?php endif; ?&gt;
+        &lt;?php  if ( $parent_permissions ): ?&gt;
+&lt;h4 id=&quot;validators&quot;&gt;&lt;?php _e('Validators for parent projects'); ?&gt;&lt;/h4&gt;
+&lt;ul class=&quot;permissions&quot;&gt;                
+                &lt;?php foreach( $parent_permissions as $permission ): ?&gt;
+                        &lt;li&gt;
+                                &lt;span class=&quot;permission-action&quot;&gt;&lt;?php _e('user'); ?&gt;&lt;/span&gt;
+                                &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;user-&gt;user_login ); ?&gt;&lt;/span&gt;
+                                &lt;span class=&quot;permission-action&quot;&gt;can &lt;?php echo esc_html( $permission-&gt;action ); ?&gt; strings with locale&lt;/span&gt;
+                                &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;locale_slug ); ?&gt;&lt;/span&gt;
+                                &lt;span class=&quot;permission-action&quot;&gt;and slug&lt;/span&gt;
+                                &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;set_slug ); ?&gt;&lt;/span&gt;
+                                &lt;span class=&quot;permission-action&quot;&gt;in the project &lt;/span&gt;
+                                &lt;span class=&quot;user&quot;&gt;&lt;?php gp_link_project( $permission-&gt;project, esc_html( $permission-&gt;project-&gt;name ) ); ?&gt;&lt;/span&gt;
+                        &lt;/li&gt;
+                &lt;? endforeach; ?&gt;
+&lt;/ul&gt;                                
+        &lt;?php endif; ?&gt;
+        &lt;?php if ( !$permissions &amp;&amp; !$parent_permissions ): ?&gt;
+                &lt;strong&gt;&lt;?php _e('No validators defined for this project.'); ?&gt;&lt;/strong&gt;
+        &lt;?php endif; ?&gt;
+&lt;form action=&quot;&quot; method=&quot;post&quot; class=&quot;secondary&quot;&gt;
+        &lt;h3&gt;&lt;?php _e('Add a validator for this project'); ?&gt;&lt;/h3&gt;
+        &lt;dl&gt;
+                &lt;dt&gt;&lt;label for=&quot;user_login&quot;&gt;&lt;?php _e('Username:'); ?&gt;&lt;/label&gt;&lt;/dt&gt;
+                &lt;dd&gt;&lt;input type=&quot;text&quot; name=&quot;user_login&quot; value=&quot;&quot; id=&quot;user_login&quot; /&gt;&lt;/dd&gt;
+                &lt;dt&gt;&lt;label for=&quot;locale&quot;&gt;&lt;?php _e('Locale:'); ?&gt;&lt;/label&gt;&lt;/dt&gt;
+                &lt;dd&gt;&lt;?php echo gp_locales_dropdown( 'locale' ); ?&gt;&lt;/dd&gt;
+                &lt;dt&gt;&lt;label for=&quot;set-slug&quot;&gt;&lt;?php _e('Translation set slug:'); ?&gt;&lt;/label&gt;&lt;/dt&gt;
+                &lt;dd&gt;&lt;input type=&quot;text&quot; name=&quot;set-slug&quot; value=&quot;default&quot; id=&quot;set-slug&quot; /&gt;&lt;/dd&gt;
+                                
+                &lt;dt&gt;
+                        &lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;&lt;?php echo esc_attr(__('Add &amp;rarr;')); ?&gt;&quot; id=&quot;submit&quot; /&gt;
+                        &lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;add-validator&quot; /&gt;
+                &lt;/dt&gt;
+&lt;/form&gt;
+&lt;?php
+echo gp_js_focus_on('user_login');
+gp_tmpl_footer();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgptemplatesprojectphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-templates/project.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/project.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-templates/project.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -74,6 +74,7 @@
</span><span class="cx"> &lt;?php if ( $can_write ): ?&gt;
</span><span class="cx">         &lt;p class=&quot;secondary actionlist&quot;&gt;
</span><span class="cx">                 &lt;?php gp_link( gp_url_project( $project, 'import-originals' ), __( 'Import originals' ) ); ?&gt; &amp;bull;
</span><ins>+                &lt;?php gp_link( gp_url_project( $project, array( '_permissions' ) ), __('Permissions') ); ?&gt; &amp;bull;
</ins><span class="cx">                 &lt;?php gp_link( gp_url_project( '', '_new', array('parent_project_id' =&gt; $project-&gt;id) ), __('Create a New Sub-Project') ); ?&gt; &amp;bull;
</span><span class="cx">                 &lt;?php gp_link( gp_url( '/sets/_new', array( 'project_id' =&gt; $project-&gt;id ) ), __('Create a New Translation Set') ); ?&gt;
</span><span class="cx">         &lt;/p&gt;
</span></span></pre></div>
<a id="trunkgptemplatestranslationsetpermissionsphp"></a>
<div class="delfile"><h4>Deleted: trunk/gp-templates/translation-set-permissions.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/translation-set-permissions.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-templates/translation-set-permissions.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -1,41 +0,0 @@
</span><del>-&lt;?php
-gp_title( sprintf( __( 'Permissions &amp;lt; %s &amp;lt; %s &amp;lt; GlotPress' ), $translation_set-&gt;name, $project-&gt;name ) );
-gp_breadcrumb( array(
-        gp_link_project_get( $project, $project-&gt;name ),
-        $locale-&gt;english_name,
-        'default' != $translation_set-&gt;slug? $translation_set-&gt;name : '',
-        __('Permissions')
-) );
-gp_tmpl_header();
-?&gt;
-&lt;h2&gt;&lt;?php _e('Permissions'); ?&gt;&lt;/h2&gt;
-&lt;ul id=&quot;translation-set-permissions&quot;&gt;
-        &lt;?php foreach( $permissions as $permission ): ?&gt;
-                &lt;li&gt;
-                        &lt;span class=&quot;permission-action&quot;&gt;&lt;?php _e('user'); ?&gt;&lt;/span&gt;
-                        &lt;span class=&quot;user&quot;&gt;&lt;?php echo esc_html( $permission-&gt;user-&gt;user_login ); ?&gt;&lt;/span&gt;
-                        &lt;span class=&quot;permission-action&quot;&gt;can &lt;?php echo esc_html( $permission-&gt;action ); ?&gt;&lt;/span&gt;
-                        &lt;a href=&quot;&lt;?php echo gp_url_join( gp_url_current(), '_delete/'.$permission-&gt;id ); ?&gt;&quot; class=&quot;action delete&quot;&gt;&lt;?php _e('Remove'); ?&gt;&lt;/a&gt;
-                &lt;/li&gt;
-        &lt;? endforeach; ?&gt;
-
-        &lt;?php if ( !$permissions ): ?&gt;
-                &lt;strong&gt;&lt;?php _e('No validators defined for this translation set.'); ?&gt;&lt;/strong&gt;
-        &lt;?php endif; ?&gt;
-&lt;/ul&gt;
-
-&lt;form action=&quot;&quot; method=&quot;post&quot; class=&quot;secondary&quot;&gt;
-        &lt;h3&gt;&lt;?php _e('Add a validator for this translation set'); ?&gt;&lt;/h3&gt;
-        &lt;p&gt;
-                &lt;label for=&quot;user_login&quot;&gt;&lt;?php _e('Username:'); ?&gt;&lt;/label&gt;
-                &lt;input type=&quot;text&quot; name=&quot;user_login&quot; value=&quot;&quot; id=&quot;user_login&quot; /&gt;
-        &lt;/p&gt;
-        &lt;p&gt;
-                &lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;&lt;?php echo esc_attr(__('Add &amp;rarr;')); ?&gt;&quot; id=&quot;submit&quot; /&gt;
-        &lt;/p&gt;
-        
-        &lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;add-approver&quot; /&gt;
-&lt;/form&gt;
-&lt;?php
-echo gp_js_focus_on('user_login');
-gp_tmpl_footer();
</del><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkgptemplatestranslationsphp"></a>
<div class="modfile"><h4>Modified: trunk/gp-templates/translations.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/gp-templates/translations.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/gp-templates/translations.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -149,9 +149,6 @@
</span><span class="cx">                 if ( $can_approve ) {
</span><span class="cx">                         $footer_links[] = gp_link_get( gp_url_project( $project, array( $locale-&gt;slug, $translation_set-&gt;slug, 'import-translations' ) ), __('Import translations') );
</span><span class="cx">                 }
</span><del>-                if ( $can_write ) {
-                    $footer_links[] = gp_link_get( gp_url_project( $project, array( $locale-&gt;slug, $translation_set-&gt;slug, '_permissions' ) ), __('Permissions') );
-                }
</del><span class="cx">                 if ( GP::$user-&gt;logged_in() ) {
</span><span class="cx">                         $export_url = gp_url_project( $project, array( $locale-&gt;slug, $translation_set-&gt;slug, 'export-translations' ) );
</span><span class="cx">                         $export_link = gp_link_get( $export_url , __('Export'), array('id' =&gt; 'export', 'filters' =&gt; add_query_arg( array( 'filters' =&gt; $filters ), $export_url ) ) );
</span></span></pre></div>
<a id="trunkttest_permissionsphp"></a>
<div class="modfile"><h4>Modified: trunk/t/test_permissions.php (457 => 458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/t/test_permissions.php        2010-04-05 12:50:17 UTC (rev 457)
+++ trunk/t/test_permissions.php        2010-04-05 17:07:27 UTC (rev 458)
</span><span class="lines">@@ -35,8 +35,8 @@
</span><span class="cx">                 $this-&gt;assertFalse( (bool)$user-&gt;can( 'write', 'project', $other-&gt;id ) );
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        function test_recursive_project_locale_set_slug_permissions() {
-                $object_type = 'project|locale|set-slug';
</del><ins>+        function test_recursive_validator_permissions() {
+                $object_type = GP::$validator_permission-&gt;object_type;
</ins><span class="cx">                 $action = 'whetever';
</span><span class="cx">                 $user = GP::$user-&gt;create( array( 'user_login' =&gt; 'gugu', 'user_email' =&gt; 'gugu@gugu.net' ) );
</span><span class="cx">                 
</span><span class="lines">@@ -44,10 +44,12 @@
</span><span class="cx">                 $root = GP::$project-&gt;create( array( 'name' =&gt; 'Root', 'slug' =&gt; 'root', 'path' =&gt; 'root') );
</span><span class="cx">                 $sub = GP::$project-&gt;create( array( 'name' =&gt; 'Sub', 'slug' =&gt; 'sub', 'parent_project_id' =&gt; $root-&gt;id, 'path' =&gt; 'root/sub' ) );
</span><span class="cx">                 
</span><del>-                GP::$permission-&gt;create( array( 'user_id' =&gt; $user-&gt;id, 'action' =&gt; 'whatever',
-                        'object_type' =&gt; $object_type, 'object_id' =&gt; $root-&gt;id.'|bg|default' ) );
-                $this-&gt;assertTrue( (bool)$user-&gt;can( 'whatever', $object_type, $root-&gt;id.'|bg|default' ) );
-                $this-&gt;assertTrue( (bool)$user-&gt;can( 'whatever', $object_type, $sub-&gt;id.'|bg|default' ) );
</del><ins>+                GP::$validator_permission-&gt;create( array( 'user_id' =&gt; $user-&gt;id, 'action' =&gt; 'whatever',
+                        'project_id' =&gt; $root-&gt;id, 'locale_slug' =&gt; 'bg', 'set_slug' =&gt; 'default' ) );
+                        
+                $this-&gt;assertTrue( (bool)$user-&gt;can( 'whatever', $object_type, GP::$validator_permission-&gt;object_id( $root-&gt;id, 'bg', 'default' ) ) );
+                $this-&gt;assertTrue( (bool)$user-&gt;can( 'whatever', $object_type, GP::$validator_permission-&gt;object_id( $sub-&gt;id, 'bg', 'default' ) ) );
+                $this-&gt;assertTrue( (bool)$user-&gt;can( 'whatever', $object_type, GP::$validator_permission-&gt;object_id( $sub-&gt;id, 'bg', 'default' ) ) );
</ins><span class="cx">                 $this-&gt;assertFalse( (bool)$user-&gt;can( 'other', $object_type, $sub-&gt;id.'|bg|default' ) );
</span><span class="cx">                 $this-&gt;assertFalse( (bool)$user-&gt;can( 'whatever', $object_type, $sub-&gt;id.'|en|default' ) );
</span><span class="cx">                 $this-&gt;assertFalse( (bool)$user-&gt;can( 'whatever', $object_type, $sub-&gt;id.'|bg|slug' ) );
</span><span class="lines">@@ -61,8 +63,8 @@
</span><span class="cx">                 $root = GP::$project-&gt;create( array( 'name' =&gt; 'Root', 'slug' =&gt; 'root', 'path' =&gt; 'root') );
</span><span class="cx">                 $sub = GP::$project-&gt;create( array( 'name' =&gt; 'Sub', 'slug' =&gt; 'sub', 'parent_project_id' =&gt; $root-&gt;id, 'path' =&gt; 'root/sub' ) );
</span><span class="cx"> 
</span><del>-                GP::$permission-&gt;create( array( 'user_id' =&gt; $user-&gt;id, 'action' =&gt; 'approve',
-                        'object_type' =&gt; 'project|locale|set-slug', 'object_id' =&gt; $root-&gt;id.'|bg|default' ) );
</del><ins>+                GP::$validator_permission-&gt;create( array( 'user_id' =&gt; $user-&gt;id, 'action' =&gt; 'approve',
+                        'project_id' =&gt; $root-&gt;id, 'locale_slug' =&gt; 'bg', 'set_slug' =&gt; 'default' ) );
</ins><span class="cx">                 
</span><span class="cx">                 $set_root_bg = GP::$translation_set-&gt;create( array( 'name' =&gt; 'Set', 'slug' =&gt; 'default', 'project_id' =&gt; $root-&gt;id, 'locale' =&gt; 'bg') );
</span><span class="cx">                 $set_sub_bg = GP::$translation_set-&gt;create( array( 'name' =&gt; 'Set', 'slug' =&gt; 'default', 'project_id' =&gt; $sub-&gt;id, 'locale' =&gt; 'bg') );
</span></span></pre>
</div>
</div>

</body>
</html>