# Coppermine Photo Gallery v1.5.x: Documentation and Manual

# Coding guidelines

## Target audience

This part of the documentation is not meant for end users of Coppermine, but only for developers. There is no support for this section, it comes as-is.

End users who wish to modify their copy of coppermine are encouraged to stick to these guidelines as well.

## Scope

As Coppermine is a team effort, the team members who contribute code need to make sure that the code remains easy to read, understand and maintain. That's why there is a set of rules defined on this page that should be taken into account when working with the coppermine core code. Although this part of the documentation is aimed at dev team members, users who plan to contribute their code in any form are requested to respect the rules as well if possible (i.e. if you understand them fully).

The coding guidelines on this page are not set in stone - if you (as a dev team member) find during development that one of the guidelines needs review or change, start a thread on the dev board for discussion.

## Indentation

- Use an indent of 4 spaces, with no tabs. Most editors can be configured to do this.
- Don't be afraid to use blank lines between logical "sections" of code, but don't use too many because it makes it too spaced out

## Encoding

Encoding standard in Coppermine is UTF-8 without BOM. All non-binary files should be encoded in UTF-8 (Unicode).

## General guidelines

- In queries or code, always have spaces before and after operators

## PHP code

### Formatting

- Equals sign should be aligned with surrounding elements
  Bad example:

      $pic_title = 'My picture';
      $album = 'lastup';
      $update_time = true;

  Good Example:

      $pic_title   = 'My picture';
      $album       = 'lastup';
      $update_time = true;

- Array with multiple values cannot be declared on a single line. However if there is only one value then it can be declared in same line
- Always put comma after last value in array declaration
- Always allign array double arrow in a single line and there should be a single space after the arrow (before value)
- Each line in an array declaration must end in a comma
  Bad examples:

      $foo = array('one', 'two', 'three');

      $bar = array(
      'one' => 1, 'two' => 3,
      'three' => 3
      );

      $multi = array('first' => 'one', 'second' => array('2'), 'third' => array('foo' => 'bar', 'hello' => 'world'));

  Good Examples:

      $foo = array(
              'one',
              'two',
              'three',
             );

      $bar = array(
              'one'   => 1,
              'two'   => 2,
              'three' => 3,
             );

      $multi = array(
                'first'  => 'one',
                'second' => array('2'), // Since it is just one value in array, it can be declared in same line
                'third'  => array(
                             'foo'   => 'bar',
                             'hello' => 'world',
                            ),
               );

- Use `echo` instead of `print`
- Use single quotes instead of double quotes
  Bad:

      $foo_array["bla"] = "whatever";

  Good:

      $foo_array['bla'] = 'whatever';

- Don't use spaces or capitalization in associative array definitions
  Bad:

      $bla_array['foo Bar'] = 'some string';

  Good:

      $bla_array['foo_bar'] = 'some string';

### Control Structures

These include `if`, `for`, `while`, `switch`.

- Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls
- Always use curly braces, even in situations where they are technically optional - having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added
- Always have a newline before an opening or closing brace
  Bad example:

      if ($foo = 'bar') { echo 'Hello world'; }

  Bad example:

      if ($foo = 'bar')
      { echo 'Hello world'; }

  Good example:

      if ($foo = 'bar') {
          echo 'Hello world';
      }

  Good example:

      if ($foo = 'bar')
      {
          echo 'Hello world';
      }

### Function Calls

- Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter, spaces between commas and each parameter, and no space between the last parameter, the closing parenthesis, and the semicolon.
- There should be one space on either side of an equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, more space may be inserted to promote readability.

### Function Definitions

- Function definitions follow the "one true brace" convention:

      <?php

      function fooFunction($arg1, $arg2 = '')
      {
          if (condition) {
              statement;
          }
          return $val;
      }

      ?>

