I'm trying to extend Member class and add a number of fields to it. At the same time I am making this DataObject behave as a page so that I can go to www.mysite.com/member/show/1 and see that user's profile. I have not yet gotten to the point of created member page. Right now I have all the fields working with the exception to ImageField. I get the following error:
PHP Fatal error: Class 'ImageField' not found in ../mysite/code/Secure/Objects/MemberDecorator.php on line 66
The code is:
<?php
class MemberDecorator extends DataExtension {
private static $db = array(
"Alias" => 'Varchar',
"About" => 'Text',
"Birthday" => 'Date',
"FavoriteGames" => 'Varchar',
"Facebook" => 'Varchar',
"Twitter" => 'Varchar',
"Instagram" => 'Varchar',
"Twitch" => 'Varchar',
"Youtube" => 'Varchar',
"SecretQuestionOne" => "Varchar",
"SecretAnswerOne" => "Varchar",
"SecretQuestionTwo" => "Varchar",
"SecretAnswerTwo" => "Varchar",
"SecretQuestionThree" => "Varchar",
"SecretAnswerThree" => "Varchar"
);
private static $has_one = array(
'Photo' => 'Image'
);
//Fields to show in the DOM table
static $summary_fields = array(
'Thumb' => 'Photo',
"Alias" => 'Alias',
"About" => 'About',
"Birthday" => 'Birthday',
"FavoriteGames" => 'FavoriteGames',
"Facebook" => 'Facebook',
"Twitter" => 'Twitter',
"Instagram" => 'Instagram',
"Twitch" => 'Twitch',
"Youtube" => 'Youtube',
"SecretQuestionOne" => "SecretQuestionOne",
"SecretAnswerOne" => "SecretAnswerOne",
"SecretQuestionTwo" => "SecretQuestionTwo",
"SecretAnswerTwo" => "SecretAnswerTwo",
"SecretQuestionThree" => "SecretQuestionThree",
"SecretAnswerThree" => "SecretAnswerThree"
);
function getCMSFields() {
$fields = parent::getCMSFields();
$this->extend('updateCMSFields', $fields);
return $fields;
}
function updateCMSFields(FieldList $fields) {
$fields->push(new TextField("Alias", "Alias"), 'Members');
$fields->push(new TextAreaField("About", "About"), 'Members');
$fields->push(new DateField("Birthday", "Birthday"), 'Members');
$fields->push(new TextField("FavoriteGames", "Favorite Games"), 'Members');
$fields->push(new TextField("Facebook", "Facebook"), 'Members');
$fields->push(new TextField("Twitter", "Twitter"), 'Members');
$fields->push(new TextField("Instagram", "Instagram"), 'Members');
$fields->push(new TextField("Twitch", "Twitch"), 'Members');
$fields->push(new TextField("Youtube", "Youtube"), 'Members');
$fields->push(new TextField("SecretQuestionOne", "Secret Question One"), 'Members');
$fields->push(new TextField("SecretAnswerOne", "Secret Answer One"), 'Members');
$fields->push(new TextField("SecretQuestionTwo", "Secret Question Two"), 'Members');
$fields->push(new TextField("SecretAnswerTwo", "Secret Answer Two"), 'Members');
$fields->push(new TextField("SecretQuestionThree", "Secret Question Three"), 'Members');
$fields->push(new TextField("SecretAnswerThree", "Secret Answer Three"), 'Members');
$fields->push(new ImageField('Photo', 'Photo', Null, Null, Null, 'Uploads/member-photos/'), 'Members');
}
function Link() {
return Director::absoluteBaseURL() . SSViewer::topLevel()->URLSegment . "/member/" . $this->ID;
}
//Generate our thumbnail for the DOM
public function getThumb()
{
if($this->PhotoID)
return $this->Photo()->CMSThumbnail();
else
return '(No Image)';
}
}
According to every example out there I found and documentation, ImageField seems to be a valid field. Last bit of detail is that I am following this guide: http://www.ssbits.com/tutorials/2010/dataobjects-as-pages-part-1-keeping-it-simple/
SilverStripe 3 uses UploadField
http://api.silverstripe.org/3.1/class-UploadField.html
Related
I want to export the "manage customers" grid, and also want to add the ip addresses of the customers at the end of the grid.
this is the code that is executed when the grid is loaded
protected function _prepareCollection()
{
$collection = Mage::getResourceModel('customer/customer_collection')
->addNameToSelect()
->addAttributeToSelect('email')
->addAttributeToSelect('created_at')
->addAttributeToSelect('group_id')
->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left');
$this->setCollection($collection);
return parent::_prepareCollection();
}
i have also added a column
$this->addColumn('ip_address', array(
'header' => Mage::helper('customer')->__('IP Address'),
'default' => Mage::helper('customer')->__('n/a'),
'index' => 'remote_addr',
'renderer' => 'adminhtml/customer_online_grid_renderer_ip',
'filter' => false,
'sort' => false
));
but i dont get any data.
How can i get the customers ip address in the added column
To add ip addresses of the customers at the end of the grid :-
We've to create a custom module :-
I'm taking namespace as Wakar & Modulename as Customeripaddress :-
1-
app/etc/modules/Wakar_Customeripaddress.xml
So first of all we've to register this module :-
<?xml version="1.0"?>
<config>
<modules>
<Wakar_Customeripaddress>
<active>true</active>
<codePool>local</codePool>
<version>0.1.0</version>
</Wakar_Customeripaddress>
</modules>
</config>
2- app/code/local/Wakar/Customeripaddress/etc/config.xml :-
In this file we're defining module configuration(Block override,controller override etc).
<?xml version="1.0"?>
<config>
<modules>
<Wakar_Customeripaddress>
<version>0.1.0</version>
</Wakar_Customeripaddress>
</modules>
<frontend>
<routers>
<customeripaddress>
<use>standard</use>
<args>
<module>Wakar_Customeripaddress</module>
<frontName>customeripaddress</frontName>
</args>
</customeripaddress>
</routers>
</frontend>
<global>
<rewrite>
<wakar_customeripaddress_customer_accountcontroller>
<from><![CDATA[#^/customer/account/#]]></from> <!-- Mage_Customer_AccountController -->
<to>/customeripaddress/customer_account/</to> <!-- Wakar_Customeripaddress_Customer_AccountController -->
</wakar_customeripaddress_customer_accountcontroller>
</rewrite>
<helpers>
<customeripaddress>
<class>Wakar_Customeripaddress_Helper</class>
</customeripaddress>
</helpers>
<blocks>
<customeripaddress>
<class>Wakar_Customeripaddress_Block</class>
</customeripaddress>
<adminhtml>
<rewrite>
<customer_grid>Wakar_Customeripaddress_Block_Adminhtml_Customer_Grid</customer_grid>
</rewrite>
</adminhtml>
</blocks>
<models>
<customeripaddress>
<class>Wakar_Customeripaddress_Model</class>
<resourceModel>customeripaddress_mysql4</resourceModel>
</customeripaddress>
</models>
<resources>
<customerattribute1523689716_setup>
<setup>
<module>Wakar_Customeripaddress</module>
<class>Mage_Customer_Model_Entity_Setup</class>
</setup>
<connection>
<use>core_setup</use>
</connection>
</customerattribute1523689716_setup>
<customerattribute1523689716_write>
<connection>
<use>core_write</use>
</connection>
</customerattribute1523689716_write>
<customerattribute1523689716_read>
<connection>
<use>core_read</use>
</connection>
</customerattribute1523689716_read>
</resources>
</global>
<admin>
<routers>
<customeripaddress>
<use>admin</use>
<args>
<module>Wakar_Customeripaddress</module>
<frontName>admin_customeripaddress</frontName>
</args>
</customeripaddress>
</routers>
</admin>
</config>
3-app/code/local/Wakar/Customeripaddress/sql/customerattribute1523689716_setup/mysql4-install-0.1.0.php
Now we're going to create a customer custom column & during customer registration we'll use this column to save visitor ip address & later we'll fetch this ip address to show customer ip address via renderer.
<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute("customer", "customer_ip_address", array(
"type" => "varchar",
"backend" => "",
"label" => "IP Address",
"input" => "text",
"source" => "",
"visible" => true,
"required" => false,
"default" => "",
"frontend" => "",
"unique" => false,
"note" => "Customer Ip Address"
));
$attribute = Mage::getSingleton("eav/config")->getAttribute("customer", "customer_ip_address");
$used_in_forms=array();
$used_in_forms[]="adminhtml_customer";
$used_in_forms[]="checkout_register";
$used_in_forms[]="customer_account_create";
$used_in_forms[]="customer_account_edit";
$used_in_forms[]="adminhtml_checkout";
$attribute->setData("used_in_forms", $used_in_forms)
->setData("is_used_for_customer_segment", true)
->setData("is_system", 0)
->setData("is_user_defined", 1)
->setData("is_visible", 1)
->setData("sort_order", 100)
;
$attribute->save();
$installer->endSetup();
4-
app/code/local/Wakar/Customeripaddress/controllers/Customer/AccountController.php :-
Save Customer Ip address during registration:-
<?php
require_once "Mage/Customer/controllers/AccountController.php";
class Wakar_Customercontrolleroverride_Customer_AccountController extends Mage_Customer_AccountController{
public function postDispatch()
{
parent::postDispatch();
Mage::dispatchEvent('controller_action_postdispatch_adminhtml', array('controller_action' => $this));
}
public function createPostAction()
{
$errUrl = $this->_getUrl('*/*/create', array('_secure' => true));
if (!$this->_validateFormKey()) {
$this->_redirectError($errUrl);
return;
}
/** #var $session Mage_Customer_Model_Session */
$session = $this->_getSession();
if ($session->isLoggedIn()) {
$this->_redirect('*/*/');
return;
}
if (!$this->getRequest()->isPost()) {
$this->_redirectError($errUrl);
return;
}
$customer = $this->_getCustomer();
try {
$errors = $this->_getCustomerErrors($customer);
// Get Visitor Ip address
if (empty($errors)) {
if (!empty($_SERVER["HTTP_CLIENT_IP"]))
{
//check for ip from share internet
$ip = $_SERVER["HTTP_CLIENT_IP"];
}
elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
{
// Check for the Proxy User
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else
{
$ip = $_SERVER["REMOTE_ADDR"];
}
$customer['customer_ip_address']=$ip;
$customer->cleanPasswordsValidationData();
$customer->save();
$this->_dispatchRegisterSuccess($customer);
$this->_successProcessRegistration($customer);
return;
} else {
$this->_addSessionError($errors);
}
} catch (Mage_Core_Exception $e) {
$session->setCustomerFormData($this->getRequest()->getPost());
if ($e->getCode() === Mage_Customer_Model_Customer::EXCEPTION_EMAIL_EXISTS) {
$url = $this->_getUrl('customer/account/forgotpassword');
$message = $this->__('There is already an account with this email address. If you are sure that it is your email address, click here to get your password and access your account.', $url);
} else {
$message = $this->_escapeHtml($e->getMessage());
}
$session->addError($message);
} catch (Exception $e) {
$session->setCustomerFormData($this->getRequest()->getPost());
$session->addException($e, $this->__('Cannot save the customer.'));
}
$this->_redirectError($errUrl);
}
}
5-
app/code/local/Wakar/Customeripaddress/Block/Adminhtml/Customer/Grid.php :-
Add Ip address in customer grid:-
<?php
class Wakar_Customeripaddress_Block_Adminhtml_Customer_Grid extends Mage_Adminhtml_Block_Customer_Grid
{
protected function _prepareCollection()
{
$collection = Mage::getResourceModel('customer/customer_collection')
->addNameToSelect()
->addAttributeToSelect('email')
->addAttributeToSelect('created_at')
->addAttributeToSelect('group_id')
->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left');
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _prepareColumns()
{
$this->addColumn('entity_id', array(
'header' => Mage::helper('customer')->__('ID'),
'width' => '50px',
'index' => 'entity_id',
'type' => 'number',
));
/*$this->addColumn('firstname', array(
'header' => Mage::helper('customer')->__('First Name'),
'index' => 'firstname'
));
$this->addColumn('lastname', array(
'header' => Mage::helper('customer')->__('Last Name'),
'index' => 'lastname'
));*/
$this->addColumn('name', array(
'header' => Mage::helper('customer')->__('Name'),
'index' => 'name'
));
$this->addColumn('email', array(
'header' => Mage::helper('customer')->__('Email'),
'width' => '150',
'index' => 'email'
));
$groups = Mage::getResourceModel('customer/group_collection')
->addFieldToFilter('customer_group_id', array('gt'=> 0))
->load()
->toOptionHash();
$this->addColumn('group', array(
'header' => Mage::helper('customer')->__('Group'),
'width' => '100',
'index' => 'group_id',
'type' => 'options',
'options' => $groups,
));
$this->addColumn('Telephone', array(
'header' => Mage::helper('customer')->__('Telephone'),
'width' => '100',
'index' => 'billing_telephone'
));
$this->addColumn('billing_postcode', array(
'header' => Mage::helper('customer')->__('ZIP'),
'width' => '90',
'index' => 'billing_postcode',
));
$this->addColumn('billing_country_id', array(
'header' => Mage::helper('customer')->__('Country'),
'width' => '100',
'type' => 'country',
'index' => 'billing_country_id',
));
$this->addColumn('billing_region', array(
'header' => Mage::helper('customer')->__('State/Province'),
'width' => '100',
'index' => 'billing_region',
));
$this->addColumn('customer_since', array(
'header' => Mage::helper('customer')->__('Customer Since'),
'type' => 'datetime',
'align' => 'center',
'index' => 'created_at',
'gmtoffset' => true
));
if (!Mage::app()->isSingleStoreMode()) {
$this->addColumn('website_id', array(
'header' => Mage::helper('customer')->__('Website'),
'align' => 'center',
'width' => '80px',
'type' => 'options',
'options' => Mage::getSingleton('adminhtml/system_store')->getWebsiteOptionHash(true),
'index' => 'website_id',
));
}
$this->addColumn('ip_address', array(
'header' => Mage::helper('customer')->__('IP Address'),
'default' => Mage::helper('customer')->__('N/A'),
'index' => 'remote_addr',
'renderer' => 'customeripaddress/adminhtml_renderer_location',
'filter' => false,
'sort' => false
));
$this->addColumn('action',
array(
'header' => Mage::helper('customer')->__('Action'),
'width' => '100',
'type' => 'action',
'getter' => 'getId',
'actions' => array(
array(
'caption' => Mage::helper('customer')->__('Edit'),
'url' => array('base'=> '*/*/edit'),
'field' => 'id'
)
),
'filter' => false,
'sortable' => false,
'index' => 'stores',
'is_system' => true,
));
$this->addExportType('*/*/exportCsv', Mage::helper('customer')->__('CSV'));
$this->addExportType('*/*/exportXml', Mage::helper('customer')->__('Excel XML'));
return parent::_prepareColumns();
}
}
6-
app/code/local/Wakar/Customeripaddress/Block/Adminhtml/Renderer/Location.php
Using renderer to show ip address in the customer grid:-
<?php
class Wakar_Customeripaddress_Block_Adminhtml_Renderer_Location extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
// Instance of customer loaded by the given ID
$customer = Mage::getModel('customer/customer')->load($row->getData('entity_id'));
return $customer['customer_ip_address'] ;
}
}
Hope this will resolve your problem...!!!
I was wondering if it's possible to send batched requests to maps.googleapis.com. As far as I can tell, it isn't.
I was using the Google API Client Library with supports batching, but it's only for www.googleapis.com. I went ahead and hacked it so that I could call the Places API, and it worked fine for normal calls, but when I actually tried to batch them, I got a 404 error:
"The requested URL /batch was not found on this server. That’s all we know."
So it appears that maps.googleapis.com does not support batching, but I wanted to be sure this is true. If anyone knows otherwise, please tell me how. Thanks!
inside google-api-php-client/src/Google/Config.php:
- 'base_path' => 'https://www.googleapis.com',
+ 'base_path' => 'https://maps.googleapis.com',
google-api-php-client/src/Google/Service/Maps.php:
(I added this file to make Places calls possible.)
<?php
class Google_Service_Maps extends Google_Service
{
const MAPS = "https://maps.googleapis.com/auth/maps";
public function __construct(Google_Client $client)
{
parent::__construct($client);
$this->servicePath = 'maps/api/';
$this->version = 'v3';
$this->serviceName = 'maps';
$this->places = new Google_Service_Maps_Places_Resource(
$this,
$this->serviceName,
'places',
array(
'methods' => array(
'autocomplete' => array(
'path' => 'place/autocomplete/json',
'httpMethod' => 'GET',
'parameters' => array(
'input' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'sensor' => array(
'location' => 'query',
'type' => 'boolean',
'required' => true,
),
'location' => array(
'location' => 'query',
'type' => 'string',
),
'radius' => array(
'location' => 'query',
'type' => 'integer',
),
),
),
)
)
);
}
}
class Google_Service_Maps_Places_Resource extends Google_Service_Resource
{
public function autocomplete($input, $lat, $lng, $radius, $optParams = array())
{
$params = array('input' => $input, 'location' => "$lat,$lng", 'radius' => $radius, 'sensor' => false);
$params = array_merge($params, $optParams);
return $this->call('autocomplete', array($params));
}
}
API batch calling code:
<?php
const API_KEY = 'MY_API_KEY';
set_include_path("google-api-php-client/src/" . PATH_SEPARATOR . get_include_path());
require_once 'Google/Client.php';
require_once 'Google/Service/Maps.php';
require_once 'Google/Http/Batch.php';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey(API_KEY);
$client->setUseBatch(true);
$batch = new Google_Http_Batch($client);
$service = new Google_Service_Maps($client);
$inputs = array(
'Dolore',
'MacAl',
'App Aca'
);
foreach($inputs as $input) {
$req = $service->places->autocomplete($input, 37.7833, -122.4167, 500);
$batch->add($req, $input);
}
$results = $batch->execute();
print_r($results);
print_r($req);
I am working on a Drupal module that provides a jvectormap node type.
Everything works fine except the drupal .load(). I use
jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code +'?ajax=1');
The following happens i click a country on the map and this calls /content/institutes/BE
/content/institutes is an views page with a contextual filter witch grabs the last part of the url and displays some data.
The jvectormap node is included on this same page trough a mini-panel and blocks (the view resides in div #content and the jvectormap in a mini-panel block)
Up to this point everything is ok. Now when i click a second region the URL suddenly switches to /content/undefined.
Let me clarify with an example: I click on Belgium the URL changes to /content/institutes/BE and the view picks this up, then I click France and the URL changes to /content/undefined but the view still reacts correctly and shows the France info. Now I hit F5 to refresh the browser and drupal says that /content/undefined does not exist. If I hit F5 after the first click (Belgium) it reloads the page correctly. The problem seems to happen with consecutive ajax requests. I coud fix this with an url alias so this would handle the F5 refresh edge case seeing everything else works correctly, but if some one else needs more than one node they have a (small) problem.
I suspect the .load is the reason why this is happening.
Any help is welcome thanks.
jvectormapnode.js
(function ($)
{
Drupal.behaviors.jvectormapnode =
{
attach: function (context, settings)
{
$('#jvectormapnode').once('jvectormapnode', function() { //fix duplicating behavior when using ajax
highlighted=JSON.parse(Drupal.settings.jvectormapnode.coloredregions);
//console.log(Drupal.settings.jvectormapnode.coloredregions);
//console.log(highlighted);
//change color of clicked region ==> todo
/*
currentSelected = '';
defaultColor = '#00FF00';
selectedColor = '#FF00FF';
maphandle = $('#map-teste');
maphandle.vectorMap({
map: 'br_en',
onRegionClick: function(event, code){
if(currentSelected !== code) {
if(currentSelected !== ''){
// Deselect, then select new choice
maphandle.vectorMap('set', 'colors', currentSelected, defaultColor);
maphandle.vectorMap('set', 'colors', code, selectedColor);
currentSelected = code;
} else {
// Nothing currently selected, go ahead and select
maphandle.vectorMap('set', 'colors', code, selectedColor);
currentSelected = code;
}
} else {
// Deselect
maphandle.vectorMap('set', 'colors', code, defaultColor);
currentSelected = '';
}
alert(code); // return the state
}
});*/
$('#jvectormapnode').vectorMap({
map: 'world_mill_en',
focusOn: {
x: Drupal.settings.jvectormapnode.x,
y: Drupal.settings.jvectormapnode.y,
scale: Drupal.settings.jvectormapnode.scale
},
color: '#aaaaaa',
hoverColor: false,
hoverOpacity: 0.5,
backgroundColor: 'false',
onRegionClick: function (event, code) {
//if(typeof(afunctiontodo!='undefined') afunctiontodo();
//else
//{
//window.location = Drupal.settings.jvectormapnode.url+'/'+ code;
jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code +'?ajax=1');
//$('#jvectormapnode').vectorMap('set', 'focus', code);
//showSelectedCountry;
//}
},
series: {
regions: [{
values: highlighted ,
attribute: 'fill'
}]
}
});
});
}
};
}(jQuery));
jvectormapnode.module
<?php
/**
* #file
*/
/**
* #defgroup jvectormapnode : Node
* #ingroup jvectormapnode
* #{
* 20130812 pieterm
* Integrates jvectormapnode into Drupal through the node type system
*/
/**
* Implements hook_libraries_info().
*/
function jvectormapnode_libraries_info() {
$libraries['jvectormap'] = array(
'name' => 'jVectorMap',
'vendor url' => 'http://jvectormap.com/',
'download url' => 'http://jvectormap.com/download/',
'version arguments' => array(
'file' => 'jquery.jvectormap.min.js',
'pattern' => '#jVectorMap version ([0-9\.]+)#',
'lines' => 2,
'cols' => 30,
),
'versions' => array(
'1.2.2' => array(
'files' => array(
'js' => array('jquery.jvectormap.min.js'),
'css' => array('jquery.jvectormap.css'),
),
),
),
);
return $libraries;
}
/**
* Implements hook_view().
*/
function jvectormapnode_view($node, $view_mode) {
$node->content['jvectormapnodebody'] = array(
'#markup' => _jvectormapnode_page($node),
'#weight' => 1,
);
return $node;
}
/**
* Implements hook_theme().
* Overriding the default node template for jvectormapnode pages
*/
function jvectormapnode_theme($existing, $type, $theme, $path) {
$items = array(
'node__jvectormapnode' => array(
// Don't specify the path in the template name.
// Unless you have your template inside a directory within this module.
'template' => 'templates/node--jvectormapnode',
'variables' => array('node' => (object)array()),
// If you want to put the tpl in another location, you can use this key.
//'theme path' => drupal_get_path('module', 'another_module'),
),
);
return $items;
}
/**
* Implements hook_node_info().
*
* We use hook_node_info() to define our node content type.
*/
function jvectormapnode_node_info() {
// We define the node type as an associative array.
return array(
'jvectormapnode' => array(
'name' => t('jvectormapnode'),
'base' => 'jvectormapnode', //function prefix hooks
'description' => t('This is the jvectormapnode node type. It can display interactive maps.'),
'title_label' => t('jvectormapnode page title'),
'locked' => FALSE, //TODO SET TRUE
),
);
}
/**
* Implements hook_node_type_insert().
* lets us know that a new content type has been inserted.
* this gives us a chance to add the fields we want. (called for all node isnert!==>check type)
*/
function jvectormapnode_node_type_insert($content_type) {
if ($content_type->type == 'jvectormapnode') {
// Add default body field
$body_instance = node_add_body_field($content_type, t('Information you want to show on each page before the content of the jvectormapnode module'));
$body_instance['display']['example_node_list'] = array(
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
);
// Save our changes to the body field instance.
field_update_instance($body_instance);
// Create all the fields we are adding to our content type.
foreach (_jvectormapnode_installed_fields() as $field) {
field_create_field($field);
}
// Create all the instances for our fields.
foreach (_jvectormapnode_installed_instances() as $instance) {
$instance['entity_type'] = 'node';
$instance['bundle'] = 'jvectormapnode';
field_create_instance($instance);
}
}
}
/**
* Define the fields for our content type.
*
* This big array is factored into this function for readability.
*
* #return
* An associative array specifying the fields we wish to add to our
* new node type.
*/
function _jvectormapnode_installed_fields() {
return array(
'jvectormapnode_field_color' => array(
'field_name' => 'jvectormapnode_field_color',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_url' => array(
'field_name' => 'jvectormapnode_field_url',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_width' => array(
'field_name' => 'jvectormapnode_field_width',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_height' => array(
'field_name' => 'jvectormapnode_field_height',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_regions' => array(
'field_name' => 'jvectormapnode_field_regions',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_scale' => array(
'field_name' => 'jvectormapnode_field_scale',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_x' => array(
'field_name' => 'jvectormapnode_field_x',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_y' => array(
'field_name' => 'jvectormapnode_field_y',
'cardinality' => 1,
'type' => 'text',
),
);
}
/**
* Define the field instances for our content type.
*
* The instance lets Drupal know which widget to use to allow the user to enter
* data and how to react in different view modes.
*
* This big array is factored into this function for readability.
*
* #return
* An associative array specifying the instances we wish to add to our new
* node type.
*/
function _jvectormapnode_installed_instances() {
return array(
'jvectormapnode_field_url' => array(
'field_name' => 'jvectormapnode_field_url',
'label' => t('URL, format http://www.vliz.be/en/...'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_width' => array(
'field_name' => 'jvectormapnode_field_width',
'label' => t('Map width, format px or %'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_height' => array(
'field_name' => 'jvectormapnode_field_height',
'label' => t('Map height, format px or %'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_regions' => array(
'field_name' => 'jvectormapnode_field_regions',
'label' => t('Regions to be highlighted'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_color' => array(
'field_name' => 'jvectormapnode_field_color',
'label' => t('Highlight color, HEX format #ffffff.'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_scale' => array(
'field_name' => 'jvectormapnode_field_scale',
'label' => t('Initial zoom, nummeric format.'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_x' => array(
'field_name' => 'jvectormapnode_field_x',
'label' => t('Initial x-axis focus, nummeric format.'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_y' => array(
'field_name' => 'jvectormapnode_field_y',
'label' => t('Initial y-axis focus, nummeric format.'),
'widget' => array(
'type' => 'text_textfield',
),
),
);
}
/**
* Implements hook_entity_info_alter().
*
* We need to modify the default node entity info by adding a new view mode to
* be used in functions like node_view() or node_build_content().
*/
function jvectormapnode_entity_info_alter(&$entity_info) {
// Add our new view mode to the list of view modes...
$entity_info['node']['view modes']['example_node_list'] = array(
'label' => t('Example Node List'),
'custom settings' => TRUE,
);
}
/**
* Implement hook_form().
*
* Drupal needs for us to provide a form that lets the user
* add content. This is the form that the user will see if
* they go to node/add/node-example.
*/
function jvectormapnode_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_field_formatter_info().
*/
function jvectormapnode_field_formatter_info() {
return array(
'jvectormapnode_field_color' => array(
'label' => t('jvectormapnode color Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_url' => array(
'label' => t('jvectormapnode url Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_width' => array(
'label' => t('jvectormapnode width Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_height' => array(
'label' => t('jvectormapnode height Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_regions' => array(
'label' => t('jvectormapnode regions Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_scale' => array(
'label' => t('jvectormapnode scale Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_x' => array(
'label' => t('jvectormapnode x Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_y' => array(
'label' => t('jvectormapnode y Handle'),
'field types' => array('text'),
),
);
}
/**
* Implements hook_help().
*/
function jvectormapnode_help($path, $arg) {
switch ($path) {
case 'examples/jvectormapnode':
return "<p>" . t("The Node Example module provides a custom node type.
You can create new Example Node nodes using the <a href='!nodeadd'>node add form</a>.",
array('!nodeadd' => url('node/add/node-example'))) . "</p>";
}
}
/**
* Page callback to show jvectormapnode
*/
function _jvectormapnode_page($n) {
//get params from drupal entity created by user in add content
$dcolor= field_get_items('node', $n, 'jvectormapnode_field_color');
$dcolor=render(field_view_value('node', $n, 'jvectormapnode_field_color',$dcolor[0]));
$durl= field_get_items('node', $n, 'jvectormapnode_field_url');
$durl=render(field_view_value('node', $n, 'jvectormapnode_field_url',$durl[0]));
$dwidth= field_get_items('node', $n, 'jvectormapnode_field_width');
$dwidth=render(field_view_value('node', $n, 'jvectormapnode_field_width',$dwidth[0]));
$dheight= field_get_items('node', $n, 'jvectormapnode_field_height');
$dheight=render(field_view_value('node', $n, 'jvectormapnode_field_height',$dheight[0]));
$dregions= field_get_items('node', $n, 'jvectormapnode_field_regions');
$dregions=render(field_view_value('node', $n, 'jvectormapnode_field_regions',$dregions[0]));
$dscale= field_get_items('node', $n, 'jvectormapnode_field_scale');
$dscale=render(field_view_value('node', $n, 'jvectormapnode_field_scale',$dscale[0]));
$dx= field_get_items('node', $n, 'jvectormapnode_field_x');
$dx=render(field_view_value('node', $n, 'jvectormapnode_field_x',$dx[0]));
$dy= field_get_items('node', $n, 'jvectormapnode_field_y');
$dy=render(field_view_value('node', $n, 'jvectormapnode_field_y',$dy[0]));
//$coloredregions=array();
$exploderegions = explode(",", $dregions);
$coloredregions=array();
foreach ($exploderegions as $region)
{
$coloredregions[$region] = $dcolor ;
}
$coloredregions_object = json_encode($coloredregions);
$jvectormapnodebody.= '<div style="width: '.$dwidth.'; height: '.$dheight.'" id="jvectormapnode"></div>';
libraries_load('jvectormap');
drupal_add_js('/sites/all/modules/vliz/jvectormapnode/js/maps/jquery-jvectormap-world-mill-en.js');
drupal_add_js(array('jvectormapnode' => array('url' => $durl,'coloredregions'=> $coloredregions_object,'scale' => $dscale,'x' => $dx,'y' => $dy)), 'setting');
drupal_add_js('/sites/all/modules/vliz/jvectormapnode/js/jvectormapnode.js');
return $jvectormapnodebody;
}
/**
* #} End of "defgroup jvectormapnode".
*/
It seems that the code argument passed within the onRegionClick callback is undefined.
Can you do a console.log() of that argument to know the exact value? Normally this should be the region code as a string. (i.e.: 'BE', 'NL', ...)
onRegionClick: function (event, code) {
console.log(code);
}
I found out what was causing the undefined, here's the code that works
jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code ,'ajax=1' ,
function() {Drupal.attachBehaviors('#content');});
hope this helps someone else
I can't find a solution or right example for something that should be quite simple: assign a role to an user when creating it, this is what I'm trying:
$edit = array(
'name' => $_POST['name'],
'pass' => $password,
'mail' => $_POST['email'],
'status' => 0,
'language' => 'es',
'init' => $_POST['email'],
array(2 =>'authenticated', 4=>'my custom role') //as id and named in role db table
);
user_save(NULL, $edit);
The user is not being created, how can I do this?
Thank you
You haven't named the roles member as such. Try his modified version:
$edit = array(
'name' => $_POST['name'],
'pass' => $password,
'mail' => $_POST['email'],
'status' => 0,
'language' => 'es',
'init' => $_POST['email'],
'roles' => array(
2 => 'authenticated',
4 => 'my custom role',
),
);
user_save(NULL, $edit);
And you can use objects to do that.
// Check if user's email is unique
if (!user_load_by_mail($_POST['email'])) {
$account = new stdClass;
$account->name = $_POST['name'];
$account->pass = user_hash_password($password);
$account->mail = $_POST['email'];
$account->status = FALSE;
$account->language = 'es';
$account->init = $_POST['email'];
$account->roles = array(
DRUPAL_AUTHENTICATED_RID => TRUE,
'Your custom role' => TRUE,
);
user_save($account);
}
Here is a hook I've written to add a role to a user when a new user is inserted:
<?php
function MYMODULE_user_insert(&$edit, $account, $category){
if (array_key_exists('profile_1', $account)) {
$is_university = FALSE;
if ($account->profile_sport_club['field_club']['und'][0]['value'] == 1 ) {
$is_university = TRUE;
}
if ($is_university) {
$uid = $account->uid;
$role_name = 'uni_club';
if ($role = user_role_load_by_name($role_name)) {
user_multiple_role_edit(array($uid), 'add_role', $role->rid);
}
}
}
}
?>
Thanks to this tip, it's now much simpler.
function first_user_insert(&$edit, $account, $category, $node){
$uid = $account->uid;
$role_name = 'role name';
if ($role = user_role_load_by_name($role_name)) {
user_multiple_role_edit(array($uid), 'add_role', $role->rid);
}
}
I'm building a module (my_module) in Drupal 7.
It has some functionality and also will create new content type.
In my_module.install I implemented the hook_install (my_module_install).
Can I use more one implementation of hook_install to create new content type (my_cck_install) in this module?
If (yes), how should I do this?
Else: have I do this in another module? :-)
You can't use more than one implementation of hook_install in the same module; in PHP you can't have 2 function with the same name which rules this out.
You would just need to add your new content type in the same hook_install anyway (have a look at how the standard installation profile does it at /profiles/standard/standard.install). This is how I always add new content types from the install file (using the example of a testimonials module):
function testimonial_install() {
// Make sure a testimonial content type doesn't already exist
if (!in_array('testimonial', node_type_get_names())) {
$type = array(
'type' => 'testimonial',
'name' => st('Testimonial'),
'base' => 'node_content',
'custom' => 1,
'modified' => 1,
'locked' => 0,
'title_label' => 'Customer / Client Name'
);
$type = node_type_set_defaults($type);
node_type_save($type);
node_add_body_field($type);
}
}
The following code will create a content type called "Event" with a machine name of 'event' and a title field -
//CREATE NEW CONTENT TYPE
function orderform_node_info() {
return array(
'event' => array(
'name' => t('Event'),
'base' => 'event',
'description' => t('A event content type'),
'has_title' => TRUE
),
);
}
function event_form($node,$form_state) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('event Title'),
'#default_value' => !empty($node->title) ? $node->title : '',
'#required' => TRUE,
'#weight' => -5
);
return $form;
}
//END CONTENT TYPE
you should place it in your .module file... if you want do add additional fields to it, let me know and I'll patch you up with the code... good luck!
/**
* Implements hook_node_info()
*/
function mymodule_node_info() {
return array(
'news' => array(
'name' => t('News'),
'base' => 'news',
'description' => t('You can add News here'),
'has_title' => TRUE,
'title_label' => t('News title')
)
);
}
/**
* Implement hook_form()
*/
function mymodule_form($node, $form_state) {
return node_content_form($node, $form_state);
}
Add the implementation to mymodule.install is as follows:
/**
* Implements hook_install().
*/
function mymodule_install() {
node_types_rebuild();
$types = node_type_get_types();|
node_add_body_field($types['news']);
}
You can get a detailed description with code from here
/*
* Implementation in hook node info in .Module file
*/
function test_node_info() {
return array(
'product' => array(
'name' => t('Product'),
'base' => 'product',
'description' => t('Product Title'),
)
);
}
/**
* Implement hook_form()
*/
function product_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_install() in .install file.
*/
function test_install() {
node_types_rebuild();
$types = node_type_get_types();
node_add_body_field($types['product']);
//New way to implement to add fields in your content type
foreach (_test_installed_fields() as $field) {
field_create_field($field);
}
foreach (_test_installed_instances() as $fieldinstance) {
$fieldinstance['entity_type'] = 'node';
$fieldinstance['bundle'] = 'product';
field_create_instance($fieldinstance);
}
}
/*
* Define your fields
*/
function _test_installed_fields() {
$t = get_t();
return array(
'product_title123' => array(
'field_name' => 'product_title123',
'label' => $t('Product Title'),
'type' => 'text'
),
'description123' => array(
'field_name' => 'description123',
'label' => $t('Description'),
'type' => 'text'
),
);
}
/*
* Define your instance of fields
*/
function _test_installed_instances() {
$t = get_t();
return array(
'product_title123' => array(
'field_name' => 'product_title123',
'type' => 'text',
'label' => $t('Product Title'),
'widget' => array(
'type' => 'text_textfield'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Product Title'),
'type' => 'text'
)
)
),
'description123' => array(
'field_name' => 'description123',
'type' => 'text',
'label' => $t('Description'),
'widget' => array(
'type' => 'text_textarea_with_summary'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Description'),
'type' => 'text'
)
)
),
);
}
/**
* Implements hook_uninstall().
*/
function test_uninstall() {
$ournewtype = 'product';
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => $ournewtype));
$nodeids = array();
foreach ($result as $row) {
$nodeids[] = $row->nid;
}
node_delete_multiple($nodeids);
node_type_delete($ournewtype);
}
That's it.