Controllers

Authentication was moved from the member controller the new AuthController.
User entity created strictly for session management

Symfony config
Service and parameter configuration has been switched to YAML and consolidated into app/config/config.yml
Removed Twig extension from the service container (services.xml)

Presentation
LABJS test added
Some sample js added to test inline js vs callbacks vs Twig/Angular/etc

Tests
New units tests for Landing, Profile, Auth and Member controllers
This commit is contained in:
root
2012-09-24 10:53:36 +10:00
parent 9e4a5f2cb0
commit 0cd92dfa9f
33 changed files with 1460 additions and 119 deletions

45
composer.json Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "symfony/framework-standard-edition",
"description": "The \"Symfony Standard Edition\" distribution",
"autoload": {
"psr-0": { "": "src/" }
},
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"doctrine/doctrine-bundle": "1.0.*",
"twig/extensions": "1.0.*",
"symfony/assetic-bundle": "2.1.*",
"symfony/swiftmailer-bundle": "2.1.*",
"symfony/monolog-bundle": "2.1.*",
"sensio/distribution-bundle": "2.1.*",
"sensio/framework-extra-bundle": "2.1.*",
"sensio/generator-bundle": "2.1.*",
"jms/security-extra-bundle": "1.2.*",
"jms/di-extra-bundle": "1.1.*",
"knplabs/doctrine-behaviors": "dev-master"
},
"scripts": {
"post-install-cmd": [
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
],
"post-update-cmd": [
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
]
},
"config": {
"bin-dir": "bin"
},
"minimum-stability": "dev",
"extra": {
"symfony-app-dir": "app",
"symfony-web-dir": "web"
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace BodyRep\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\RedirectResponse;
# Annotations & templates
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class AuthController extends Controller
{
/**
* @Route("/", name="_auth")
* @Template()
*/
public function indexAction()
{
return new RedirectResponse($this->generateUrl('_login'));
}
/**
/**
* @Route("/login", name="_login")
* @Template()
*/
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('BodyRep:Auth:login.html.twig', array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
/**
* @Route("/login/check", name="_login_check")
* @Template()
*/
public function securityCheckAction()
{
// The security layer will intercept this request
}
/**
* @Route("/logout", name="_logout")
* @Template()
*/
public function logoutAction()
{
// The security layer will intercept this request
}
public function navbarAction()
{
// The security layer will intercept this request
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace BodyRep\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\RedirectResponse;
use JMS\SecurityExtraBundle\Annotation\Secure;
# Annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class CommentController extends Controller
{
/**
* @Route("/", name="_profile")
* @Template()
*/
public function indexAction($username)
{
if ($this->getUser()->getUsername() == $username)
return new RedirectResponse($this->generateUrl('_member_profile'));
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
SELECT p
FROM BodyRep:Profile p
WHERE p.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$profile = $query->getSingleResult();
$username = $this->getUser()->getUsername();
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
SELECT m
FROM BodyRep:Member m
WHERE m.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$member = $query->getSingleResult();
return (array('sFullName' => $profile->getFullName(), 'name' => $member->getFullName()));
}
/**
* @Route("/rep", name="_profile_reputation")
* @Template()
*/
public function reputationAction($username)
{
return $this->indexAction($username);
}
}

View File

@@ -22,6 +22,7 @@ class LandingController extends Controller
* or @Template annotation as demonstrated in DemoController.
*
*/
return $this->render('BodyRep:Landing:index.html.twig');
}

View File

@@ -1,50 +1,63 @@
<?php
namespace BodyRep\Controller;
use BodyRep\Form\Profile;
use Symfony\Component\HttpFoundation\Response;
# Core requirements
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
# use JMS\SecurityExtraBundle\Annotation\Secure;
# Entities
use BodyRep\Form\Profile;
# Annotations & templates
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use JMS\SecurityExtraBundle\Annotation\Secure;
# Ensure container access to member object
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MemberController extends Controller
{
/**
* @Route("/login", name="_login")
* @Template()
*/
public function loginAction()
private $member;
public function setContainer(ContainerInterface $container = null)
{
if ($this->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
parent::setContainer($container);
return array(
'last_username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME),
'error' => $error,
);
# Lookup member if logged in
$user = $this->getUser();
if (method_exists($user, 'getUsername'))
{
$db = $this->getDoctrine()->getManager();
$username = $this->getUser()->getUsername();
$query = $db->createQuery('
SELECT m
FROM BodyRep:Member m
WHERE m.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$this->member = $query->getSingleResult();
}
else
trigger_error("Container cannot determine member information");
}
/**
* @Route("/login_check", name="_security_check")
*/
public function securityCheckAction()
private function getMember()
{
// The security layer will intercept this request
return $this->member;
}
/**
* @Route("/logout", name="_logout")
*/
public function logoutAction()
public function navbarAction()
{
// The security layer will intercept this request
}
@@ -56,20 +69,9 @@ class MemberController extends Controller
public function indexAction()
{
$username = $this->getUser()->getUsername();
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
SELECT m
FROM BodyRep:Member m
WHERE m.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$member = $query->getSingleResult();
return array('name' => $member->getFullName());
return array('name' => $this->getMember()->getFullName());
}
/**
@@ -78,7 +80,7 @@ class MemberController extends Controller
*/
public function profileAction()
{
$username = $this->getUser()->getUsername();
$username = $this->getUser()->getUsername();
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
@@ -91,22 +93,10 @@ class MemberController extends Controller
throw $this->createNotFoundException("User '".$username."' not found");
$profile = $query->getSingleResult();
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
SELECT m
FROM BodyRep:Member m
WHERE m.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$member = $query->getSingleResult();
return (array('sFullName' => $profile->getFullName(), 'name' => $member->getFullName()));
return (array('sFullName' => $profile->getFullName(), 'name' => $this->getMember()->getFullName()));
}
/**
* @Route("/profile/edit", name="_member_profile_edit")
* @Template()
@@ -114,41 +104,19 @@ class MemberController extends Controller
public function editProfileAction()
{
$username = $this->getUser()->getUsername();
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
SELECT m
FROM BodyRep:Member m
WHERE m.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
$form = $this->get('form.factory')->create(new Profile(), array('fullname' => $this->getMember()->getFullName()));
$error = '';
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$member = $query->getSingleResult();
$form = $this->get('form.factory')->create(new Profile(), array('fullname' => $member->getFullName()));
$error = '';
return array('form' => $form->createView(), 'error' => '');
return array('form' => $form->createView(), 'error' => '');
}
/**
/**
* @Route("/profile/save", name="_member_profile_save")
*/
public function saveAction()
{
$username = $this->getUser()->getUsername();
$db = $this->getDoctrine()->getManager();
$query = $db->createQuery('
SELECT m
FROM BodyRep:Member m
WHERE m.username = :username')
->setParameter('username', $username)
->setMaxResults(1);
if (sizeof($query->getResult()) != 1)
throw $this->createNotFoundException("User '".$username."' not found");
$member = $query->getSingleResult();
$json = array('result' => 0);
$form = $this->get('form.factory')->create(new Profile());
@@ -156,18 +124,30 @@ class MemberController extends Controller
$form->bind($request);
$np1 = $request->get('_newpass1');
$np2 = $request->get('_newpass2');
// if (!empty($np1) && !$np1 != $np2)
// $form->get("fullname")->addError(new FormError('Passwords do not match'));
if ($form->isValid())
if ($form->isValid() && sizeof($_POST) > 0)
{
$json['result'] = 1;
if (!empty($np1))
{
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($this->getUser());
$password = $encoder->encodePassword($np1, $this->getUser()->getSalt());
$this->member->setPassword($password);
}
$d = $form->getClientData();
$member->setFullName($d['fullname']);
$db->persist($member);
$this->getMember()->setFullName($d['fullname']);
$db->persist($this->getMember());
$db->flush();
}
$resp = new Response (json_encode($json));
$resp->headers->set('Content-Type', 'text/plain');
$resp->headers->set('Content-Type', 'application/json');
return $resp;
}
@@ -179,7 +159,7 @@ class MemberController extends Controller
{
/*
* Integreted suggester response
* Integrated suggester response
*
*/
$em = $this->getDoctrine()->getManager();
@@ -208,7 +188,5 @@ class MemberController extends Controller
}
else*/
return array('search' => $res);
}
}

View File

@@ -14,11 +14,12 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class ProfileController extends Controller
{
/**
* @Route("/{username}", name="_profile")
* @Route("/", name="_profile")
* @Template()
*/
public function indexAction($username)
{
if ($this->getUser()->getUsername() == $username)
return new RedirectResponse($this->generateUrl('_member_profile'));
@@ -48,10 +49,17 @@ class ProfileController extends Controller
$member = $query->getSingleResult();
return (array('sFullName' => $profile->getFullName(), 'name' => $member->getFullName()));
}
/**
* @Route("/rep", name="_profile_reputation")
* @Template()
*/
public function reputationAction($username)
{
return $this->indexAction($username);
}
}

View File

@@ -3,16 +3,16 @@
namespace BodyRep\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\FileLocator;
#use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
#use Symfony\Component\Config\FileLocator;
class BodyRepExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
#$loader = new YamlFileLoader($container, new FileLocator(__DIR__));
#$loader->load('/data/www/br/src/BodyRep/Resources/config/services.yml');
}
public function getAlias()

View File

@@ -0,0 +1,115 @@
<?php
namespace BodyRep\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="comments")
*/
class Comment
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(name="author", type="string", length=255)
*/
protected $author;
/**
* @ORM\Column(name="text", type="string", length=255)
*/
protected $text;
/**
* @ORM\Column(name="created", type="timestamp")
*/
protected $created;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set author
*
* @param string $author
* @return Comment
*/
public function setAuthor($author)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* @return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* Set text
*
* @param string $text
* @return Comment
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* Set created
*
* @param timestamp $created
* @return Comment
*/
public function setCreated(\timestamp $created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* @return timestamp
*/
public function getCreated()
{
return $this->created;
}
}

View File

@@ -114,6 +114,20 @@ class Member implements UserInterface
return $this;
}
/**
* Set password
*
* @param string $password
* @return Member
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get fullName
*

110
src/BodyRep/Entity/User.php Normal file
View File

@@ -0,0 +1,110 @@
<?php
namespace BodyRep\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="member")
*/
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
protected $username;
/**
* @ORM\Column(name="password", type="string", length=255)
*/
protected $password;
/**
* @ORM\Column(name="salt", type="string", length=255)
*/
protected $salt;
protected $roles = array();
public function getRoles()
{
return $this->roles;
}
public function getSalt()
{
return $this->salt;
}
public function getUsername()
{
return $this->username;
}
public function eraseCredentials()
{
}
public function getPassword()
{
return $this->password;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* @param string $username
* @return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set password
*
* @param string $password
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set salt
*
* @param string $salt
* @return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace BodyRep\Entity;
use Doctrine\ORM\EntityRepository;
/**
* UserRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class UserRepository extends EntityRepository
{
}

View File

@@ -0,0 +1,32 @@
<?php
// FooVendor/BarBundle/EventListener/CommentListener.php
use FooVendorBarBundleEventCommentEvent;
class CommentListener
{
protected $mailer;
public function __construct(Swift_Mailer $mailer)
{
$this->mailer = $mailer;
}
public function onCommentEvent(CommentEvent $event)
{
$post = $event->getPost();
$comment = $event->getComment();
foreach ($post->getSubscribers() as $subscriber) {
$message = Swift_Message::newInstance()
->setSubject('New comment posted on ' . $post->getTitle())
->setFrom('send@example.com')
->setTo($subscriber->getEmail())
->setBody("Hey, somebody left a new comment on a post you're subscribed to! It says: " . $comment->getBody())
;
$this->mailer->send($message);
}
}
}
?>

View File

@@ -23,4 +23,24 @@ class ControllerListener
$this->extension->setController($event->getController());
}
}
public function preExecute(\Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event){
//result returned by the controller
$data = $event->getControllerResult();
//Get the current route
$route = $event->getRequest()->get('_route');
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
$template = $request->get('_template');
$route = $request->get('_route');
if(substr($route,0,7) == 'mobile_'){
$newTemplate = str_replace('html.twig','mobile.html.twig',$template);
//Overwrite original template with the mobile one
$response = $this->templating->renderResponse($newTemplate, $data);
$event->setResponse($response);
}
}
}

View File

@@ -0,0 +1,20 @@
public function preExecute(\Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event){
//result returned by the controller
$data = $event->getControllerResult();
//Get the current route
$route = $event->getRequest()->get('_route');
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
$template = $request->get('_template');
$route = $request->get('_route');
if(substr($route,0,7) == 'mobile_'){
$newTemplate = str_replace('html.twig','mobile.html.twig',$template);
//Overwrite original template with the mobile one
$response = $this->templating->renderResponse($newTemplate, $data);
$event->setResponse($response);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace BodyRep\EventListener;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Security\Core\SecurityContext;
use Doctrine\Bundle\DoctrineBundle\Registry as Doctrine; // for Symfony 2.1.x
// use Symfony\Bundle\DoctrineBundle\Registry as Doctrine; // for Symfony 2.0.x
/**
* Custom login listener.
*/
class LoginListener
{
/** @var \Symfony\Component\Security\Core\SecurityContext */
private $context;
/** @var \Doctrine\ORM\EntityManager */
private $em;
/**
* Constructor
*
* @param SecurityContext $context
* @param Doctrine $doctrine
*/
public function __construct(SecurityContext $context, Doctrine $doctrine)
{
$this->context = $context;
$this->em = $doctrine->getEntityManager();
}
/**
* Do the magic.
*
* @param Event $event
*/
public function onSecurityInteractiveLogin(Event $event)
{
$user = $this->context->getToken()->getUser();
// do all your magic here
}
}
?>

View File

@@ -0,0 +1,34 @@
{% extends 'BodyRep::layout.html.twig' %}
{% block js %}
$(document).ready(function()
{
if($('#username').val().length > 0)
$('#password').focus();
else
$('#username').focus();
});
{% endblock %}
{% block content %}
<h1>Login</h1>
{% if error %}
<div class="error">{{ error.message }}</div>
{% endif %}
<form name='login' action="{{ path("_login_check") }}" method="post" id="login">
<div>
<label for="username">Username</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" />
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" name="_password" />
</div>
<input type="submit" class="btn btn-primary btn-mini" id='loginbtn' value="LOGIN" />
</form>
{% endblock %}

View File

@@ -0,0 +1,35 @@
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<img src="/img/logo-nav.png" class='pull-left' style='padding-right : 5px; margin-top : 10px;' />
<a class="brand" href="#">BODY<b>REP</b></a>
<div class="btn-group pull-right">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#" style="background : transparent; color : white; text-shadow : none; border : none; box-shadow : 0 0 0 #fff;">
<i class="icon-user icon-white"></i> {{name}}
<span class="caret" style='border-top-color : white; border-bottom-color : white;'></span>
</a>
<ul class="dropdown-menu">
<li><a href="{{ path('_member_profile') }}">Profile</a></li>
<li class="divider"></li>
<li><a href="{{ path('_logout') }}">Sign Out</a></li>
</ul>
</div>
<div class='offset2'>
<form class="navbar-search pull-left" id='topsearch' action="{{ path('_member_search') }}">
<input type="text" class="search-query span4" id="topsearch" style='height : 28px;' placeholder="Search"><span id='msg_topsearch'></span>
</form>
</div>
<a class="btn dropdown-toggle pull-right" data-toggle="dropdown" href="#" style="margin : 0; background : transparent; color : white; text-shadow : none; border : none; box-shadow : 0 0 0 #fff;">
<i class='licon-calendar licon-white'></i>
</a>
<a class="btn dropdown-toggle pull-right" data-toggle="dropdown" href="#" style="margin : 0; background : transparent; color : white; text-shadow : none; border : none; box-shadow : 0 0 0 #fff;">
<i class='licon-mail-new licon-white'></i>
</a>
</div>
</div>
</div>

View File

@@ -20,6 +20,6 @@
<div>&nbsp;</div>
{{ form_rest(form) }}
<input type="submit" class="btn btn-primary btn-mini" value="Save" />
<input type="submit" class="btn btn-primary btn-small" value="Save" />
</form>
{% endblock %}

View File

@@ -3,10 +3,11 @@
{% block title "Hello " ~ name %}
{% block content %}
{% include 'BodyRep:Member:navbar.html.twig' %}
{% include 'BodyRep:Auth:navbar.html.twig' %}
<div class='row-fluid'>
<h1>Member landing page</h1>
{{name}}
<h3>{{name}}</h3>
</div>
{% endblock %}

View File

@@ -5,7 +5,7 @@
{% block content_header '' %}
{% block content %}
{% include 'BodyRep:Member:navbar.html.twig' %}
{% include 'BodyRep:Auth:navbar.html.twig' %}
<div class="row-fluid">
<div class="span2">

View File

@@ -0,0 +1,12 @@
{% for comment in comments %}
<div class="user-sub-comment">
<div class='sub-avatar user1'></div>
<a>{{ comment.author }}</a>
<p>{{ comment.text }} </p>
<div class="like-comment-time">
{{ comment.thumbs }}
<i class="icon-comment"></i>
<span>{{ comment.dateHuman }} </span>
</div>
</div>
{% endfor %}

View File

@@ -1,11 +1,18 @@
{% extends 'BodyRep::layout.html.twig' %}
{% block title %}BodyRep{% endblock %}
{% block documentReady %}
$('#rep').live('click', function() {
$.get('{{ path("_profile_reputation", { 'username': app.request.get('username') }) }}', {}, function (data) {
$('#mcnt').html(data);
});
});
{% endblock %}
{% block content_header '' %}
{% block content %}
{% include 'BodyRep:Member:navbar.html.twig' %}
{% include 'BodyRep:Auth:navbar.html.twig' %}
<div class="row-fluid">
<div class="span2">
@@ -13,7 +20,7 @@
<ul class="nav nav-list">
<li class="nav-header">Profile</li>
<li class="active"><a href="#">Body Stats</a></li>
<li><a href="#">Body Reputation</a></li>
<li><a href="#" id='rep'>Body Reputation</a></li>
<li><a href="#">Challenges</a></li>
<li class="nav-header">Workouts</li>
<li class="nav-header">Meals</li>

View File

@@ -0,0 +1,10 @@
{% block js %}
{% endblock %}
{% block content_header '' %}
{% block content %}
<div class="row-fluid">
Reputation page
</div>
{% endblock %}

View File

@@ -8,7 +8,7 @@
<title>{% block title %}BodyRep{% endblock %}</title>
<link rel="stylesheet" href="{{ asset('css/bootstrap.css') }}" media="all" />
<style type="text/css">
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
@@ -17,22 +17,35 @@
padding: 9px 0;
}
</style>
<link rel="stylesheet" href="{{ asset('css/bootstrap-responsive.css') }}" />
<link rel="stylesheet" href="{{ asset('css/site.css') }}" />
<link rel="stylesheet" href="{{ asset('css/chosen.css') }}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<script type="text/javascript" src="{{ asset('js/application.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/jquery.chosen.min.js') }}"></script>
{% block javascripts %}
<script type="text/javascript" src="{{ asset('js/LAB.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/bootstrap.js') }}"></script>
<script type="text/javascript">
var loadb;
$LAB.script('https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js')
.script('//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js')
.script("{{ asset('js/application.js') }}")
.script("{{ asset('js/jquery.chosen.min.js') }}")
.script("{{ asset('js/bootstrap.js') }}").wait(function() {
{% block documentReady %}
{% endblock %}
clearTimeout(loadb);
$('#loadmast').hide();
$('#mast').removeClass('hidden');
});
</script>
{% endblock %}
</head>
<body>
<div id='mast' class='hidden'>
<div class="container-fluid symfony-content">
{% block content %}
@@ -46,8 +59,9 @@
<p>&copy; BodyRep 2012</p>
</footer>
</div><!--/.fluid-container-->
</div>
</div>
<div id='loadmast'><img align="absmiddle" style="margin-left: 10px; margin-bottom: 3px;" src="/img/progress.gif"> Loading</div>
</body>

View File

@@ -0,0 +1,47 @@
<?php
namespace Bodyrep\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\File\File;
class AuthControllerTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient();
$client->followRedirects(true);
$crawler = $client->request('GET', '/u/login');
$this->assertTrue($crawler->filter('html:contains("Username")')->count() > 0);
}
public function testLogin()
{
$client = static::createClient();
$client->followRedirects(true);
$crawler = $client->request('GET', '/u/login');
$form = $crawler->selectButton('loginbtn')->form();
$crawler = $client->submit($form, array(
'_username' => 'alexl',
'_password' => 'd559ko54'
));
$this->assertTrue($crawler->filter('html:contains("Member")')->count() > 0);
}
public function testLogout()
{
$client = static::createClient();
$client->followRedirects(true);
$crawler = $client->request('GET', '/u/logout');
$this->assertTrue($crawler->filter('html:contains("Landing")')->count() > 0);
}
}
?>