- Arguments with default values must be at the end of the argument list
- There should be two blank lines above and below the function declration
- Do not use functions that do not exist in PHP4.3 or lower (and don't use functions that have been removed later either!) unless you define them for those versions.

### PHP Code Tags

- Always use `<?php ?>` to delimit PHP code, not the `<? ?>` shorthand, as the long version will work on all server setups, but the short version might not work everywhere.

### Nesting of HTML in PHP

When more than one line of HTML needs to be printed, the heredoc syntax should be used instead of ending the PHP processing and starting it later.

Good:

    // PHP content here
    if ($foo == $bar) {
    	print <<< EOT
    	<h1>Hello {$bla}</h1>
    EOT;
    }

Bad:

    // PHP content here
    if ($foo == $bar) {
    	?>
    	<h1>Hello <?php echo $bla; ?></h1>
    <?php
    }

### Line breaks

To echo line breaks to the HTML output, use the heredoc syntax or use the variable `$LINEBREAK` instead of hardcoding line breaks into the code.

Remember to make the variable `$LINEBREAK` global inside functions.

Good:

    echo '<h1>Hello world</h1>' . $LINEBREAK;
    echo '<p>foo bar</p>';
    }

Bad:

    echo "<h1>Hello world</h1>\n";
    echo '<p>foo bar</p>';
    }

### Naming Conventions

- Functions should always be named in lowercase and using the underscore notation eg: `function_name()`
- Variables also follow the same conventions (lowercase and using the underscore notation), however globally accessed variables should be UPPERCASE (eg: `$CONFIG`)
- Superglobals (e.g. $_GET or $_POST) need to be sanitized using Inspekt - refer to the section "Sanitization of Superglobals using Inspekt"
- Constants should be defined in UPPERCASE with underscore separation of words
- Filenames should also follow the same underscore convention and be all lowercase
- As always, descriptive names (for folders/files/functions/variables/constants) are much better than "$egYtesIopnfer" type ones. (except when using counters, $i, etc.)

For plugin authors there is a more detailed naming conventions section available that describes package names as well.

## Database queries

- Always free MySQL result resources. (as well as other resources!)
- In queries, always capitalize commands: `SELECT`, `INSERT`, `REPLACE`, `UPDATE`, `DELETE`, etc. should be all uppercase
- In queries, always capitalize `WHERE`, `AND`, `OR`, `LIMIT`, `FROM`, `JOIN`, `AS`, `ON`, etc.
- Avoid field names that are also keywords in MySQL
- Do not use any features of MySQL not available in MySQL 3.23.4 and lower
- Optimize all queries for MySQL 4, although they as above should work in lower
- Use `LIMIT` for queries whenever possible
- `LEFT JOIN`s are slower than regular `JOIN`s (or commas) so they should be avoided if possible
- It's not `messages as m`, but `messages AS m`, because `AS` is a MySQL keyword
- When doing a `JOIN`, the joined table's column(s) come first in the `ON` clause

## Documentation

- Keep correct inline documentation at the tops of files
- Keep the documentation/comments at the tops of files limited to a width of 80 characters
- Start each comment line with a capital letter, and use proper grammar. (periods at the end and all!)
- There is a sub-section of the developer documentation that deals with editing the documentation - please pay attention to it
- There are special steps required when adding a config option - please pay attention to the corresponding section of the docs.

## HTML output

- Always close input, img, hr, and other elements that can't contain anything. (`<tagname />`)
- Coppermine is aimed to be web standards compliant, so you should always try to come up with output that qualifies as valid HTML and CSS. Especially the output that the gallery visitor (and the search engine spiders) see should clearly be valid; output that only the admin will see can be less strict (although you should try to come up with valid output for the admin as well). There is one exception to this standards-compliance rule: if standards-compliant code breaks core functionality for major browsers like the current implementation of object embedding that is not standards compliant because of IE5.x " misbehaving" in standards-compliant mode, it is acceptable to create output that doesn't validate. If this is the case, make sure to at least make others aware of this (known issues section of the docs is the best place, but at least add some comment to the code).
- Make sure that there are no unescaped `&`-signs (ampersands) in the HTML output. Ampersands must always be escaped as `&amp;`.
- `<` and `>`-signs that are meant to be actually displayed in the output (that do not compose tags) must be encoded as `&lt;` and `&gt;`
- Keep all id attributes unique, and try to keep id and name the same if both are specified

