Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Managing Legacy Applications With Composer and Laravel

Managing Legacy Applications With Composer and Laravel

All programmers face the challenge of working on a codebase they would've done differently. "I wish I could just start from scratch" you hear them mutter. But is that really the best solution? Is throwing away years of development a good move?

In this talk we will look at the different methods available to upgrade the current spaghetti mess into a well structured Object Orientated dream. Learn how to go about bootstrapping Laravel into your existing codebase, allowing you to slowly upgrade and refactor to a well structured, Composer based MVC system, without any downtime.

Bernhard Breytenbach

September 30, 2016
Tweet

Other Decks in Programming

Transcript

  1. MAINTAINING LEGACY
    APPLICATIONS WITH
    COMPOSER AND
    LARAVEL
    by Bernhard Breytenbach

    View full-size slide

  2. ABOUT ME
    Started with PHP in 2005
    Supporter of all things Open Source!
    https://github.com/Xethron
    Laravel Migrations Generator
    Developer at MDS Technologies
    @BBreyten on Twitter
    joind.in/talk/788d8

    View full-size slide

  3. WHAT IS LEGACY SOFTWARE?
    “The secondary value of software is its
    behaviour... It’s achieved when the current
    software meets the current needs of the
    current user... But the needs of the users
    change, and they do so frequently... Thus the
    primary value of software is its ability to
    change.”
    — Robert C. Martin (Uncle Bob)

    View full-size slide

  4. WHAT IS LEGACY SOFTWARE?
    Legacy software is software that is unable to change easily
    Software that is difficult to read and reuse

    View full-size slide

  5. “DON’T MAINTAIN, REWRITE!”

    View full-size slide

  6. NETSCAPE NAVIGATOR

    View full-size slide

  7. THE DANGERS OF REWRITE

    View full-size slide

  8. REFACTORING
    Refactoring is the process of restructuring
    existing code without changing its external
    behaviour, in order to improve readability and
    reduce code complexity, as to improve source
    code maintainability and create a more
    expressive internal architecture or object
    model to improve extensibility.
    https://en.wikipedia.org/wiki/Code_refactoring

    View full-size slide

  9. RULES OF REFACTORING
    Small iterative changes
    Make sure everything still works
    Send to QA, Push to Production
    Release regularly (weekly at most)
    Do the next small change

    View full-size slide

  10. VERSION CONTROL

    View full-size slide

  11. PICK A CODING STANDARD
    PSR1 / PSR2 / Symfony
    Only one standard
    php-cs-fixer: https://github.com/FriendsOfPhp/PHP-CS-Fixer

    View full-size slide

  12. DIRECTORY STRUCTURE
    public/
    src/
    vendor/
    bootstrap/

    View full-size slide

  13. MOVE FUNCTIONALITY INTO CLASSES
    Get rid of includes
    One class per file
    Files should declare new symbols, or cause side effects, but
    not do both.

    View full-size slide

  14. REPLACE MAGIC NUMBERS WITH CONSTANTS
    i
    f (
    $
    s
    t
    a
    t
    u
    s
    ­
    >
    i
    d =
    =
    = 1
    5
    )
    i
    f (
    $
    u
    s
    e
    r
    ­
    >
    t
    y
    p
    e =
    =
    = 3
    )
    i
    f (
    $
    c
    o
    d
    e =
    =
    = 4
    1
    8
    )
    i
    f (
    $
    s
    t
    a
    t
    u
    s
    ­
    >
    i
    d =
    =
    = S
    t
    a
    t
    u
    s
    :
    :
    C
    A
    N
    C
    E
    L
    L
    E
    D
    )
    i
    f (
    $
    u
    s
    e
    r
    ­
    >
    t
    y
    p
    e =
    =
    = U
    s
    e
    r
    :
    :
    T
    Y
    P
    E
    _
    A
    D
    M
    I
    N
    )
    i
    f (
    $
    c
    o
    d
    e =
    =
    = R
    e
    s
    p
    o
    n
    s
    e
    :
    :
    H
    T
    T
    P
    _
    I
    _
    A
    M
    _
    A
    _
    T
    E
    A
    P
    O
    T
    )

    View full-size slide

  15. BREAK UP LARGE CLASSES/FUNCTIONS
    Large functions is where classes go to hide.

    View full-size slide

  16. PLAN OF ACTION
    Take Charge!
    Baby steps
    Fail fast, fail cheap

    View full-size slide

  17. SETUP AUTOLOADING
    <
    ?
    p
    h
    p
    s
    p
    l
    _
    a
    u
    t
    o
    l
    o
    a
    d
    _
    r
    e
    g
    i
    s
    t
    e
    r
    (
    f
    u
    n
    c
    t
    i
    o
    n (
    $
    c
    l
    a
    s
    s
    )
    {
    $
    p
    r
    e
    f
    i
    x = '
    F
    o
    o
    \
    \
    B
    a
    r
    \
    \
    '
    ;
    $
    b
    a
    s
    e
    _
    d
    i
    r = _
    _
    D
    I
    R
    _
    _ . '
    /
    s
    r
    c
    /
    '
    ;
    $
    l
    e
    n = s
    t
    r
    l
    e
    n
    (
    $
    p
    r
    e
    f
    i
    x
    )
    ;
    i
    f (
    s
    t
    r
    n
    c
    m
    p
    (
    $
    p
    r
    e
    f
    i
    x
    , $
    c
    l
    a
    s
    s
    , $
    l
    e
    n
    ) !
    =
    = 0
    ) {
    r
    e
    t
    u
    r
    n
    ;
    }
    $
    r
    e
    l
    a
    t
    i
    v
    e
    _
    c
    l
    a
    s
    s = s
    u
    b
    s
    t
    r
    (
    $
    c
    l
    a
    s
    s
    , $
    l
    e
    n
    )
    ;
    $
    f
    i
    l
    e = $
    b
    a
    s
    e
    _
    d
    i
    r . s
    t
    r
    _
    r
    e
    p
    l
    a
    c
    e
    (
    '
    \
    \
    '
    , '
    /
    '
    , $
    r
    e
    l
    a
    t
    i
    v
    e
    _
    c
    l
    a
    s
    s
    ) . '
    .
    p
    h
    p
    '
    ;
    /
    / i
    f t
    h
    e f
    i
    l
    e e
    x
    i
    s
    t
    s
    , r
    e
    q
    u
    i
    r
    e i
    t
    i
    f (
    f
    i
    l
    e
    _
    e
    x
    i
    s
    t
    s
    (
    $
    f
    i
    l
    e
    )
    ) {
    r
    e
    q
    u
    i
    r
    e $
    f
    i
    l
    e
    ;
    }
    }
    )
    ;

    View full-size slide

  18. WHAT IS COMPOSER?

    View full-size slide

  19. WHY USE COMPOSER?

    View full-size slide

  20. BUT I CAN WRITE IT MYSELF?

    View full-size slide

  21. SETTING UP COMPOSER

    View full-size slide

  22. BOOTSTRAP COMPOSER
    r
    e
    q
    u
    i
    r
    e "
    v
    e
    n
    d
    o
    r
    /
    a
    u
    t
    o
    l
    o
    a
    d
    .
    p
    h
    p
    "

    View full-size slide

  23. LOAD THIRD PARTY LIBRARIES VIA COMPOSER
    Require third party libraries with Composer
    Look for files using those libraries
    Make sure they require your bootstrapping file

    View full-size slide

  24. COMPOSER AUTOLOADING
    {
    "
    a
    u
    t
    o
    l
    o
    a
    d
    "
    : {
    "
    c
    l
    a
    s
    s
    m
    a
    p
    "
    : [
    "
    l
    e
    g
    a
    c
    y
    ­
    c
    l
    a
    s
    s
    e
    s
    "
    ,
    "
    s
    o
    m
    e
    O
    t
    h
    e
    r
    F
    o
    l
    d
    e
    r
    "
    ]
    ,
    "
    p
    s
    r
    ­
    0
    "
    : {
    "
    M
    d
    s
    \
    \
    C
    o
    l
    l
    i
    v
    e
    r
    y
    "
    :
    "
    m
    y
    ­
    a
    p
    p
    /
    "
    ,
    }
    ,
    "
    p
    s
    r
    ­
    4
    "
    : {
    "
    M
    d
    s
    \
    \
    V
    i
    s
    a
    P
    a
    k
    "
    :
    "
    a
    l
    s
    o
    ­
    m
    y
    ­
    a
    p
    p
    /
    "
    ,
    }
    }
    }

    View full-size slide

  25. START USING OTHER THIRD PARTY LIBRARIES!
    Carbon

    View full-size slide

  26. SETTING UP LARAVEL

    View full-size slide

  27. APACHE
    <
    V
    i
    r
    t
    u
    a
    l
    H
    o
    s
    t *
    :
    8
    0
    >
    D
    o
    c
    u
    m
    e
    n
    t
    R
    o
    o
    t /
    v
    a
    r
    /
    w
    w
    w
    /
    l
    e
    g
    a
    c
    y
    /
    h
    t
    d
    o
    c
    s
    S
    e
    r
    v
    e
    r
    A
    d
    m
    i
    n b
    e
    r
    n
    h
    a
    r
    d
    @
    c
    o
    f
    f
    e
    e
    c
    o
    d
    e
    .
    c
    o
    .
    z
    a
    S
    e
    r
    v
    e
    r
    N
    a
    m
    e w
    w
    w
    .
    l
    e
    g
    a
    c
    y
    .
    l
    o
    c
    a
    l
    S
    e
    r
    v
    e
    r
    A
    l
    i
    a
    s l
    e
    g
    a
    c
    y
    .
    l
    o
    c
    a
    l
    T
    r
    a
    n
    s
    f
    e
    r
    L
    o
    g /
    v
    a
    r
    /
    l
    o
    g
    /
    a
    p
    a
    c
    h
    e
    2
    /
    l
    e
    g
    a
    c
    y
    _
    a
    c
    c
    e
    s
    s
    .
    l
    o
    g
    E
    r
    r
    o
    r
    L
    o
    g /
    v
    a
    r
    /
    l
    o
    g
    /
    a
    p
    a
    c
    h
    e
    2
    /
    l
    e
    g
    a
    c
    y
    _
    e
    r
    r
    o
    r
    .
    l
    o
    g
    <
    D
    i
    r
    e
    c
    t
    o
    r
    y /
    v
    a
    r
    /
    w
    w
    w
    /
    l
    e
    g
    a
    c
    y
    /
    h
    t
    d
    o
    c
    s
    >
    R
    e
    w
    r
    i
    t
    e
    E
    n
    g
    i
    n
    e O
    n
    # R
    e
    d
    i
    r
    e
    c
    t T
    r
    a
    i
    l
    i
    n
    g S
    l
    a
    s
    h
    e
    s
    .
    .
    .
    R
    e
    w
    r
    i
    t
    e
    R
    u
    l
    e ^
    (
    .
    *
    )
    /
    $ /
    $
    1 [
    L
    ,
    R
    =
    3
    0
    1
    ]
    R
    e
    w
    r
    i
    t
    e
    C
    o
    n
    d %
    {
    R
    E
    Q
    U
    E
    S
    T
    _
    F
    I
    L
    E
    N
    A
    M
    E
    } !
    ­
    d
    R
    e
    w
    r
    i
    t
    e
    C
    o
    n
    d %
    {
    R
    E
    Q
    U
    E
    S
    T
    _
    F
    I
    L
    E
    N
    A
    M
    E
    } !
    ­
    f
    R
    e
    w
    r
    i
    t
    e
    R
    u
    l
    e ^ a
    p
    p
    .
    p
    h
    p [
    L
    ]
    <
    /
    D
    i
    r
    e
    c
    t
    o
    r
    y
    >
    <
    /
    V
    i
    r
    t
    u
    a
    l
    H
    o
    s
    t
    >

    View full-size slide

  28. ROUTES
    <
    ?
    p
    h
    p
    R
    o
    u
    t
    e
    :
    :
    g
    e
    t
    (
    '
    r
    e
    g
    i
    s
    t
    e
    r
    '
    , R
    e
    g
    i
    s
    t
    e
    r
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    :
    :
    c
    l
    a
    s
    s
    .
    '
    @
    i
    n
    d
    e
    x
    '
    )
    ;
    R
    o
    u
    t
    e
    :
    :
    g
    e
    t
    (
    '
    r
    e
    g
    i
    s
    t
    e
    r
    .
    p
    h
    p
    '
    , R
    e
    g
    i
    s
    t
    e
    r
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    :
    :
    c
    l
    a
    s
    s
    .
    '
    @
    i
    n
    d
    e
    x
    '
    )
    ;

    View full-size slide

  29. BOOTSTRAPPING LARAVEL
    <
    ?
    p
    h
    p
    u
    s
    e A
    c
    m
    e
    \
    B
    o
    o
    t
    s
    t
    r
    a
    p
    \
    R
    a
    v
    e
    n
    S
    e
    r
    v
    i
    c
    e
    P
    r
    o
    v
    i
    d
    e
    r
    ;
    u
    s
    e I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    i
    l
    e
    s
    y
    s
    t
    e
    m
    \
    F
    i
    l
    e
    s
    y
    s
    t
    e
    m
    ;
    u
    s
    e I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    o
    u
    n
    d
    a
    t
    i
    o
    n
    \
    P
    r
    o
    v
    i
    d
    e
    r
    R
    e
    p
    o
    s
    i
    t
    o
    r
    y
    ;
    u
    s
    e I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    H
    t
    t
    p
    \
    R
    e
    q
    u
    e
    s
    t
    ;
    d
    a
    t
    e
    _
    d
    e
    f
    a
    u
    l
    t
    _
    t
    i
    m
    e
    z
    o
    n
    e
    _
    s
    e
    t
    (
    '
    A
    f
    r
    i
    c
    a
    /
    J
    o
    h
    a
    n
    n
    e
    s
    b
    u
    r
    g
    '
    )
    ;
    r
    e
    q
    u
    i
    r
    e _
    _
    D
    I
    R
    _
    _
    .
    '
    /
    a
    u
    t
    o
    l
    o
    a
    d
    .
    p
    h
    p
    '
    ;
    /
    *
    * @
    v
    a
    r \
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    o
    u
    n
    d
    a
    t
    i
    o
    n
    \
    A
    p
    p
    l
    i
    c
    a
    t
    i
    o
    n $
    a
    p
    p *
    /
    $
    a
    p
    p = r
    e
    q
    u
    i
    r
    e
    _
    o
    n
    c
    e _
    _
    D
    I
    R
    _
    _
    .
    '
    /
    a
    p
    p
    .
    p
    h
    p
    '
    ;
    $
    a
    p
    p
    ­
    >
    i
    n
    s
    t
    a
    n
    c
    e
    (
    '
    r
    e
    q
    u
    e
    s
    t
    '
    , R
    e
    q
    u
    e
    s
    t
    :
    :
    c
    a
    p
    t
    u
    r
    e
    (
    )
    )
    ;
    $
    a
    p
    p
    ­
    >
    b
    o
    o
    t
    s
    t
    r
    a
    p
    W
    i
    t
    h
    (
    [
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    o
    u
    n
    d
    a
    t
    i
    o
    n
    \
    B
    o
    o
    t
    s
    t
    r
    a
    p
    \
    D
    e
    t
    e
    c
    t
    E
    n
    v
    i
    r
    o
    n
    m
    e
    n
    t
    :
    :
    c
    l
    a
    s
    s
    ,
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    o
    u
    n
    d
    a
    t
    i
    o
    n
    \
    B
    o
    o
    t
    s
    t
    r
    a
    p
    \
    L
    o
    a
    d
    C
    o
    n
    f
    i
    g
    u
    r
    a
    t
    i
    o
    n
    :
    :
    c
    l
    a
    s
    s
    ,
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    o
    u
    n
    d
    a
    t
    i
    o
    n
    \
    B
    o
    o
    t
    s
    t
    r
    a
    p
    \
    C
    o
    n
    f
    i
    g
    u
    r
    e
    L
    o
    g
    g
    i
    n
    g
    :
    :
    c
    l
    a
    s
    s
    ,
    A
    c
    m
    e
    \
    B
    o
    o
    t
    s
    t
    r
    a
    p
    \
    H
    a
    n
    d
    l
    e
    E
    x
    c
    e
    p
    t
    i
    o
    n
    s
    :
    :
    c
    l
    a
    s
    s
    ,
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    F
    o
    u
    n
    d
    a
    t
    i
    o
    n
    \
    B
    o
    o
    t
    s
    t
    r
    a
    p
    \
    R
    e
    g
    i
    s
    t
    e
    r
    F
    a
    c
    a
    d
    e
    s
    :
    :
    c
    l
    a
    s
    s
    ,
    ]
    )
    ;
    /
    *

    View full-size slide

  30. USING LARAVEL OUTSIDE OF LARAVEL

    View full-size slide

  31. SIMPLE: REQUESTS/COLLECTIONS
    <
    ?
    p
    h
    p
    i
    f (
    i
    s
    s
    e
    t
    (
    $
    _
    G
    E
    T
    [
    '
    n
    a
    m
    e
    '
    ]
    )
    ) {
    $
    n
    a
    m
    e = $
    _
    G
    E
    T
    [
    '
    n
    a
    m
    e
    '
    ]
    ;
    } e
    l
    s
    e {
    $
    n
    a
    m
    e = '
    D
    e
    m
    o U
    s
    e
    r
    '
    ;
    }
    /
    / ­
    ­
    ­
    $
    n
    a
    m
    e = R
    e
    q
    u
    e
    s
    t
    :
    :
    g
    e
    t
    (
    '
    n
    a
    m
    e
    '
    )
    ;

    View full-size slide

  32. SIMPLE: REQUESTS/COLLECTIONS
    <
    ?
    p
    h
    p
    $
    a
    r
    r
    a
    y = n
    e
    w \
    I
    l
    l
    u
    m
    i
    n
    a
    t
    e
    \
    S
    u
    p
    p
    o
    r
    t
    \
    C
    o
    l
    l
    e
    c
    t
    i
    o
    n
    (
    )
    ;
    $
    a
    r
    r
    a
    y
    ­
    >
    f
    i
    l
    t
    e
    r
    (
    )
    ;
    $
    a
    r
    r
    a
    y
    ­
    >
    m
    a
    p
    (
    )
    ;
    $
    a
    r
    r
    a
    y
    ­
    >
    r
    e
    d
    u
    c
    e
    (
    )
    ;

    View full-size slide

  33. IOC
    <
    ?
    p
    h
    p
    $
    c
    o
    l
    l
    i
    v
    e
    r
    y = a
    p
    p
    (
    '
    c
    o
    l
    l
    i
    v
    e
    r
    y
    '
    )
    ;

    View full-size slide

  34. ELOQUENT/DATABASE
    <
    ?
    p
    h
    p
    $
    u
    s
    e
    r
    s = U
    s
    e
    r
    :
    :
    a
    l
    l
    (
    )
    ;
    D
    B
    :
    :
    c
    o
    n
    n
    e
    c
    t
    i
    o
    n
    (
    '
    m
    y
    s
    q
    l
    '
    )
    ­
    >
    t
    a
    b
    l
    e
    (
    '
    u
    s
    e
    r
    s
    '
    )
    ­
    >
    w
    h
    e
    r
    e
    N
    u
    l
    l
    (
    '
    d
    e
    l
    e
    t
    e
    d
    A
    t
    '
    )
    ­
    >
    g
    e
    t
    (
    )
    ;

    View full-size slide

  35. VIEWS
    <
    ?
    p
    h
    p
    $
    u
    s
    e
    r = A
    u
    t
    h
    :
    :
    u
    s
    e
    r
    (
    )
    ;
    e
    c
    h
    o v
    i
    e
    w
    (
    '
    i
    n
    d
    e
    x
    '
    , c
    o
    m
    p
    a
    c
    t
    (
    '
    u
    s
    e
    r
    '
    )
    )
    ­
    >
    r
    e
    n
    d
    e
    r
    (
    )
    ;

    View full-size slide

  36. EMAILS
    <
    ?
    p
    h
    p
    $
    h
    t
    m
    l
    m
    s
    g
    h
    e
    a
    d = "
    <
    h
    t
    m
    l
    >
    <
    h
    e
    a
    d
    >
    <
    /
    h
    e
    a
    d
    >
    <
    b
    o
    d
    y
    >
    <
    p
    >
    <
    d
    i
    v a
    l
    i
    g
    n
    =
    \
    "
    l
    e
    f
    t
    \
    " w
    i
    d
    t
    h
    =
    \
    "
    6
    0
    0
    p
    t
    ;
    \
    "
    >
    <
    /
    d
    i
    v
    $
    h
    t
    m
    l
    m
    s
    g
    h
    e
    a
    d .
    = "
    <
    p
    >
    <
    s
    p
    a
    n s
    t
    y
    l
    e
    =
    \
    "
    f
    o
    n
    t
    ­
    s
    i
    z
    e
    : 1
    2
    p
    t
    ; f
    o
    n
    t
    ­
    f
    a
    m
    i
    l
    y
    : '
    A
    r
    i
    a
    l
    '
    ,
    '
    s
    a
    n
    s
    ­
    s
    e
    r
    i
    f
    '
    \
    "
    $
    h
    t
    m
    l
    m
    s
    g
    f
    o
    o
    t = "
    <
    s
    p
    a
    n s
    t
    y
    l
    e
    =
    \
    "
    f
    o
    n
    t
    ­
    s
    i
    z
    e
    : 1
    0
    p
    t
    ; f
    o
    n
    t
    ­
    f
    a
    m
    i
    l
    y
    : '
    A
    r
    i
    a
    l
    '
    ,
    '
    s
    a
    n
    s
    ­
    s
    e
    r
    i
    f
    '
    \
    "
    >
    <
    b
    r
    $
    h
    t
    m
    l
    m
    s
    g
    f
    o
    o
    t .
    = "
    <
    s
    p
    a
    n s
    t
    y
    l
    e
    =
    \
    "
    f
    o
    n
    t
    ­
    s
    i
    z
    e
    : 1
    6
    p
    t
    ; f
    o
    n
    t
    ­
    f
    a
    m
    i
    l
    y
    : '
    T
    i
    m
    e
    N
    e
    w
    R
    o
    m
    a
    n
    '
    ,
    '
    s
    a
    n
    s
    ­
    s
    e
    r
    i
    $
    h
    t
    m
    l
    m
    s
    g
    f
    o
    o
    t .
    = "
    <
    b
    r /
    >
    "
    .
    $
    _
    S
    E
    S
    S
    I
    O
    N
    [
    '
    e
    m
    a
    i
    l
    '
    ]
    .
    "
    <
    /
    s
    p
    a
    n
    >
    <
    p
    >
    <
    b
    >
    <
    s
    p
    a
    n s
    t
    y
    l
    e
    =
    \
    "
    f
    o
    n
    t
    ­
    s
    i
    z
    e
    : 1
    0
    p
    t
    ; c
    o
    l
    o
    r
    : n
    a
    v
    y
    ; f
    o
    n
    t
    ­
    f
    a
    m
    i
    l
    y
    : '
    A
    r
    i
    a
    l
    '
    ,
    '
    s
    a
    n
    s
    ­
    s
    e
    r
    i
    f
    '
    \
    "
    >
    <
    p
    >
    <
    b
    >
    <
    s
    p
    a
    n s
    t
    y
    l
    e
    =
    \
    "
    f
    o
    n
    t
    ­
    s
    i
    z
    e
    : 1
    0
    p
    t
    ; c
    o
    l
    o
    r
    : n
    a
    v
    y
    ; f
    o
    n
    t
    ­
    f
    a
    m
    i
    l
    y
    : '
    A
    r
    i
    a
    l
    '
    ,
    '
    s
    a
    n
    s
    ­
    s
    e
    r
    i
    f
    '
    \
    "
    >
    <
    p
    >
    <
    d
    i
    v a
    l
    i
    g
    n
    =
    \
    "
    l
    e
    f
    t
    \
    " w
    i
    d
    t
    h
    =
    \
    "
    6
    0
    0
    p
    t
    ;
    \
    "
    >
    <
    i
    m
    g s
    r
    c
    =
    \
    "
    c
    i
    d
    :
    m
    a
    i
    l
    _
    b
    o
    t
    t
    o
    m
    \
    "
    >
    <
    /
    d
    i
    v
    >
    <
    /
    p
    >
    <
    /
    b
    o
    d
    y
    >
    <
    /
    h
    t
    m
    l
    >
    "
    ;
    i
    n
    c
    l
    u
    d
    e
    _
    o
    n
    c
    e '
    .
    .
    /
    s
    r
    c
    /
    p
    h
    p
    m
    a
    i
    l
    e
    r
    /
    c
    l
    a
    s
    s
    .
    p
    h
    p
    m
    a
    i
    l
    e
    r
    .
    p
    h
    p
    '
    ;
    $
    m
    a
    i
    l = n
    e
    w P
    H
    P
    M
    a
    i
    l
    e
    r (
    t
    r
    u
    e
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    I
    s
    H
    T
    M
    L
    (
    t
    r
    u
    e
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    C
    h
    a
    r
    S
    e
    t = "
    U
    T
    F
    ­
    8
    "
    ;
    t
    r
    y {
    $
    m
    a
    i
    l
    ­
    >
    A
    d
    d
    A
    d
    d
    r
    e
    s
    s
    (
    $
    _
    P
    O
    S
    T [
    '
    e
    m
    a
    i
    l
    '
    ]
    , $
    _
    P
    O
    S
    T [
    '
    n
    a
    m
    e
    '
    ]
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    S
    e
    t
    F
    r
    o
    m
    (
    $
    _
    S
    E
    S
    S
    I
    O
    N [
    '
    e
    m
    a
    i
    l
    '
    ]
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    A
    d
    d
    R
    e
    p
    l
    y
    T
    o
    (
    $
    _
    S
    E
    S
    S
    I
    O
    N [
    '
    e
    m
    a
    i
    l
    '
    ]
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    A
    d
    d
    E
    m
    b
    e
    d
    d
    e
    d
    I
    m
    a
    g
    e
    (
    '
    m
    a
    i
    l
    _
    t
    o
    p
    .
    p
    n
    g
    '
    , '
    m
    a
    i
    l
    _
    t
    o
    p
    '
    , '
    m
    a
    i
    l
    _
    t
    o
    p
    .
    p
    n
    g
    '
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    A
    d
    d
    E
    m
    b
    e
    d
    d
    e
    d
    I
    m
    a
    g
    e
    (
    '
    m
    a
    i
    l
    _
    b
    o
    t
    t
    o
    m
    .
    p
    n
    g
    '
    , '
    m
    a
    i
    l
    _
    b
    o
    t
    t
    o
    m
    '
    , '
    m
    a
    i
    l
    _
    b
    o
    t
    t
    o
    m
    .
    p
    n
    g
    '
    )
    ;
    $
    m
    a
    i
    l
    ­
    >
    S
    u
    b
    j
    e
    c
    t = "
    G
    r
    e
    e
    t
    i
    n
    g
    s P
    H
    P J
    o
    b
    u
    r
    g
    !
    "
    ;
    $
    m
    a
    i
    l
    ­
    >
    M
    s
    g
    H
    T
    M
    L
    (
    $
    h
    t
    m
    l
    m
    s
    g
    h
    e
    a
    d
    .
    "
    "
    .
    n
    l
    2
    b
    r
    (
    $
    _
    P
    O
    S
    T
    [
    '
    m
    e
    s
    s
    a
    g
    e
    '
    ]
    )
    .
    "
    "
    .
    $
    h
    t
    m
    l
    m
    s
    g
    f
    o
    o
    t
    )
    ;

    View full-size slide

  37. EMAILS
    <
    ?
    p
    h
    p
    t
    r
    y {
    $
    d
    a
    t
    a = [
    '
    t
    o
    N
    a
    m
    e
    ' =
    > R
    e
    q
    u
    e
    s
    t
    :
    :
    g
    e
    t
    (
    '
    n
    a
    m
    e
    '
    )
    ,
    '
    f
    r
    o
    m
    N
    a
    m
    e
    ' =
    > $
    _
    S
    E
    S
    S
    I
    O
    N
    [
    '
    n
    a
    m
    e
    '
    ]
    ,
    '
    f
    r
    o
    m
    E
    m
    a
    i
    l
    ' =
    > $
    _
    S
    E
    S
    S
    I
    O
    N
    [
    '
    e
    m
    a
    i
    l
    '
    ]
    ,
    '
    h
    t
    m
    l
    B
    o
    d
    y
    ' =
    > n
    l
    2
    b
    r
    (
    R
    e
    q
    u
    e
    s
    t
    :
    :
    g
    e
    t
    (
    '
    m
    e
    s
    s
    a
    g
    e
    '
    )
    )
    ]
    ;
    M
    a
    i
    l
    :
    :
    s
    e
    n
    d
    (
    '
    e
    m
    a
    i
    l
    s
    .
    s
    t
    a
    n
    d
    a
    r
    d
    '
    , $
    d
    a
    t
    a
    , f
    u
    n
    c
    t
    i
    o
    n (
    M
    e
    s
    s
    a
    g
    e $
    m
    e
    s
    s
    a
    g
    e
    ) {
    $
    m
    e
    s
    s
    a
    g
    e
    ­
    >
    f
    r
    o
    m
    (
    $
    _
    S
    E
    S
    S
    I
    O
    N
    [
    '
    e
    m
    a
    i
    l
    '
    ]
    , $
    _
    S
    E
    S
    S
    I
    O
    N
    [
    '
    n
    a
    m
    e
    '
    ]
    )
    ­
    >
    t
    o
    (
    R
    e
    q
    u
    e
    s
    t
    :
    :
    g
    e
    t
    (
    '
    e
    m
    a
    i
    l
    '
    )
    , R
    e
    q
    u
    e
    s
    t
    :
    :
    g
    e
    t
    (
    '
    n
    a
    m
    e
    '
    )
    )
    ­
    >
    r
    e
    p
    l
    y
    T
    o
    (
    $
    _
    S
    E
    S
    S
    I
    O
    N
    [
    '
    e
    m
    a
    i
    l
    '
    ]
    )
    ­
    >
    s
    u
    b
    j
    e
    c
    t
    (
    '
    G
    r
    e
    e
    t
    i
    n
    g
    s P
    H
    P J
    o
    b
    u
    r
    g
    !
    '
    )
    ;
    }
    )
    ;
    p
    r
    i
    n
    t (
    "
    <
    d
    i
    v c
    l
    a
    s
    s
    =
    \
    "
    s
    u
    c
    c
    e
    s
    s
    \
    "
    >
    E
    m
    a
    i
    l s
    e
    n
    t t
    o <
    b
    >
    "
    .
    R
    e
    q
    u
    e
    s
    t
    :
    :
    g
    e
    t
    (
    '
    n
    a
    m
    e
    '
    )
    .
    "
    <
    /
    b
    > o
    n e
    m
    } c
    a
    t
    c
    h (
    E
    x
    c
    e
    p
    t
    i
    o
    n $
    e
    r
    r
    ) {
    e
    c
    h
    o $
    e
    r
    r
    ­
    >
    g
    e
    t
    M
    e
    s
    s
    a
    g
    e
    (
    )
    ;
    }

    View full-size slide

  38. CONSOLE COMMANDS

    View full-size slide

  39. The key to success is not perfection, but making peace with the
    term good enough, and then moving on.

    View full-size slide