View File

@@ -0,0 +1,19 @@
<?php
namespace Bodyrep\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class LandingControllerTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient();
$crawler = $client->request('GET', '/');
$this->assertTrue($crawler->filter('html:contains("Landing Page")')->count() > 0);
}
}
?>

View File

@@ -0,0 +1,45 @@
<?php
namespace Bodyrep\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
class MemberControllerTest extends WebTestCase
{
private $authcrawler;
private $authclient;
function __construct()
{
$this->authclient = static::createClient();
$this->authclient->followRedirects(true);
$this->authcrawler = $this->authclient->request('GET', '/u/login');
$form = $this->authcrawler->selectButton('loginbtn')->form();
$this->authcrawler = $this->authclient->submit($form, array(
'_username' => 'alexl',
'_password' => 'd559ko54'
));
}
public function testIndex()
{
$this->assertTrue($this->authcrawler->filter('html:contains("Member landing")')->count() > 0);
}
public function testEditProfile()
{
$this->authcrawler = $this->authclient->request('GET', '/m/profile');
$this->assertTrue($this->authcrawler->filter('html:contains("Edit Profile")')->count() > 0);
}
}
?>

View File

@@ -0,0 +1,51 @@
<?php
namespace Bodyrep\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
class ProfileControllerTest extends WebTestCase
{
public function testProfile()
{
$client = static::createClient();
$client->followRedirects(true);
$crawler = $client->request('GET', '/u/login');
$form = $crawler->selectButton('loginbtn')->form();
$crawler = $client->submit($form, array(
'_username' => 'alexl',
'_password' => 'd559ko54'
));
$crawler = $client->request('GET', '/alexl');
$this->assertTrue($crawler->filter('html:contains("Alex")')->count() > 0);
}
public function testEditProfile()
{
$client = static::createClient();
$client->followRedirects(true);
$crawler = $client->request('GET', '/u/login');
$form = $crawler->selectButton('loginbtn')->form();
$crawler = $client->submit($form, array(
'_username' => 'alexl',
'_password' => 'd559ko54'
));
$crawler = $client->request('GET', '/alexl');
$this->assertTrue($crawler->filter('html:contains("Alex")')->count() > 0);
}
}
?>

