Section03 : Les outils et les facteurs de réussite du CRM
B- Le centre d’appel :
term.php: Este script devolve um formulário para edição de um termo. O formulário é construído através de várias queries à base de dados. Após ser definida a variável $termID=$_REQUEST["term"]; a base de dados é interrogada e caso a condição if ($termID) seja validade como verdadeira a query “SELECT entry.term AS term, entry.language AS lang, entry.gloss AS gloss, entry.part_of_speech AS
pos, entry.multimedia AS mm FROM entry WHERE entry.id='$termID' AND
entry.editable=1;” é executada. A expressão “SELECT * AS” permite criar um nome alternativo para o nome da coluna. Este nome alternativo é utilizado nas variáveis seguintes para que sejam devolvidas linhas em tabela relativas às opções seleccionadas. Por exemplo:
Query:
SELECT entry.term AS term, entry.language AS lang, entry.gloss AS
gloss, entry.part_of_speech AS pos, entry.multimedia AS mm FROM entry
WHERE entry.id='$termID' AND entry.editable=1; Variável:
$pos = $row[pos]; Instrução:
//iniciar menu Part of Speech
?> <tr>
<td width="500" height="20"> <select name='part_of_speech'>
<option value="0"></option> <?php
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){ $option=$row[id];
$value=$row[description];
echo "<option value=\"$option\" ";
if ($option==$pos) echo "selected=\"selected\"";
echo ">$value</option>\n"; }; ?> </select> </td> </tr> Entretanto é criada a primeira parte da tabela que constitui o formulário. A primeira linha do formulário contém duas colunas: a primeira contém o título “Term:” e a segunda contém o termo a inserir/editar através da expressão <input name="term" size="106" value="<?php echo $term;?>"/> incluída na célula (<td>) , em que é impresso o valor da variável $term, isto é, o valor da respectiva coluna “term” na tabela “entry” da base de dados. Seguem‐se os campos que constam da tabela “beta.field_description”. Uma vez que o objectivo é que o utilizador também tome parte da criação da própria estrutura do formulário, optou‐se por que este fosse criado dinamicamente. Assim, no futuro, se o utilizador assim o entender, poderá acrescentar um campo à tabela “beta.field_description” e o mesmo surgirá no formulário dinamicamente. A base de dados é, então, interrogada através de uma query que devolve várias linhas com duas colunas cada, em que a primeira contém o nome do campo existente na tabela e a segunda contém o valor dos campos a serem preenchidos, caso o mesmo já exista na base de dados caso contrário o campo permanecerá vazio:
//query field_description
$query = "SELECT * FROM field_description ORDER BY
90 | Capítulo IV – Desenvolvimento e implementação da plataforma
$result = mysql_query($query); (…)
<?php
while($row = mysql_fetch_array($result, MYSQL_ASSOC)){ $descriptionID=$row[id];
if ($termID){
$query=" SELECT input_value FROM field_value WHERE entry=$termID AND field_description='$descriptionID'";
$values = mysql_fetch_array(mysql_query($query), MYSQL_ASSOC); $value=$values[input_value]; }else{ $value=''; }; ?> <tr>
<td width="100" height="20"><?php echo $row[description]?>:</td> <td width="500" height="20"><textarea name="description_<?php echo
$row[id]?>" rows="1" cols="80"><?php echo "$value";
?></textarea></td> </tr> <?php }; ?>
As caixas de selecção “Language” e “Glossary” são geradas da forma idêntica à caixa de selecção “Part of Speech”, já descrita, sendo que cada uma delas é gerada individualmente no código do ficheiro.
O botão “Insert term” irá permitir a submissão de todos os valores do formulário para a base de dados e chamará o ficheiro “update_term.php”.
update_term.php: Este script será responsável pela inserção da nova informação na tabela. Através da estrutura de controlo “if… else” é executado um bloco de código de forma condicional. Se (if) a expressão (!$termID) for validada como verdadeira, então a query INSERT INTO é executada para a inserção de nova informação na base de dados:
INSERT INTO entry (term, language, gloss, part_of_speech, editable)
VALUES ('$term', '$lang', '$gloss', '$pos', 1)
Caso contrário (else) as tabelas não receberam um novo registo, mas antes será actualizada a informação nas linhas existentes correspondentes à variável $termID através de uma query UPDATE:
UPDATE entry SET term='$term', language='$lang', gloss='$gloss', part_of_speech='$pos' WHERE id='$termID'
Na falha de preenchimento de campos obrigatórios (“Term”, “Glossary”, “Language” e “Part of speech”), o utilizador recebe a indicação que os dados pedidos estão em falta e o script não será executado sem que todos eles estejam preenchidos.
Utilizadores não registados não estão autorizados a inserir termos na base de dados:
//verificação de utilizador com sessão iniciada if($_SESSION[access_level]<5){
(…)
}else{
echo "Guest users are not allowed to insert new terms."; };
No final do bloco de código existe um elemento <meta>, responsável por reencaminhar o utilizador para a anexação de conteúdo multimédia ao termo em questão:
<meta http-equiv="refresh" content="3;URL=ask4multimedia.php? entry=<?php echo $termID ?>" />
92 | Capítulo IV – Desenvolvimento e implementação da plataforma
O atributo http-equiv="refresh" é utilizado como substituto de name="refresh" e identifica o nome de uma propriedade. O atributo content="..." especifica o valor da propriedade "refresh". Em termos práticos é invocada a propriedade "refresh" com o URL “ask4multimedia.php” de acordo com os parâmetros que se seguem ao operador “?”. No caso concreto, o parâmetro passado indica que na base de dados, o campo “entry” terá que corresponder à variável impressa pelo código PHP ($termID).
view_term.php: É ainda possível apenas visualizar o conteúdo de um termo sem que os seus campos estejam abertos para edição. Este script pode ser invocado através de um atributo href presente no ficheiro list_terms.php e é responsável por imprimir todo o conteúdo relacionado com o termo em causa, desde a sua definição até à lista de documentos multimédia que o acompanham. Os documentos anexos ao termo poderão ser reproduzidos através de uma hiperligação gerada para cada um dos documentos existentes. Esta hiperligação executa o documento multimédia em causa e o leitor/reprodutor por defeito existente no computador do utilizador para o tipo de ficheiro em causa é aberto. Existem ainda três hiperligações: uma para editar o termo (update_term.php), outra para o remover (delete_term.php) e ainda outra para fazer uma pesquisa.
delete_term.php: Este script é dos mais complexos pois efectua alterações simultâneas em várias tabelas da base de dados e é responsável pela eliminação de todos os registos referentes a um determinado termo: ao ser eliminado um termo da tabela beta.entry da base de dados, são eliminadas, em simultâneo, outras entradas na base de dados cujo identificador seja igual ao da linha eliminada na tabela beta.entry, nomeadamente: beta.filed_value, beta.docs2entry, beta.translation e beta.entry. A base de dados é interrogada para eliminar cada um dos registos em cada uma das tabelas com um campo “entry” cujo valor seja idêntico ao identificador do campo “term” da tabela entry. Caso cada uma das ocorrências seja de facto eliminada, o utilizador recebe uma mensagem com a confirmação da eliminação do termo, caso contrário, a mensagem recebida indicará que ocorreu um erro:
$query = "DELETE FROM table WHERE entry=$termID";
echo "Term deleted from table.<br>"; }else{
echo "Problems when deleting entry $termID from table"; };
Em todo o caso, só será possível a eliminação de um termo por parte do seu criador, por parte de um professor ou por parte de um administrador.
if($row[creator] == $_SESSION[id] and $row[editable] == 1){ (…)
}else{
echo "You have no permissions to delete this term."; };
list_terms.php: Nesta fase, este script gera um rol de todos os termos existentes na base de dados, no entanto, e numa fase futura, ele gerará uma lista dos termos que correspondam a uma pesquisa efectuada. A tabela gerada contém 5 (cinco) colunas: a primeira coluna contém o valor do termo encontrado na base de dados após esta ser interrogada, a segunda coluna contém o nome do criador do termo em causa e a terceira coluna contém uma hiperligação para a visualização detalhada do termo:
<td width="200" height="20"><?php echo $row[term]?></td> <td width="200" height="20"><?php echo $row[creator]?></td>
<td width="200" height="20"><a href="view_term.php?id=<?php echo $id;
?>">View term</a></td>
No entanto duas das colunas apenas serão geradas caso o utilizador com sessão iniciada seja o criador do termo:
<?php
if($row[creator] == $_SESSION[id] and $row[editable] == 1){
94 | Capítulo IV – Desenvolvimento e implementação da plataforma
<td width="200" height="20"><a href="term.php?id=<?php echo $id;
?>">Edit term</a></td>
<td width="200" height="20"><a href="delete_term.php?id=
<?php echo $id; ?>">Remove term</a></td> <?php }else{ ?> <td width="200" height="20"></td> <td width="200" height="20"></td> <?php }; ?>
4.7.1.6 Gestão de conteúdo multimédia
ask4multimedia.php: Após o preenchimento do formulário de inserção de um termo, é dada a opção ao utilizador de anexar conteúdo multimédia ao termo em questão. Este script é invocado através de um elemento <meta> no final do bloco de código do ficheiro update_term.php, já explicado anteriormente, e contém apenas uma pergunta (“Attach multimedia file to term?”) com duas possibilidades de resposta. Caso o utilizador opte por não adicionar conteúdo multimédia ao termo, voltará ao formulário do termo; no entanto, caso o utilizador opte por anexar conteúdo multimédia, uma hiperligação redireccioná‐lo‐á para um ficheiro responsável pela transferência de ficheiros para o servidor: add_mm.php de acordo com os parâmetros que se seguem ao operador “?”:<a href="add_mm.php?entry=<?php echo $_REQUEST[entry]?>">
Yes
</a>
Os parâmetros passados indicam que será adicionado conteúdo multimédia ao termo cujo identificador na base de dados corresponda à variável $_REQUEST impressa pelo código PHP.
add_mm.php: Este script é invocado quando o utilizador opta por anexar conteúdo multimédia a um termo e de todos os scripts concebidos é o que possui uma maior componente de JavaScript. O elemento <HEAD> … </HEAD> deste documento contém um elemento <SCRIPT> </SCRIPT> cujo atributo “type” tem o valor “text/javascript”. Este bloco de código JavaScript no cabeçalho do documento é responsável pelas múltiplas transferências de ficheiros, limitando o número de transferências a 6 (seis) de cada vez e define a função attachmore() que é invocada cada vez que o utilizador opta por enviar mais um ficheiro. Esta função é também responsável por definir e incrementar o valor da variável “attachmentid” e quando o valor desta for igual ao valor da variável “attachmentlimit” a opção “Add another file” deixa de ser visualizada, ou seja, o utilizador deixa de poder anexar mais documentos.
Através de um formulário, o utilizador tem a possibilidade de seleccionar o tipo de ficheiro multimédia a transferir através de uma caixa de selecção que é gerada a da mesma forma que são geradas as caixas de selecção “Glossary” e “Part of speech” no formulário de inserção/actualização de um termo. Em seguida é possível seleccionar o caminho do directório onde se encontra o ficheiro a anexar e, caso opte por adicionar um outro ficheiro, é invocada a função attachmore(), gerando um novo campo para selecção do directório onde se encontra o ficheiro a anexar e um outro para descrição do ficheiro. Após a anexação dos ficheiros, o utilizador pode submeter o formulário que, por sua vez, invocará um outro script, upload.php, responsável pelo processamento da transferência, tratamento e armazenamento do ficheiro, bem como da inserção da informação nas respectivas tabelas da base de dados.
upload.php: Este script é responsável pelo processo de transferência de ficheiros para o servidor. O directório alvo para a transferência dos ficheiros é estabelecido pela variável $targetpath = "multimediadocs/"; e dependendo do tipo de ficheiro seleccionado pelo utilizador, este será transferido para uma pasta concreta no servidor:
<?php
// configuração do directório alvo para o upload de ficheiros multimédia $targetpath = "multimediadocs/";
for($i=1;$i<=6;$i++){ $mmtypes = 'mmtype_'.$i; (…)
96 | Capítulo IV – Desenvolvimento e implementação da plataforma
//verificar se o nome do ficheiro está vazio
if($FileName != ""){
//verificar tipo de ficheiro seleccionado
$FileType = $_FILES[$attachments]['type'];
if ($_REQUEST[$mmtypes] == 1){
$targetpath = $targetpath."image/"; }elseif ($_REQUEST[$mmtypes] == 2){
$targetpath = $targetpath."movie/"; }elseif ($_REQUEST[$mmtypes] == 3){
$targetpath = $targetpath."sound/"; }else ($_REQUEST[$mmtypes] == 4){
$targetpath = $targetpath."text/"; };
(…)
As seguintes extensões são definidas como suportadas na transferência dos ficheiros: *.gif, *.jpg, *.png, *.swf, *.flv, *.avi, *.wmv, *.mpeg, *.mp3, *.wav e *.wma. Numa fase futura, restringir‐se‐á os tipos de ficheiros às pastas adequadas.
O tamanho máximo de cada um dos ficheiros a anexar é definido através da variável $FileSize à qual é atribuída a função round(), responsável por arredondar um número ao próximo inteiro:
$FileSize = round($_FILES[$attachments]['size']/1024);
Uma vez que o tamanho do ficheiro é calculado em bytes, o arredondamento será efectuado tendo em conta o princípio básico que 1 Megabyte equivale a 1024 Kilobytes e 1Kilobyte equivale a 1024 bytes. Assim, o número de bytes do ficheiro será dividido por 1024 e o resultado ficará registado em Kilobytes. Optou‐se por esta estratégia e não por dividir novamente o valor por 1024, para que a variável responsável pelo resultado pudesse imprimir um valor inteiro na respectiva tabela da base de dados, caso contrário, sempre que um ficheiro tenha apenas poucas dezenas de kilobytes, o valor inserido na base de dados seria 0 (zero). Se
o número inteiro resultante for superior a 10 vezes 1024 (o tamanho máximo em Megabytes permitido para a transferência de um ficheiro), o utilizador recebe uma mensagem de erro, mas caso contrário, o ficheiro é movido para o servidor e são inseridos os valores necessários na base de dados através de uma variável $query:
INSERT INTO docs (relative_path, description, multimedia, file_size, file_extension) VALUES ('$FileLocation', '$description', '$FileSize', '$FileExtension')
Após uma nova interrogação à base de dados para inquirir sobre o máximo valor do identificador na tabela beta.docs, e no caso de uma transferência com sucesso do ficheiro, é adicionalmente registada a relação do ficheiro transferido com o termo em causa na tabela beta.docs2entry através de uma outra variável $query:
INSERT INTO docs2entry (entry, docs, description, mmtype) VALUES ('$entry', '$docs', '$description', '$_REQUEST[$mmtypes]')
Para cada valor registado na tabela e para cada erro ocorrido, é enviada uma mensagem gerada através de código JavaScript e da utilização de métodos como document.getElementById(’elementID’) ou getElementsByTagName('tagName'). O método document.getElementById() pertence ao objecto do documento, o que implica que o escopo do método abarca o documento por inteiro, incluindo o cabeçalho (<HEAD>) e o corpo (<BODY>) de um documento HTML. Por outro lado, o método getElementsByTagName() pode ser invocado em qualquer nó elemento, restringindo a área do DOM a partir da qual se pretende que os nós sejam seleccionados. Por exemplo:
add_mm.php:
document.getElementById('attachmentdiv').appendChild(newnode); (…)
<div id="attachmentdiv" style="margin-left:30px"> (…)
</div>
98 | Capítulo IV – Desenvolvimento e implementação da plataforma
upload.php:
if (mysql_query($query)){
echo "<script type='text/javascript'>parent.document.getElementById ('".$attachmentdiv."').innerHTML = 'File $FileName of type $FileType with size $FileSize Kb, stored in $FileLocation' </script>";
echo "<script type='text/javascript'>parent.document.getElementById ('".$attachmentdiv."').innerHTML += '<br>The relation docs/entry was successful.' </script>"; }(…)
4.7.1.7 Folha de estilo
style.css: O objectivo primário deste script é estabelecer a separação entre a apresentação e o conteúdo. Ele está associado a todos os outros scripts através do elemento <link> dentro da marca <HEAD>…</HEAD>. Este elemento contém os atributos “type", “rel" e “href" e a sua sintaxe completa é a seguinte: <link type="text/css" rel="stylesheet" href="style.css">. Aos vários selectores são atribuídas propriedades e respectivos valores, e o seu conjunto traduz‐se na apresentação da plataforma.
4.8 A plataforma
Após o desenvolvimento dos blocos de código que constituem o esqueleto da plataforma, esta vai começando a ganhar corpo, forma e cor. A personalização da plataforma teve início pela escolha da sua designação.
4.8.1 O nome
Desde a fase de conceptualização da plataforma que houve uma preocupação com o nome que esta teria. Após algumas tentativas através da utilização de anagramas e algumas palavras‐chave, optou‐se por utilizar uma palavra que não tem um significado directo com o objectivo da plataforma, mas com um dos conceitos em que esta assenta.
Optou‐se, então, pelo nome “Beta”. Este nome representa o conceito muito associado à produção de software e aplica‐se, essencialmente, ao conteúdo lógico que já passou uma fase
prévia de testes no seu desenvolvimento e é, então, disponibilizado a uma comunidade de utilizadores enquanto protótipo. A fase beta de testes permite que o software seja sujeito a uma série de variáveis não calculadas e permite que haja um retorno de informação sobre a detecção de erros e problemas que os utilizadores tenham eventualmente efectuado e, consequentemente, a resolução dos mesmos por parte da equipa de desenvolvimento. No entanto, o conceito de “versão beta” de um produto tem ganho outros contornos no decorrer dos últimos anos.
Na Web 2.0, em que os sítios e as aplicações são de natureza dinâmica e estão em constante evolução e adaptação, dificilmente se atinge uma versão final. O facto de as aplicações estarem em rede implica que o retorno de informação por parte dos utilizadores é constante, assim como a resolução de erros e problemas ou implementação de novas funcionalidades. Este procedimento deu origem ao conceito de “beta permanente”, o que implica que os conteúdos e as aplicações estão sujeitos a uma evolução e adequação ad eternum. Algumas marcas adoptaram este conceito durante um longo período de tempo, como foi o caso do Gmail ou do Flickr e algumas marcas ainda hoje o utilizam, como é o caso da rede social Orkut.
4.8.2 O logótipo
De uma forma muito generalista, um logótipo é um símbolo que identifica um produto, bem, serviço, marca, empresa, instituição, etc. e consiste na estilização de uma ou mais letras com um aspecto característico, fixo e peculiar [104.]. Como se trata de uma plataforma para gestão terminológica, optou‐se apenas por construi um logótipo tipográfico em que as letras que o compõem se encontram contornadas por um traço espesso de cor. A escolha da cor, no entanto, foi alvo de maior indecisão, mas temporariamente optou‐se por um logótipo de cor azul, por se tratar de uma cor neutra e sóbria. Tanto a cor sólida como os Figura 30 ‐ Logótipo da plataforma100 | Capítulo IV – Desenvolvimento e implementação da plataforma
tons mais claros que constituem o logótipo fazem parte uma paleta de cores seguras para a Web (ver anexo C): Tabela 6 ‐ Tabela de cores utilizadas no logótipo e respectivas referências por sistema de cor Valores Sist em a Hexadecimal #003366 #99ccff RGB 0 / 51 / 102 153 / 204 / 255 CMYK 100% / 87% / 33% / 23% 35% / 10% / 0% / 0% HSB 210º / 100% / 40% 210º / 40% / 100% Lab 21 / 2 / ‐35 80 / ‐8 / ‐31 As figuras seguintes ilustram mais duas opções de cor. Figura 31 ‐ Logótipo de cor bordeaux Figura 32 ‐ Logótipo de cor verde
4.8.3 Navegação
Uma grande preocupação advinda do inquérito inicial foi a usabilidade da plataforma e a facilidade de navegação na mesma. Um ambiente sóbrio, claro e com pequenos laivos de cor para destaque de pormenores importantes foi o pretendido com a criação da folha de estilo associada a toda a aplicação (style.css).
Optou‐se, também, por um menu superior horizontal e pela ausência de menus verticais, sendo que no futuro poderá ser possível adoptar uma das áreas laterais para pequenos patrocínios, protocolos, parcerias ou outros destaques académicos.
Outros pormenores foram tidos em consideração na concepção da plataforma, tais como a resolução escolhida para as dimensões da plataforma e por que explorador optar para optimização geral.