In google no more information about modules enabled and disabled so I am troubling here.
I have build some modules in yii2 like users, payments, subscriptions, news etc. I want to disabled subscriptions modules. Is it possible?
Edit: Enable and Disable function should allow for end user.
I would place the following code in the module class(es) that support being disabled/enabled.
So for every module (users, subscriptions, news, etc) you have module class somewhere that extends \yii\base\Module. Place code like this in every module class and check the appropriate setting.
public function init() {
if (!$this->_isModuleEnabled()) {
// This can also be another exception of course.
throw new \Exception("This module isn't enabled.");
}
parent::init();
}
private function _isModuleEnabled() {
/**
* Probably check some setting in the database or someting. Then
* return true or false depending on that setting.
*/
return true;
}
Related
I try to set permissions for my new module. Otherwise they seem to work, but the defaults are ignored, nothing is checked for role-permission pairs I've set in the code. My code (Permissions.cs) seems OK:
using System.Collections.Generic;
using Orchard.Environment.Extensions.Models;
using Orchard.Security.Permissions;
using Orchard.Environment.Extensions;
using My.Module.Utils;
namespace My.Module
{
public class Permissions : IPermissionProvider {
public static readonly Permission AccessMyModule = new Permission {
Description = Constants.AccessAddon, Name = "AccessMyModule"
};
public virtual Feature Feature { get; set; }
public IEnumerable<Permission> GetPermissions() {
return new[] {
AccessMyModule
};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = Constants.MyModuleAdministratorRole,
Permissions = new[] { AccessMyModule }
}
};
}
}
}
I double checked that all the constants stored in Constants and the references for them are valid. The code snippet here is simplified, in fact I have more permissions and more roles in my project, but I confirmed commenting out everything but one permission and one role doesn't fix the problem. The defaults for the other modules in the same solution work fine, though there's no bug reported by IntelliSense and everything else in the module seems to work. So where else could be the root of the problem?
EDIT: I followed #mdameer's comment and confirmed that GetDefaultStereotypes() really runs only after reinstall. However, an error occurred while enabling the module after reinstall, so the defaults were not loaded. I know that the supposed way is to check the role - permission name in the dashboard, but I would like to find another workaround, because
I would like to solve the error that occurred and not to risk it happenning on the production server as well, and I can't delete and reinstall this rather complex module several times just to debug this. It was likely caused by the reinstall process, nowhere in the permission initialization, but I can't know without running the code.
there are tens of roles affected, so relying on someone to click the permissions by hand each time means that there will likely be errors due to human factor.
The GetDefaultStereotypes() method is being called from class DefaultRoleUpdater in Orchard.Roles. It is called automatically from somewhere deep in the Orchard core, so simply mimicking the call and running it on startup isn't that easy. I also tried to mimic the whole function and placed it into my permissions class (or into a custom service), but now I got lost on how to run it. It is not static, but it either is part of or refers to my Permissions class, which doesn't allow for ordinary referencing by default (it has no proper constructor) and I don't want to mess it even more by changing the class to something it is not and shouldn't be.
Just set the default permissions you need in a migration instead of using GetDefaultStereotypes(). Here is a short example:
public class MyMigration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public MyMigration(Orchard.Roles.Services.IRoleService aRoleService)
{
mRoleService = aRoleService;
}
public int Create()
{
//mRoleService.CreateRole("MyRoleName");
//mRoleService.UpdateRole("MyRoleName", MyPermissions)
return 1;
}
// private
Orchard.Roles.Services.IRoleService aRoleService mRoleService;
}
I want to enable a specific module in a migration but the module is not enabled immediately.
The issue here seems to be the state of the module, it is set to Rising in table Orchard_Settings_ShellFeatureStateRecord. In this case I cannot enable the module manually in Admin anymore, I need to restart the web server after the migration has been executed to get the module to state Up.
The migration code looks like
public class Migration: Orchard.Data.Migration.DataMigrationImpl
{
// public
public Migration(Orchard.Environment.Features.IFeatureManager aFeatureManager)
{
mFeatureManager = aFeatureManager;
}
...
public int UpdateFrom1()
{
System.Collections.Generic.Dictionary<string, Orchard.Environment.Extensions.Models.FeatureDescriptor> lFeatures =
mFeatureManager.GetAvailableFeatures().ToDictionary(m => m.Id, m => m);
if (lFeatures.ContainsKey("Orchard.Taxonomies"))
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"}, true);
...
}
// private
private readonly Orchard.Environment.Features.IFeatureManager mFeatureManager;
}
I also tried using IModuleManager, did not work. Then I tried enabling another simple feature like Orchard.Alias.UI, did not work either.
Is this intended behavior or what might be wrong in the code?
If your feature has a dependency on taxonomies, enabling it will also enable taxonomies. You don't need to do anything else. That is, unless the dependency is something new that you're adding with the new version. In that case, I'd probably display a warning asking the user to enable it, and I'd make the code resilient to taxonomies not being enabled (which is a good idea no matter what)
Change this line:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"},true);
to this one:
mFeatureManager.EnableFeatures(new string[] {"Orchard.Taxonomies"});
Has anyone tried or found an example of a class derived from CModel that replicates CActiveRecord functionality with WebServices instead of database connection???
If done with RESTFULL WebServices it would be great. If data is transmitted JSON encoded, wonderful!!...
I'd appretiate your help. Thanks.
I spend a lot of time looking for that as well, I came across this Yii extension on Github:
https://github.com/Haensel/ActiveResource
It allows you to have exactly what you are looking for, the readme isn't updated with the changes reflected in changes.md, so I recommend you read through this document as well.
EActiveResource for Yii
...is an extension for the Yii PHP framework allowing the user to create models that use RESTful services as persistent storage.
The implementation is inspired by Yii's CActiveRecord class and the Ruby on Rails implementation of ActiveResource (http://api.rubyonrails.org/classes/ActiveResource/Base.html).
HINT:
CAUTION: THIS IS STILL AN ALPHA RELEASE!
This project started as a draft and is still under development, so as long is there is no 1.0 release you may experience changes that could break your code. Look at the CHANGES.md file for further information
As there are thousands of different REST services out there that use a thousand different approaches it can be tricky to debug errors. Because of that I added extensive
tracing to all major functions, so you should always be able to see every request, which method it used and how the service responded. Just enable the tracing functionality of Yii
and look for the category "ext.EActiveResource"
INSTALL:
Add the extension to Yii by placing it in your application's extension folder (for example '/protected/extensions')
Edit your applications main.php config file and add 'application.extensions.EActiveResource.*' to your import definitions
Add the configuration for your resources to the main config
'activeresource'=>array(
'class'=>'EActiveResourceConnection',
'site'=>'http://api.aRESTservice.com',
'contentType'=>'application/json',
'acceptType'=>'application/json',
)),
'queryCacheId'=>'SomeCacheComponent')
4.) Now create a class extending EActiveResource like this (don't forget the model() function!):
QUICK OVERVIEW:
class Person extends EActiveResource
{
/* The id that uniquely identifies a person. This attribute is not defined as a property
* because we don't want to send it back to the service like a name, surname or gender etc.
*/
public $id;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function rest()
{
return CMap::mergeArray(
parent::rest(),
array(
'resource'=>'people',
)
);
}
/* Let's define some properties and their datatypes
public function properties()
{
return array(
'name'=>array('type'=>'string'),
'surname'=>array('type'=>'string'),
'gender'=>array('type'=>'string'),
'age'=>array('type'=>'integer'),
'married'=>array('type'=>'boolean'),
'salary'=>array('type'=>'double'),
);
}
/* Define rules as usual */
public function rules()
{
return array(
array('name,surname,gender,age,married,salary','safe'),
array('age','numerical','integerOnly'=>true),
array('married','boolean'),
array('salary','numerical')
);
}
/* Add some custom labels for forms etc. */
public function attributeLabels()
{
return array(
'name'=>'First name',
'surname'=>'Last name',
'salary'=>'Your monthly salary',
);
}
}
Usage:
/* sends GET to http://api.example.com/person/1 and populates a single Person model*/
$person=Person::model()->findById(1);
/* sends GET to http://api.example.com/person and populates Person models with the response */
$persons=Person::model()->findAll();
/* create a resource
$person=new Person;
$person->name='A name';
$person->age=21;
$person->save(); //New resource, send POST request. Returns false if the model doesn't validate
/* Updating a resource (sending a PUT request)
$person=Person::model()->findById(1);
$person->name='Another name';
$person->save(); //Not at new resource, update it. Returns false if the model doesn't validate
//or short version
Person::model()->updateById(1,array('name'=>'Another name'));
/* DELETE a resource
$person=Person::model()->findById(1);
$person->destroy(); //DELETE to http://api.example.com/person/1
//or short version
Person::model()->deleteById(1);
Hope this helps you
I want to create custom user checker to validate login action against last accepted eula.
'
Idea is quite simple, there will be many versions of eula and user can't login untill he accept the lastest eula.
Scenario is:
User creates new account and accepts eula.
Eula gets updated
User tries to login, but he didnt accept lastest eula
User gets the same login form but with additional field "accept newest eula"
User logs in and system inserts information: Current date and time, User id, Eula id to keep track of eula acceptance.
I found this:
https://groups.google.com/forum/#!msg/symfony2/D0V0bFks9S0/Qg9mrbpfB3IJ
But unfortunately there is no full version of custom user checker. How do I implement the rest of it?
The answer is actually quite obvious.
In your custom bundle:
config.yml
parameters:
security.user_checker.class: Acme\Bundle\UserBundle\Security\UserChecker
Userchecker:
class UserChecker extends BaseUserChecker
{
/**
* {#inheritdoc}
*/
public function checkPreAuth(UserInterface $user)
{
//do your custom preauth stuff here
parent::checkPreAuth($user);
}
}
You can redefine Symfony's user checker service (security.user_checker) in your bundle:
# services.yml
security.user_checker:
class: MyBundle\Checker\UserChecker
arguments: [ "#some.service", "%some.param%" ]
Then extend Symfony's UserChecker:
# UserChecker.php
use Symfony\Component\Security\Core\User\UserChecker as BaseUserChecker;
class UserChecker extends BaseUserChecker
{
public function checkPreAuth(UserInterface $user)
{
parent::checkPreAuth($user);
// your stuff
}
public function checkPostAuth(UserInterface $user)
{
parent::checkPostAuth($user);
// your stuff
}
}
The security.user_checker service gets called in \Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider::authenticate() during the authentication process
Why not attach event listener to the kernel.request event and watch if the current logged user has accepted the latest EULA?
To get the current user you can use something like this:
$securityContext = $this->container->get('security.context');
if (!$securityContext) {
return;
}
$user = $securityContext->getToken()->getUser();
I have an Eclipse plug-in with a checkbox in the plug-in's preference page.
This checkbox is used for enabling and disabling an editor, which is being launched from this plug-in.
However, the problem is, I would also like to be able to enable and disable this 'editor-launch' from another plug-in, by having actions which change the value of the checkbox in the above mentioned preference page.
Here's the problem, how do I access that local preference store from another plug-in?
I've tried things like..
View myView = (View) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("ViewID");
But this 'myView' always seems to be null.. And also, what would I do with the view since it's the Plug-in I want.
Platform.getBundle('bundleName')...
Same here, want the Plugin, not the bundle corresponding to is.
No matter what I try nothing seems to work.
Does anyone have any ideas?
There are two ways of doing this:
Please refer to http://www.vogella.com/tutorials/EclipsePreferences/article.html#preferences_pluginaccess
Using .getPluginPreferences(). For example, there is a plugin class "com.xxx.TestPlugin" which extends org.eclipse.ui.plugin.AbstractUIPlugin.Plugin, in order to get access to the preferences of TestPlugin. The plugin code could be below:
public class TestPlugin extends AbstractUIPlugin {
private static TestPlugin plugin;
public static final String PREF_TEST = "test_preference";
/**
* The constructor.
*/
public TestPlugin() {
plugin = this;
}
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
}
/**
* Returns the shared instance.
*/
public static TestPlugin getDefault() {
return plugin;
}
}
To access the preference of TestPlugin, the code could be:
TestPlugin.getDefault().getPluginPreferences().getDefaultBoolean(TestPlugin.PREF_TEST);
Or have a look at this answer: Writing Eclipse plugin to modify Editor Preferences
This thread recommend the use of a Service tracker:
ServiceTracker tracker = new ServiceTracker(ToolkitPlugin.getDefault().getBundle().getBundleContext(),
IProxyService.class.getName(), null);
tracker.open();
proxyService = (IProxyService) tracker.getService();
proxyService.addProxyChangeListener(this);
This may work.
Prefs stores are found per plugin. This is one way to get a prefs store for the plugin whose activator class is ActivatorA.
IPreferenceStore store = ActivatorA.getDefault().getPreferenceStore();
If you want another plugin to refer to the same store, perhaps you could expose some api on ActivatorA for it to get there, e.g.
public IPreferenceStore getSharedPrefs() {
return ActivatorA.getDefault().getPreferenceStore();
}
The second plugin would find the shared store by doing this
IPreferenceStore sharedPrefs = ActivatorA.getSharedPrefs();
Good luck.