5
web/js/LAB-debug.min.js vendored Executable file

File diff suppressed because one or more lines are too long

5
web/js/LAB.js Executable file

File diff suppressed because one or more lines are too long

5
web/js/LAB.min.js vendored Executable file

File diff suppressed because one or more lines are too long

514
web/js/LAB.src.js Executable file
View File

@@ -0,0 +1,514 @@
/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
v2.0.3 (c) Kyle Simpson
MIT License
*/
(function(global){
var _$LAB = global.$LAB,
// constants for the valid keys of the options object
_UseLocalXHR = "UseLocalXHR",
_AlwaysPreserveOrder = "AlwaysPreserveOrder",
_AllowDuplicates = "AllowDuplicates",
_CacheBust = "CacheBust",
/*!START_DEBUG*/_Debug = "Debug",/*!END_DEBUG*/
_BasePath = "BasePath",
// stateless variables used across all $LAB instances
root_page = /^[^?#]*\//.exec(location.href)[0],
root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0],
append_to = document.head || document.getElementsByTagName("head"),
// inferences... ick, but still necessary
opera_or_gecko = (global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]") || ("MozAppearance" in document.documentElement.style),
/*!START_DEBUG*/
// console.log() and console.error() wrappers
log_msg = function(){},
log_error = log_msg,
/*!END_DEBUG*/
// feature sniffs (yay!)
test_script_elem = document.createElement("script"),
explicit_preloading = typeof test_script_elem.preload == "boolean", // http://wiki.whatwg.org/wiki/Script_Execution_Control#Proposal_1_.28Nicholas_Zakas.29
real_preloading = explicit_preloading || (test_script_elem.readyState && test_script_elem.readyState == "uninitialized"), // will a script preload with `src` set before DOM append?
script_ordered_async = !real_preloading && test_script_elem.async === true, // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
// XHR preloading (same-domain) and cache-preloading (remote-domain) are the fallbacks (for some browsers)
xhr_or_cache_preloading = !real_preloading && !script_ordered_async && !opera_or_gecko
;
/*!START_DEBUG*/
// define console wrapper functions if applicable
if (global.console && global.console.log) {
if (!global.console.error) global.console.error = global.console.log;
log_msg = function(msg) { global.console.log(msg); };
log_error = function(msg,err) { global.console.error(msg,err); };
}
/*!END_DEBUG*/
// test for function
function is_func(func) { return Object.prototype.toString.call(func) == "[object Function]"; }
// test for array
function is_array(arr) { return Object.prototype.toString.call(arr) == "[object Array]"; }
// make script URL absolute/canonical
function canonical_uri(src,base_path) {
var absolute_regex = /^\w+\:\/\//;
// is `src` is protocol-relative (begins with // or ///), prepend protocol
if (/^\/\/\/?/.test(src)) {
src = location.protocol + src;
}
// is `src` page-relative? (not an absolute URL, and not a domain-relative path, beginning with /)
else if (!absolute_regex.test(src) && src.charAt(0) != "/") {
// prepend `base_path`, if any
src = (base_path || "") + src;
}
// make sure to return `src` as absolute
return absolute_regex.test(src) ? src : ((src.charAt(0) == "/" ? root_domain : root_page) + src);
}
// merge `source` into `target`
function merge_objs(source,target) {
for (var k in source) { if (source.hasOwnProperty(k)) {
target[k] = source[k]; // TODO: does this need to be recursive for our purposes?
}}
return target;
}
// does the chain group have any ready-to-execute scripts?
function check_chain_group_scripts_ready(chain_group) {
var any_scripts_ready = false;
for (var i=0; i<chain_group.scripts.length; i++) {
if (chain_group.scripts[i].ready && chain_group.scripts[i].exec_trigger) {
any_scripts_ready = true;
chain_group.scripts[i].exec_trigger();
chain_group.scripts[i].exec_trigger = null;
}
}
return any_scripts_ready;
}
// creates a script load listener
function create_script_load_listener(elem,registry_item,flag,onload) {
elem.onload = elem.onreadystatechange = function() {
if ((elem.readyState && elem.readyState != "complete" && elem.readyState != "loaded") || registry_item[flag]) return;
elem.onload = elem.onreadystatechange = null;
onload();
};
}
// script executed handler
function script_executed(registry_item) {
registry_item.ready = registry_item.finished = true;
for (var i=0; i<registry_item.finished_listeners.length; i++) {
registry_item.finished_listeners[i]();
}
registry_item.ready_listeners = [];
registry_item.finished_listeners = [];
}
// make the request for a scriptha
function request_script(chain_opts,script_obj,registry_item,onload,preload_this_script) {
// setTimeout() "yielding" prevents some weird race/crash conditions in older browsers
setTimeout(function(){
var script, src = script_obj.real_src, xhr;
// don't proceed until `append_to` is ready to append to
if ("item" in append_to) { // check if `append_to` ref is still a live node list
if (!append_to[0]) { // `append_to` node not yet ready
// try again in a little bit -- note: will re-call the anonymous function in the outer setTimeout, not the parent `request_script()`
setTimeout(arguments.callee,25);
return;
}
// reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
append_to = append_to[0];
}
script = document.createElement("script");
if (script_obj.type) script.type = script_obj.type;
if (script_obj.charset) script.charset = script_obj.charset;
// should preloading be used for this script?
if (preload_this_script) {
// real script preloading?
if (real_preloading) {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload: "+src);/*!END_DEBUG*/
registry_item.elem = script;
if (explicit_preloading) { // explicit preloading (aka, Zakas' proposal)
script.preload = true;
script.onpreload = onload;
}
else {
script.onreadystatechange = function(){
if (script.readyState == "loaded") onload();
};
}
script.src = src;
// NOTE: no append to DOM yet, appending will happen when ready to execute
}
// same-domain and XHR allowed? use XHR preloading
else if (preload_this_script && src.indexOf(root_domain) == 0 && chain_opts[_UseLocalXHR]) {
xhr = new XMLHttpRequest(); // note: IE never uses XHR (it supports true preloading), so no more need for ActiveXObject fallback for IE <= 7
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (xhr): "+src);/*!END_DEBUG*/
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
xhr.onreadystatechange = function(){}; // fix a memory leak in IE
registry_item.text = xhr.responseText + "\n//@ sourceURL=" + src; // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
onload();
}
};
xhr.open("GET",src);
xhr.send();
}
// as a last resort, use cache-preloading
else {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (cache): "+src);/*!END_DEBUG*/
script.type = "text/cache-script";
create_script_load_listener(script,registry_item,"ready",function() {
append_to.removeChild(script);
onload();
});
script.src = src;
append_to.insertBefore(script,append_to.firstChild);
}
}
// use async=false for ordered async? parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
else if (script_ordered_async) {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load (ordered async): "+src);/*!END_DEBUG*/
script.async = false;
create_script_load_listener(script,registry_item,"finished",onload);
script.src = src;
append_to.insertBefore(script,append_to.firstChild);
}
// otherwise, just a normal script element
else {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load: "+src);/*!END_DEBUG*/
create_script_load_listener(script,registry_item,"finished",onload);
script.src = src;
append_to.insertBefore(script,append_to.firstChild);
}
},0);
}
// create a clean instance of $LAB
function create_sandbox() {
var global_defaults = {},
can_use_preloading = real_preloading || xhr_or_cache_preloading,
queue = [],
registry = {},
instanceAPI
;
// global defaults
global_defaults[_UseLocalXHR] = true;
global_defaults[_AlwaysPreserveOrder] = false;
global_defaults[_AllowDuplicates] = false;
global_defaults[_CacheBust] = false;
/*!START_DEBUG*/global_defaults[_Debug] = false;/*!END_DEBUG*/
global_defaults[_BasePath] = "";
// execute a script that has been preloaded already
function execute_preloaded_script(chain_opts,script_obj,registry_item) {
var script;
function preload_execute_finished() {
if (script != null) { // make sure this only ever fires once
script = null;
script_executed(registry_item);
}
}
if (registry[script_obj.src].finished) return;
if (!chain_opts[_AllowDuplicates]) registry[script_obj.src].finished = true;
script = registry_item.elem || document.createElement("script");
if (script_obj.type) script.type = script_obj.type;
if (script_obj.charset) script.charset = script_obj.charset;
create_script_load_listener(script,registry_item,"finished",preload_execute_finished);
// script elem was real-preloaded
if (registry_item.elem) {
registry_item.elem = null;
}
// script was XHR preloaded
else if (registry_item.text) {
script.onload = script.onreadystatechange = null; // script injection doesn't fire these events
script.text = registry_item.text;
}
// script was cache-preloaded
else {
script.src = script_obj.real_src;
}
append_to.insertBefore(script,append_to.firstChild);
// manually fire execution callback for injected scripts, since events don't fire
if (registry_item.text) {
preload_execute_finished();
}
}
// process the script request setup
function do_script(chain_opts,script_obj,chain_group,preload_this_script) {
var registry_item,
registry_items,
ready_cb = function(){ script_obj.ready_cb(script_obj,function(){ execute_preloaded_script(chain_opts,script_obj,registry_item); }); },
finished_cb = function(){ script_obj.finished_cb(script_obj,chain_group); }
;
script_obj.src = canonical_uri(script_obj.src,chain_opts[_BasePath]);
script_obj.real_src = script_obj.src +
// append cache-bust param to URL?
(chain_opts[_CacheBust] ? ((/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=") : "")
;
if (!registry[script_obj.src]) registry[script_obj.src] = {items:[],finished:false};
registry_items = registry[script_obj.src].items;
// allowing duplicates, or is this the first recorded load of this script?
if (chain_opts[_AllowDuplicates] || registry_items.length == 0) {
registry_item = registry_items[registry_items.length] = {
ready:false,
finished:false,
ready_listeners:[ready_cb],
finished_listeners:[finished_cb]
};
request_script(chain_opts,script_obj,registry_item,
// which callback type to pass?
(
(preload_this_script) ? // depends on script-preloading
function(){
registry_item.ready = true;
for (var i=0; i<registry_item.ready_listeners.length; i++) {
registry_item.ready_listeners[i]();
}
registry_item.ready_listeners = [];
} :
function(){ script_executed(registry_item); }
),
// signal if script-preloading should be used or not
preload_this_script
);
}
else {
registry_item = registry_items[0];
if (registry_item.finished) {
finished_cb();
}
else {
registry_item.finished_listeners.push(finished_cb);
}
}
}
// creates a closure for each separate chain spawned from this $LAB instance, to keep state cleanly separated between chains
function create_chain() {
var chainedAPI,
chain_opts = merge_objs(global_defaults,{}),
chain = [],
exec_cursor = 0,
scripts_currently_loading = false,
group
;
// called when a script has finished preloading
function chain_script_ready(script_obj,exec_trigger) {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script preload finished: "+script_obj.real_src);/*!END_DEBUG*/
script_obj.ready = true;
script_obj.exec_trigger = exec_trigger;
advance_exec_cursor(); // will only check for 'ready' scripts to be executed
}
// called when a script has finished executing
function chain_script_executed(script_obj,chain_group) {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script execution finished: "+script_obj.real_src);/*!END_DEBUG*/
script_obj.ready = script_obj.finished = true;
script_obj.exec_trigger = null;
// check if chain group is all finished
for (var i=0; i<chain_group.scripts.length; i++) {
if (!chain_group.scripts[i].finished) return;
}
// chain_group is all finished if we get this far
chain_group.finished = true;
advance_exec_cursor();
}
// main driver for executing each part of the chain
function advance_exec_cursor() {
while (exec_cursor < chain.length) {
if (is_func(chain[exec_cursor])) {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("$LAB.wait() executing: "+chain[exec_cursor]);/*!END_DEBUG*/
try { chain[exec_cursor++](); } catch (err) {
/*!START_DEBUG*/if (chain_opts[_Debug]) log_error("$LAB.wait() error caught: ",err);/*!END_DEBUG*/
}
continue;
}
else if (!chain[exec_cursor].finished) {
if (check_chain_group_scripts_ready(chain[exec_cursor])) continue;
break;
}
exec_cursor++;
}
// we've reached the end of the chain (so far)
if (exec_cursor == chain.length) {
scripts_currently_loading = false;
group = false;
}
}
// setup next chain script group
function init_script_chain_group() {
if (!group || !group.scripts) {
chain.push(group = {scripts:[],finished:true});
}
}
// API for $LAB chains
chainedAPI = {
// start loading one or more scripts
script:function(){
for (var i=0; i<arguments.length; i++) {
(function(script_obj,script_list){
var splice_args;
if (!is_array(script_obj)) {
script_list = [script_obj];
}
for (var j=0; j<script_list.length; j++) {
init_script_chain_group();
script_obj = script_list[j];
if (is_func(script_obj)) script_obj = script_obj();
if (!script_obj) continue;
if (is_array(script_obj)) {
// set up an array of arguments to pass to splice()
splice_args = [].slice.call(script_obj); // first include the actual array elements we want to splice in
splice_args.unshift(j,1); // next, put the `index` and `howMany` parameters onto the beginning of the splice-arguments array
[].splice.apply(script_list,splice_args); // use the splice-arguments array as arguments for splice()
j--; // adjust `j` to account for the loop's subsequent `j++`, so that the next loop iteration uses the same `j` index value
continue;
}
if (typeof script_obj == "string") script_obj = {src:script_obj};
script_obj = merge_objs(script_obj,{
ready:false,
ready_cb:chain_script_ready,
finished:false,
finished_cb:chain_script_executed
});
group.finished = false;
group.scripts.push(script_obj);
do_script(chain_opts,script_obj,group,(can_use_preloading && scripts_currently_loading));
scripts_currently_loading = true;
if (chain_opts[_AlwaysPreserveOrder]) chainedAPI.wait();
}
})(arguments[i],arguments[i]);
}
return chainedAPI;
},
// force LABjs to pause in execution at this point in the chain, until the execution thus far finishes, before proceeding
wait:function(){
if (arguments.length > 0) {
for (var i=0; i<arguments.length; i++) {
chain.push(arguments[i]);
}
group = chain[chain.length-1];
}
else group = false;
advance_exec_cursor();
return chainedAPI;
}
};
// the first chain link API (includes `setOptions` only this first time)
return {
script:chainedAPI.script,
wait:chainedAPI.wait,
setOptions:function(opts){
merge_objs(opts,chain_opts);
return chainedAPI;
}
};
}
// API for each initial $LAB instance (before chaining starts)
instanceAPI = {
// main API functions
setGlobalDefaults:function(opts){
merge_objs(opts,global_defaults);
return instanceAPI;
},
setOptions:function(){
return create_chain().setOptions.apply(null,arguments);
},
script:function(){
return create_chain().script.apply(null,arguments);
},
wait:function(){
return create_chain().wait.apply(null,arguments);
},
// built-in queuing for $LAB `script()` and `wait()` calls
// useful for building up a chain programmatically across various script locations, and simulating
// execution of the chain
queueScript:function(){
queue[queue.length] = {type:"script", args:[].slice.call(arguments)};
return instanceAPI;
},
queueWait:function(){
queue[queue.length] = {type:"wait", args:[].slice.call(arguments)};
return instanceAPI;
},
runQueue:function(){
var $L = instanceAPI, len=queue.length, i=len, val;
for (;--i>=0;) {
val = queue.shift();
$L = $L[val.type].apply(null,val.args);
}
return $L;
},
// rollback `[global].$LAB` to what it was before this file was loaded, the return this current instance of $LAB
noConflict:function(){
global.$LAB = _$LAB;
return instanceAPI;
},
// create another clean instance of $LAB
sandbox:function(){
return create_sandbox();
}
};
return instanceAPI;
}
// create the main instance of $LAB
global.$LAB = create_sandbox();
/* The following "hack" was suggested by Andrea Giammarchi and adapted from: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
NOTE: this hack only operates in FF and then only in versions where document.readyState is not present (FF < 3.6?).
The hack essentially "patches" the **page** that LABjs is loaded onto so that it has a proper conforming document.readyState, so that if a script which does
proper and safe dom-ready detection is loaded onto a page, after dom-ready has passed, it will still be able to detect this state, by inspecting the now hacked
document.readyState property. The loaded script in question can then immediately trigger any queued code executions that were waiting for the DOM to be ready.
For instance, jQuery 1.4+ has been patched to take advantage of document.readyState, which is enabled by this hack. But 1.3.2 and before are **not** safe or
fixed by this hack, and should therefore **not** be lazy-loaded by script loader tools such as LABjs.
*/
(function(addEvent,domLoaded,handler){
if (document.readyState == null && document[addEvent]){
document.readyState = "loading";
document[addEvent](domLoaded,handler = function(){
document.removeEventListener(domLoaded,handler,false);
document.readyState = "complete";
},false);
}
})("addEventListener","DOMContentLoaded");
})(this);

View File

@@ -9,17 +9,17 @@ $(function() {
frm = $(this);
var searchTerm = frm.find('input').val();
url = frm.attr('action') + '/'+searchTerm;
$.get(url, {}, function(data) {
$.get(url, {}, function(data) {
$('.symfony-content > .row-fluid').html(data);
});
return false;
});
$('form#profile').live('submit', function(){
frm = $(this);
$.post(frm.attr('action'), frm.serialize(), function(data) {
response = $.parseJSON(data);
$.post(frm.attr('action'), frm.serialize(), function(response) {
if(response.result)
$('#mcnt').append('Updated');
$('#mcnt').append('<b>Updated</b>');
});
return false;
});