### Image-tags in HTML output

- Always put an alt attribute on all image elements, even if the alt is empty
- The border attribute is mandatory - if ommitted, older browsers will display a border by default
- If possible (i.e. if the dimension of an image is known already), use the width and height attributes
- do not use title for the purpose of alt, only use it when a title is needed (like for icons)
- If you need a blind gif, use the one that already comes with coppermine (`./images/spacer.gif`) instead of coming up with a new one for your custom theme, plugin or whatever

### Links in HTML output

- Never use the target attribute at all, it's invalid. Use `<a href="http://example.com/" rel="external" class="external">` instead. The end user can then easily use JavaScript to make external links open in a new window if he wishes to do so.

### Form elements in HTML output

- It is mandatory to use particular CSS classes for certain form elements:
  - `<input type="text" class="textinput" />`
  - `<input type="submit" class="button" />`
  - `<input type="radio" class="radio" />`
  - `<input type="checkbox" class="checkbox" />`
  - `<select class="listbox" />`

### Deprecated tags

Deprecated HTML tags like `<font>` mustn't be introduced into Coppermine unless there is a valid, documented reason to do so.

### Prefered tags

The popular tags `<b>` and `<i>` are considered to be deprecated tags as well. Because of their popularity, browsers will probably support them for a long time. However, there are better alternatives. For `<b>`, the replacement tag is `<strong>`. For `<i>`, the replacement tag is `<em>`. If possible, the replacement tags should be used both in HTML output generated by Coppermine as well as the documentation.

## Credits for coding guidelines

The core rules on this page have been sketched by Dr. Tarique Sani as a subset of the PEAR coding guidelines. HTML output and database sections are based on a thread created by Unknown W. Brackets from Simplemachines.

## Usability

Good coding skills are important, but it's as well important to code efficiently in terms of usability.

### Forms

#### Less clicks are better

Dropdown lists are great if there are a lot of options to choose from, but they are bad if there are only two or three options: the user needs to click on the dropdown list to find out what options exist.
Instead of coming up with a select box like
it's more intuitive for the user to display all possible options using radio buttons:
Go to first Remain where you are Jump to last
If you just want a toggle to switch an option on or off, use the checkbox like
Display graph
instead of
Display graph: Yes No
or even

#### Bigger target areas for clicks

It can be comparatively hard to hit a single checkbox or radio button - that's why the HTML tag `<label>` was invented: if you use it wisely, the text that corresponds to a particular option represented by a checkbox or radio button can be clicked on to toggle the checkbox / radio button.

Bad example | Good example
--- | ---
Output Go to first Remain where you are Jump to last Code <input type="radio" name="option_nolabel" value="0" class="radio" checked="checked" />Go to first<br /> <input type="radio" name="option_nolabel" value="1" class="radio" />Remain where you are<br /> <input type="radio" name="option_nolabel" value="2" class="radio" />Jump to last | Output Go to first Remain where you are Jump to last Code <input type="radio" name="option_label" id="option_label0" value="0" class="radio" checked="checked" /> <label for="option_label0" class="clickable_option">Go to first</label><br /> <input type="radio" name="option_label" id="option_label1" value="1" class="radio" /> <label for="option_label1" class="clickable_option">Remain where you are</label><br /> <input type="radio" name="option_label" id="option_label2" value="2" class="radio" /> <label for="option_label2" class="clickable_option">Jump to last</label>
Output Display graph Code <input type="checkbox" name="display_graph_nolabel" value="1" class="checkbox" />Display graph | Output Display graph Code <input type="checkbox" name="display_graph_label" id="display_graph_label" value="1" class="checkbox" /><label for="display_graph_label" class="clickable_option">Display graph</label>
Click on the words next to the radio buttons to see the difference!