GithubHelp home page GithubHelp logo

magic-documention's Introduction

Magic Docs

1. Select Data.


where ( fields, value ) - sets the condition of choice.
Multiple calls are united all the conditions with the operator 'AND'.
Option 1: Accept the input field and value. The field should be indicated by a sign of comparison. Value will be automatically quoted.

  1. $app->where('catid =', 5);
  2. $app->where('created >', $last_visit);
  3. // or
  4. $app->where('catid =', 5)->where('created >', $last_visit);

Option 2: Accepts associations are an array of field-value. The field should be indicated by a sign of comparison. Value will be automatically quoted.

  1. $cond = array('catid =' => 5, 'created >' => $last_visit);
  2. $app->where($cond);
Please note: all the conditions in array will be merged with the operator 'AND'.

Option 3: Accepts custom line environment, you must specify the name of the table in front of each field, to avoid any conflict in relationships with other tables. You also have to take care of yourself on preparing values.

  1. $app->where("content.catid = 5 AND content.created > '{$last_visit}'");
  2. // or
  3. $app->where("", "content.catid = 5 AND content.created > '{$last_visit}'"); // 1.5 compat.

Alternative usage

  1. // using OR glue
  2. $app->where('catid', 5);
  3. $app->or_where('created >', $last_visit);
  4.  
  5. // using IN and NOT IN
  6. $app->where('catid', array('5','7','8'); // catid IN ('5','7','8')
  7. $app->where('catid !', array('5','7','8'); // catid NOT IN ('5','7','8')

or_where() - the same as where() method, but multiple calls will be united with operator 'OR'

no_quotes( fields ) - The method allows to cancel the automatic shielding values, so you can use the functions in mysql query. Affects on where expressions and pass_var () method. Takes comma-separated fieldnames or array of fieldnames in first parameter.

  1. $app->no_quotes('created');
  2. $app->pass_var('created','now()');
  3. //or
  4. $app->where('created !=','null');

relation ( field, target_table,target_id, target_name, where, order_by, multi, concat_separator, tree, depend_field, depend_on ) - binds the current table with a list of the other table. Takes as input the name of the field in the current table, the name of the linked table, the link field, the title field , the selection condition for the linked table (optional).

  1. $app->relation('catid','categories','cid','category_name',array('published' => 1));
  2. //or
  3. $app->relation('catid','categories','cid','category_name','categories.published = 1');

Since 1.5.4 relation() has additional parameters:

relation ( field, target_table, target_id, target_name, where_array, order_by, multi, concat_separator, tree, depend_field, depend_on )

  • field - main table relation field, that will be replases; data will be written in this field
  • target_table - related (target) table, options for dropdown will be get from here
  • target_id - row id from target table, will be writen into field
  • target_name - field, that will be displayed as name of dropdown option. This can be array of few fields.
  • where - (optional) - allows to specify selection items from the target_table, see where(). Default is null.
  • order_by - (optional) - order by condition (eg. 'username desc'). Default is by target_name.
  • multi - (optional, boolean) - can change dropdown to multiselect (items will be saved separated by comma). Default is false.
  • concat_separator - (optional) - take effect only when target_name is array. Default is ' '.
  • tree - (optional) - array, sets tree rendering of dropdown list. Options: 1. array('primary_key'=>'some_id_field_name','parent_key'=>'some_field_name') - primary and parent key field name, will be created pk tree. 2. array('left_key'=>'some_field_name','level_key'=>'some_field_name') - left key and level field names, will be created nested sets tree.
  • depend_field - field from current table, options will be extracted based on parent field value ( like country_id column in cities table)
  • depend_on - field, thats will be parent to current dropdown.
You can use {field_tags} in 'where' parameter to get variable from current row

fk_relation(label, field, fk_table, in_fk_field, out_fk_field, rel_tbl, rel_field, rel_name, rel_where, rel_orderby, rel_concat_separator, before, add_data ) - allows to create, manage and display many-to-many connections. The syntax is similar to relation().

  • label - Displaing field label (mus be unique, used as alias)
  • field - connection field from current table
  • fk_table - connection table
  • in_fk_field - field, connected with main table
  • out_fk_field - field, connected with relation table
  • rel_tbl - relation table
  • **rel_field **- connection field from relation table
  • rel_name - field, that will be displayed as name of dropdown option. This can be array of few fields.
  • rel_where - (optional) - allows to specify selection items from the target_table, see where(). Default is null.
  • rel_orderby - (optional) - order by condition (eg. 'username desc'). Default is by rel_name.
  • rel_concat_separator - (optional) - take effect only when rel_name is array. Default is ' '.
  • before - (optional) - if selected, field will be inserted before this field (by default - in the end)
  • add_data (array) - (optional) - additional inserting data

Structure of connections:

  1. table
  2. |- field --|
  3. |
  4. | fk_table
  5. |-- |- in_fk_field
  6. |- out_fk_field --|
  7. |
  8. | rel_table
  9. |-- |- rel_field

nested_table ( inst_name, connect_field, nested_table, nested_connect_field ) - takes instance name in first parameter, main field in second parameter, nested table in third and connection field from nested table in 4th.

Nested tables are using for easy editing of related records in other tables, such as the order and the goods in the order (see demo).

You can specify one nested table for each field of your main table. You can set options for nested tables as well as you do for the main table. Method nested_table () creates an instance of a nested table, access to which can be obtained through the field name (specified in the first parameter of the method nested_table ()), only add to it the prefix nested_.

  1. $app->table('orders'); // main table
  2. $products_list = $app->nested_table('products_list','orderNumber','orderdetails','orderNumber'); // nested table
  3. $products_list->unset_add(); // nested table instance access

search_pattern( '%', '%' ) - allows to define search pattern for grid search. Method replaces default param ($search_pattern) from configuration.

Table joining

magic provide table joining and manipulating with a few tables in one box. You can use extended field syntax, when you type field name (column name or alias) as table and field with dot separator (sample: $app->change_type('order.total', 'price');). You no need to use this when you not use table joining.

join( field, joined_table, join_on_field [, alias] [, not_insert] )

field - field from current table to join; joined_table - table, that is joined; join_on_field - joining on this column from joined table; alias - (optional) - need to use when you join one tabes more than one times.

not_insert - allows to disable inserting and deleting rows from joined table.

  1. $app->table('users');
  2. $app->join('id','profiles','user_id'); // join users and profiles on users.id = profiles.user_id
  3.  
  4. // now join 'profiles' and 'tokens' tables
  5. $app->join('profiles.token_id','tokens','id'); // on profile.token_id = tokens.id
  6.  
  7. // simple actions with fields: default and joined
  8. $app->column('username','email','profile.city','tokens.created');
**join** uses INNER JOIN, thats mean in all tables must be present joined rows. **join** connects only one row from table, joined on fields must be unique. When joined rows in not unique magic will be worked incorrect.

Custom SQL

query( sql_query ) - custom sql query. This method allow you to use custom sql query and display read-only datagrid.

  1. $app = Magic::get_instance();
  2. $app->query('SELECT * FROM users WHERE age > 25');
  3. echo $app->render();

2. Overview table.


columns ( columns, reverse ) - sets the columns that you want to see in the review table. Takes a string, separated by commas, or an array of values. The second optional parameter causes the function to do the opposite, ie hides the selected columns. Takes tru / false, default false.

  1. $app->columns('name,email,city');
  2. //or
  3. $app->columns(array('name','email','city'));
  4.  
  5. // hide columns
  6. $app->columns('name,email,city', true);

order_by ( name, direction ) - sets the initial sorting of the table, take the field and sort order. By default - in ascending order ('asc').

  1. $app->order_by('name','desc');

label ( fieldname, your_label ) - Allows you to specify the name of your columns and fields, takes the field and the field name or an array.

  1. $app->label('name','Your Name');
  2. //or
  3. $app->label(array('name' => 'Your Name'));

column_name( fieldname, your_label ) - the same as label(), but affects only on columns in grid.

show_primary_ai_column ( bool ) - takes true / false, setting the display of primary auto-increment columns in the overview table.

  1. $app->show_primary_ai_column(true);

limit ( int ) - sets the initial limit for display tables, takes an integer in the first argument. The value set by this function is always available in the list to select the number of lines per page.

  1. $app->limit(25);

limit_list ( string_or_array ) - specifies a list of values for the limits list. Takes an array of values, or string. Option 'all' lift a moderate amount of a result (display all rows).

  1. $app->limit_list('5,10,15,all');
  2. //or
  3. $app->limit_list(array('5','10','15','all'));

table_name ( name, tooltip, tooltip_icon ) - Changes the name of the table in the title, takes a string as the first parameter, tooltip text in second parameter (optional) and tooltip icon name in 3rd (optional)

  1. $app->table_name('My custom table!');
  2. $app->table_name('My custom table!', 'Some tooltip text');
  3. $app->table_name('My custom table!', 'Some tooltip text','icon-leaf');

unset_add( true ) - hides add button from list view.

  1. $app->unset_add();

unset_edit( true ) - hide edit button from list view.

  1. $app->unset_edit();

unset_view( true ) - hides view button from list view.

  1. $app->unset_view();

unset_remove( true ) - hide remove button from list view.

  1. $app->unset_remove();

unset_csv( true ) - hides csv-export button from list view.

  1. $app->unset_csv();

unset_search( true ) - hides search feature.

  1. $app->unset_search();

unset_print( true ) - hides printout feature.

  1. $app->unset_print();

unset_title( true ) - hides table title.

  1. $app->unset_title();

unset_numbers( true ) - hides rows numbers.

  1. $app->unset_numbers();

unset_pagination( true ) - hides pagination

  1. $app->unset_pagination();

unset_limitlist( true ) - hides list with limits buttons or dropdown

  1. $app->unset_limitlist();

unset_sortable( true ) - makes columns unsortable

  1. $app->unset_sortable();

unset_list( true ) - turn of grid view. Only details can be viewed or edited. Don't forget to set view parameter in render() method.

  1. $app->unset_list();
**unset_view(), unset_edit(), unset_remove(), duplicate_button()** - this methods can get additional condition parameters (with {field_tags})
  1. $app->unset_edit(true,'username','=','admin'); // 'admin' row can't be editable

remove_confirm( true ) - removes confirmation window on remove action. Takes true / false in the first parameter.

  1. $app->remove_confirm(false);

start_minimized ( true ) - start magic instance minimized. Takes true / false in the first parameter.

  1. $app->start_minimized(true);

benchmark ( true ) - displays information about the performance in the lower right corner of the magic window. Takes true / false in the first parameter.

  1. $app->benchmark(true);

column_cut ( int, [fields] ) - sets the maximum number of characters to be displayed in columns. Takes an integer value in the first parameter. In the second parameter you can define target field(s)

  1. $app->column_cut(30); // all columns
  2. $app->column_cut(30,'title,description'); // separate columns

duplicate_button ( true ) - show duplicate button. You can duplicate only the records in those tables that have auto-incremental primary field, and have no other unique indexes. Otherwise you will get an error.

  1. $app->duplicate_button();

links_label( label ) - creates label for links in grid view. Takes new label in first parameter

  1. $app->links_label('home url');
  2. // or
  3. $app->links_label('<i class="icon-home">'); // bootstrap icon for bootstrap theme

emails_label( label ) - creates label for links in grid view. Takes new label in first parameter

  1. $app->emails_label('Contact email');

sum ( columns, classname, custom_data ) - calculates sum for columns and shows result row in the bottom of table. Calculates sum of the entire list, regardless of pagination. Takes columns list in first parameter, optional classname in second, and optional custom text pattern in third.

  1. $app->sum('price,fee,quantity');
  2. //or
  3. $app->sum(array('price','fee','quantity'));
  4. //or
  5. $app->sum('price','align-center','Total price is {value}'); // use {value} tag to get sum value in pattern

button( link, title, icon, classname, array_of_attributes, condition_array ) - adds custom link in grid, like edit or remove. You can define url in first parameter (required), name (optional) in 2nd, icon(optional) in 3rd, class attribute (optional) in 4th, additional button attributes (assoc array) as 5th.

For icon field you must use predefined classes, this is Icon glyphs for bootstrap theme (e.g. icon-glass, icon-music...).

  1. $app->button('http://example.com');
  2. $app->button('http://example.com','My Title','icon-link','',array('target'=>'_blank'));
  3.  
  4. // {column_tags} usage:
  5. $app->button('http://example.com/{user_id}/?token={user_token}');
You can use buttons with text labels. See $button_labels parameter in configuration file

Also button() supports simple condition in 6th parameter. Condition value supports {field_tags}. Example:

  1. // show button whith link from 'link' field when 'link' field is not empty
  2. $app->button('{link}','userlink','link','','',array('link','!=',''));

highlight( field, operator, value, color, classname ) - adds background color or class attribute for grid cell based on user's condition.

  1. $app->highlight('orderNumber','=','10101','red');
  2. $app->highlight('orderNumber','>=','10113','#87FF6C');
  3. $app->highlight('city','=','Madrid','','main-city'); // you can define class attribute

Also you can get value from current row using {field_tag}

  1. $app->highlight('sum', '>', '{profit}', 'red');

highlight_row**(** field, operator, value, color, classname ) - the same as highlight(), but full row will be highlighted

column_class( column(s), classname ) -  adds class atribute to column(s).

  1. $app->column_class('price,sum,count', 'align-center');

Predefined classes: align-left, align-right, align-center, font-bold, font-italic, text-underline

subselect( column_name, query, before_column ) - select to other table with parameters. This will create new column and inserts it after last column in table, or before colum defined in 3rd parameter

  1. //subselect
  2. $app->subselect('Order total','SELECT SUM(priceEach) FROM orderdetails WHERE orderNumber = {orderNumber}'); // insert as last column
  3. $app->subselect('Products count','SELECT COUNT(*) FROM orderdetails WHERE orderNumber = {orderNumber}','status'); // insert this column before 'status' column
  4.  
  5. // you can use order() and change_type() for this columns;
  6. $app->change_type('Order total','price','',array('prefix'=>'/span>));
  7. $app->order_by('Products count');

Also you can operate with fields only in current row

  1. $app->subselect('Sum','{price}*{qty}');

modal( field(s), icon ) - shows cell info in modal.

  1. $app->modal('customerName,customerDescription);
  2. $app->modal('customerName', 'icon-user');
  3. $app->modal(array('customerName'=>'icon-user'));

column_pattern(column_name, pattern_code)  - replaces default column cell output by custom pattern. Pattern can contain {field_tags} and {value} tag (value of current column)

  1. $app->column_pattern('username','My name is {value}');

Differense between {value} and {username} (see example): {username} will return raw value from current cell, but {value} will return full output if your field has some extra features (like image or formatted price)

field_tooltip( field(s), tooltip_text  [, icon ] ) - creates tooltip icon for field label in create/edit/view mode.

  1. $app->field_tooltip('productName','Enter product name here');

column_tooltip( column(s), tooltip_text  [, icon ] ) - creates tooltip icon for column label in create/edit/view mode.

  1. $app->field_tooltip('productName','Enter product name here');

search_columns( [ column(s) ] [, default_column ] ) - defines column list for search and default search column

  1. $app->search_columns('productVendor,quantityInStock,buyPrice','quantityInStock');

buttons_position( position ) - changes position of grid buttons. Can be 'left', 'right' or 'none'. 'None' option will hide buttons, their features will be available (unlike of unset_ methods). Default is 'right' and can be changed in configuration file.

  1. $app->buttons_position('left');

hide_button( button_name(s) ) - hides system or your custom button ( defined with render_button() method ). This not disables button feature (unlike of unset_ methods).

  1. $app->hide_button('save_return');

Default system buttons are: view, edit, remove, duplicate, add, csv, print, save_new, save_edit, save_return, return.

column_width( column(s), width ) - sets width of magic columns manualy.

  1. $app->column_width('description','65%');
  2. $app->column_width('first_name,last_name','100px');

3. Create / Edit


fields ( field(s), reverse, tab_name, mode ) - the table fields that you want to see when you edit or create entries. Takes a string, separated by commas, or an array of values. The second optional parameter causes the function to do the opposite, ie hides the selected fields. Takes tru / false, default false.

  1. $app->fields('name,email,city');
  2. //or
  3. $app->fields(array('name','email','city'));
  4. // hide fields
  5. $app->fields('name,email,city', true);

You can create tabs for some fields, just set tab name in 3rd parameter:

  1. $app->fields('username,email', false, 'Account info');
  2. $app->fields('country,city,sex,age', false, 'Personal');

Also you can use different columns for different actions (create, edit, view), set action in 4th parameter:

  1. $app->fields('first_name,last_name,country', false, false, 'view');

You can play with combination of this parameters. Tabs is unaviable if second parameter is true.

show_primary_ai_field () - takes true / false, setting the display of primary auto-increment field when editing the entry.

  1. $app->show_primary_ai_field(true);

Primary auto-increment field will be always disabled.

readonly ( field(s), mode ) - Sets the selected fields attribute 'readonly'. Takes a string, separated by commas, or an array of values. Second paremeter sets mode (create, edit), default is all.

  1. $app->readonly('name,email,city');
  2. //or
  3. $app->readonly(array('name','email','city'));

disabled ( field(s), mode ) - Sets the selected fields attribute 'disabled'. Takes a string, separated by commas, or an array of values. Second paremeter sets mode (create, edit), default is all.

  1. $app->disabled('name,email,city');
  2. //or
  3. $app->disabled(array('name','email','city'));
  4.  
  5. // separate screens
  6. $app->disabled('email','edit');

readonly_on_create (), readonly_on_edit (), disabled_on_create (), disabled_on_edit () - do the same thing as the methods above, but allow you to separate the creation and editing. This methods are deprecated and will be deleted.

no_editor ( field(s) ) - allows you to load a text box without an editor (it has an effect when editor is loaded). Takes a string, separated by commas, or an array of values.

  1. $app->no_editor('name,email,city');
  2. //or
  3. $app->no_editor(array('name','email','city'));

change_type ( field(s), type, default, params_or_attr ) - Allows you to change the visual representation of the field. Takes the name of the field, a new type, default value, and an additional parameter (a set of values for lists or the length of the field for the text boxes). Available field types: bool, int, float, text, textarea, texteditor, date, datetime, timestamp, time, year, select, multiselect, password, hidden, file, image, point.

  1. $app->change_type('last_visit','timestamp');
  2. $app->change_type('nickname','text','',20);
  3. $app->change_type('email','multiselect','[email protected]','[email protected],[email protected],[email protected],[email protected],[email protected]');

See more about change_type () in Field types section.

Hidden type will add hidden input in form. Use fields() and pass_var() metods to hide fields and put custom data in your table if you need to preserve your data (pass_var will not add any input).

pass_var ( field, value, mode ) - Allows you to record a variable or data directly in the database, bypassing the add / edit form. The field may not be present in the field, edit field will not affect your data. Function takes the name of the field in the first parameter, and your data, or variable in the second. Optional third parameter is available that allows you to clearly define where you want to paste the data - when creating or editing.

  1. $app->pass_var('user_id', $user_id);
  2. $app->pass_var('created', date('Y-m-d H:i:s'), 'create');
  3. $app->pass_var('was_edited', 'Yes, it was!', 'edit');
  4.  
  5. //using field from current row
  6. $app->pass_var('modified', '{last_action}');

pass_default( field, value ) - pass default value into field, takes the name of the field and default  value, or array in first parameter.

  1. $app->pass_default('name','Joe');
  2. //or
  3. $app->pass_default(array('name' => 'Joe', 'city' => 'Boston'));

condition ( field, operator, value, method, parameter(s) ) - allows you to make some changes based on the data in the form. Takes field in first parameter, operator in second, value in 3rd, in the fourth - the method that is executed when triggered conditions, and in the fifth - the parameter passed to the method. Supported methods: readonly(), readonly_on_create(), readonly_on_edit(), disabled(), disabled_on_create(), disabled_on_edit(), no_editor(), validation_required(), validation_pattern(). Supported operators: =, >, <, >=, <=, !=, ^=, $=, ~=.

  1. $app->condition('access','<','5','disabled','password,email,username');
  2. // if access < 5 than make password, email and username not editable
  3. // or
  4. $app->condition('access','<','5','validation_pattern',array('username','[0-9A-Za-z]+'));

^= - starts with, $= - ends with, ~= - contains.

validation_required ( field(s), chars ) - a simple rule that takes the name of the field and the number of characters (default - 1) or an array.

  1. $app->validation_required('name');
  2. $app->validation_required('city',3);
  3. //or
  4. $app->validation_required(array('name' => 1, 'city' => 3));
  5.  

validation_pattern ( field(s), pattren ) - uses a simple validation pattern to selected fields. Takes the field name and the name of the pattern or array. Available patterns: email, alpha, alpha_numeric, alpha_dash, numeric, integer, decimal, natural. Also you can use your own regular expression in second parameter.

  1. $app->validation_pattern('name', 'alpha');
  2. $app->validation_pattern('email', 'email');
  3. //or
  4. $app->validation_pattern(array('name' => 'alpha', 'email' => 'email'));
  5. // or
  6. $app->validation_pattern('username', '[a-zA-Z]{3,14}');

alert( email_field, cc, subject, body, link ), alert_edit(...), alert_creale(...) - sends emails when data was changed: on create, update or both. Takes email from entry (you must define column in first parameter) and carbon copy list (if defined) from second parameter(can be comma-separated string or array). You must define subject in 3rd and email body in 4th parameter. You can define additional link for email in 5th parameter (optional).

In message body you can use simple tags to retrive some values from row, just write column name in {}.

  1. $app->alert('email','[email protected]','Password changed','Your new password is {password}');
  2. $app->alert_create('email','','Email Testing','Hello!!!!!');

mass_alert(), **mass_**alert_edit(), **mass_**alert_create() - the same like alert(), but it send message to all emails from selected table.

mass_alert(email_table,email_column,email_where,subject,message,link,curent_param,param_value)

  1. $app->mass_alert('user','email','subscribe = 1','Email test','Hello!');

page_call(url, data_array, param, param_value, method), page_call_create(...), page_call_edit(...) - sends http query to another file/page. This method not receive any data. It only sends request when row was added or changed.

You can define any data into data_array, including {field_tags}, this data will be received in target page like $GET or $POST array. If param is defined, method will run only if field value from current row (param) will be equal to param_value. Method defines type of request (get or post), default is get.

  1. $app->page_call('http://mysite/admin/mytarget.php', array('id'=>'{user_id}','text'=>'User {user_name} here!'));
If your site using authorization, you can try to send browser cookie with request. This featue is experimental and can be turn on from configuration file. **BE CAREFUL: DON'T USE IT FOR REQUESTS TO EXTERNAL SITES!!!**

set_attr( field(s), array attr ) - allows to set custom attributes for fields in edit form. field(s) - form field(s), attr - assoc array with attributes.

  1. $app->set_attr('user',array('id'=>'user','data-role'=>'admin'));

4. Field types


Function change_type () a little difficult to understand, because it uses a specific syntax, which varies depending on the task. Let's try to beat these tasks for conventional groups.

The first three parameters are always the same. They take the name of the field, the desired type of field and default value. The third and the fourth parameter is not required. If you do not specify them, will be loaded values by default.

4th parameter - array with type-parameters and/or html attributes. You can use custom html attributes in most of types.

1. Text fields.

This group includes the following types of fields: text, int, float, hidden.

For these types the function of the default value in the third parameter, and the maximum number of characters in the fourth parameter (exclude hidden).

  1. $app->change_type('user_code', 'int', '000', 10); // v1.5 legacy
  2. $app->change_type('user_code', 'int', '000', array('maxlength'=>10)); // v1.6

Use fields() and pass_var() metods to hide fields and put custom data in your table.

2. Multi-line text fields.

This group includes the following types of fields: textarea, texteditor**.**

This types no need any additional parameters.

  1. $app->change_type('user_desc', 'textarea');

3. Date fields.

This group includes the following types of fields: date, datetime, time, year, timestamp.

These types of fields will only accept the default value in the third parameter.

  1. $app->change_type('created', 'datetime', '2012-10-22 07:01:33');

Date range can be used with date type:

  1. $app->change_type('created', 'date', '', array('range_end'=>'end_date')); // this is start date field and it points to end date field
  2. $app->change_type('created', 'date', '', array('range_start'=>'start_date')); // this is end of range date and it points to the start date range date

This will create relation between two date fields.

4. Lists.

This group includes the following types of fields: select, multiselect, radio, checkboxes

These types of fields are set to default in the third argument, and a list of available values, separated by commas, in the second parameter. multiselect can contain several values by default.

  1. $app->change_type('adm_email','select','[email protected]','[email protected],[email protected],[email protected],[email protected],[email protected]');
  2. $app->change_type('fav_color','multiselect','black,white','red,blue,yellow,green,black,white');
  3.  
  4. // v1.6 new syntax
  5. $app->change_type('fav_color','multiselect','black,white', array('values'=>'red,blue,yellow,green,black,white'));

You  can show optgroups in dropdowns. Just us multidimensional array:

  1. $app->change_type('country','select','',array('values'=>array('Europe'=>array('UK'=>'United Kindom','FR'=>'France'),'Asia'=>array('RU'=>'Russia','CH'=>'China'))));

5. Password.

This group includes the following types of fields: password.

Takes the type of hashing in the third parameter (e.g. md5 or sha1 or sha256... , leave blank if you do not want to use hashing) and the maximum number of characters in the fourth. The peculiarity of this field is that it does not load the values and does not store the null value (not allowing you to change the previous one to null). This is due to the fact that passwords are usually encrypted or hashed before being stored in the database.

  1. $app->change_type('user_key', 'password', '', 32);
  2. $app->change_type('user_pass', 'password', 'sha256', 8);
  3. // attributes example
  4. $app->change_type('user_pass', 'password', 'md5', array('maxlength'=>10,'placeholder'=>'enter password'));

6. Upload.

This group includes the following types of fields: file, image.

Takes the path to the upload folder (must exist and be writable) in the third parameter and configuration array in the fourth.

For all uploaded files magic creates a unique name to avoid overwriting, but you can cancel the renaming. In this case, the file name will be brought to the alpha-numeric pattern.

  1. $app->change_type('attach', 'file', '', array('not_rename'=>true));

You can resize the uploaded image, and crop them at different proportions.

  1. $app->change_type('photo','image','',array('width'=>300)); // resize main image
  2. $app->change_type('photo','image','',array('width'=>300, 'height'=>300, 'crop'=>true)); // auto-crop
  3. $app->change_type('photo','image','',array('manual_crop'=>true)); // crop it as you want

You can create a preview picture for your image to be stored in that same folder, and a marker will differ at the end of the name.  You can also specify the size of thumbnails, resize method and subfolder.

Note: 'Manual crop' will crop thumbnails in same proportion as main image

You can add any number of thumbs, you must create subarray in thumbs array  for each thumbnail

  1. $app->change_type('photo','image','',array(
  2. 'thumbs'=>array(
  3. array('width'=> 50, 'marker'=>'_small'),
  4. array('width'=> 100, 'marker'=>'_middle'),
  5. array('width' => 150, 'folder' => 'thumbs' // using 'thumbs' subfolder
  6. )
  7. ));

You can save your image as a binary string in the database. For this field in your database must be of type BLOB, MEDIUMBLOB or LONGBLOB. Thumbnail creation in this case is not available. If you do not know how to extract data from these fields, it is better use the normal load.

  1. $app->change_type('photo','image','',array('blob'=>true));

Uploads parameters:

Files:

  • not_rename - (true/false) - disables auto-renaming of uploaded files
  • text - (string) - display custom file name
  • path - relative or absolute path to uploads folder
  • blob - (true/false) - saves image as binary string in database blob field
  • filename - (string) - name of downloadable file
  • url - (string) -real url to upload folder (optional, if you want to use real links)

Images:

  • not_rename - (true/false) - disables auto-renaming of uploaded files
  • path - relative or absolute path to uploads folder
  • width, height - (integer) - sets dimensions for image, if both is not set image will not been resized
  • crop - (true/false) - image will be cropped (if not set, image will be saved with saving proportions). Both width and height required
  • manual_crop - (true/false) -  Allows to crop image manually
  • ratio - (float) - cropped area ratio (uses with manual_crop)
  • watermark - (string) - relative or absolute path to watermark image
  • watermark_position - (array) - array with two elements (left,top), sets watermark offsets in persents (example: array(95,5) - right top corner)
  • blob - (true/false) - saves image as binary string in database blob field. Thumbnails creation is not available.
  • grid_thumb - (int) - number of thumb, which will be displayed in grid. If not set, original image will be displayed.
  • detail_thumb - (int) - number of thumb, which will be displayed in detail view/create/edit . If not set, original image will be displayed.
  • url - (string) -real url to upload folder (optional, if you want to use real links)
  • thumbs - array of thumb arrays**:**
    • width, height, crop, watermark, watermark_position - see parent
    • marker - (string) - thumbnail marker (if you not set marker or folder, the main image will be replaced with thumbnail)
    • folder - (string) - thumbnail subfolder, relative to uploads folder (if you not set marker or folder, the main image will be replaced with thumbnail)
All paths are always relative to magic's folder

7. Price

This group includes the following types of fields: price.

Takes default value in third parameter and array of parameters in 4th.

  1. $app->change_type('amount', 'price', '5', array('prefix'=>'/span>));

Parameters:

  • max - (integer) - maximal length of text field (create/update), default is 10
  • decimals - (integer) - cout of decimals, default is 2
  • separator - (string) - thousands separator, default is comma (list view)
  • prefix - (string) - prefix for list view
  • suffix - (string) - suffix for list view
  • point - (string) - decimal point for list view

8. Remote images

This group includes the following types of fields: remote_image.

Takes default value in 3rd parameter and link part in 4th (e.g. if your field contains only file name, not full url).

  1. $app->change_type('avatar', 'remote_image');
  2. // or
  3. $app->change_type('avatar', 'remote_image', '', 'http://my-img-host.net/my-folder/');
  4. // 1.6
  5. $app->change_type('avatar', 'remote_image', '', array('link'=>'http://my-img-host.net/my-folder/'));

9. Locations and maps

This group includes the following types of fields: point.

This automatically works with 'POINT' mysql field type. In text field type coordinates will be saved as string separated with comma. 4th parameter gets array with map settings, also you can define them in configuration file to use by default.

  1. $app->change_type('my_location','point','39.909736,-6.679687',array('text'=>'Your are here'));

Parameters:

  • width - (integer) - width of map
  • height - (integer) - height of map
  • zoom - (integer) - map zoom
  • text - (string) - text in info window
  • search_text - (string) - placeholder for search field
  • search - (true/false) - show search field
  • coords - (true/false) - show coordinates field

5. Data manipulation


magic use loadable libraries for data manipulation. You can use static functions in the classes, methods, objects, or simply a set of procedural functions. You need to specify the path to your library functions, and magic it connects itself, when in fact will need. magic will call own functions.php file when path is not defined. magic instance will be always available in your function as last parameter.

**callable** - is callable parameter, if you want to call method from class, you must use an array, e.g. array('class', 'method'). For procedural function just set function name.

$postdata - the object, which represented magic's form data sent to server side. It has three methods:

  • $postdata->get( field ) - returns value of a field or FALSE if field is not exist
  • $postdata->set( field, value ) - sets new value in a field or creates new field in $postdata. Returns nothing. You no need to use unlock_field() method anymore.
  • $postdata->to_array() - returns all data in array.
  • $postdata->del( field ) - removes field from dataset. Be careful, this can make errors in application.

before_insert (callable, path) - allows you to prepare the data before inserting it into the database. Takes an callable in first parameter and the library path in second.  Your function should take postdata object in the first parameter, magic's instance in second and no need to return anything.

  1. // function in functions.php

  2. function hash_password($postdata, $app){

  3. $postdata->set('password', sha1( $postdata->get('password') ));

  4. }

  5. // creating action

  6. $app->before_insert('hash_password'); // automatic call of functions.php

  7. //or

  8. $app->before_insert('hash_password', 'functions.php'); // manualy load

before_update (callable, path) - allows you to prepare the data before updating the records in the database. Takes a callable as the first parameter and the library path in second. Your function should take an array of data in the first parameter and the same return. As well as optionally the primary key in the second parameter.

  1. // function in functions.php

  2. function hash_password($postdata, $primary, $app){

  3. $postdata->set('password', sha1( $postdata->get('password') ));

  4. }

  5. // creating action

  6. $app->before_update('hash_password');

after_insert (callable, path), after_update (callable, path) - allow you to pass data and primary key after upgrading to the custom function. The syntax is the same as in before_update (), except that the function is not obliged to return something.

before_remove (callable, path), after_remove (callable, path) - sends to user-defined function only the primary key record to be deleted in the first parameter. The syntax is the same as in previous examples. User-defined function is not obliged to return something.

  1. // function in functions.php

  2. function delete_user_data($primary, $app){

  3. $db = magic_db::get_instance();

  4. $db->query('DELETE FROM gallery WHERE user_id = ' . $db->escape($primary));

  5. }

  6. // creating action

  7. $app->before_remove('delete_user_data');

column_callback (column, callable, path) - allows you to define custom layer for your column data.

  1. $app->column_callback('name','add_user_icon');

functions.php:

  1. <?php
  2. function add_user_icon($value, $fieldname, $primary_key, $row, $app)
  3. {
  4. return '' . $value;
  5. }
  6. ?>

$row - full current row.

field_callback (field, callable, path) - allows you to define custom layer for your edit field.

  1. $app->field_callback('name','nice_input');

functions.php:

  1. <?php
  2. function nice_input($value, $field, $priimary_key, $list, $app)
  3. {
  4. return '
    '
  5. . '$'
  6. . '<input type="text" name="'.$app->fieldname_encode($fieldname).'" value="'.$value.'" class="magic-input" />'
  7. . '.00'
  8.     . '
';
  • }
  • ?>
  • $list - all fields data

    fieldname_encode() - this encodes field name in compatible format.

    You can use data-required and data-pattern attributes, and unique class.

    Important: you need to use magic-input class for your custom inputs to make its usable by magic.

    replace_insert(callable, path), replase_update(...), replace_remove(...) - replaces standsrt magic actions (insert, update, remove) by custom function. Each of this methods passes in the the target function its parameters.

    Target function for replace_remove()

    1. function remove_replacer($primary_key, $app){ ... }

    Target function for replace_insert()

    1. function insert_replacer($postdata, $app){ ... }

    Target function for replace_update()

    1. function update_replacer($postdata, $primary_key, $app){ ... }

    $app - magic current instance object.

    **replace_insert()** and **replace_update()** methods must return value of primary key!

    call_update( postdata, primary_key )

    You can call magic update method in your replace_insert(), replase_update(), replace_remove() target functions:

    1. $app->call_update($postdata, $primary_key);

    Upload callbacks

    before_upload(c_allable, path_) - runs when files was sent to a server, but not processed yet.

    after_upload(c_allable, path_) - file was uploaded and moved to deinstanation folder (but not resized yet, if image).

    after_resize(c_allable, path_) - file was already resized.  Available only for images.

    Callback function example:

    1. function file_callback($field,$filename,$file_path,$config,$app){
    2. ...
    3. }
    • $field - full field name (table and culumn with dot separator)
    • $filename - name of the file (not available for before_upload())
    • $file_path - full file path with file name (not available for before_upload())
    • $config - array with parameters from change_type() method (4th parameter).
    • $app - magic instance

    Other callbacks

    before_list(c_allable, path_) - can run before grid will be displayed.

    1. // function in functions.php
    2. function before_list_callback($grid_data, $app){
    3. print_r($grid_data);
    4. }

    before_create(c_allable, path_) , before_edit(...), before_view(...) - can run before details view will be displayed.

    1. // function in functions.php (before edit/view)

    2. function before_details_callback($row_data, $primary, $app){

    3. echo $row_data->get('username'); // like 'postdata'

    4. }

    5. // function in functions.php (before create, there is no primary)

    6. function before_details_callback($row_data, $app){

    7. echo $row_data->get('username'); // like 'postdata'

    8. }

    Database instanse

    In all external files you can use magic database instanse:

    1. $db = magic_db::get_instance();
    2. $db->query(...) // executes query, returns count of affected rows
    3. $db->result(); // loads results as list of arrays
    4. $db->row(); // loads one result row as associative array
    5. $var = $db->escape($var); // escapes variable, ads single quotes
    6. $db->insert_id(); // returns last insert id

    Control file type with upload callback (quick sample):

    1. $app->after_upload('after_upload_example');

    functions.php:

    1. function after_upload_example($field, $file_name, $file_path, $params, $app){
    2. $ext = trim(strtolower(strrchr($file_name, '.')), '.');
    3. if($ext != 'pdf' && $field == 'uploads.simple_upload'){ // you can use other check-in
    4. unlink($file_path);
    5. $app->set_exception('simple_upload','This is not PDF','error');
    6. }
    7. }

    Additional variables

    This methods allow you to send custom data in magic's templates or in calback functions.

    set_var( var_name, value ) - set user variable

    get_var( var_name ) - get user variable

    unset_var( var_name ) - unset user variable

    Interactive ajax callbacks

    You can easy create some actions with callback on server side in magic's grid

    First you must create callback (like other callbacks) with method 'create action()'.

    create_action( action_name, callable, [path] ) - action_name - name of your action, callable - name of your callback (function or method), path (optional) - path to your file with function, default is 'functions.php'.

    1. $app->create_action('my_action','my_function');

    Than, create function in your functions.php (or you can use other file)

    1. function my_functions($app){
    2. // some manipulations
    3. }

    Finally, create button or link (or any) with specific class and data attributes. Simpliest button will be:

    1. <button class="magic-action" data-task="action" data-action="my_action">GO!

    This is required. You can define any other data attributes and all of them will be sent with action. To receive them in callback function you must call get() method with your attribute name in parameter (without data- prefix):

    1. function my_functions($app){
    2. $myvalue = $app->get('myvalue'); // data-myvalue attr.
    3. // some manipulations
    4. }

    Returning errors from callback function

    You can do you own validation or something more in any callback function during saving and return user back to form.

    set_exception( [fields] , [text], [message_type] ) - fields - highlighted fields in form, text - error message, message_type - type of error message (error, note, success, info), just css class for message box, default is 'error'.
     All arguments is optional.

    1. // function in functions.php
    2. function hash_password($postdata, $primary, $app){
    3. $pass = $postdata->get('password');
    4. if(preg_match('/[a-zA-Z]+/u',$pass) && preg_match('/[0-9]+/u',$pass)){
    5. $postdata->set('password', sha1( $pass ) );
    6. }
    7. else{
    8. $app->set_exception('password','Your password is too simple.');
    9. }
    10. }

    6. Themes guide


    You can create you own themes and customize standart themes in very simple way.

    Theme structure and files

    magic's theme has 5 required files:

    1. magic_container.php
    2. magic_list_view.php
    3. magic_detail_view.php
    4. magic.ini
    5. magic.css

    magic_container.php - this file is static container for ajax side of magic.  It can be non-styled, but all magic's event are delegated to this container. I not recommend to change something in this file.

    magic_list_view.php - grid rendering.

    magic_detail_view.php - rendering of create/edit/view screen

    magic.ini - List of class names of core html elements, which cannot be changed in theme files.

    magic.css - theme styles.

    All this files will be loaded automatically.

    Global variables in templates

    $mode - shows current action. It can be list, create, edit, view.

    Standart render methods

    Some of render methods can accept **tag** paremeter. It can be a simple string ('div','h1' etc) or array (array('tag'=>'div')). In array you can add any other html attributes (array('tag'=>'a','href'=>'http://example.com')).

    csv_button( classname, icon ) - render csv export button

    print_button( classname, icon ) - render print button button

    add_button( classname, icon ) - render Add button button

    render_limitlist( buttons ) - render dropdown list or buttons with available rows per page. buttons = true - enable buttons instead of dropdown, default is false.

    render_pagination( numbers, offsets ) - pagination; numbers - count of pagination buttons (default is 10); offsets -  first and last buttons offsets (default is 2)

    render_search() - search form

    render_button( name, task, mode_after_task, classname, icon, primary_key ) - sender system action button.

    render_benchmark( tag ) - shows benchmark info. Recomended to put it in the end of template.

    render_grid_head( row_tag, item_tag, arrows_array ) - return grid heading. Arrorws array contains arrows for ordered column. Default is array('asc' => '↑ ', 'desc' => '↓ ')

    render_grid_body( row_tag, item_tag ) - main grid rendering

    render_grid_footer( row_tag, item_tag ) - renders grid footer if available ( eg sum row)

    render_fields_list( mode, container, row, label, field, tabs_container, tabs_menu_container, tabs_menu_row, tabs_menu_link, tabs_content_container, tabs_pane ) - big method, creates details row grid and tabs. Default values: ($mode, $container = 'table', $row = 'tr', $label = 'td', $field = 'td', $tabs_block = 'div', $tabs_head = 'ul', $tabs_row = 'li', $tabs_link = 'a', $tabs_content = 'div', $tabs_pane = 'div'). $mode parameter is required.

    render_table_name( mode, tag, minimized ) - render table heading with table tooltip and toggle arrow. minimized - used only in container file.

    Sending custom variables in template

    set_var( var_name, value ) - set user variable

    get_var( var_name ) - get user variable

    unset_var( var_name ) - unset user variable

    In theme files current instance can be accessed as **$this**, e.g. **$this->get_var('my_var');**

    Relocating template files

    load_view( task, file ) - this method allows you to replace default view file by your custom by task for current instance.

    1. $app->load_view('create','my_custom_create_form.php');

    Your custom theme files must be in your theme folder.

    Creating non-standart rendering

    $this->result_list - array of arrays with full result from database (grid). You can use it to create your own grid rendering.

    $this->result_row - array with full result form database (create/edit/view).

    $this->fields_output - array with rendered fields, exept hidden and additional fields. Every element contains:

    1. label - field name, generated by magic or defined by label() method
    2. name - full field name, used by magic.
    3. value - raw value from database
    4. field - already rendered form field by magic.

    $this->hidden_fields_output - array of rendered hidden fields

    7. Date and time formats


    PHP date format

    Link: http://www.php.net/manual/en/function.date.php

    The format of the outputted date string. See the formatting options below. There are also several predefined date constants that may be used instead, so for example DATE_RSS contains the format string 'D, d M Y H:i:s'.

    **The following characters are recognized in the _`format`_ parameter string**
    _`format`_ character Description Example returned values
    _Day_ --- ---
    _d_ Day of the month, 2 digits with leading zeros _01_ to _31_
    _D_ A textual representation of a day, three letters _Mon_ through _Sun_
    _j_ Day of the month without leading zeros _1_ to _31_
    _l_ (lowercase 'L') A full textual representation of the day of the week _Sunday_ through _Saturday_
    _N_ ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) _1_ (for Monday) through _7_ (for Sunday)
    _S_ English ordinal suffix for the day of the month, 2 characters _st_, _nd_, _rd_ or _th_. Works well with _j_
    _w_ Numeric representation of the day of the week _0_ (for Sunday) through _6_ (for Saturday)
    _z_ The day of the year (starting from 0) _0_ through _365_
    _Week_ --- ---
    _W_ ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) Example: _42_ (the 42nd week in the year)
    _Month_ --- ---
    _F_ A full textual representation of a month, such as January or March _January_ through _December_
    _m_ Numeric representation of a month, with leading zeros _01_ through _12_
    _M_ A short textual representation of a month, three letters _Jan_ through _Dec_
    _n_ Numeric representation of a month, without leading zeros _1_ through _12_
    _t_ Number of days in the given month _28_ through _31_
    _Year_ --- ---
    _L_ Whether it's a leap year _1_ if it is a leap year, _0_ otherwise.
    _o_ ISO-8601 year number. This has the same value as _Y_, except that if the ISO week number (_W_) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0) Examples: _1999_ or _2003_
    _Y_ A full numeric representation of a year, 4 digits Examples: _1999_ or _2003_
    _y_ A two digit representation of a year Examples: _99_ or _03_
    _Time_ --- ---
    _a_ Lowercase Ante meridiem and Post meridiem _am_ or _pm_
    _A_ Uppercase Ante meridiem and Post meridiem _AM_ or _PM_
    _B_ Swatch Internet time _000_ through _999_
    _g_ 12-hour format of an hour without leading zeros _1_ through _12_
    _G_ 24-hour format of an hour without leading zeros _0_ through _23_
    _h_ 12-hour format of an hour with leading zeros _01_ through _12_
    _H_ 24-hour format of an hour with leading zeros _00_ through _23_
    _i_ Minutes with leading zeros _00_ to _59_
    _s_ Seconds, with leading zeros _00_ through _59_
    _u_ Microseconds (added in PHP 5.2.2). Note that **date()** will always generate _000000_ since it takes an [integer](http://www.php.net/manual/en/language.types.integer.php) parameter, whereas [DateTime::format()](http://www.php.net/manual/en/datetime.format.php) does support microseconds. Example: _654321_
    _Timezone_ --- ---
    _e_ Timezone identifier (added in PHP 5.1.0) Examples: _UTC_, _GMT_, _Atlantic/Azores_
    _I_ (capital i) Whether or not the date is in daylight saving time _1_ if Daylight Saving Time, _0_ otherwise.
    _O_ Difference to Greenwich time (GMT) in hours Example: _+0200_
    _P_ Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3) Example: _+02:00_
    _T_ Timezone abbreviation Examples: _EST_, _MDT_ ...
    _Z_ Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. _-43200_ through _50400_
    _Full Date/Time_ --- ---
    _c_ ISO 8601 date (added in PHP 5) 2004-02-12T15:19:21+00:00
    _r_ [» RFC 2822](http://www.faqs.org/rfcs/rfc2822) formatted date Example: _Thu, 21 Dec 2000 16:01:07 +0200_
    _U_ Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) See also [time()](http://www.php.net/manual/en/function.time.php)

    jQuery UI date format

    Link: http://api.jqueryui.com/datepicker/#utility-formatDate

    Link: http://trentrichardson.com/examples/timepicker/

    Format a date into a string value with a specified format.

    The format can be combinations of the following:

    • d - day of month (no leading zero)
    • dd - day of month (two digit)
    • o - day of the year (no leading zeros)
    • oo - day of the year (three digit)
    • D - day name short
    • DD - day name long
    • m - month of year (no leading zero)
    • mm - month of year (two digit)
    • M - month name short
    • MM - month name long
    • y - year (two digit)
    • yy - year (four digit)
    • @ - Unix timestamp (ms since 01/01/1970)
    • ! - Windows ticks (100ns since 01/01/0001)
    • '...' - literal text
    • '' - single quote
    • anything else - literal text

    There are also a number of predefined standard date formats available from $.datepicker:

    • ATOM - 'yy-mm-dd' (Same as RFC 3339/ISO 8601)
    • COOKIE - 'D, dd M yy'
    • ISO_8601 - 'yy-mm-dd'
    • RFC_822 - 'D, d M y' (See RFC 822)
    • RFC_850 - 'DD, dd-M-y' (See RFC 850)
    • RFC_1036 - 'D, d M y' (See RFC 1036)
    • RFC_1123 - 'D, d M yy' (See RFC 1123)
    • RFC_2822 - 'D, d M yy' (See RFC 2822)
    • RSS - 'D, d M y' (Same as RFC 822)
    • TICKS - '!'
    • TIMESTAMP - '@'
    • W3C - 'yy-mm-dd' (Same as ISO 8601)

    Time format

    • H - Hour with no leading 0 (24 hour)
    • HH - Hour with leading 0 (24 hour)
    • h - Hour with no leading 0 (12 hour)
    • hh - Hour with leading 0 (12 hour)
    • m - Minute with no leading 0
    • mm - Minute with leading 0
    • s - Second with no leading 0
    • ss - Second with leading 0
    • l - Milliseconds always with leading 0
    • c - Microseconds always with leading 0
    • t - a or p for AM/PM
    • T - A or P for AM/PM
    • tt - am or pm for AM/PM
    • TT - AM or PM for AM/PM
    • z - Timezone as defined by timezoneList
    • Z - Timezone in Iso 8601 format (+04:45)
    • '...' - Literal text (Uses single quotes)

    magic-documention's People

    Watchers

    James Cloos avatar Rahul G. avatar

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.